26 integer(I4B),
pointer :: nlay => null()
27 integer(I4B),
pointer :: ncpl => null()
28 integer(I4B),
pointer :: nvert => null()
29 real(dp),
dimension(:, :),
pointer,
contiguous :: vertices => null()
30 real(dp),
dimension(:, :),
pointer,
contiguous :: cellxy => null()
31 integer(I4B),
dimension(:),
pointer,
contiguous :: iavert => null()
32 integer(I4B),
dimension(:),
pointer,
contiguous :: javert => null()
33 real(dp),
dimension(:),
pointer,
contiguous :: top1d => null()
34 real(dp),
dimension(:, :),
pointer,
contiguous :: bot2d => null()
35 integer(I4B),
dimension(:, :),
pointer,
contiguous :: idomain => null()
86 logical :: length_units = .false.
87 logical :: nogrb = .false.
88 logical :: xorigin = .false.
89 logical :: yorigin = .false.
90 logical :: angrot = .false.
91 logical :: nlay = .false.
92 logical :: ncpl = .false.
93 logical :: nvert = .false.
94 logical :: top = .false.
95 logical :: botm = .false.
96 logical :: idomain = .false.
97 logical :: iv = .false.
98 logical :: xv = .false.
99 logical :: yv = .false.
100 logical :: icell2d = .false.
101 logical :: xc = .false.
102 logical :: yc = .false.
103 logical :: ncvert = .false.
104 logical :: icvert = .false.
111 subroutine disv_cr(dis, name_model, input_mempath, inunit, iout)
114 character(len=*),
intent(in) :: name_model
115 character(len=*),
intent(in) :: input_mempath
116 integer(I4B),
intent(in) :: inunit
117 integer(I4B),
intent(in) :: iout
121 character(len=*),
parameter :: fmtheader = &
122 "(1X, /1X, 'DISV -- VERTEX GRID DISCRETIZATION PACKAGE,', &
123 &' VERSION 1 : 12/23/2015 - INPUT READ FROM MEMPATH: ', A, //)"
127 call disnew%allocate_scalars(name_model, input_mempath)
136 write (iout, fmtheader) dis%input_mempath
140 call disnew%disv_load()
152 call this%source_options()
153 call this%source_dimensions()
154 call this%source_griddata()
155 call this%source_vertices()
156 call this%source_cell2d()
166 call this%grid_finalize()
182 call this%DisBaseType%dis_da()
208 character(len=LENVARNAME),
dimension(3) :: lenunits = &
209 &[character(len=LENVARNAME) ::
'FEET',
'METERS',
'CENTIMETERS']
213 call mem_set_value(this%lenuni,
'LENGTH_UNITS', this%input_mempath, &
214 lenunits, found%length_units)
215 call mem_set_value(this%nogrb,
'NOGRB', this%input_mempath, found%nogrb)
216 call mem_set_value(this%xorigin,
'XORIGIN', this%input_mempath, found%xorigin)
217 call mem_set_value(this%yorigin,
'YORIGIN', this%input_mempath, found%yorigin)
218 call mem_set_value(this%angrot,
'ANGROT', this%input_mempath, found%angrot)
221 if (this%iout > 0)
then
222 call this%log_options(found)
234 write (this%iout,
'(1x,a)')
'Setting Discretization Options'
236 if (found%length_units)
then
237 write (this%iout,
'(4x,a,i0)')
'Model length unit [0=UND, 1=FEET, &
238 &2=METERS, 3=CENTIMETERS] set as ', this%lenuni
241 if (found%nogrb)
then
242 write (this%iout,
'(4x,a,i0)')
'Binary grid file [0=GRB, 1=NOGRB] &
243 &set as ', this%nogrb
246 if (found%xorigin)
then
247 write (this%iout,
'(4x,a,G0)')
'XORIGIN = ', this%xorigin
250 if (found%yorigin)
then
251 write (this%iout,
'(4x,a,G0)')
'YORIGIN = ', this%yorigin
254 if (found%angrot)
then
255 write (this%iout,
'(4x,a,G0)')
'ANGROT = ', this%angrot
258 write (this%iout,
'(1x,a,/)')
'End Setting Discretization Options'
272 call mem_set_value(this%nlay,
'NLAY', this%input_mempath, found%nlay)
273 call mem_set_value(this%ncpl,
'NCPL', this%input_mempath, found%ncpl)
274 call mem_set_value(this%nvert,
'NVERT', this%input_mempath, found%nvert)
277 if (this%iout > 0)
then
278 call this%log_dimensions(found)
282 if (this%nlay < 1)
then
284 'NLAY was not specified or was specified incorrectly.')
287 if (this%ncpl < 1)
then
289 'NCPL was not specified or was specified incorrectly.')
292 if (this%nvert < 1)
then
294 'NVERT was not specified or was specified incorrectly.')
299 this%nodesuser = this%nlay * this%ncpl
302 call mem_allocate(this%idomain, this%ncpl, this%nlay,
'IDOMAIN', &
304 call mem_allocate(this%top1d, this%ncpl,
'TOP1D', this%memoryPath)
305 call mem_allocate(this%bot2d, this%ncpl, this%nlay,
'BOT2D', &
309 call mem_allocate(this%vertices, 2, this%nvert,
'VERTICES', this%memoryPath)
310 call mem_allocate(this%cellxy, 2, this%ncpl,
'CELLXY', this%memoryPath)
315 this%idomain(j, k) = 1
328 write (this%iout,
'(1x,a)')
'Setting Discretization Dimensions'
331 write (this%iout,
'(4x,a,i0)')
'NLAY = ', this%nlay
335 write (this%iout,
'(4x,a,i0)')
'NCPL = ', this%ncpl
338 if (found%nvert)
then
339 write (this%iout,
'(4x,a,i0)')
'NVERT = ', this%nvert
342 write (this%iout,
'(1x,a,/)')
'End Setting Discretization Dimensions'
355 call mem_set_value(this%top1d,
'TOP', this%input_mempath, found%top)
356 call mem_set_value(this%bot2d,
'BOTM', this%input_mempath, found%botm)
357 call mem_set_value(this%idomain,
'IDOMAIN', this%input_mempath, found%idomain)
360 if (this%iout > 0)
then
361 call this%log_griddata(found)
373 write (this%iout,
'(1x,a)')
'Setting Discretization Griddata'
376 write (this%iout,
'(4x,a)')
'TOP set from input file'
380 write (this%iout,
'(4x,a)')
'BOTM set from input file'
383 if (found%idomain)
then
384 write (this%iout,
'(4x,a)')
'IDOMAIN set from input file'
387 write (this%iout,
'(1x,a,/)')
'End Setting Discretization Griddata'
397 integer(I4B) :: node, noder, j, k
401 character(len=*),
parameter :: fmtdz = &
402 "('CELL (',i0,',',i0,') THICKNESS <= 0. ', &
403 &'TOP, BOT: ',2(1pg24.15))"
404 character(len=*),
parameter :: fmtnr = &
405 "(/1x, 'The specified IDOMAIN results in a reduced number of cells.',&
406 &/1x, 'Number of user nodes: ',I0,&
407 &/1X, 'Number of nodes in solution: ', I0, //)"
413 if (this%idomain(j, k) > 0) this%nodes = this%nodes + 1
418 if (this%nodes == 0)
then
419 call store_error(
'Model does not have any active nodes. &
420 &Ensure IDOMAIN array has some values greater &
428 if (this%idomain(j, k) == 0) cycle
429 if (this%idomain(j, k) > 0)
then
431 top = this%bot2d(j, k - 1)
435 dz = top - this%bot2d(j, k)
436 if (dz <=
dzero)
then
437 write (
errmsg, fmt=fmtdz) k, j, top, this%bot2d(j, k)
448 if (this%nodes < this%nodesuser)
then
449 write (this%iout, fmtnr) this%nodesuser, this%nodes
453 call this%allocate_arrays()
459 if (this%nodes < this%nodesuser)
then
464 if (this%idomain(j, k) > 0)
then
465 this%nodereduced(node) = noder
467 elseif (this%idomain(j, k) < 0)
then
468 this%nodereduced(node) = -1
470 this%nodereduced(node) = 0
478 if (this%nodes < this%nodesuser)
then
483 if (this%idomain(j, k) > 0)
then
484 this%nodeuser(noder) = node
499 if (this%nodes < this%nodesuser) noder = this%nodereduced(node)
500 if (noder <= 0) cycle
502 top = this%bot2d(j, k - 1)
506 this%top(noder) = top
507 this%bot(noder) = this%bot2d(j, k)
508 this%xc(noder) = this%cellxy(1, j)
509 this%yc(noder) = this%cellxy(2, j)
525 real(DP),
dimension(:),
contiguous,
pointer :: vert_x => null()
526 real(DP),
dimension(:),
contiguous,
pointer :: vert_y => null()
529 call mem_setptr(vert_x,
'XV', this%input_mempath)
530 call mem_setptr(vert_y,
'YV', this%input_mempath)
533 if (
associated(vert_x) .and.
associated(vert_y))
then
535 this%vertices(1, i) = vert_x(i)
536 this%vertices(2, i) = vert_y(i)
539 call store_error(
'Required Vertex arrays not found.')
543 if (this%iout > 0)
then
544 write (this%iout,
'(1x,a)')
'Discretization Vertex data loaded'
558 integer(I4B),
dimension(:),
contiguous,
pointer,
intent(in) :: icell2d
559 integer(I4B),
dimension(:),
contiguous,
pointer,
intent(in) :: ncvert
560 integer(I4B),
dimension(:),
contiguous,
pointer,
intent(in) :: icvert
563 integer(I4B) :: i, j, ierr
564 integer(I4B) :: icv_idx, startvert, maxnnz = 5
567 call vert_spm%init(this%ncpl, this%nvert, maxnnz)
572 if (icell2d(i) /= i)
call store_error(
'ICELL2D input sequence violation.')
574 call vert_spm%addconnection(i, icvert(icv_idx), 0)
576 startvert = icvert(icv_idx)
577 elseif (j == ncvert(i) .and. (icvert(icv_idx) /= startvert))
then
578 call vert_spm%addconnection(i, startvert, 0)
580 icv_idx = icv_idx + 1
585 call mem_allocate(this%iavert, this%ncpl + 1,
'IAVERT', this%memoryPath)
586 call mem_allocate(this%javert, vert_spm%nnz,
'JAVERT', this%memoryPath)
587 call vert_spm%filliaja(this%iavert, this%javert, ierr)
588 call vert_spm%destroy()
598 integer(I4B),
dimension(:),
contiguous,
pointer :: icell2d => null()
599 integer(I4B),
dimension(:),
contiguous,
pointer :: ncvert => null()
600 integer(I4B),
dimension(:),
contiguous,
pointer :: icvert => null()
601 real(DP),
dimension(:),
contiguous,
pointer :: cell_x => null()
602 real(DP),
dimension(:),
contiguous,
pointer :: cell_y => null()
606 call mem_setptr(icell2d,
'ICELL2D', this%input_mempath)
607 call mem_setptr(ncvert,
'NCVERT', this%input_mempath)
608 call mem_setptr(icvert,
'ICVERT', this%input_mempath)
611 if (
associated(icell2d) .and.
associated(ncvert) &
612 .and.
associated(icvert))
then
613 call this%define_cellverts(icell2d, ncvert, icvert)
615 call store_error(
'Required cell vertex array(s) [ICELL2D, NCVERT, ICVERT] &
620 call mem_setptr(cell_x,
'XC', this%input_mempath)
621 call mem_setptr(cell_y,
'YC', this%input_mempath)
624 if (
associated(cell_x) .and.
associated(cell_y))
then
626 this%cellxy(1, i) = cell_x(i)
627 this%cellxy(2, i) = cell_y(i)
630 call store_error(
'Required cell center arrays not found.')
634 if (this%iout > 0)
then
635 write (this%iout,
'(1x,a)')
'Discretization Cell2d data loaded'
653 integer(I4B) :: noder, nrsize
654 integer(I4B) :: narea_eq_zero
655 integer(I4B) :: narea_lt_zero
664 area = this%get_cell2d_area(j)
666 noder = this%get_nodenumber(k, j, 0)
667 if (noder > 0) this%area(noder) = area
669 if (area <
dzero)
then
670 narea_lt_zero = narea_lt_zero + 1
671 write (
errmsg,
'(a,i0,a)') &
672 &
'Calculated CELL2D area less than zero for cell ', j,
'.'
675 if (area ==
dzero)
then
676 narea_eq_zero = narea_eq_zero + 1
677 write (
errmsg,
'(a,i0,a)') &
678 'Calculated CELL2D area is zero for cell ', j,
'.'
685 if (narea_lt_zero > 0)
then
686 write (
errmsg,
'(i0,a)') narea_lt_zero, &
687 ' cell(s) have an area less than zero. Calculated cell &
688 &areas must be greater than zero. Negative areas often &
689 &mean vertices are not listed in clockwise order.'
692 if (narea_eq_zero > 0)
then
693 write (
errmsg,
'(i0,a)') narea_eq_zero, &
694 ' cell(s) have an area equal to zero. Calculated cell &
695 &areas must be greater than zero. Calculated cell &
696 &areas equal to zero indicate that the cell is not defined &
697 &by a valid polygon.'
705 if (this%nodes < this%nodesuser) nrsize = this%nodes
707 call this%con%disvconnections(this%name_model, this%nodes, &
708 this%ncpl, this%nlay, nrsize, &
709 this%nvert, this%vertices, this%iavert, &
710 this%javert, this%cellxy, &
711 this%top, this%bot, &
712 this%nodereduced, this%nodeuser)
713 this%nja = this%con%nja
714 this%njas = this%con%njas
726 integer(I4B),
dimension(:),
intent(in) :: icelltype
728 integer(I4B) :: iunit, i, ntxt, version
729 integer(I4B),
parameter :: lentxt = 100
730 character(len=50) :: txthdr
731 character(len=lentxt) :: txt
732 character(len=LINELENGTH) :: fname
733 character(len=LENBIGLINE) :: crs
734 logical(LGP) :: found_crs
736 character(len=*),
parameter :: fmtgrdsave = &
737 "(4X,'BINARY GRID INFORMATION WILL BE WRITTEN TO:', &
738 &/,6X,'UNIT NUMBER: ', I0,/,6X, 'FILE NAME: ', A)"
744 call mem_set_value(crs,
'CRS', this%input_mempath, found_crs)
753 fname = trim(this%output_fname)
755 write (this%iout, fmtgrdsave) iunit, trim(adjustl(fname))
756 call openfile(iunit, this%iout, trim(adjustl(fname)),
'DATA(BINARY)', &
760 write (txthdr,
'(a)')
'GRID DISV'
761 txthdr(50:50) = new_line(
'a')
763 write (txthdr,
'(a, i0)')
'VERSION ', version
764 txthdr(50:50) = new_line(
'a')
766 write (txthdr,
'(a, i0)')
'NTXT ', ntxt
767 txthdr(50:50) = new_line(
'a')
769 write (txthdr,
'(a, i0)')
'LENTXT ', lentxt
770 txthdr(50:50) = new_line(
'a')
774 write (txt,
'(3a, i0)')
'NCELLS ',
'INTEGER ',
'NDIM 0 # ', this%nodesuser
775 txt(lentxt:lentxt) = new_line(
'a')
777 write (txt,
'(3a, i0)')
'NLAY ',
'INTEGER ',
'NDIM 0 # ', this%nlay
778 txt(lentxt:lentxt) = new_line(
'a')
780 write (txt,
'(3a, i0)')
'NCPL ',
'INTEGER ',
'NDIM 0 # ', this%ncpl
781 txt(lentxt:lentxt) = new_line(
'a')
783 write (txt,
'(3a, i0)')
'NVERT ',
'INTEGER ',
'NDIM 0 # ', this%nvert
784 txt(lentxt:lentxt) = new_line(
'a')
786 write (txt,
'(3a, i0)')
'NJAVERT ',
'INTEGER ',
'NDIM 0 # ',
size(this%javert)
787 txt(lentxt:lentxt) = new_line(
'a')
789 write (txt,
'(3a, i0)')
'NJA ',
'INTEGER ',
'NDIM 0 # ', this%con%nja
790 txt(lentxt:lentxt) = new_line(
'a')
792 write (txt,
'(3a, 1pg25.15e3)') &
793 'XORIGIN ',
'DOUBLE ',
'NDIM 0 # ', this%xorigin
794 txt(lentxt:lentxt) = new_line(
'a')
796 write (txt,
'(3a, 1pg25.15e3)') &
797 'YORIGIN ',
'DOUBLE ',
'NDIM 0 # ', this%yorigin
798 txt(lentxt:lentxt) = new_line(
'a')
800 write (txt,
'(3a, 1pg25.15e3)')
'ANGROT ',
'DOUBLE ',
'NDIM 0 # ', this%angrot
801 txt(lentxt:lentxt) = new_line(
'a')
803 write (txt,
'(3a, i0)')
'TOP ',
'DOUBLE ',
'NDIM 1 ', this%ncpl
804 txt(lentxt:lentxt) = new_line(
'a')
806 write (txt,
'(3a, i0)')
'BOTM ',
'DOUBLE ',
'NDIM 1 ', this%nodesuser
807 txt(lentxt:lentxt) = new_line(
'a')
809 write (txt,
'(3a, i0)')
'VERTICES ',
'DOUBLE ',
'NDIM 2 2 ', this%nvert
810 txt(lentxt:lentxt) = new_line(
'a')
812 write (txt,
'(3a, i0)')
'CELLX ',
'DOUBLE ',
'NDIM 1 ', this%ncpl
813 txt(lentxt:lentxt) = new_line(
'a')
815 write (txt,
'(3a, i0)')
'CELLY ',
'DOUBLE ',
'NDIM 1 ', this%ncpl
816 txt(lentxt:lentxt) = new_line(
'a')
818 write (txt,
'(3a, i0)')
'IAVERT ',
'INTEGER ',
'NDIM 1 ', this%ncpl + 1
819 txt(lentxt:lentxt) = new_line(
'a')
821 write (txt,
'(3a, i0)')
'JAVERT ',
'INTEGER ',
'NDIM 1 ',
size(this%javert)
822 txt(lentxt:lentxt) = new_line(
'a')
824 write (txt,
'(3a, i0)')
'IA ',
'INTEGER ',
'NDIM 1 ', this%nodesuser + 1
825 txt(lentxt:lentxt) = new_line(
'a')
827 write (txt,
'(3a, i0)')
'JA ',
'INTEGER ',
'NDIM 1 ',
size(this%con%jausr)
828 txt(lentxt:lentxt) = new_line(
'a')
830 write (txt,
'(3a, i0)')
'IDOMAIN ',
'INTEGER ',
'NDIM 1 ', this%nodesuser
831 txt(lentxt:lentxt) = new_line(
'a')
833 write (txt,
'(3a, i0)')
'ICELLTYPE ',
'INTEGER ',
'NDIM 1 ', this%nodesuser
834 txt(lentxt:lentxt) = new_line(
'a')
838 if (version == 2)
then
840 write (txt,
'(3a, i0)')
'CRS ',
'CHARACTER ',
'NDIM 1 ', &
842 txt(lentxt:lentxt) = new_line(
'a')
848 write (iunit) this%nodesuser
849 write (iunit) this%nlay
850 write (iunit) this%ncpl
851 write (iunit) this%nvert
852 write (iunit)
size(this%javert)
853 write (iunit) this%nja
854 write (iunit) this%xorigin
855 write (iunit) this%yorigin
856 write (iunit) this%angrot
857 write (iunit) this%top1d
858 write (iunit) this%bot2d
859 write (iunit) this%vertices
860 write (iunit) (this%cellxy(1, i), i=1, this%ncpl)
861 write (iunit) (this%cellxy(2, i), i=1, this%ncpl)
862 write (iunit) this%iavert
863 write (iunit) this%javert
864 write (iunit) this%con%iausr
865 write (iunit) this%con%jausr
866 write (iunit) this%idomain
867 write (iunit) icelltype
870 if (version == 2)
then
871 if (found_crs)
write (iunit) trim(crs)
884 integer(I4B),
intent(in) :: nodeu
885 character(len=*),
intent(inout) :: str
887 integer(I4B) :: i, j, k
888 character(len=10) :: kstr, jstr
890 call get_ijk(nodeu, 1, this%ncpl, this%nlay, i, j, k)
891 write (kstr,
'(i10)') k
892 write (jstr,
'(i10)') j
893 str =
'('//trim(adjustl(kstr))//
','// &
894 trim(adjustl(jstr))//
')'
903 integer(I4B),
intent(in) :: nodeu
904 integer(I4B),
dimension(:),
intent(inout) :: arr
906 integer(I4B) :: isize
907 integer(I4B) :: i, j, k
911 if (isize /= this%ndim)
then
912 write (
errmsg,
'(a,i0,a,i0,a)') &
913 'Program error: nodeu_to_array size of array (', isize, &
914 ') is not equal to the discretization dimension (', this%ndim,
').'
919 call get_ijk(nodeu, 1, this%ncpl, this%nlay, i, j, k)
931 integer(I4B) :: nodenumber
934 integer(I4B),
intent(in) :: nodeu
935 integer(I4B),
intent(in) :: icheck
939 if (icheck /= 0)
then
942 if (nodeu < 1 .or. nodeu > this%nodesuser)
then
944 write (
errmsg,
'(a,i0,a,i0,a)') &
945 'Node number (', nodeu,
') is less than 1 or greater than nodes (', &
950 if (this%nodes < this%nodesuser) nodenumber = this%nodereduced(nodeu)
954 if (this%nodes < this%nodesuser) nodenumber = this%nodereduced(nodeu)
963 integer(I4B) :: nodenumber
966 integer(I4B),
intent(in) :: k, j
967 integer(I4B),
intent(in) :: icheck
969 integer(I4B) :: nodeu
971 character(len=*),
parameter :: fmterr = &
972 &
"('Error in disv grid cell indices: layer = ',i0,', node = ',i0)"
974 nodeu =
get_node(k, 1, j, this%nlay, 1, this%ncpl)
976 write (
errmsg, fmterr) k, j
980 if (this%nodes < this%nodesuser) nodenumber = this%nodereduced(nodeu)
983 if (icheck /= 0)
then
987 if (k < 1 .or. k > this%nlay)
then
988 write (
errmsg,
'(a,i0,a)') &
989 'Layer number in list (', k,
') is outside of the grid.'
991 if (j < 1 .or. j > this%ncpl)
then
992 write (
errmsg,
'(a,1x,a,i0,a)') &
993 trim(adjustl(
errmsg)),
'Node number in list (', j, &
994 ') is outside of the grid.'
998 if (nodeu < 1 .or. nodeu > this%nodesuser)
then
999 write (
errmsg,
'(a,1x,a,i0,a,i0,a)') &
1001 'Node number (', nodeu,
') is less than 1 or greater '// &
1002 'than nodes (', this%nodesuser,
').'
1005 if (len_trim(adjustl(
errmsg)) > 0)
then
1021 integer(I4B),
intent(in) :: noden
1022 integer(I4B),
intent(in) :: nodem
1023 integer(I4B),
intent(in) :: ihc
1024 real(DP),
intent(inout) :: xcomp
1025 real(DP),
intent(inout) :: ycomp
1026 real(DP),
intent(inout) :: zcomp
1027 integer(I4B),
intent(in) :: ipos
1029 real(DP) :: angle, dmult
1035 if (nodem < noden)
then
1048 angle = this%con%anglex(this%con%jas(ipos))
1050 if (nodem < noden) dmult = -
done
1051 xcomp = cos(angle) * dmult
1052 ycomp = sin(angle) * dmult
1064 xcomp, ycomp, zcomp, conlen)
1067 integer(I4B),
intent(in) :: noden
1068 integer(I4B),
intent(in) :: nodem
1069 logical,
intent(in) :: nozee
1070 real(DP),
intent(in) :: satn
1071 real(DP),
intent(in) :: satm
1072 integer(I4B),
intent(in) :: ihc
1073 real(DP),
intent(inout) :: xcomp
1074 real(DP),
intent(inout) :: ycomp
1075 real(DP),
intent(inout) :: zcomp
1076 real(DP),
intent(inout) :: conlen
1078 integer(I4B) :: nodeu, ncell2d, mcell2d, k
1079 real(DP) :: xn, xm, yn, ym, zn, zm
1087 if (nodem < noden)
then
1092 zn = this%bot(noden) +
dhalf * (this%top(noden) - this%bot(noden))
1093 zm = this%bot(nodem) +
dhalf * (this%top(nodem) - this%bot(nodem))
1094 conlen = abs(zm - zn)
1103 zn = this%bot(noden) +
dhalf * satn * (this%top(noden) - this%bot(noden))
1104 zm = this%bot(nodem) +
dhalf * satm * (this%top(nodem) - this%bot(nodem))
1106 nodeu = this%get_nodeuser(noden)
1107 call get_jk(nodeu, this%ncpl, this%nlay, ncell2d, k)
1108 nodeu = this%get_nodeuser(nodem)
1109 call get_jk(nodeu, this%ncpl, this%nlay, mcell2d, k)
1110 xn = this%cellxy(1, ncell2d)
1111 yn = this%cellxy(2, ncell2d)
1112 xm = this%cellxy(1, mcell2d)
1113 ym = this%cellxy(2, mcell2d)
1124 class(
disvtype),
intent(in) :: this
1125 character(len=*),
intent(out) :: dis_type
1134 class(
disvtype),
intent(in) :: this
1135 integer(I4B) :: dis_enum
1144 character(len=*),
intent(in) :: name_model
1145 character(len=*),
intent(in) :: input_mempath
1148 call this%DisBaseType%allocate_scalars(name_model, input_mempath)
1153 call mem_allocate(this%nvert,
'NVERT', this%memoryPath)
1170 call this%DisBaseType%allocate_arrays()
1173 if (this%nodes < this%nodesuser)
then
1174 call mem_allocate(this%nodeuser, this%nodes,
'NODEUSER', this%memoryPath)
1175 call mem_allocate(this%nodereduced, this%nodesuser,
'NODEREDUCED', &
1178 call mem_allocate(this%nodeuser, 1,
'NODEUSER', this%memoryPath)
1179 call mem_allocate(this%nodereduced, 1,
'NODEREDUCED', this%memoryPath)
1182 this%mshape(1) = this%nlay
1183 this%mshape(2) = this%ncpl
1197 integer(I4B),
intent(in) :: icell2d
1201 integer(I4B) :: ivert
1202 integer(I4B) :: nvert
1203 integer(I4B) :: icount
1211 nvert = this%iavert(icell2d + 1) - this%iavert(icell2d)
1213 iv1 = this%javert(this%iavert(icell2d))
1214 x1 = this%vertices(1, iv1)
1215 y1 = this%vertices(2, iv1)
1216 do ivert = this%iavert(icell2d), this%iavert(icell2d + 1) - 1
1217 x = this%vertices(1, this%javert(ivert))
1218 if (icount < nvert)
then
1219 y = this%vertices(2, this%javert(ivert + 1))
1221 y = this%vertices(2, this%javert(this%iavert(icell2d)))
1223 area = area + (x - x1) * (y - y1)
1228 do ivert = this%iavert(icell2d), this%iavert(icell2d + 1) - 1
1229 y = this%vertices(2, this%javert(ivert))
1230 if (icount < nvert)
then
1231 x = this%vertices(1, this%javert(ivert + 1))
1233 x = this%vertices(1, this%javert(this%iavert(icell2d)))
1235 area = area - (x - x1) * (y - y1)
1250 flag_string, allow_zero)
result(nodeu)
1253 integer(I4B),
intent(inout) :: lloc
1254 integer(I4B),
intent(inout) :: istart
1255 integer(I4B),
intent(inout) :: istop
1256 integer(I4B),
intent(in) :: in
1257 integer(I4B),
intent(in) :: iout
1258 character(len=*),
intent(inout) :: line
1259 logical,
optional,
intent(in) :: flag_string
1260 logical,
optional,
intent(in) :: allow_zero
1261 integer(I4B) :: nodeu
1263 integer(I4B) :: j, k, nlay, nrow, ncpl
1264 integer(I4B) :: lloclocal, ndum, istat, n
1267 if (
present(flag_string))
then
1268 if (flag_string)
then
1271 call urword(line, lloclocal, istart, istop, 1, ndum, r, iout, in)
1272 read (line(istart:istop), *, iostat=istat) n
1273 if (istat /= 0)
then
1281 nlay = this%mshape(1)
1283 ncpl = this%mshape(2)
1285 call urword(line, lloc, istart, istop, 2, k, r, iout, in)
1286 call urword(line, lloc, istart, istop, 2, j, r, iout, in)
1288 if (k == 0 .and. j == 0)
then
1289 if (
present(allow_zero))
then
1290 if (allow_zero)
then
1299 if (k < 1 .or. k > nlay)
then
1300 write (
errmsg,
'(a,i0,a)') &
1301 'Layer number in list (', k,
') is outside of the grid.'
1303 if (j < 1 .or. j > ncpl)
then
1304 write (
errmsg,
'(a,1x,a,i0,a)') &
1305 trim(adjustl(
errmsg)),
'Cell2d number in list (', j, &
1306 ') is outside of the grid.'
1309 nodeu =
get_node(k, 1, j, nlay, nrow, ncpl)
1311 if (nodeu < 1 .or. nodeu > this%nodesuser)
then
1312 write (
errmsg,
'(a,1x,a,i0,a)') &
1314 "Node number in list (", nodeu,
") is outside of the grid. "// &
1315 "Cell number cannot be determined in line '"// &
1316 trim(adjustl(line))//
"'."
1319 if (len_trim(adjustl(
errmsg)) > 0)
then
1335 allow_zero)
result(nodeu)
1337 integer(I4B) :: nodeu
1340 character(len=*),
intent(inout) :: cellid
1341 integer(I4B),
intent(in) :: inunit
1342 integer(I4B),
intent(in) :: iout
1343 logical,
optional,
intent(in) :: flag_string
1344 logical,
optional,
intent(in) :: allow_zero
1346 integer(I4B) :: j, k, nlay, nrow, ncpl
1347 integer(I4B) :: lloclocal, ndum, istat, n
1348 integer(I4B) :: istart, istop
1351 if (
present(flag_string))
then
1352 if (flag_string)
then
1355 call urword(cellid, lloclocal, istart, istop, 1, ndum, r, iout, inunit)
1356 read (cellid(istart:istop), *, iostat=istat) n
1357 if (istat /= 0)
then
1365 nlay = this%mshape(1)
1367 ncpl = this%mshape(2)
1370 call urword(cellid, lloclocal, istart, istop, 2, k, r, iout, inunit)
1371 call urword(cellid, lloclocal, istart, istop, 2, j, r, iout, inunit)
1373 if (k == 0 .and. j == 0)
then
1374 if (
present(allow_zero))
then
1375 if (allow_zero)
then
1384 if (k < 1 .or. k > nlay)
then
1385 write (
errmsg,
'(a,i0,a)') &
1386 'Layer number in list (', k,
') is outside of the grid.'
1388 if (j < 1 .or. j > ncpl)
then
1389 write (
errmsg,
'(a,1x,a,i0,a)') &
1390 trim(adjustl(
errmsg)),
'Cell2d number in list (', j, &
1391 ') is outside of the grid.'
1394 nodeu =
get_node(k, 1, j, nlay, nrow, ncpl)
1396 if (nodeu < 1 .or. nodeu > this%nodesuser)
then
1397 write (
errmsg,
'(a,1x,a,i0,a)') &
1399 "Cell number cannot be determined for cellid ("// &
1400 trim(adjustl(cellid))//
") and results in a user "// &
1401 "node number (", nodeu,
") that is outside of the grid."
1404 if (len_trim(adjustl(
errmsg)) > 0)
then
1438 class(
disvtype),
intent(inout) :: this
1439 integer(I4B),
intent(in) :: ic
1440 real(DP),
allocatable,
intent(out) :: polyverts(:, :)
1441 logical(LGP),
intent(in),
optional :: closed
1443 integer(I4B) :: icu, icu2d, iavert, ncpl, nverts, m, j
1444 logical(LGP) :: lclosed
1447 ncpl = this%get_ncpl()
1448 icu = this%get_nodeuser(ic)
1449 icu2d = icu - ((icu - 1) / ncpl) * ncpl
1450 nverts = this%iavert(icu2d + 1) - this%iavert(icu2d) - 1
1453 if (.not. (
present(closed)))
then
1461 allocate (polyverts(2, nverts + 1))
1463 allocate (polyverts(2, nverts))
1467 iavert = this%iavert(icu2d)
1469 j = this%javert(iavert - 1 + m)
1470 polyverts(:, m) = (/this%vertices(1, j), this%vertices(2, j)/)
1475 polyverts(:, nverts + 1) = polyverts(:, 1)
1481 class(
disvtype),
intent(inout) :: this
1482 integer(I4B),
intent(in) :: ic
1483 logical(LGP),
intent(in),
optional :: closed
1484 integer(I4B) :: npolyverts
1486 integer(I4B) :: ncpl, icu, icu2d
1488 ncpl = this%get_ncpl()
1489 icu = this%get_nodeuser(ic)
1490 icu2d = icu - ((icu - 1) / ncpl) * ncpl
1491 npolyverts = this%iavert(icu2d + 1) - this%iavert(icu2d) - 1
1492 if (
present(closed))
then
1493 if (closed) npolyverts = npolyverts + 1
1499 class(
disvtype),
intent(inout) :: this
1500 logical(LGP),
intent(in),
optional :: closed
1501 integer(I4B) :: max_npolyverts
1505 do ic = 1, this%nodes
1506 max_npolyverts = max(max_npolyverts, this%get_npolyverts(ic, closed))
1515 class(
disvtype),
intent(inout) :: this
1516 character(len=*),
intent(inout) :: line
1517 integer(I4B),
intent(inout) :: lloc
1518 integer(I4B),
intent(inout) :: istart
1519 integer(I4B),
intent(inout) :: istop
1520 integer(I4B),
intent(in) :: in
1521 integer(I4B),
intent(in) :: iout
1522 integer(I4B),
dimension(:),
pointer,
contiguous,
intent(inout) :: iarray
1523 character(len=*),
intent(in) :: aname
1525 integer(I4B) :: ival
1527 integer(I4B) :: nlay
1528 integer(I4B) :: nrow
1529 integer(I4B) :: ncol
1530 integer(I4B) :: nval
1531 integer(I4B),
dimension(:),
pointer,
contiguous :: itemp
1537 nlay = this%mshape(1)
1539 ncol = this%mshape(2)
1541 if (this%nodes < this%nodesuser)
then
1542 nval = this%nodesuser
1550 call urword(line, lloc, istart, istop, 1, ival, rval, iout, in)
1551 if (line(istart:istop) .EQ.
'LAYERED')
then
1554 call readarray(in, itemp, aname, this%ndim, ncol, nrow, nlay, nval, &
1559 call readarray(in, itemp, aname, this%ndim, nval, iout, 0)
1563 if (this%nodes < this%nodesuser)
then
1564 call this%fill_grid_array(itemp, iarray)
1574 class(
disvtype),
intent(inout) :: this
1575 character(len=*),
intent(inout) :: line
1576 integer(I4B),
intent(inout) :: lloc
1577 integer(I4B),
intent(inout) :: istart
1578 integer(I4B),
intent(inout) :: istop
1579 integer(I4B),
intent(in) :: in
1580 integer(I4B),
intent(in) :: iout
1581 real(DP),
dimension(:),
pointer,
contiguous,
intent(inout) :: darray
1582 character(len=*),
intent(in) :: aname
1584 integer(I4B) :: ival
1586 integer(I4B) :: nlay
1587 integer(I4B) :: nrow
1588 integer(I4B) :: ncol
1589 integer(I4B) :: nval
1590 real(DP),
dimension(:),
pointer,
contiguous :: dtemp
1596 nlay = this%mshape(1)
1598 ncol = this%mshape(2)
1600 if (this%nodes < this%nodesuser)
then
1601 nval = this%nodesuser
1609 call urword(line, lloc, istart, istop, 1, ival, rval, iout, in)
1610 if (line(istart:istop) .EQ.
'LAYERED')
then
1613 call readarray(in, dtemp, aname, this%ndim, ncol, nrow, nlay, nval, &
1618 call readarray(in, dtemp, aname, this%ndim, nval, iout, 0)
1622 if (this%nodes < this%nodesuser)
then
1623 call this%fill_grid_array(dtemp, darray)
1634 icolbnd, aname, inunit, iout)
1637 integer(I4B),
intent(in) :: ncolbnd
1638 integer(I4B),
intent(in) :: maxbnd
1639 integer(I4B),
dimension(maxbnd) :: nodelist
1640 real(DP),
dimension(ncolbnd, maxbnd),
intent(inout) :: darray
1641 integer(I4B),
intent(in) :: icolbnd
1642 character(len=*),
intent(in) :: aname
1643 integer(I4B),
intent(in) :: inunit
1644 integer(I4B),
intent(in) :: iout
1646 integer(I4B) :: ir, ic, ncol, nrow, nlay, nval, ipos, nodeu
1649 nlay = this%mshape(1)
1651 ncol = this%mshape(2)
1655 call readarray(inunit, this%dbuff, aname, this%ndim, nval, iout, 0)
1664 nodeu =
get_node(1, ir, ic, nlay, nrow, ncol)
1665 darray(icolbnd, ipos) = this%dbuff(nodeu)
1678 cdatafmp, nvaluesp, nwidthp, editdesc, dinact)
1680 class(
disvtype),
intent(inout) :: this
1681 real(DP),
dimension(:),
pointer,
contiguous,
intent(inout) :: darray
1682 integer(I4B),
intent(in) :: iout
1683 integer(I4B),
intent(in) :: iprint
1684 integer(I4B),
intent(in) :: idataun
1685 character(len=*),
intent(in) :: aname
1686 character(len=*),
intent(in) :: cdatafmp
1687 integer(I4B),
intent(in) :: nvaluesp
1688 integer(I4B),
intent(in) :: nwidthp
1689 character(len=*),
intent(in) :: editdesc
1690 real(DP),
intent(in) :: dinact
1692 integer(I4B) :: k, ifirst
1693 integer(I4B) :: nlay
1694 integer(I4B) :: nrow
1695 integer(I4B) :: ncol
1696 integer(I4B) :: nval
1697 integer(I4B) :: nodeu, noder
1698 integer(I4B) :: istart, istop
1699 real(DP),
dimension(:),
pointer,
contiguous :: dtemp
1701 character(len=*),
parameter :: fmthsv = &
1702 "(1X,/1X,a,' WILL BE SAVED ON UNIT ',I4, &
1703 &' AT END OF TIME STEP',I5,', STRESS PERIOD ',I4)"
1706 nlay = this%mshape(1)
1708 ncol = this%mshape(2)
1712 if (this%nodes < this%nodesuser)
then
1715 do nodeu = 1, this%nodesuser
1716 noder = this%get_nodenumber(nodeu, 0)
1717 if (noder <= 0)
then
1718 dtemp(nodeu) = dinact
1721 dtemp(nodeu) = darray(noder)
1729 if (iprint /= 0)
then
1732 istop = istart + nrow * ncol - 1
1734 aname, cdatafmp, nvaluesp, nwidthp, editdesc)
1740 if (idataun > 0)
then
1745 istop = istart + nrow * ncol - 1
1746 if (ifirst == 1)
write (iout, fmthsv) &
1747 trim(adjustl(aname)), idataun, &
1754 elseif (idataun < 0)
then
1757 call ubdsv1(
kstp,
kper, aname, -idataun, dtemp, ncol, nrow, nlay, &
1766 dstmodel, dstpackage, naux, auxtxt, &
1767 ibdchn, nlist, iout)
1770 character(len=16),
intent(in) :: text
1771 character(len=16),
intent(in) :: textmodel
1772 character(len=16),
intent(in) :: textpackage
1773 character(len=16),
intent(in) :: dstmodel
1774 character(len=16),
intent(in) :: dstpackage
1775 integer(I4B),
intent(in) :: naux
1776 character(len=16),
dimension(:),
intent(in) :: auxtxt
1777 integer(I4B),
intent(in) :: ibdchn
1778 integer(I4B),
intent(in) :: nlist
1779 integer(I4B),
intent(in) :: iout
1781 integer(I4B) :: nlay, nrow, ncol
1783 nlay = this%mshape(1)
1785 ncol = this%mshape(2)
1788 call ubdsv06(
kstp,
kper, text, textmodel, textpackage, dstmodel, dstpackage, &
1789 ibdchn, naux, auxtxt, ncol, nrow, nlay, &
1799 integer(I4B),
intent(in) :: maxbnd
1800 integer(I4B),
dimension(:),
pointer,
contiguous :: darray
1801 integer(I4B),
dimension(maxbnd),
intent(inout) :: nodelist
1802 integer(I4B),
intent(inout) :: nbound
1803 character(len=*),
intent(in) :: aname
1805 integer(I4B) :: il, ir, ic, ncol, nrow, nlay, nval, nodeu, noder, ipos, ierr
1808 nlay = this%mshape(1)
1810 ncol = this%mshape(2)
1819 nodeu =
get_node(1, ir, ic, nlay, nrow, ncol)
1821 if (il < 1 .or. il > nlay)
then
1822 write (
errmsg,
'(a,i0,a)') &
1823 'Invalid layer number (', il,
').'
1826 nodeu =
get_node(il, ir, ic, nlay, nrow, ncol)
1827 noder = this%get_nodenumber(nodeu, 0)
1828 if (ipos > maxbnd)
then
1831 nodelist(ipos) = noder
1840 write (
errmsg,
'(a,i0,a)') &
1841 'MAXBOUND dimension is too small. Increase MAXBOUND to ', ierr,
'.'
1846 if (nbound < maxbnd)
then
1847 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)
subroutine, public memorystore_release(varname, memory_path)
Release a single variable from the memory store.
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.