25 integer(I4B),
pointer :: nlay => null()
26 integer(I4B),
pointer :: ncpl => null()
27 integer(I4B),
pointer :: nvert => null()
28 real(dp),
dimension(:, :),
pointer,
contiguous :: vertices => null()
29 real(dp),
dimension(:, :),
pointer,
contiguous :: cellxy => null()
30 integer(I4B),
dimension(:),
pointer,
contiguous :: iavert => null()
31 integer(I4B),
dimension(:),
pointer,
contiguous :: javert => null()
32 real(dp),
dimension(:),
pointer,
contiguous :: top1d => null()
33 real(dp),
dimension(:, :),
pointer,
contiguous :: bot2d => null()
34 integer(I4B),
dimension(:, :),
pointer,
contiguous :: idomain => null()
85 logical :: length_units = .false.
86 logical :: nogrb = .false.
87 logical :: xorigin = .false.
88 logical :: yorigin = .false.
89 logical :: angrot = .false.
90 logical :: nlay = .false.
91 logical :: ncpl = .false.
92 logical :: nvert = .false.
93 logical :: top = .false.
94 logical :: botm = .false.
95 logical :: idomain = .false.
96 logical :: iv = .false.
97 logical :: xv = .false.
98 logical :: yv = .false.
99 logical :: icell2d = .false.
100 logical :: xc = .false.
101 logical :: yc = .false.
102 logical :: ncvert = .false.
103 logical :: icvert = .false.
110 subroutine disv_cr(dis, name_model, input_mempath, inunit, iout)
113 character(len=*),
intent(in) :: name_model
114 character(len=*),
intent(in) :: input_mempath
115 integer(I4B),
intent(in) :: inunit
116 integer(I4B),
intent(in) :: iout
120 character(len=*),
parameter :: fmtheader = &
121 "(1X, /1X, 'DISV -- VERTEX GRID DISCRETIZATION PACKAGE,', &
122 &' VERSION 1 : 12/23/2015 - INPUT READ FROM MEMPATH: ', A, //)"
126 call disnew%allocate_scalars(name_model, input_mempath)
135 write (iout, fmtheader) dis%input_mempath
139 call disnew%disv_load()
151 call this%source_options()
152 call this%source_dimensions()
153 call this%source_griddata()
154 call this%source_vertices()
155 call this%source_cell2d()
165 call this%grid_finalize()
181 call this%DisBaseType%dis_da()
207 character(len=LENVARNAME),
dimension(3) :: lenunits = &
208 &[character(len=LENVARNAME) ::
'FEET',
'METERS',
'CENTIMETERS']
212 call mem_set_value(this%lenuni,
'LENGTH_UNITS', this%input_mempath, &
213 lenunits, found%length_units)
214 call mem_set_value(this%nogrb,
'NOGRB', this%input_mempath, found%nogrb)
215 call mem_set_value(this%xorigin,
'XORIGIN', this%input_mempath, found%xorigin)
216 call mem_set_value(this%yorigin,
'YORIGIN', this%input_mempath, found%yorigin)
217 call mem_set_value(this%angrot,
'ANGROT', this%input_mempath, found%angrot)
220 if (this%iout > 0)
then
221 call this%log_options(found)
233 write (this%iout,
'(1x,a)')
'Setting Discretization Options'
235 if (found%length_units)
then
236 write (this%iout,
'(4x,a,i0)')
'Model length unit [0=UND, 1=FEET, &
237 &2=METERS, 3=CENTIMETERS] set as ', this%lenuni
240 if (found%nogrb)
then
241 write (this%iout,
'(4x,a,i0)')
'Binary grid file [0=GRB, 1=NOGRB] &
242 &set as ', this%nogrb
245 if (found%xorigin)
then
246 write (this%iout,
'(4x,a,G0)')
'XORIGIN = ', this%xorigin
249 if (found%yorigin)
then
250 write (this%iout,
'(4x,a,G0)')
'YORIGIN = ', this%yorigin
253 if (found%angrot)
then
254 write (this%iout,
'(4x,a,G0)')
'ANGROT = ', this%angrot
257 write (this%iout,
'(1x,a,/)')
'End Setting Discretization Options'
271 call mem_set_value(this%nlay,
'NLAY', this%input_mempath, found%nlay)
272 call mem_set_value(this%ncpl,
'NCPL', this%input_mempath, found%ncpl)
273 call mem_set_value(this%nvert,
'NVERT', this%input_mempath, found%nvert)
276 if (this%iout > 0)
then
277 call this%log_dimensions(found)
281 if (this%nlay < 1)
then
283 'NLAY was not specified or was specified incorrectly.')
286 if (this%ncpl < 1)
then
288 'NCPL was not specified or was specified incorrectly.')
291 if (this%nvert < 1)
then
293 'NVERT was not specified or was specified incorrectly.')
298 this%nodesuser = this%nlay * this%ncpl
301 call mem_allocate(this%idomain, this%ncpl, this%nlay,
'IDOMAIN', &
303 call mem_allocate(this%top1d, this%ncpl,
'TOP1D', this%memoryPath)
304 call mem_allocate(this%bot2d, this%ncpl, this%nlay,
'BOT2D', &
308 call mem_allocate(this%vertices, 2, this%nvert,
'VERTICES', this%memoryPath)
309 call mem_allocate(this%cellxy, 2, this%ncpl,
'CELLXY', this%memoryPath)
314 this%idomain(j, k) = 1
327 write (this%iout,
'(1x,a)')
'Setting Discretization Dimensions'
330 write (this%iout,
'(4x,a,i0)')
'NLAY = ', this%nlay
334 write (this%iout,
'(4x,a,i0)')
'NCPL = ', this%ncpl
337 if (found%nvert)
then
338 write (this%iout,
'(4x,a,i0)')
'NVERT = ', this%nvert
341 write (this%iout,
'(1x,a,/)')
'End Setting Discretization Dimensions'
354 call mem_set_value(this%top1d,
'TOP', this%input_mempath, found%top)
355 call mem_set_value(this%bot2d,
'BOTM', this%input_mempath, found%botm)
356 call mem_set_value(this%idomain,
'IDOMAIN', this%input_mempath, found%idomain)
359 if (this%iout > 0)
then
360 call this%log_griddata(found)
372 write (this%iout,
'(1x,a)')
'Setting Discretization Griddata'
375 write (this%iout,
'(4x,a)')
'TOP set from input file'
379 write (this%iout,
'(4x,a)')
'BOTM set from input file'
382 if (found%idomain)
then
383 write (this%iout,
'(4x,a)')
'IDOMAIN set from input file'
386 write (this%iout,
'(1x,a,/)')
'End Setting Discretization Griddata'
396 integer(I4B) :: node, noder, j, k
400 character(len=*),
parameter :: fmtdz = &
401 "('CELL (',i0,',',i0,') THICKNESS <= 0. ', &
402 &'TOP, BOT: ',2(1pg24.15))"
403 character(len=*),
parameter :: fmtnr = &
404 "(/1x, 'The specified IDOMAIN results in a reduced number of cells.',&
405 &/1x, 'Number of user nodes: ',I0,&
406 &/1X, 'Number of nodes in solution: ', I0, //)"
412 if (this%idomain(j, k) > 0) this%nodes = this%nodes + 1
417 if (this%nodes == 0)
then
418 call store_error(
'Model does not have any active nodes. &
419 &Ensure IDOMAIN array has some values greater &
427 if (this%idomain(j, k) == 0) cycle
428 if (this%idomain(j, k) > 0)
then
430 top = this%bot2d(j, k - 1)
434 dz = top - this%bot2d(j, k)
435 if (dz <=
dzero)
then
436 write (
errmsg, fmt=fmtdz) k, j, top, this%bot2d(j, k)
447 if (this%nodes < this%nodesuser)
then
448 write (this%iout, fmtnr) this%nodesuser, this%nodes
452 call this%allocate_arrays()
458 if (this%nodes < this%nodesuser)
then
463 if (this%idomain(j, k) > 0)
then
464 this%nodereduced(node) = noder
466 elseif (this%idomain(j, k) < 0)
then
467 this%nodereduced(node) = -1
469 this%nodereduced(node) = 0
477 if (this%nodes < this%nodesuser)
then
482 if (this%idomain(j, k) > 0)
then
483 this%nodeuser(noder) = node
498 if (this%nodes < this%nodesuser) noder = this%nodereduced(node)
499 if (noder <= 0) cycle
501 top = this%bot2d(j, k - 1)
505 this%top(noder) = top
506 this%bot(noder) = this%bot2d(j, k)
507 this%xc(noder) = this%cellxy(1, j)
508 this%yc(noder) = this%cellxy(2, j)
524 real(DP),
dimension(:),
contiguous,
pointer :: vert_x => null()
525 real(DP),
dimension(:),
contiguous,
pointer :: vert_y => null()
528 call mem_setptr(vert_x,
'XV', this%input_mempath)
529 call mem_setptr(vert_y,
'YV', this%input_mempath)
532 if (
associated(vert_x) .and.
associated(vert_y))
then
534 this%vertices(1, i) = vert_x(i)
535 this%vertices(2, i) = vert_y(i)
538 call store_error(
'Required Vertex arrays not found.')
542 if (this%iout > 0)
then
543 write (this%iout,
'(1x,a)')
'Discretization Vertex data loaded'
555 integer(I4B),
dimension(:),
contiguous,
pointer,
intent(in) :: icell2d
556 integer(I4B),
dimension(:),
contiguous,
pointer,
intent(in) :: ncvert
557 integer(I4B),
dimension(:),
contiguous,
pointer,
intent(in) :: icvert
560 integer(I4B) :: i, j, ierr
561 integer(I4B) :: icv_idx, startvert, maxnnz = 5
564 call vert_spm%init(this%ncpl, this%nvert, maxnnz)
569 if (icell2d(i) /= i)
call store_error(
'ICELL2D input sequence violation.')
571 call vert_spm%addconnection(i, icvert(icv_idx), 0)
573 startvert = icvert(icv_idx)
574 elseif (j == ncvert(i) .and. (icvert(icv_idx) /= startvert))
then
575 call vert_spm%addconnection(i, startvert, 0)
577 icv_idx = icv_idx + 1
582 call mem_allocate(this%iavert, this%ncpl + 1,
'IAVERT', this%memoryPath)
583 call mem_allocate(this%javert, vert_spm%nnz,
'JAVERT', this%memoryPath)
584 call vert_spm%filliaja(this%iavert, this%javert, ierr)
585 call vert_spm%destroy()
595 integer(I4B),
dimension(:),
contiguous,
pointer :: icell2d => null()
596 integer(I4B),
dimension(:),
contiguous,
pointer :: ncvert => null()
597 integer(I4B),
dimension(:),
contiguous,
pointer :: icvert => null()
598 real(DP),
dimension(:),
contiguous,
pointer :: cell_x => null()
599 real(DP),
dimension(:),
contiguous,
pointer :: cell_y => null()
603 call mem_setptr(icell2d,
'ICELL2D', this%input_mempath)
604 call mem_setptr(ncvert,
'NCVERT', this%input_mempath)
605 call mem_setptr(icvert,
'ICVERT', this%input_mempath)
608 if (
associated(icell2d) .and.
associated(ncvert) &
609 .and.
associated(icvert))
then
610 call this%define_cellverts(icell2d, ncvert, icvert)
612 call store_error(
'Required cell vertex array(s) [ICELL2D, NCVERT, ICVERT] &
617 call mem_setptr(cell_x,
'XC', this%input_mempath)
618 call mem_setptr(cell_y,
'YC', this%input_mempath)
621 if (
associated(cell_x) .and.
associated(cell_y))
then
623 this%cellxy(1, i) = cell_x(i)
624 this%cellxy(2, i) = cell_y(i)
627 call store_error(
'Required cell center arrays not found.')
631 if (this%iout > 0)
then
632 write (this%iout,
'(1x,a)')
'Discretization Cell2d data loaded'
644 integer(I4B) :: noder, nrsize
645 integer(I4B) :: narea_eq_zero
646 integer(I4B) :: narea_lt_zero
655 area = this%get_cell2d_area(j)
657 noder = this%get_nodenumber(k, j, 0)
658 if (noder > 0) this%area(noder) = area
660 if (area <
dzero)
then
661 narea_lt_zero = narea_lt_zero + 1
662 write (
errmsg,
'(a,i0,a)') &
663 &
'Calculated CELL2D area less than zero for cell ', j,
'.'
666 if (area ==
dzero)
then
667 narea_eq_zero = narea_eq_zero + 1
668 write (
errmsg,
'(a,i0,a)') &
669 'Calculated CELL2D area is zero for cell ', j,
'.'
676 if (narea_lt_zero > 0)
then
677 write (
errmsg,
'(i0,a)') narea_lt_zero, &
678 ' cell(s) have an area less than zero. Calculated cell &
679 &areas must be greater than zero. Negative areas often &
680 &mean vertices are not listed in clockwise order.'
683 if (narea_eq_zero > 0)
then
684 write (
errmsg,
'(i0,a)') narea_eq_zero, &
685 ' cell(s) have an area equal to zero. Calculated cell &
686 &areas must be greater than zero. Calculated cell &
687 &areas equal to zero indicate that the cell is not defined &
688 &by a valid polygon.'
696 if (this%nodes < this%nodesuser) nrsize = this%nodes
698 call this%con%disvconnections(this%name_model, this%nodes, &
699 this%ncpl, this%nlay, nrsize, &
700 this%nvert, this%vertices, this%iavert, &
701 this%javert, this%cellxy, &
702 this%top, this%bot, &
703 this%nodereduced, this%nodeuser)
704 this%nja = this%con%nja
705 this%njas = this%con%njas
717 integer(I4B),
dimension(:),
intent(in) :: icelltype
719 integer(I4B) :: iunit, i, ntxt, version
720 integer(I4B),
parameter :: lentxt = 100
721 character(len=50) :: txthdr
722 character(len=lentxt) :: txt
723 character(len=LINELENGTH) :: fname
724 character(len=LENBIGLINE) :: crs
725 logical(LGP) :: found_crs
727 character(len=*),
parameter :: fmtgrdsave = &
728 "(4X,'BINARY GRID INFORMATION WILL BE WRITTEN TO:', &
729 &/,6X,'UNIT NUMBER: ', I0,/,6X, 'FILE NAME: ', A)"
735 call mem_set_value(crs,
'CRS', this%input_mempath, found_crs)
744 fname = trim(this%output_fname)
746 write (this%iout, fmtgrdsave) iunit, trim(adjustl(fname))
747 call openfile(iunit, this%iout, trim(adjustl(fname)),
'DATA(BINARY)', &
751 write (txthdr,
'(a)')
'GRID DISV'
752 txthdr(50:50) = new_line(
'a')
754 write (txthdr,
'(a, i0)')
'VERSION ', version
755 txthdr(50:50) = new_line(
'a')
757 write (txthdr,
'(a, i0)')
'NTXT ', ntxt
758 txthdr(50:50) = new_line(
'a')
760 write (txthdr,
'(a, i0)')
'LENTXT ', lentxt
761 txthdr(50:50) = new_line(
'a')
765 write (txt,
'(3a, i0)')
'NCELLS ',
'INTEGER ',
'NDIM 0 # ', this%nodesuser
766 txt(lentxt:lentxt) = new_line(
'a')
768 write (txt,
'(3a, i0)')
'NLAY ',
'INTEGER ',
'NDIM 0 # ', this%nlay
769 txt(lentxt:lentxt) = new_line(
'a')
771 write (txt,
'(3a, i0)')
'NCPL ',
'INTEGER ',
'NDIM 0 # ', this%ncpl
772 txt(lentxt:lentxt) = new_line(
'a')
774 write (txt,
'(3a, i0)')
'NVERT ',
'INTEGER ',
'NDIM 0 # ', this%nvert
775 txt(lentxt:lentxt) = new_line(
'a')
777 write (txt,
'(3a, i0)')
'NJAVERT ',
'INTEGER ',
'NDIM 0 # ',
size(this%javert)
778 txt(lentxt:lentxt) = new_line(
'a')
780 write (txt,
'(3a, i0)')
'NJA ',
'INTEGER ',
'NDIM 0 # ', this%con%nja
781 txt(lentxt:lentxt) = new_line(
'a')
783 write (txt,
'(3a, 1pg25.15e3)') &
784 'XORIGIN ',
'DOUBLE ',
'NDIM 0 # ', this%xorigin
785 txt(lentxt:lentxt) = new_line(
'a')
787 write (txt,
'(3a, 1pg25.15e3)') &
788 'YORIGIN ',
'DOUBLE ',
'NDIM 0 # ', this%yorigin
789 txt(lentxt:lentxt) = new_line(
'a')
791 write (txt,
'(3a, 1pg25.15e3)')
'ANGROT ',
'DOUBLE ',
'NDIM 0 # ', this%angrot
792 txt(lentxt:lentxt) = new_line(
'a')
794 write (txt,
'(3a, i0)')
'TOP ',
'DOUBLE ',
'NDIM 1 ', this%ncpl
795 txt(lentxt:lentxt) = new_line(
'a')
797 write (txt,
'(3a, i0)')
'BOTM ',
'DOUBLE ',
'NDIM 1 ', this%nodesuser
798 txt(lentxt:lentxt) = new_line(
'a')
800 write (txt,
'(3a, i0)')
'VERTICES ',
'DOUBLE ',
'NDIM 2 2 ', this%nvert
801 txt(lentxt:lentxt) = new_line(
'a')
803 write (txt,
'(3a, i0)')
'CELLX ',
'DOUBLE ',
'NDIM 1 ', this%ncpl
804 txt(lentxt:lentxt) = new_line(
'a')
806 write (txt,
'(3a, i0)')
'CELLY ',
'DOUBLE ',
'NDIM 1 ', this%ncpl
807 txt(lentxt:lentxt) = new_line(
'a')
809 write (txt,
'(3a, i0)')
'IAVERT ',
'INTEGER ',
'NDIM 1 ', this%ncpl + 1
810 txt(lentxt:lentxt) = new_line(
'a')
812 write (txt,
'(3a, i0)')
'JAVERT ',
'INTEGER ',
'NDIM 1 ',
size(this%javert)
813 txt(lentxt:lentxt) = new_line(
'a')
815 write (txt,
'(3a, i0)')
'IA ',
'INTEGER ',
'NDIM 1 ', this%nodesuser + 1
816 txt(lentxt:lentxt) = new_line(
'a')
818 write (txt,
'(3a, i0)')
'JA ',
'INTEGER ',
'NDIM 1 ',
size(this%con%jausr)
819 txt(lentxt:lentxt) = new_line(
'a')
821 write (txt,
'(3a, i0)')
'IDOMAIN ',
'INTEGER ',
'NDIM 1 ', this%nodesuser
822 txt(lentxt:lentxt) = new_line(
'a')
824 write (txt,
'(3a, i0)')
'ICELLTYPE ',
'INTEGER ',
'NDIM 1 ', this%nodesuser
825 txt(lentxt:lentxt) = new_line(
'a')
829 if (version == 2)
then
831 write (txt,
'(3a, i0)')
'CRS ',
'CHARACTER ',
'NDIM 1 ', &
833 txt(lentxt:lentxt) = new_line(
'a')
839 write (iunit) this%nodesuser
840 write (iunit) this%nlay
841 write (iunit) this%ncpl
842 write (iunit) this%nvert
843 write (iunit)
size(this%javert)
844 write (iunit) this%nja
845 write (iunit) this%xorigin
846 write (iunit) this%yorigin
847 write (iunit) this%angrot
848 write (iunit) this%top1d
849 write (iunit) this%bot2d
850 write (iunit) this%vertices
851 write (iunit) (this%cellxy(1, i), i=1, this%ncpl)
852 write (iunit) (this%cellxy(2, i), i=1, this%ncpl)
853 write (iunit) this%iavert
854 write (iunit) this%javert
855 write (iunit) this%con%iausr
856 write (iunit) this%con%jausr
857 write (iunit) this%idomain
858 write (iunit) icelltype
861 if (version == 2)
then
862 if (found_crs)
write (iunit) trim(crs)
875 integer(I4B),
intent(in) :: nodeu
876 character(len=*),
intent(inout) :: str
878 integer(I4B) :: i, j, k
879 character(len=10) :: kstr, jstr
881 call get_ijk(nodeu, 1, this%ncpl, this%nlay, i, j, k)
882 write (kstr,
'(i10)') k
883 write (jstr,
'(i10)') j
884 str =
'('//trim(adjustl(kstr))//
','// &
885 trim(adjustl(jstr))//
')'
894 integer(I4B),
intent(in) :: nodeu
895 integer(I4B),
dimension(:),
intent(inout) :: arr
897 integer(I4B) :: isize
898 integer(I4B) :: i, j, k
902 if (isize /= this%ndim)
then
903 write (
errmsg,
'(a,i0,a,i0,a)') &
904 'Program error: nodeu_to_array size of array (', isize, &
905 ') is not equal to the discretization dimension (', this%ndim,
').'
910 call get_ijk(nodeu, 1, this%ncpl, this%nlay, i, j, k)
922 integer(I4B) :: nodenumber
925 integer(I4B),
intent(in) :: nodeu
926 integer(I4B),
intent(in) :: icheck
930 if (icheck /= 0)
then
933 if (nodeu < 1 .or. nodeu > this%nodesuser)
then
935 write (
errmsg,
'(a,i0,a,i0,a)') &
936 'Node number (', nodeu,
') is less than 1 or greater than nodes (', &
941 if (this%nodes < this%nodesuser) nodenumber = this%nodereduced(nodeu)
945 if (this%nodes < this%nodesuser) nodenumber = this%nodereduced(nodeu)
954 integer(I4B) :: nodenumber
957 integer(I4B),
intent(in) :: k, j
958 integer(I4B),
intent(in) :: icheck
960 integer(I4B) :: nodeu
962 character(len=*),
parameter :: fmterr = &
963 &
"('Error in disv grid cell indices: layer = ',i0,', node = ',i0)"
965 nodeu =
get_node(k, 1, j, this%nlay, 1, this%ncpl)
967 write (
errmsg, fmterr) k, j
971 if (this%nodes < this%nodesuser) nodenumber = this%nodereduced(nodeu)
974 if (icheck /= 0)
then
978 if (k < 1 .or. k > this%nlay)
then
979 write (
errmsg,
'(a,i0,a)') &
980 'Layer number in list (', k,
') is outside of the grid.'
982 if (j < 1 .or. j > this%ncpl)
then
983 write (
errmsg,
'(a,1x,a,i0,a)') &
984 trim(adjustl(
errmsg)),
'Node number in list (', j, &
985 ') is outside of the grid.'
989 if (nodeu < 1 .or. nodeu > this%nodesuser)
then
990 write (
errmsg,
'(a,1x,a,i0,a,i0,a)') &
992 'Node number (', nodeu,
') is less than 1 or greater '// &
993 'than nodes (', this%nodesuser,
').'
996 if (len_trim(adjustl(
errmsg)) > 0)
then
1012 integer(I4B),
intent(in) :: noden
1013 integer(I4B),
intent(in) :: nodem
1014 integer(I4B),
intent(in) :: ihc
1015 real(DP),
intent(inout) :: xcomp
1016 real(DP),
intent(inout) :: ycomp
1017 real(DP),
intent(inout) :: zcomp
1018 integer(I4B),
intent(in) :: ipos
1020 real(DP) :: angle, dmult
1026 if (nodem < noden)
then
1039 angle = this%con%anglex(this%con%jas(ipos))
1041 if (nodem < noden) dmult = -
done
1042 xcomp = cos(angle) * dmult
1043 ycomp = sin(angle) * dmult
1055 xcomp, ycomp, zcomp, conlen)
1058 integer(I4B),
intent(in) :: noden
1059 integer(I4B),
intent(in) :: nodem
1060 logical,
intent(in) :: nozee
1061 real(DP),
intent(in) :: satn
1062 real(DP),
intent(in) :: satm
1063 integer(I4B),
intent(in) :: ihc
1064 real(DP),
intent(inout) :: xcomp
1065 real(DP),
intent(inout) :: ycomp
1066 real(DP),
intent(inout) :: zcomp
1067 real(DP),
intent(inout) :: conlen
1069 integer(I4B) :: nodeu, ncell2d, mcell2d, k
1070 real(DP) :: xn, xm, yn, ym, zn, zm
1078 if (nodem < noden)
then
1083 zn = this%bot(noden) +
dhalf * (this%top(noden) - this%bot(noden))
1084 zm = this%bot(nodem) +
dhalf * (this%top(nodem) - this%bot(nodem))
1085 conlen = abs(zm - zn)
1094 zn = this%bot(noden) +
dhalf * satn * (this%top(noden) - this%bot(noden))
1095 zm = this%bot(nodem) +
dhalf * satm * (this%top(nodem) - this%bot(nodem))
1097 nodeu = this%get_nodeuser(noden)
1098 call get_jk(nodeu, this%ncpl, this%nlay, ncell2d, k)
1099 nodeu = this%get_nodeuser(nodem)
1100 call get_jk(nodeu, this%ncpl, this%nlay, mcell2d, k)
1101 xn = this%cellxy(1, ncell2d)
1102 yn = this%cellxy(2, ncell2d)
1103 xm = this%cellxy(1, mcell2d)
1104 ym = this%cellxy(2, mcell2d)
1115 class(
disvtype),
intent(in) :: this
1116 character(len=*),
intent(out) :: dis_type
1125 class(
disvtype),
intent(in) :: this
1126 integer(I4B) :: dis_enum
1135 character(len=*),
intent(in) :: name_model
1136 character(len=*),
intent(in) :: input_mempath
1139 call this%DisBaseType%allocate_scalars(name_model, input_mempath)
1144 call mem_allocate(this%nvert,
'NVERT', this%memoryPath)
1161 call this%DisBaseType%allocate_arrays()
1164 if (this%nodes < this%nodesuser)
then
1165 call mem_allocate(this%nodeuser, this%nodes,
'NODEUSER', this%memoryPath)
1166 call mem_allocate(this%nodereduced, this%nodesuser,
'NODEREDUCED', &
1169 call mem_allocate(this%nodeuser, 1,
'NODEUSER', this%memoryPath)
1170 call mem_allocate(this%nodereduced, 1,
'NODEREDUCED', this%memoryPath)
1173 this%mshape(1) = this%nlay
1174 this%mshape(2) = this%ncpl
1188 integer(I4B),
intent(in) :: icell2d
1192 integer(I4B) :: ivert
1193 integer(I4B) :: nvert
1194 integer(I4B) :: icount
1202 nvert = this%iavert(icell2d + 1) - this%iavert(icell2d)
1204 iv1 = this%javert(this%iavert(icell2d))
1205 x1 = this%vertices(1, iv1)
1206 y1 = this%vertices(2, iv1)
1207 do ivert = this%iavert(icell2d), this%iavert(icell2d + 1) - 1
1208 x = this%vertices(1, this%javert(ivert))
1209 if (icount < nvert)
then
1210 y = this%vertices(2, this%javert(ivert + 1))
1212 y = this%vertices(2, this%javert(this%iavert(icell2d)))
1214 area = area + (x - x1) * (y - y1)
1219 do ivert = this%iavert(icell2d), this%iavert(icell2d + 1) - 1
1220 y = this%vertices(2, this%javert(ivert))
1221 if (icount < nvert)
then
1222 x = this%vertices(1, this%javert(ivert + 1))
1224 x = this%vertices(1, this%javert(this%iavert(icell2d)))
1226 area = area - (x - x1) * (y - y1)
1241 flag_string, allow_zero)
result(nodeu)
1244 integer(I4B),
intent(inout) :: lloc
1245 integer(I4B),
intent(inout) :: istart
1246 integer(I4B),
intent(inout) :: istop
1247 integer(I4B),
intent(in) :: in
1248 integer(I4B),
intent(in) :: iout
1249 character(len=*),
intent(inout) :: line
1250 logical,
optional,
intent(in) :: flag_string
1251 logical,
optional,
intent(in) :: allow_zero
1252 integer(I4B) :: nodeu
1254 integer(I4B) :: j, k, nlay, nrow, ncpl
1255 integer(I4B) :: lloclocal, ndum, istat, n
1258 if (
present(flag_string))
then
1259 if (flag_string)
then
1262 call urword(line, lloclocal, istart, istop, 1, ndum, r, iout, in)
1263 read (line(istart:istop), *, iostat=istat) n
1264 if (istat /= 0)
then
1272 nlay = this%mshape(1)
1274 ncpl = this%mshape(2)
1276 call urword(line, lloc, istart, istop, 2, k, r, iout, in)
1277 call urword(line, lloc, istart, istop, 2, j, r, iout, in)
1279 if (k == 0 .and. j == 0)
then
1280 if (
present(allow_zero))
then
1281 if (allow_zero)
then
1290 if (k < 1 .or. k > nlay)
then
1291 write (
errmsg,
'(a,i0,a)') &
1292 'Layer number in list (', k,
') is outside of the grid.'
1294 if (j < 1 .or. j > ncpl)
then
1295 write (
errmsg,
'(a,1x,a,i0,a)') &
1296 trim(adjustl(
errmsg)),
'Cell2d number in list (', j, &
1297 ') is outside of the grid.'
1300 nodeu =
get_node(k, 1, j, nlay, nrow, ncpl)
1302 if (nodeu < 1 .or. nodeu > this%nodesuser)
then
1303 write (
errmsg,
'(a,1x,a,i0,a)') &
1305 "Node number in list (", nodeu,
") is outside of the grid. "// &
1306 "Cell number cannot be determined in line '"// &
1307 trim(adjustl(line))//
"'."
1310 if (len_trim(adjustl(
errmsg)) > 0)
then
1326 allow_zero)
result(nodeu)
1328 integer(I4B) :: nodeu
1331 character(len=*),
intent(inout) :: cellid
1332 integer(I4B),
intent(in) :: inunit
1333 integer(I4B),
intent(in) :: iout
1334 logical,
optional,
intent(in) :: flag_string
1335 logical,
optional,
intent(in) :: allow_zero
1337 integer(I4B) :: j, k, nlay, nrow, ncpl
1338 integer(I4B) :: lloclocal, ndum, istat, n
1339 integer(I4B) :: istart, istop
1342 if (
present(flag_string))
then
1343 if (flag_string)
then
1346 call urword(cellid, lloclocal, istart, istop, 1, ndum, r, iout, inunit)
1347 read (cellid(istart:istop), *, iostat=istat) n
1348 if (istat /= 0)
then
1356 nlay = this%mshape(1)
1358 ncpl = this%mshape(2)
1361 call urword(cellid, lloclocal, istart, istop, 2, k, r, iout, inunit)
1362 call urword(cellid, lloclocal, istart, istop, 2, j, r, iout, inunit)
1364 if (k == 0 .and. j == 0)
then
1365 if (
present(allow_zero))
then
1366 if (allow_zero)
then
1375 if (k < 1 .or. k > nlay)
then
1376 write (
errmsg,
'(a,i0,a)') &
1377 'Layer number in list (', k,
') is outside of the grid.'
1379 if (j < 1 .or. j > ncpl)
then
1380 write (
errmsg,
'(a,1x,a,i0,a)') &
1381 trim(adjustl(
errmsg)),
'Cell2d number in list (', j, &
1382 ') is outside of the grid.'
1385 nodeu =
get_node(k, 1, j, nlay, nrow, ncpl)
1387 if (nodeu < 1 .or. nodeu > this%nodesuser)
then
1388 write (
errmsg,
'(a,1x,a,i0,a)') &
1390 "Cell number cannot be determined for cellid ("// &
1391 trim(adjustl(cellid))//
") and results in a user "// &
1392 "node number (", nodeu,
") that is outside of the grid."
1395 if (len_trim(adjustl(
errmsg)) > 0)
then
1429 class(
disvtype),
intent(inout) :: this
1430 integer(I4B),
intent(in) :: ic
1431 real(DP),
allocatable,
intent(out) :: polyverts(:, :)
1432 logical(LGP),
intent(in),
optional :: closed
1434 integer(I4B) :: icu, icu2d, iavert, ncpl, nverts, m, j
1435 logical(LGP) :: lclosed
1438 ncpl = this%get_ncpl()
1439 icu = this%get_nodeuser(ic)
1440 icu2d = icu - ((icu - 1) / ncpl) * ncpl
1441 nverts = this%iavert(icu2d + 1) - this%iavert(icu2d) - 1
1444 if (.not. (
present(closed)))
then
1452 allocate (polyverts(2, nverts + 1))
1454 allocate (polyverts(2, nverts))
1458 iavert = this%iavert(icu2d)
1460 j = this%javert(iavert - 1 + m)
1461 polyverts(:, m) = (/this%vertices(1, j), this%vertices(2, j)/)
1466 polyverts(:, nverts + 1) = polyverts(:, 1)
1472 class(
disvtype),
intent(inout) :: this
1473 integer(I4B),
intent(in) :: ic
1474 logical(LGP),
intent(in),
optional :: closed
1475 integer(I4B) :: npolyverts
1477 integer(I4B) :: ncpl, icu, icu2d
1479 ncpl = this%get_ncpl()
1480 icu = this%get_nodeuser(ic)
1481 icu2d = icu - ((icu - 1) / ncpl) * ncpl
1482 npolyverts = this%iavert(icu2d + 1) - this%iavert(icu2d) - 1
1483 if (
present(closed))
then
1484 if (closed) npolyverts = npolyverts + 1
1490 class(
disvtype),
intent(inout) :: this
1491 logical(LGP),
intent(in),
optional :: closed
1492 integer(I4B) :: max_npolyverts
1496 do ic = 1, this%nodes
1497 max_npolyverts = max(max_npolyverts, this%get_npolyverts(ic, closed))
1506 class(
disvtype),
intent(inout) :: this
1507 character(len=*),
intent(inout) :: line
1508 integer(I4B),
intent(inout) :: lloc
1509 integer(I4B),
intent(inout) :: istart
1510 integer(I4B),
intent(inout) :: istop
1511 integer(I4B),
intent(in) :: in
1512 integer(I4B),
intent(in) :: iout
1513 integer(I4B),
dimension(:),
pointer,
contiguous,
intent(inout) :: iarray
1514 character(len=*),
intent(in) :: aname
1516 integer(I4B) :: ival
1518 integer(I4B) :: nlay
1519 integer(I4B) :: nrow
1520 integer(I4B) :: ncol
1521 integer(I4B) :: nval
1522 integer(I4B),
dimension(:),
pointer,
contiguous :: itemp
1528 nlay = this%mshape(1)
1530 ncol = this%mshape(2)
1532 if (this%nodes < this%nodesuser)
then
1533 nval = this%nodesuser
1541 call urword(line, lloc, istart, istop, 1, ival, rval, iout, in)
1542 if (line(istart:istop) .EQ.
'LAYERED')
then
1545 call readarray(in, itemp, aname, this%ndim, ncol, nrow, nlay, nval, &
1550 call readarray(in, itemp, aname, this%ndim, nval, iout, 0)
1554 if (this%nodes < this%nodesuser)
then
1555 call this%fill_grid_array(itemp, iarray)
1565 class(
disvtype),
intent(inout) :: this
1566 character(len=*),
intent(inout) :: line
1567 integer(I4B),
intent(inout) :: lloc
1568 integer(I4B),
intent(inout) :: istart
1569 integer(I4B),
intent(inout) :: istop
1570 integer(I4B),
intent(in) :: in
1571 integer(I4B),
intent(in) :: iout
1572 real(DP),
dimension(:),
pointer,
contiguous,
intent(inout) :: darray
1573 character(len=*),
intent(in) :: aname
1575 integer(I4B) :: ival
1577 integer(I4B) :: nlay
1578 integer(I4B) :: nrow
1579 integer(I4B) :: ncol
1580 integer(I4B) :: nval
1581 real(DP),
dimension(:),
pointer,
contiguous :: dtemp
1587 nlay = this%mshape(1)
1589 ncol = this%mshape(2)
1591 if (this%nodes < this%nodesuser)
then
1592 nval = this%nodesuser
1600 call urword(line, lloc, istart, istop, 1, ival, rval, iout, in)
1601 if (line(istart:istop) .EQ.
'LAYERED')
then
1604 call readarray(in, dtemp, aname, this%ndim, ncol, nrow, nlay, nval, &
1609 call readarray(in, dtemp, aname, this%ndim, nval, iout, 0)
1613 if (this%nodes < this%nodesuser)
then
1614 call this%fill_grid_array(dtemp, darray)
1625 icolbnd, aname, inunit, iout)
1628 integer(I4B),
intent(in) :: ncolbnd
1629 integer(I4B),
intent(in) :: maxbnd
1630 integer(I4B),
dimension(maxbnd) :: nodelist
1631 real(DP),
dimension(ncolbnd, maxbnd),
intent(inout) :: darray
1632 integer(I4B),
intent(in) :: icolbnd
1633 character(len=*),
intent(in) :: aname
1634 integer(I4B),
intent(in) :: inunit
1635 integer(I4B),
intent(in) :: iout
1637 integer(I4B) :: ir, ic, ncol, nrow, nlay, nval, ipos, nodeu
1640 nlay = this%mshape(1)
1642 ncol = this%mshape(2)
1646 call readarray(inunit, this%dbuff, aname, this%ndim, nval, iout, 0)
1655 nodeu =
get_node(1, ir, ic, nlay, nrow, ncol)
1656 darray(icolbnd, ipos) = this%dbuff(nodeu)
1669 cdatafmp, nvaluesp, nwidthp, editdesc, dinact)
1671 class(
disvtype),
intent(inout) :: this
1672 real(DP),
dimension(:),
pointer,
contiguous,
intent(inout) :: darray
1673 integer(I4B),
intent(in) :: iout
1674 integer(I4B),
intent(in) :: iprint
1675 integer(I4B),
intent(in) :: idataun
1676 character(len=*),
intent(in) :: aname
1677 character(len=*),
intent(in) :: cdatafmp
1678 integer(I4B),
intent(in) :: nvaluesp
1679 integer(I4B),
intent(in) :: nwidthp
1680 character(len=*),
intent(in) :: editdesc
1681 real(DP),
intent(in) :: dinact
1683 integer(I4B) :: k, ifirst
1684 integer(I4B) :: nlay
1685 integer(I4B) :: nrow
1686 integer(I4B) :: ncol
1687 integer(I4B) :: nval
1688 integer(I4B) :: nodeu, noder
1689 integer(I4B) :: istart, istop
1690 real(DP),
dimension(:),
pointer,
contiguous :: dtemp
1692 character(len=*),
parameter :: fmthsv = &
1693 "(1X,/1X,a,' WILL BE SAVED ON UNIT ',I4, &
1694 &' AT END OF TIME STEP',I5,', STRESS PERIOD ',I4)"
1697 nlay = this%mshape(1)
1699 ncol = this%mshape(2)
1703 if (this%nodes < this%nodesuser)
then
1706 do nodeu = 1, this%nodesuser
1707 noder = this%get_nodenumber(nodeu, 0)
1708 if (noder <= 0)
then
1709 dtemp(nodeu) = dinact
1712 dtemp(nodeu) = darray(noder)
1720 if (iprint /= 0)
then
1723 istop = istart + nrow * ncol - 1
1725 aname, cdatafmp, nvaluesp, nwidthp, editdesc)
1731 if (idataun > 0)
then
1736 istop = istart + nrow * ncol - 1
1737 if (ifirst == 1)
write (iout, fmthsv) &
1738 trim(adjustl(aname)), idataun, &
1745 elseif (idataun < 0)
then
1748 call ubdsv1(
kstp,
kper, aname, -idataun, dtemp, ncol, nrow, nlay, &
1757 dstmodel, dstpackage, naux, auxtxt, &
1758 ibdchn, nlist, iout)
1761 character(len=16),
intent(in) :: text
1762 character(len=16),
intent(in) :: textmodel
1763 character(len=16),
intent(in) :: textpackage
1764 character(len=16),
intent(in) :: dstmodel
1765 character(len=16),
intent(in) :: dstpackage
1766 integer(I4B),
intent(in) :: naux
1767 character(len=16),
dimension(:),
intent(in) :: auxtxt
1768 integer(I4B),
intent(in) :: ibdchn
1769 integer(I4B),
intent(in) :: nlist
1770 integer(I4B),
intent(in) :: iout
1772 integer(I4B) :: nlay, nrow, ncol
1774 nlay = this%mshape(1)
1776 ncol = this%mshape(2)
1779 call ubdsv06(
kstp,
kper, text, textmodel, textpackage, dstmodel, dstpackage, &
1780 ibdchn, naux, auxtxt, ncol, nrow, nlay, &
1790 integer(I4B),
intent(in) :: maxbnd
1791 integer(I4B),
dimension(:),
pointer,
contiguous :: darray
1792 integer(I4B),
dimension(maxbnd),
intent(inout) :: nodelist
1793 integer(I4B),
intent(inout) :: nbound
1794 character(len=*),
intent(in) :: aname
1796 integer(I4B) :: il, ir, ic, ncol, nrow, nlay, nval, nodeu, noder, ipos, ierr
1799 nlay = this%mshape(1)
1801 ncol = this%mshape(2)
1810 nodeu =
get_node(1, ir, ic, nlay, nrow, ncol)
1812 if (il < 1 .or. il > nlay)
then
1813 write (
errmsg,
'(a,i0,a)') &
1814 'Invalid layer number (', il,
').'
1817 nodeu =
get_node(il, ir, ic, nlay, nrow, ncol)
1818 noder = this%get_nodenumber(nodeu, 0)
1819 if (ipos > maxbnd)
then
1822 nodelist(ipos) = noder
1831 write (
errmsg,
'(a,i0,a)') &
1832 'MAXBOUND dimension is too small. Increase MAXBOUND to ', ierr,
'.'
1837 if (nbound < maxbnd)
then
1838 do ipos = nbound + 1, maxbnd
This module contains simulation constants.
integer(i4b), parameter linelength
maximum length of a standard line
integer(i4b), parameter lenbigline
maximum length of a big line
@ disv
DISU6 discretization.
integer(i4b), parameter lenvarname
maximum length of a variable name
real(dp), parameter dhalf
real constant 1/2
real(dp), parameter dzero
real constant zero
integer(i4b), parameter lenmempath
maximum length of the memory path
real(dp), parameter done
real constant 1
subroutine, public line_unit_vector(x0, y0, z0, x1, y1, z1, xcomp, ycomp, zcomp, vmag)
Calculate the vector components (xcomp, ycomp, and zcomp) for a line defined by two points,...
subroutine write_grb(this, icelltype)
Write a binary grid file.
real(dp) function get_cell2d_area(this, icell2d)
Get the signed area of the cell.
integer(i4b) function get_ncpl(this)
Get number of cells per layer (ncpl)
integer(i4b) function get_max_npolyverts(this, closed)
Get the maximum number of cell polygon vertices.
subroutine record_array(this, darray, iout, iprint, idataun, aname, cdatafmp, nvaluesp, nwidthp, editdesc, dinact)
Record a double precision array.
subroutine grid_finalize(this)
Finalize grid (check properties, allocate arrays, compute connections)
subroutine log_dimensions(this, found)
Write dimensions to list file.
subroutine log_griddata(this, found)
Write griddata found to list file.
subroutine disv_da(this)
Deallocate variables.
subroutine source_dimensions(this)
Copy dimensions from IDM into package.
subroutine log_options(this, found)
Write user options to list file.
subroutine connection_vector(this, noden, nodem, nozee, satn, satm, ihc, xcomp, ycomp, zcomp, conlen)
Get unit vector components between the cell and a given neighbor.
integer(i4b) function get_nodenumber_idx2(this, k, j, icheck)
Get reduced node number from layer and within-layer node indices.
subroutine nodeu_to_string(this, nodeu, str)
Convert a user nodenumber to a string (nodenumber) or (k,j)
subroutine nlarray_to_nodelist(this, darray, nodelist, maxbnd, nbound, aname)
Convert an integer array (layer numbers) to nodelist.
integer(i4b) function get_nodenumber_idx1(this, nodeu, icheck)
Get reduced node number from user node number.
subroutine get_polyverts(this, ic, polyverts, closed)
Get a 2D array of polygon vertices, listed in clockwise order beginning with the lower left corner.
integer(i4b) function get_npolyverts(this, ic, closed)
Get the number of cell polygon vertices.
subroutine disv_df(this)
Define the discretization.
subroutine record_srcdst_list_header(this, text, textmodel, textpackage, dstmodel, dstpackage, naux, auxtxt, ibdchn, nlist, iout)
Record list header for imeth=6.
subroutine read_dbl_array(this, line, lloc, istart, istop, iout, in, darray, aname)
Read a double precision array.
subroutine source_cell2d(this)
Copy cell2d data from IDM into package.
subroutine source_options(this)
Copy options from IDM into package.
subroutine nodeu_to_array(this, nodeu, arr)
Convert a user nodenumber to an array (nodenumber) or (k,j)
subroutine connect(this)
Build grid connections.
integer(i4b) function nodeu_from_cellid(this, cellid, inunit, iout, flag_string, allow_zero)
Convert a cellid string to a user nodenumber.
subroutine source_griddata(this)
Copy grid data from IDM into package.
subroutine disv_load(this)
Transfer IDM data into this discretization object.
subroutine, public disv_cr(dis, name_model, input_mempath, inunit, iout)
Create a new discretization by vertices object.
subroutine define_cellverts(this, icell2d, ncvert, icvert)
Build data structures to hold cell vertex info.
subroutine source_vertices(this)
Load grid vertices from IDM into package.
subroutine read_int_array(this, line, lloc, istart, istop, iout, in, iarray, aname)
Read an integer array.
subroutine read_layer_array(this, nodelist, darray, ncolbnd, maxbnd, icolbnd, aname, inunit, iout)
Read a 2d double array into col icolbnd of darray.
subroutine connection_normal(this, noden, nodem, ihc, xcomp, ycomp, zcomp, ipos)
Get normal vector components between the cell and a given neighbor.
subroutine allocate_arrays(this)
Allocate and initialize arrays.
subroutine get_dis_type(this, dis_type)
Get the discretization type.
subroutine allocate_scalars(this, name_model, input_mempath)
Allocate and initialize scalars.
logical function supports_layers(this)
Indicates whether the grid discretization supports layers.
integer(i4b) function get_dis_enum(this)
Get the discretization type enumeration.
integer(i4b) function nodeu_from_string(this, lloc, istart, istop, in, iout, line, flag_string, allow_zero)
Convert a string to a user nodenumber.
integer(i4b) function, public get_node(ilay, irow, icol, nlay, nrow, ncol)
Get node number, given layer, row, and column indices for a structured grid. If any argument is inval...
subroutine, public get_ijk(nodenumber, nrow, ncol, nlay, irow, icol, ilay)
Get row, column and layer indices from node number and grid dimensions. If nodenumber is invalid,...
subroutine, public get_jk(nodenumber, ncpl, nlay, icpl, ilay)
Get layer index and within-layer node index from node number and grid dimensions. If nodenumber is in...
This module defines variable data types.
subroutine, public memorystore_remove(component, subcomponent, context)
This module contains simulation methods.
subroutine, public store_error(msg, terminate)
Store an error message.
integer(i4b) function, public count_errors()
Return number of errors.
subroutine, public store_error_filename(filename, terminate)
Store the erroring file name.
subroutine, public store_error_unit(iunit, terminate)
Store the file unit number.
This module contains simulation variables.
character(len=maxcharlen) errmsg
error message string
character(len=linelength) idm_context
real(dp), pointer, public pertim
time relative to start of stress period
real(dp), pointer, public totim
time relative to start of simulation
integer(i4b), pointer, public kstp
current time step number
integer(i4b), pointer, public kper
current stress period number
real(dp), pointer, public delt
length of the current time step
Vertex grid discretization.