27 public :: swfdfwtype, dfw_cr
30 type :: dfwoptionsfoundtype
31 logical(LGP) :: icentral = .false.
32 logical(LGP) :: iswrcond = .false.
33 logical(LGP) :: lengthconv = .false.
34 logical(LGP) :: timeconv = .false.
35 logical(LGP) :: iprflow = .false.
36 logical(LGP) :: ipakcb = .false.
37 logical(LGP) :: isavvelocity = .false.
38 logical(LGP) :: obs6_filename = .false.
39 end type dfwoptionsfoundtype
42 type :: dfwgriddatafoundtype
43 logical(LGP) :: manningsn = .false.
44 logical(LGP) :: idcxs = .false.
45 end type dfwgriddatafoundtype
50 integer(I4B),
pointer :: is2d => null()
51 integer(I4B),
pointer :: icentral => null()
52 integer(I4B),
pointer :: iswrcond => null()
53 real(DP),
pointer :: unitconv
54 real(DP),
pointer :: timeconv
55 real(DP),
pointer :: lengthconv
56 real(DP),
dimension(:),
pointer,
contiguous :: hnew => null()
57 real(DP),
dimension(:),
pointer,
contiguous :: manningsn => null()
58 integer(I4B),
dimension(:),
pointer,
contiguous :: idcxs => null()
59 integer(I4B),
dimension(:),
pointer,
contiguous :: ibound => null()
60 integer(I4B),
dimension(:),
pointer,
contiguous :: icelltype => null()
63 integer(I4B),
pointer :: icalcvelocity => null()
64 integer(I4B),
pointer :: isavvelocity => null()
65 real(DP),
dimension(:, :),
pointer,
contiguous :: vcomp => null()
66 real(DP),
dimension(:),
pointer,
contiguous :: vmag => null()
67 integer(I4B),
pointer :: nedges => null()
68 integer(I4B),
pointer :: lastedge => null()
69 integer(I4B),
dimension(:),
pointer,
contiguous :: nodedge => null()
70 integer(I4B),
dimension(:),
pointer,
contiguous :: ihcedge => null()
71 real(DP),
dimension(:, :),
pointer,
contiguous :: propsedge => null()
72 real(DP),
dimension(:),
pointer,
contiguous :: grad_dhds_mag => null()
73 real(DP),
dimension(:),
pointer,
contiguous :: dhdsja => null()
76 integer(I4B),
pointer :: inobspkg => null()
77 type(ObsType),
pointer :: obs => null()
80 type(SwfCxsType),
pointer :: cxs
85 procedure :: allocate_scalars
86 procedure :: allocate_arrays
88 procedure :: source_options
89 procedure :: log_options
90 procedure :: source_griddata
91 procedure :: log_griddata
96 procedure :: dfw_qnm_fc_nr
102 procedure :: dfw_save_model_flows
103 procedure :: dfw_print_model_flows
105 procedure :: dfw_df_obs
106 procedure :: dfw_rp_obs
107 procedure :: dfw_bd_obs
109 procedure :: get_cond
110 procedure :: get_cond_swr
111 procedure :: get_cond_n
112 procedure :: get_flow_area_nm
113 procedure :: calc_velocity
114 procedure :: sav_velocity
115 procedure,
public :: increase_edge_count
116 procedure,
public :: set_edge_properties
117 procedure :: calc_dhds
118 procedure :: write_cxs_tables
126 subroutine dfw_cr(dfwobj, name_model, input_mempath, inunit, iout, &
131 type(SwfDfwType),
pointer :: dfwobj
132 character(len=*),
intent(in) :: name_model
133 character(len=*),
intent(in) :: input_mempath
134 integer(I4B),
intent(in) :: inunit
135 integer(I4B),
intent(in) :: iout
136 type(SwfCxsType),
pointer,
intent(in) :: cxs
138 logical(LGP) :: found_fname
140 character(len=*),
parameter :: fmtheader = &
141 "(1x, /1x, 'DFW -- DIFFUSIVE WAVE (DFW) PACKAGE, VERSION 1, 9/25/2023', &
142 &' INPUT READ FROM MEMPATH: ', A, /)"
148 call dfwobj%set_names(1, name_model,
'DFW',
'DFW')
151 call dfwobj%allocate_scalars()
154 dfwobj%input_mempath = input_mempath
155 dfwobj%inunit = inunit
159 call mem_set_value(dfwobj%input_fname,
'INPUT_FNAME', dfwobj%input_mempath, &
166 call obs_cr(dfwobj%obs, dfwobj%inobspkg)
172 write (iout, fmtheader) input_mempath
176 end subroutine dfw_cr
180 subroutine dfw_df(this, dis)
182 class(SwfDfwType) :: this
183 class(DisBaseType),
pointer,
intent(inout) :: dis
189 if (this%dis%is_2d())
then
198 call this%allocate_arrays()
205 end subroutine dfw_df
213 subroutine allocate_scalars(this)
216 class(SwfDfwtype) :: this
219 call this%NumericalPackageType%allocate_scalars()
223 call mem_allocate(this%icentral,
'ICENTRAL', this%memoryPath)
224 call mem_allocate(this%iswrcond,
'ISWRCOND', this%memoryPath)
225 call mem_allocate(this%unitconv,
'UNITCONV', this%memoryPath)
226 call mem_allocate(this%lengthconv,
'LENGTHCONV', this%memoryPath)
227 call mem_allocate(this%timeconv,
'TIMECONV', this%memoryPath)
228 call mem_allocate(this%inobspkg,
'INOBSPKG', this%memoryPath)
229 call mem_allocate(this%icalcvelocity,
'ICALCVELOCITY', this%memoryPath)
230 call mem_allocate(this%isavvelocity,
'ISAVVELOCITY', this%memoryPath)
231 call mem_allocate(this%nedges,
'NEDGES', this%memoryPath)
232 call mem_allocate(this%lastedge,
'LASTEDGE', this%memoryPath)
238 this%lengthconv =
done
241 this%icalcvelocity = 0
242 this%isavvelocity = 0
246 end subroutine allocate_scalars
250 subroutine allocate_arrays(this)
252 class(SwfDfwType) :: this
258 'MANNINGSN', this%memoryPath)
260 'IDCXS', this%memoryPath)
262 'ICELLTYPE', this%memoryPath)
265 call mem_allocate(this%nodedge, 0,
'NODEDGE', this%memoryPath)
266 call mem_allocate(this%ihcedge, 0,
'IHCEDGE', this%memoryPath)
267 call mem_allocate(this%propsedge, 0, 0,
'PROPSEDGE', this%memoryPath)
270 call mem_allocate(this%vcomp, 3, 0,
'VCOMP', this%memoryPath)
271 call mem_allocate(this%vmag, 0,
'VMAG', this%memoryPath)
273 do n = 1, this%dis%nodes
274 this%manningsn(n) =
dzero
276 this%icelltype(n) = 1
280 if (this%is2d == 1)
then
282 'GRAD_DHDS_MAG', this%memoryPath)
284 'DHDSJA', this%memoryPath)
285 do n = 1, this%dis%nodes
286 this%grad_dhds_mag(n) =
dzero
288 do n = 1, this%dis%njas
289 this%dhdsja(n) =
dzero
293 end subroutine allocate_arrays
297 subroutine dfw_load(this)
299 class(SwfDfwType) :: this
302 call this%source_options()
303 call this%source_griddata()
305 end subroutine dfw_load
309 subroutine source_options(this)
316 class(SwfDfwType) :: this
318 integer(I4B) :: isize
319 type(DfwOptionsFoundType) :: found
320 type(CharacterStringType),
dimension(:),
pointer, &
321 contiguous :: obs6_fnames
325 this%input_mempath, found%icentral)
327 this%input_mempath, found%iswrcond)
329 this%input_mempath, found%lengthconv)
331 this%input_mempath, found%timeconv)
333 this%input_mempath, found%iprflow)
335 this%input_mempath, found%ipakcb)
337 this%input_mempath, found%isavvelocity)
340 if (found%icentral) this%icentral = 1
341 if (found%ipakcb) this%ipakcb = -1
344 this%unitconv = this%lengthconv**
donethird
345 this%unitconv = this%unitconv * this%timeconv
348 if (found%isavvelocity) this%icalcvelocity = this%isavvelocity
351 call get_isize(
'OBS6_FILENAME', this%input_mempath, isize)
355 errmsg =
'Multiple OBS6 keywords detected in OPTIONS block.'// &
356 ' Only one OBS6 entry allowed.'
361 call mem_setptr(obs6_fnames,
'OBS6_FILENAME', this%input_mempath)
363 found%obs6_filename = .true.
364 this%obs%inputFilename = obs6_fnames(1)
365 this%obs%active = .true.
367 this%obs%inUnitObs = this%inobspkg
368 call openfile(this%inobspkg, this%iout, this%obs%inputFilename,
'OBS')
369 call this%obs%obs_df(this%iout, this%packName, this%filtyp, this%dis)
370 call this%dfw_df_obs()
376 if (this%iout > 0)
then
377 call this%log_options(found)
380 end subroutine source_options
384 subroutine log_options(this, found)
385 class(SwfDfwType) :: this
386 type(DfwOptionsFoundType),
intent(in) :: found
388 write (this%iout,
'(1x,a)')
'Setting DFW Options'
390 if (found%lengthconv)
then
391 write (this%iout,
'(4x,a, G0)')
'Mannings length conversion value &
392 &specified as ', this%lengthconv
395 if (found%timeconv)
then
396 write (this%iout,
'(4x,a, G0)')
'Mannings time conversion value &
397 &specified as ', this%timeconv
400 if (found%lengthconv .or. found%timeconv)
then
401 write (this%iout,
'(4x,a, G0)')
'Mannings conversion value calculated &
402 &from user-provided length_conversion and &
403 &time_conversion is ', this%unitconv
406 if (found%iprflow)
then
407 write (this%iout,
'(4x,a)')
'Cell-by-cell flow information will be printed &
408 &to listing file whenever ICBCFL is not zero.'
411 if (found%ipakcb)
then
412 write (this%iout,
'(4x,a)')
'Cell-by-cell flow information will be printed &
413 &to listing file whenever ICBCFL is not zero.'
416 if (found%obs6_filename)
then
417 write (this%iout,
'(4x,a)')
'Observation package is active.'
420 if (found%isavvelocity) &
421 write (this%iout,
'(4x,a)')
'Velocity will be calculated at cell &
422 ¢ers and written to DATA-VCOMP in budget &
423 &file when requested.'
425 if (found%iswrcond)
then
426 write (this%iout,
'(4x,a, G0)')
'Conductance will be calculated using &
427 &the SWR development option.'
430 write (this%iout,
'(1x,a,/)')
'End Setting DFW Options'
432 end subroutine log_options
436 subroutine source_griddata(this)
443 class(SwfDfwType) :: this
445 character(len=LENMEMPATH) :: idmMemoryPath
446 type(DfwGriddataFoundType) :: found
447 integer(I4B),
dimension(:),
pointer,
contiguous :: map
454 if (this%dis%nodes < this%dis%nodesuser) map => this%dis%nodeuser
458 idmmemorypath, map, found%manningsn)
459 call mem_set_value(this%idcxs,
'IDCXS', idmmemorypath, map, found%idcxs)
462 if (.not. found%manningsn)
then
463 write (errmsg,
'(a)')
'Error in GRIDDATA block: MANNINGSN not found.'
468 call store_error_filename(this%input_fname)
472 if (this%iout > 0)
then
473 call this%log_griddata(found)
476 end subroutine source_griddata
480 subroutine log_griddata(this, found)
481 class(SwfDfwType) :: this
482 type(DfwGriddataFoundType),
intent(in) :: found
484 write (this%iout,
'(1x,a)')
'Setting DFW Griddata'
486 if (found%manningsn)
then
487 write (this%iout,
'(4x,a)')
'MANNINGSN set from input file'
490 if (found%idcxs)
then
491 write (this%iout,
'(4x,a)')
'IDCXS set from input file'
494 call this%write_cxs_tables()
496 write (this%iout,
'(1x,a,/)')
'End Setting DFW Griddata'
498 end subroutine log_griddata
500 subroutine write_cxs_tables(this)
503 class(SwfDfwType) :: this
516 end subroutine write_cxs_tables
520 subroutine dfw_ar(this, ibound, hnew)
523 class(SwfDfwType) :: this
524 integer(I4B),
dimension(:),
pointer,
contiguous :: ibound
525 real(DP),
dimension(:),
pointer,
contiguous,
intent(inout) :: hnew
530 this%ibound => ibound
533 if (this%icalcvelocity == 1)
then
534 call mem_reallocate(this%vcomp, 3, this%dis%nodes,
'VCOMP', this%memoryPath)
535 call mem_reallocate(this%vmag, this%dis%nodes,
'VMAG', this%memoryPath)
536 call mem_reallocate(this%nodedge, this%nedges,
'NODEDGE', this%memoryPath)
537 call mem_reallocate(this%ihcedge, this%nedges,
'IHCEDGE', this%memoryPath)
538 call mem_reallocate(this%propsedge, 5, this%nedges,
'PROPSEDGE', &
540 do n = 1, this%dis%nodes
541 this%vcomp(:, n) =
dzero
547 call this%obs%obs_ar()
549 end subroutine dfw_ar
553 subroutine dfw_rp(this)
556 class(SwfDfwType) :: this
559 call this%dfw_rp_obs()
561 end subroutine dfw_rp
565 subroutine dfw_ad(this, irestore)
566 class(SwfDfwType) :: this
567 integer(I4B),
intent(in) :: irestore
570 call this%obs%obs_ad()
572 end subroutine dfw_ad
580 subroutine dfw_fc(this, kiter, matrix_sln, idxglo, rhs, stage, stage_old)
583 class(SwfDfwType) :: this
584 integer(I4B) :: kiter
585 class(MatrixBaseType),
pointer :: matrix_sln
586 integer(I4B),
intent(in),
dimension(:) :: idxglo
587 real(DP),
intent(inout),
dimension(:) :: rhs
588 real(DP),
intent(inout),
dimension(:) :: stage
589 real(DP),
intent(inout),
dimension(:) :: stage_old
593 if (this%is2d == 1)
then
594 call this%calc_dhds()
598 call this%dfw_qnm_fc_nr(kiter, matrix_sln, idxglo, rhs, stage, stage_old)
600 end subroutine dfw_fc
605 subroutine dfw_qnm_fc_nr(this, kiter, matrix_sln, idxglo, rhs, stage, stage_old)
609 class(SwfDfwType) :: this
610 integer(I4B) :: kiter
611 class(MatrixBaseType),
pointer :: matrix_sln
612 integer(I4B),
intent(in),
dimension(:) :: idxglo
613 real(DP),
intent(inout),
dimension(:) :: rhs
614 real(DP),
intent(inout),
dimension(:) :: stage
615 real(DP),
intent(inout),
dimension(:) :: stage_old
617 integer(I4B) :: n, m, ii, idiag
624 do n = 1, this%dis%nodes
627 idiag = this%dis%con%ia(n)
630 do ii = this%dis%con%ia(n) + 1, this%dis%con%ia(n + 1) - 1
633 if (this%dis%con%mask(ii) == 0) cycle
636 m = this%dis%con%ja(ii)
639 qnm = this%qcalc(n, m, stage(n), stage(m), ii)
640 rhs(n) = rhs(n) - qnm
644 qeps = this%qcalc(n, m, stage(n) + eps, stage(m), ii)
645 derv = (qeps - qnm) / eps
646 call matrix_sln%add_value_pos(idxglo(idiag), derv)
647 rhs(n) = rhs(n) + derv * stage(n)
651 qeps = this%qcalc(n, m, stage(n), stage(m) + eps, ii)
652 derv = (qeps - qnm) / eps
653 call matrix_sln%add_value_pos(idxglo(ii), derv)
654 rhs(n) = rhs(n) + derv * stage(m)
659 end subroutine dfw_qnm_fc_nr
663 subroutine dfw_fn(this, kiter, matrix_sln, idxglo, rhs, stage)
665 class(SwfDfwType) :: this
666 integer(I4B) :: kiter
667 class(MatrixBaseType),
pointer :: matrix_sln
668 integer(I4B),
intent(in),
dimension(:) :: idxglo
669 real(DP),
intent(inout),
dimension(:) :: rhs
670 real(DP),
intent(inout),
dimension(:) :: stage
677 end subroutine dfw_fn
681 function qcalc(this, n, m, stage_n, stage_m, ipos)
result(qnm)
683 class(SwfDfwType) :: this
684 integer(I4B),
intent(in) :: n
685 integer(I4B),
intent(in) :: m
686 real(DP),
intent(in) :: stage_n
687 real(DP),
intent(in) :: stage_m
688 integer(I4B),
intent(in) :: ipos
690 integer(I4B) :: isympos
697 isympos = this%dis%con%jas(ipos)
699 cl1 = this%dis%con%cl1(isympos)
700 cl2 = this%dis%con%cl2(isympos)
702 cl1 = this%dis%con%cl2(isympos)
703 cl2 = this%dis%con%cl1(isympos)
707 if (this%iswrcond == 0)
then
708 cond = this%get_cond(n, m, ipos, stage_n, stage_m, cl1, cl2)
709 else if (this%iswrcond == 1)
then
710 cond = this%get_cond_swr(n, m, ipos, stage_n, stage_m, cl1, cl2)
714 qnm = cond * (stage_m - stage_n)
723 function get_cond(this, n, m, ipos, stage_n, stage_m, cln, clm)
result(cond)
727 class(SwfDfwType) :: this
728 integer(I4B),
intent(in) :: n
729 integer(I4B),
intent(in) :: m
730 integer(I4B),
intent(in) :: ipos
731 real(DP),
intent(in) :: stage_n
732 real(DP),
intent(in) :: stage_m
733 real(DP),
intent(in) :: cln
734 real(DP),
intent(in) :: clm
742 real(DP) :: range = 1.d-6
744 real(DP) :: smooth_factor
745 real(DP) :: length_nm
753 length_nm = cln + clm
755 if (length_nm >
dprec)
then
758 depth_n = stage_n - this%dis%bot(n)
759 depth_m = stage_m - this%dis%bot(m)
762 if (this%is2d == 0)
then
763 dhds_n = abs(stage_m - stage_n) / (cln + clm)
766 dhds_n = this%grad_dhds_mag(n)
767 dhds_m = this%grad_dhds_mag(m)
771 if (this%icentral == 0)
then
773 if (stage_n > stage_m)
then
782 call squadratic(depth_n, range, dydx, smooth_factor)
783 depth_n = depth_n * smooth_factor
784 call squadratic(depth_m, range, dydx, smooth_factor)
785 depth_m = depth_m * smooth_factor
788 call this%dis%get_flow_width(n, m, ipos, width_n, width_m)
792 cn = this%get_cond_n(n, depth_n, cln, width_n, dhds_n)
793 cm = this%get_cond_n(m, depth_m, clm, width_m, dhds_m)
798 if ((cn + cm) >
dprec)
then
799 cond = cn * cm / (cn + cm)
806 end function get_cond
812 function get_cond_n(this, n, depth, dx, width, dhds)
result(c)
815 class(SwfDfwType) :: this
816 integer(I4B),
intent(in) :: n
817 real(DP),
intent(in) :: depth
818 real(DP),
intent(in) :: dx
819 real(DP),
intent(in) :: width
820 real(DP),
intent(in) :: dhds
826 real(DP) :: conveyance
829 rough = this%manningsn(n)
830 conveyance = this%cxs%get_conveyance(this%idcxs(n), width, depth, rough)
831 dhds_sqr = dhds**
dhalf
832 if (dhds_sqr <
dem10)
then
837 c = this%unitconv * conveyance / dx / dhds_sqr
839 end function get_cond_n
847 function get_cond_swr(this, n, m, ipos, stage_n, stage_m, cln, clm)
result(cond)
851 class(SwfDfwType) :: this
852 integer(I4B),
intent(in) :: n
853 integer(I4B),
intent(in) :: m
854 integer(I4B),
intent(in) :: ipos
855 real(DP),
intent(in) :: stage_n
856 real(DP),
intent(in) :: stage_m
857 real(DP),
intent(in) :: cln
858 real(DP),
intent(in) :: clm
868 real(DP) :: range = 1.d-6
870 real(DP) :: smooth_factor
871 real(DP) :: length_nm
875 real(DP) :: area_n, area_m, area_avg
876 real(DP) :: rhn, rhm, rhavg
884 length_nm = cln + clm
886 if (length_nm >
dprec)
then
889 depth_n = stage_n - this%dis%bot(n)
890 depth_m = stage_m - this%dis%bot(m)
893 if (this%icentral == 0)
then
895 if (stage_n > stage_m)
then
904 call squadratic(depth_n, range, dydx, smooth_factor)
905 depth_n = depth_n * smooth_factor
906 call squadratic(depth_m, range, dydx, smooth_factor)
907 depth_m = depth_m * smooth_factor
910 call this%dis%get_flow_width(n, m, ipos, width_n, width_m)
913 weight_n = clm / length_nm
914 weight_m =
done - weight_n
917 area_n = this%cxs%get_area(this%idcxs(n), width_n, depth_n)
918 area_m = this%cxs%get_area(this%idcxs(m), width_m, depth_m)
919 area_avg = weight_n * area_n + weight_m * area_m
922 if (this%is2d == 0)
then
923 rhn = this%cxs%get_hydraulic_radius(this%idcxs(n), width_n, &
925 rhm = this%cxs%get_hydraulic_radius(this%idcxs(m), width_m, &
927 rhavg = weight_n * rhn + weight_m * rhm
929 rhavg = area_avg / width_n
934 if (this%is2d == 0)
then
935 dhds_nm = abs(stage_m - stage_n) / (length_nm)
937 dhds_n = this%grad_dhds_mag(n)
938 dhds_m = this%grad_dhds_mag(m)
939 dhds_nm = weight_n * dhds_n + weight_m * dhds_m
941 dhds_sqr = dhds_nm**
dhalf
942 if (dhds_sqr <
dem10)
then
947 weight_n = cln / length_nm
948 weight_m =
done - weight_n
949 rough_n = this%cxs%get_roughness(this%idcxs(n), width_n, depth_n, &
950 this%manningsn(n), dhds_nm)
951 rough_m = this%cxs%get_roughness(this%idcxs(m), width_m, depth_m, &
952 this%manningsn(m), dhds_nm)
953 ravg = (weight_n + weight_m) / &
954 (weight_n / rough_n + weight_m / rough_m)
955 rinv_avg =
done / ravg
958 cond = this%unitconv * rinv_avg * area_avg * rhavg / dhds_sqr / length_nm
962 end function get_cond_swr
970 function get_flow_area_nm(this, n, m, stage_n, stage_m, cln, clm, &
971 ipos)
result(area_avg)
975 class(SwfDfwType) :: this
976 integer(I4B),
intent(in) :: n
977 integer(I4B),
intent(in) :: m
978 real(DP),
intent(in) :: stage_n
979 real(DP),
intent(in) :: stage_m
980 real(DP),
intent(in) :: cln
981 real(DP),
intent(in) :: clm
982 integer(I4B),
intent(in) :: ipos
992 real(DP) :: length_nm
993 real(DP) :: range = 1.d-6
995 real(DP) :: smooth_factor
1000 depth_n = stage_n - this%dis%bot(n)
1001 depth_m = stage_m - this%dis%bot(m)
1004 if (this%icentral == 0)
then
1006 if (stage_n > stage_m)
then
1015 call squadratic(depth_n, range, dydx, smooth_factor)
1016 depth_n = depth_n * smooth_factor
1017 call squadratic(depth_m, range, dydx, smooth_factor)
1018 depth_m = depth_m * smooth_factor
1021 call this%dis%get_flow_width(n, m, ipos, width_n, width_m)
1024 length_nm = cln + clm
1025 weight_n = clm / length_nm
1026 weight_m =
done - weight_n
1029 area_n = this%cxs%get_area(this%idcxs(n), width_n, depth_n)
1030 area_m = this%cxs%get_area(this%idcxs(m), width_m, depth_m)
1031 area_avg = weight_n * area_n + weight_m * area_m
1033 end function get_flow_area_nm
1041 subroutine calc_dhds(this)
1045 class(SwfDfwType) :: this
1049 integer(I4B) :: ipos
1050 integer(I4B) :: isympos
1054 do n = 1, this%dis%nodes
1055 this%grad_dhds_mag(n) =
dzero
1056 do ipos = this%dis%con%ia(n) + 1, this%dis%con%ia(n + 1) - 1
1057 m = this%dis%con%ja(ipos)
1058 isympos = this%dis%con%jas(ipos)
1062 cl1 = this%dis%con%cl1(isympos)
1063 cl2 = this%dis%con%cl2(isympos)
1065 cl1 = this%dis%con%cl2(isympos)
1066 cl2 = this%dis%con%cl1(isympos)
1071 if (cl1 + cl2 >
dprec)
then
1072 this%dhdsja(isympos) = (this%hnew(m) - this%hnew(n)) / (cl1 + cl2)
1074 this%dhdsja(isympos) =
dzero
1084 end subroutine calc_dhds
1089 subroutine dfw_nur(this, neqmod, x, xtemp, dx, inewtonur, dxmax, locmax)
1091 class(SwfDfwType) :: this
1092 integer(I4B),
intent(in) :: neqmod
1093 real(DP),
dimension(neqmod),
intent(inout) :: x
1094 real(DP),
dimension(neqmod),
intent(in) :: xtemp
1095 real(DP),
dimension(neqmod),
intent(inout) :: dx
1096 integer(I4B),
intent(inout) :: inewtonur
1097 real(DP),
intent(inout) :: dxmax
1098 integer(I4B),
intent(inout) :: locmax
1106 do n = 1, this%dis%nodes
1107 if (this%ibound(n) < 1) cycle
1108 if (this%icelltype(n) > 0)
then
1109 botm = this%dis%bot(n)
1112 if (x(n) < botm)
then
1116 if (abs(dxx) > abs(dxmax))
then
1126 end subroutine dfw_nur
1130 subroutine dfw_cq(this, stage, stage_old, flowja)
1132 class(SwfDfwType) :: this
1133 real(DP),
intent(inout),
dimension(:) :: stage
1134 real(DP),
intent(inout),
dimension(:) :: stage_old
1135 real(DP),
intent(inout),
dimension(:) :: flowja
1137 integer(I4B) :: n, ipos, m
1140 do n = 1, this%dis%nodes
1141 do ipos = this%dis%con%ia(n) + 1, this%dis%con%ia(n + 1) - 1
1142 m = this%dis%con%ja(ipos)
1144 qnm = this%qcalc(n, m, stage(n), stage(m), ipos)
1146 flowja(this%dis%con%isym(ipos)) = -qnm
1150 end subroutine dfw_cq
1154 subroutine dfw_bd(this, isuppress_output, model_budget)
1158 class(SwfDfwType) :: this
1159 integer(I4B),
intent(in) :: isuppress_output
1160 type(BudgetType),
intent(inout) :: model_budget
1165 end subroutine dfw_bd
1169 subroutine dfw_save_model_flows(this, flowja, icbcfl, icbcun)
1171 class(SwfDfwType) :: this
1172 real(DP),
dimension(:),
intent(in) :: flowja
1173 integer(I4B),
intent(in) :: icbcfl
1174 integer(I4B),
intent(in) :: icbcun
1176 integer(I4B) :: ibinun
1179 if (this%ipakcb < 0)
then
1181 elseif (this%ipakcb == 0)
then
1184 ibinun = this%ipakcb
1186 if (icbcfl == 0) ibinun = 0
1189 if (ibinun /= 0)
then
1191 call this%dis%record_connection_array(flowja, ibinun, this%iout)
1195 if (this%isavvelocity /= 0)
then
1196 if (ibinun /= 0)
call this%sav_velocity(ibinun)
1199 end subroutine dfw_save_model_flows
1203 subroutine dfw_print_model_flows(this, ibudfl, flowja)
1208 class(SwfDfwType) :: this
1209 integer(I4B),
intent(in) :: ibudfl
1210 real(DP),
intent(inout),
dimension(:) :: flowja
1212 character(len=LENBIGLINE) :: line
1213 character(len=30) :: tempstr
1214 integer(I4B) :: n, ipos, m
1217 character(len=*),
parameter :: fmtiprflow = &
1218 &
"(/,4x,'CALCULATED INTERCELL FLOW FOR PERIOD ', i0, ' STEP ', i0)"
1221 if (ibudfl /= 0 .and. this%iprflow > 0)
then
1222 write (this%iout, fmtiprflow)
kper,
kstp
1223 do n = 1, this%dis%nodes
1225 call this%dis%noder_to_string(n, tempstr)
1226 line = trim(tempstr)//
':'
1227 do ipos = this%dis%con%ia(n) + 1, this%dis%con%ia(n + 1) - 1
1228 m = this%dis%con%ja(ipos)
1229 call this%dis%noder_to_string(m, tempstr)
1230 line = trim(line)//
' '//trim(tempstr)
1232 write (tempstr,
'(1pg15.6)') qnm
1233 line = trim(line)//
' '//trim(adjustl(tempstr))
1235 write (this%iout,
'(a)') trim(line)
1239 end subroutine dfw_print_model_flows
1243 subroutine dfw_da(this)
1249 class(SwfDfwType) :: this
1263 if (this%is2d == 1)
then
1282 call this%obs%obs_da()
1283 deallocate (this%obs)
1288 call this%NumericalPackageType%da()
1293 end subroutine dfw_da
1299 subroutine calc_velocity(this, flowja)
1302 class(SwfDfwType) :: this
1303 real(DP),
intent(in),
dimension(:) :: flowja
1307 integer(I4B) :: ipos
1308 integer(I4B) :: isympos
1334 real(DP),
allocatable,
dimension(:) :: vi
1335 real(DP),
allocatable,
dimension(:) :: di
1336 real(DP),
allocatable,
dimension(:) :: viz
1337 real(DP),
allocatable,
dimension(:) :: diz
1338 real(DP),
allocatable,
dimension(:) :: nix
1339 real(DP),
allocatable,
dimension(:) :: niy
1340 real(DP),
allocatable,
dimension(:) :: wix
1341 real(DP),
allocatable,
dimension(:) :: wiy
1342 real(DP),
allocatable,
dimension(:) :: wiz
1343 real(DP),
allocatable,
dimension(:) :: bix
1344 real(DP),
allocatable,
dimension(:) :: biy
1345 logical :: nozee = .true.
1349 if (this%icalcvelocity /= 0 .and. this%dis%con%ianglex == 0)
then
1350 call store_error(
'Error. ANGLDEGX not provided in '// &
1351 'discretization file. ANGLDEGX required for '// &
1352 'calculation of velocity.', terminate=.true.)
1357 do n = 1, this%dis%nodes
1360 ic = this%dis%con%ia(n + 1) - this%dis%con%ia(n) - 1
1363 do m = 1, this%nedges
1364 if (this%nodedge(m) == n)
then
1370 if (ic > nc) nc = ic
1387 do n = 1, this%dis%nodes
1399 do ipos = this%dis%con%ia(n) + 1, this%dis%con%ia(n + 1) - 1
1400 m = this%dis%con%ja(ipos)
1401 isympos = this%dis%con%jas(ipos)
1402 ihc = this%dis%con%ihc(isympos)
1404 call this%dis%connection_normal(n, m, ihc, xn, yn, zn, ipos)
1405 call this%dis%connection_vector(n, m, nozee,
done,
done, &
1406 ihc, xc, yc, zc, dltot)
1407 cl1 = this%dis%con%cl1(isympos)
1408 cl2 = this%dis%con%cl2(isympos)
1410 cl1 = this%dis%con%cl2(isympos)
1411 cl2 = this%dis%con%cl1(isympos)
1413 ooclsum =
done / (cl1 + cl2)
1416 di(ic) = dltot * cl1 * ooclsum
1417 area = this%get_flow_area_nm(n, m, this%hnew(n), this%hnew(m), &
1419 if (area >
dzero)
then
1420 vi(ic) = flowja(ipos) / area
1429 do m = 1, this%nedges
1430 if (this%nodedge(m) == n)
then
1433 ihc = this%ihcedge(m)
1434 area = this%propsedge(2, m)
1437 nix(ic) = -this%propsedge(3, m)
1438 niy(ic) = -this%propsedge(4, m)
1439 di(ic) = this%propsedge(5, m)
1440 if (area >
dzero)
then
1441 vi(ic) = this%propsedge(1, m) / area
1459 dsumz = dsumz + diz(iz)
1461 denom = (ncz -
done)
1463 dsumz = dsumz +
dem10 * dsumz
1465 if (dsumz >
dzero) wiz(iz) =
done - diz(iz) / dsumz
1467 wiz(iz) = wiz(iz) / denom
1475 vz = vz + wiz(iz) * viz(iz)
1484 wix(ic) = di(ic) * abs(nix(ic))
1485 wiy(ic) = di(ic) * abs(niy(ic))
1486 dsumx = dsumx + wix(ic)
1487 dsumy = dsumy + wiy(ic)
1494 dsumx = dsumx +
dem10 * dsumx
1495 dsumy = dsumy +
dem10 * dsumy
1497 wix(ic) = (dsumx - wix(ic)) * abs(nix(ic))
1498 wiy(ic) = (dsumy - wiy(ic)) * abs(niy(ic))
1505 bix(ic) = wix(ic) * sign(
done, nix(ic))
1506 biy(ic) = wiy(ic) * sign(
done, niy(ic))
1507 dsumx = dsumx + wix(ic) * abs(nix(ic))
1508 dsumy = dsumy + wiy(ic) * abs(niy(ic))
1515 bix(ic) = bix(ic) * dsumx
1516 biy(ic) = biy(ic) * dsumy
1517 axy = axy + bix(ic) * niy(ic)
1518 ayx = ayx + biy(ic) * nix(ic)
1531 vx = vx + (bix(ic) - axy * biy(ic)) * vi(ic)
1532 vy = vy + (biy(ic) - ayx * bix(ic)) * vi(ic)
1534 denom =
done - axy * ayx
1535 if (denom /=
dzero)
then
1540 this%vcomp(1, n) = vx
1541 this%vcomp(2, n) = vy
1542 this%vcomp(3, n) = vz
1543 this%vmag(n) = sqrt(vx**2 + vy**2 + vz**2)
1558 end subroutine calc_velocity
1565 subroutine increase_edge_count(this, nedges)
1567 class(SwfDfwType) :: this
1568 integer(I4B),
intent(in) :: nedges
1570 this%nedges = this%nedges + nedges
1572 end subroutine increase_edge_count
1578 subroutine set_edge_properties(this, nodedge, ihcedge, q, area, nx, ny, &
1581 class(SwfDfwType) :: this
1582 integer(I4B),
intent(in) :: nodedge
1583 integer(I4B),
intent(in) :: ihcedge
1584 real(DP),
intent(in) :: q
1585 real(DP),
intent(in) :: area
1586 real(DP),
intent(in) :: nx
1587 real(DP),
intent(in) :: ny
1588 real(DP),
intent(in) :: distance
1590 integer(I4B) :: lastedge
1592 this%lastedge = this%lastedge + 1
1593 lastedge = this%lastedge
1594 this%nodedge(lastedge) = nodedge
1595 this%ihcedge(lastedge) = ihcedge
1596 this%propsedge(1, lastedge) = q
1597 this%propsedge(2, lastedge) = area
1598 this%propsedge(3, lastedge) = nx
1599 this%propsedge(4, lastedge) = ny
1600 this%propsedge(5, lastedge) = distance
1604 if (this%lastedge == this%nedges) this%lastedge = 0
1606 end subroutine set_edge_properties
1612 subroutine sav_velocity(this, ibinun)
1614 class(SwfDfwType) :: this
1615 integer(I4B),
intent(in) :: ibinun
1617 character(len=16) :: text
1618 character(len=16),
dimension(3) :: auxtxt
1620 integer(I4B) :: naux
1623 text =
' DATA-VCOMP'
1625 auxtxt(:) = [
' vx',
' vy',
' vz']
1626 call this%dis%record_srcdst_list_header(text, this%name_model, &
1627 this%packName, this%name_model, &
1628 this%packName, naux, auxtxt, ibinun, &
1629 this%dis%nodes, this%iout)
1632 do n = 1, this%dis%nodes
1633 call this%dis%record_mf6_list_entry(ibinun, n, n,
dzero, naux, &
1637 end subroutine sav_velocity
1642 subroutine dfw_df_obs(this)
1644 class(SwfDfwType) :: this
1646 integer(I4B) :: indx
1650 call this%obs%StoreObsType(
'ext-outflow', .true., indx)
1651 this%obs%obsData(indx)%ProcessIdPtr => dfwobsidprocessor
1653 end subroutine dfw_df_obs
1655 subroutine dfwobsidprocessor(obsrv, dis, inunitobs, iout)
1657 type(ObserveType),
intent(inout) :: obsrv
1658 class(DisBaseType),
intent(in) :: dis
1659 integer(I4B),
intent(in) :: inunitobs
1660 integer(I4B),
intent(in) :: iout
1663 character(len=LINELENGTH) :: string
1666 string = obsrv%IDstring
1670 obsrv%NodeNumber = n
1672 errmsg =
'Error reading data from ID string'
1677 end subroutine dfwobsidprocessor
1682 subroutine dfw_bd_obs(this)
1684 class(SwfDfwType) :: this
1690 character(len=100) :: msg
1691 type(ObserveType),
pointer :: obsrv => null()
1694 if (this%obs%npakobs > 0)
then
1695 call this%obs%obs_bd_clear()
1696 do i = 1, this%obs%npakobs
1697 obsrv => this%obs%pakobs(i)%obsrv
1698 do j = 1, obsrv%indxbnds_count
1699 n = obsrv%indxbnds(j)
1701 select case (obsrv%ObsTypeId)
1703 msg =
'Unrecognized observation type: '//trim(obsrv%ObsTypeId)
1706 call this%obs%SaveOneSimval(obsrv, v)
1716 end subroutine dfw_bd_obs
1721 subroutine dfw_rp_obs(this)
1725 class(SwfDfwType),
intent(inout) :: this
1730 class(ObserveType),
pointer :: obsrv => null()
1736 do i = 1, this%obs%npakobs
1737 obsrv => this%obs%pakobs(i)%obsrv
1740 nn1 = obsrv%NodeNumber
1741 if (nn1 < 1 .or. nn1 > this%dis%nodes)
then
1742 write (
errmsg,
'(a,1x,a,1x,i0,1x,a,1x,i0,a)') &
1743 trim(adjustl(obsrv%ObsTypeId)), &
1744 'reach must be greater than 0 and less than or equal to', &
1745 this%dis%nodes,
'(specified value is ', nn1,
')'
1748 if (obsrv%indxbnds_count == 0)
then
1749 call obsrv%AddObsIndex(nn1)
1751 errmsg =
'Programming error in dfw_rp_obs'
1757 do j = 1, obsrv%indxbnds_count
1758 nn1 = obsrv%indxbnds(j)
1759 if (nn1 < 1 .or. nn1 > this%dis%nodes)
then
1760 write (
errmsg,
'(a,1x,a,1x,i0,1x,a,1x,i0,a)') &
1761 trim(adjustl(obsrv%ObsTypeId)), &
1762 'reach must be greater than 0 and less than or equal to', &
1763 this%dis%nodes,
'(specified value is ', nn1,
')'
1776 end subroutine dfw_rp_obs
1778 end module swfdfwmodule
This module contains the BudgetModule.
This module contains simulation constants.
integer(i4b), parameter linelength
maximum length of a standard line
real(dp), parameter dtwothirds
real constant 2/3
real(dp), parameter dp9
real constant 9/10
real(dp), parameter dem10
real constant 1e-10
real(dp), parameter donethird
real constant 1/3
integer(i4b), parameter lenbigline
maximum length of a big line
real(dp), parameter dhalf
real constant 1/2
real(dp), parameter dzero
real constant zero
real(dp), parameter dprec
real constant machine precision
real(dp), parameter dtwo
real constant 2
integer(i4b), parameter lenmempath
maximum length of the memory path
real(dp), parameter done
real constant 1
This module defines variable data types.
real(dp) function, public get_perturbation(x)
Calculate a numerical perturbation given the value of x.
character(len=lenmempath) function create_mem_path(component, subcomponent, context)
returns the path to the memory object
subroutine, public memorystore_remove(component, subcomponent, context)
subroutine, public memorystore_release(varname, memory_path)
Release a single variable from the memory store.
subroutine, public get_isize(name, mem_path, isize)
@ brief Get the number of elements for this variable
This module contains the base numerical package type.
This module contains the derived types ObserveType and ObsDataType.
This module contains the derived type ObsType.
subroutine, public obs_cr(obs, inobs)
@ brief Create a new ObsType object
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
subroutine squadratic(x, range, dydx, y)
@ brief sQuadratic
integer(i4b), pointer, public kstp
current time step number
integer(i4b), pointer, public kper
current stress period number
subroutine, public vector_interpolation_2d(dis, flowja, nedges, nodedge, propsedge, vcomp, vmag, flowareaja)
Interpolate 2D vector components at cell center.
Derived type for the Budget object.
This class is used to store a single deferred-length character string. It was designed to work in an ...