30 public :: swfdfwtype, dfw_cr
35 integer(I4B),
pointer :: is2d => null()
36 integer(I4B),
pointer :: icentral => null()
37 integer(I4B),
pointer :: iswrcond => null()
38 real(DP),
pointer :: unitconv
39 real(DP),
pointer :: timeconv
40 real(DP),
pointer :: lengthconv
41 real(DP),
dimension(:),
pointer,
contiguous :: hnew => null()
42 real(DP),
dimension(:),
pointer,
contiguous :: manningsn => null()
43 integer(I4B),
dimension(:),
pointer,
contiguous :: idcxs => null()
44 integer(I4B),
dimension(:),
pointer,
contiguous :: ibound => null()
45 integer(I4B),
dimension(:),
pointer,
contiguous :: icelltype => null()
48 integer(I4B),
pointer :: icalcvelocity => null()
49 integer(I4B),
pointer :: isavvelocity => null()
50 real(DP),
dimension(:, :),
pointer,
contiguous :: vcomp => null()
51 real(DP),
dimension(:),
pointer,
contiguous :: vmag => null()
52 integer(I4B),
pointer :: nedges => null()
53 integer(I4B),
pointer :: lastedge => null()
54 integer(I4B),
dimension(:),
pointer,
contiguous :: nodedge => null()
55 integer(I4B),
dimension(:),
pointer,
contiguous :: ihcedge => null()
56 real(DP),
dimension(:, :),
pointer,
contiguous :: propsedge => null()
57 real(DP),
dimension(:),
pointer,
contiguous :: grad_dhds_mag => null()
58 real(DP),
dimension(:),
pointer,
contiguous :: dhdsja => null()
61 integer(I4B),
pointer :: inobspkg => null()
62 type(ObsType),
pointer :: obs => null()
65 type(SwfCxsType),
pointer :: cxs
70 procedure :: allocate_scalars
71 procedure :: allocate_arrays
73 procedure :: source_options
74 procedure :: log_options
75 procedure :: source_griddata
76 procedure :: log_griddata
81 procedure :: dfw_qnm_fc_nr
87 procedure :: dfw_save_model_flows
88 procedure :: dfw_print_model_flows
90 procedure :: dfw_df_obs
91 procedure :: dfw_rp_obs
92 procedure :: dfw_bd_obs
95 procedure :: get_cond_swr
96 procedure :: get_cond_n
97 procedure :: get_flow_area_nm
98 procedure :: calc_velocity
99 procedure :: sav_velocity
100 procedure,
public :: increase_edge_count
101 procedure,
public :: set_edge_properties
102 procedure :: calc_dhds
103 procedure :: write_cxs_tables
111 subroutine dfw_cr(dfwobj, name_model, input_mempath, inunit, iout, &
116 type(SwfDfwType),
pointer :: dfwobj
117 character(len=*),
intent(in) :: name_model
118 character(len=*),
intent(in) :: input_mempath
119 integer(I4B),
intent(in) :: inunit
120 integer(I4B),
intent(in) :: iout
121 type(SwfCxsType),
pointer,
intent(in) :: cxs
123 logical(LGP) :: found_fname
125 character(len=*),
parameter :: fmtheader = &
126 "(1x, /1x, 'DFW -- DIFFUSIVE WAVE (DFW) PACKAGE, VERSION 1, 9/25/2023', &
127 &' INPUT READ FROM MEMPATH: ', A, /)"
133 call dfwobj%set_names(1, name_model,
'DFW',
'DFW')
136 call dfwobj%allocate_scalars()
139 dfwobj%input_mempath = input_mempath
140 dfwobj%inunit = inunit
144 call mem_set_value(dfwobj%input_fname,
'INPUT_FNAME', dfwobj%input_mempath, &
151 call obs_cr(dfwobj%obs, dfwobj%inobspkg)
157 write (iout, fmtheader) input_mempath
163 end subroutine dfw_cr
167 subroutine dfw_df(this, dis)
169 class(SwfDfwType) :: this
170 class(DisBaseType),
pointer,
intent(inout) :: dis
172 character(len=10) :: distype =
''
178 call this%dis%get_dis_type(distype)
179 if (distype ==
"DIS2D")
then
182 if (distype ==
"DISV2D")
then
191 call this%allocate_arrays()
198 end subroutine dfw_df
206 subroutine allocate_scalars(this)
209 class(SwfDfwtype) :: this
212 call this%NumericalPackageType%allocate_scalars()
216 call mem_allocate(this%icentral,
'ICENTRAL', this%memoryPath)
217 call mem_allocate(this%iswrcond,
'ISWRCOND', this%memoryPath)
218 call mem_allocate(this%unitconv,
'UNITCONV', this%memoryPath)
219 call mem_allocate(this%lengthconv,
'LENGTHCONV', this%memoryPath)
220 call mem_allocate(this%timeconv,
'TIMECONV', this%memoryPath)
221 call mem_allocate(this%inobspkg,
'INOBSPKG', this%memoryPath)
222 call mem_allocate(this%icalcvelocity,
'ICALCVELOCITY', this%memoryPath)
223 call mem_allocate(this%isavvelocity,
'ISAVVELOCITY', this%memoryPath)
224 call mem_allocate(this%nedges,
'NEDGES', this%memoryPath)
225 call mem_allocate(this%lastedge,
'LASTEDGE', this%memoryPath)
231 this%lengthconv =
done
234 this%icalcvelocity = 0
235 this%isavvelocity = 0
240 end subroutine allocate_scalars
244 subroutine allocate_arrays(this)
246 class(SwfDfwType) :: this
252 'MANNINGSN', this%memoryPath)
254 'IDCXS', this%memoryPath)
256 'ICELLTYPE', this%memoryPath)
259 call mem_allocate(this%nodedge, 0,
'NODEDGE', this%memoryPath)
260 call mem_allocate(this%ihcedge, 0,
'IHCEDGE', this%memoryPath)
261 call mem_allocate(this%propsedge, 0, 0,
'PROPSEDGE', this%memoryPath)
264 call mem_allocate(this%vcomp, 3, 0,
'VCOMP', this%memoryPath)
265 call mem_allocate(this%vmag, 0,
'VMAG', this%memoryPath)
267 do n = 1, this%dis%nodes
268 this%manningsn(n) =
dzero
270 this%icelltype(n) = 1
274 if (this%is2d == 1)
then
276 'GRAD_DHDS_MAG', this%memoryPath)
278 'DHDSJA', this%memoryPath)
279 do n = 1, this%dis%nodes
280 this%grad_dhds_mag(n) =
dzero
282 do n = 1, this%dis%njas
283 this%dhdsja(n) =
dzero
289 end subroutine allocate_arrays
293 subroutine dfw_load(this)
295 class(SwfDfwType) :: this
299 call this%source_options()
300 call this%source_griddata()
304 end subroutine dfw_load
308 subroutine source_options(this)
316 class(SwfDfwType) :: this
318 integer(I4B) :: isize
319 type(SwfDfwParamFoundType) :: 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()
374 if (this%iout > 0)
then
375 call this%log_options(found)
380 end subroutine source_options
384 subroutine log_options(this, found)
386 class(SwfDfwType) :: this
387 type(SwfDfwParamFoundType),
intent(in) :: found
389 write (this%iout,
'(1x,a)')
'Setting DFW Options'
391 if (found%lengthconv)
then
392 write (this%iout,
'(4x,a, G0)')
'Mannings length conversion value &
393 &specified as ', this%lengthconv
396 if (found%timeconv)
then
397 write (this%iout,
'(4x,a, G0)')
'Mannings time conversion value &
398 &specified as ', this%timeconv
401 if (found%lengthconv .or. found%timeconv)
then
402 write (this%iout,
'(4x,a, G0)')
'Mannings conversion value calculated &
403 &from user-provided length_conversion and &
404 &time_conversion is ', this%unitconv
407 if (found%iprflow)
then
408 write (this%iout,
'(4x,a)')
'Cell-by-cell flow information will be printed &
409 &to listing file whenever ICBCFL is not zero.'
412 if (found%ipakcb)
then
413 write (this%iout,
'(4x,a)')
'Cell-by-cell flow information will be printed &
414 &to listing file whenever ICBCFL is not zero.'
417 if (found%obs6_filename)
then
418 write (this%iout,
'(4x,a)')
'Observation package is active.'
421 if (found%isavvelocity) &
422 write (this%iout,
'(4x,a)')
'Velocity will be calculated at cell &
423 ¢ers and written to DATA-VCOMP in budget &
424 &file when requested.'
426 if (found%iswrcond)
then
427 write (this%iout,
'(4x,a, G0)')
'Conductance will be calculated using &
428 &the SWR development option.'
431 write (this%iout,
'(1x,a,/)')
'End Setting DFW Options'
433 end subroutine log_options
437 subroutine source_griddata(this)
445 class(SwfDfwType) :: this
447 character(len=LENMEMPATH) :: idmMemoryPath
448 type(SwfDfwParamFoundType) :: found
449 integer(I4B),
dimension(:),
pointer,
contiguous :: map
457 if (this%dis%nodes < this%dis%nodesuser) map => this%dis%nodeuser
461 idmmemorypath, map, found%manningsn)
462 call mem_set_value(this%idcxs,
'IDCXS', idmmemorypath, map, found%idcxs)
465 if (.not. found%manningsn)
then
466 write (errmsg,
'(a)')
'Error in GRIDDATA block: MANNINGSN not found.'
471 call store_error_filename(this%input_fname)
475 if (this%iout > 0)
then
476 call this%log_griddata(found)
481 end subroutine source_griddata
485 subroutine log_griddata(this, found)
487 class(SwfDfwType) :: this
488 type(SwfDfwParamFoundType),
intent(in) :: found
490 write (this%iout,
'(1x,a)')
'Setting DFW Griddata'
492 if (found%manningsn)
then
493 write (this%iout,
'(4x,a)')
'MANNINGSN set from input file'
496 if (found%idcxs)
then
497 write (this%iout,
'(4x,a)')
'IDCXS set from input file'
500 call this%write_cxs_tables()
502 write (this%iout,
'(1x,a,/)')
'End Setting DFW Griddata'
504 end subroutine log_griddata
506 subroutine write_cxs_tables(this)
509 class(SwfDfwType) :: this
522 end subroutine write_cxs_tables
526 subroutine dfw_ar(this, ibound, hnew)
529 class(SwfDfwType) :: this
530 integer(I4B),
dimension(:),
pointer,
contiguous :: ibound
531 real(DP),
dimension(:),
pointer,
contiguous,
intent(inout) :: hnew
536 this%ibound => ibound
539 if (this%icalcvelocity == 1)
then
540 call mem_reallocate(this%vcomp, 3, this%dis%nodes,
'VCOMP', this%memoryPath)
541 call mem_reallocate(this%vmag, this%dis%nodes,
'VMAG', this%memoryPath)
542 call mem_reallocate(this%nodedge, this%nedges,
'NODEDGE', this%memoryPath)
543 call mem_reallocate(this%ihcedge, this%nedges,
'IHCEDGE', this%memoryPath)
544 call mem_reallocate(this%propsedge, 5, this%nedges,
'PROPSEDGE', &
546 do n = 1, this%dis%nodes
547 this%vcomp(:, n) =
dzero
553 call this%obs%obs_ar()
556 end subroutine dfw_ar
560 subroutine dfw_rp(this)
563 class(SwfDfwType) :: this
566 call this%dfw_rp_obs()
568 end subroutine dfw_rp
572 subroutine dfw_ad(this, irestore)
574 class(SwfDfwType) :: this
575 integer(I4B),
intent(in) :: irestore
578 call this%obs%obs_ad()
583 end subroutine dfw_ad
591 subroutine dfw_fc(this, kiter, matrix_sln, idxglo, rhs, stage, stage_old)
595 class(SwfDfwType) :: this
596 integer(I4B) :: kiter
597 class(MatrixBaseType),
pointer :: matrix_sln
598 integer(I4B),
intent(in),
dimension(:) :: idxglo
599 real(DP),
intent(inout),
dimension(:) :: rhs
600 real(DP),
intent(inout),
dimension(:) :: stage
601 real(DP),
intent(inout),
dimension(:) :: stage_old
605 if (this%is2d == 1)
then
606 call this%calc_dhds()
610 call this%dfw_qnm_fc_nr(kiter, matrix_sln, idxglo, rhs, stage, stage_old)
614 end subroutine dfw_fc
621 subroutine dfw_qnm_fc_nr(this, kiter, matrix_sln, idxglo, rhs, stage, stage_old)
625 class(SwfDfwType) :: this
626 integer(I4B) :: kiter
627 class(MatrixBaseType),
pointer :: matrix_sln
628 integer(I4B),
intent(in),
dimension(:) :: idxglo
629 real(DP),
intent(inout),
dimension(:) :: rhs
630 real(DP),
intent(inout),
dimension(:) :: stage
631 real(DP),
intent(inout),
dimension(:) :: stage_old
633 integer(I4B) :: n, m, ii, idiag
640 do n = 1, this%dis%nodes
643 idiag = this%dis%con%ia(n)
646 do ii = this%dis%con%ia(n) + 1, this%dis%con%ia(n + 1) - 1
649 if (this%dis%con%mask(ii) == 0) cycle
652 m = this%dis%con%ja(ii)
655 qnm = this%qcalc(n, m, stage(n), stage(m), ii)
656 rhs(n) = rhs(n) - qnm
660 qeps = this%qcalc(n, m, stage(n) + eps, stage(m), ii)
661 derv = (qeps - qnm) / eps
662 call matrix_sln%add_value_pos(idxglo(idiag), derv)
663 rhs(n) = rhs(n) + derv * stage(n)
667 qeps = this%qcalc(n, m, stage(n), stage(m) + eps, ii)
668 derv = (qeps - qnm) / eps
669 call matrix_sln%add_value_pos(idxglo(ii), derv)
670 rhs(n) = rhs(n) + derv * stage(m)
677 end subroutine dfw_qnm_fc_nr
679 subroutine dfw_fn(this, kiter, matrix_sln, idxglo, rhs, stage)
681 class(SwfDfwType) :: this
682 integer(I4B) :: kiter
683 class(MatrixBaseType),
pointer :: matrix_sln
684 integer(I4B),
intent(in),
dimension(:) :: idxglo
685 real(DP),
intent(inout),
dimension(:) :: rhs
686 real(DP),
intent(inout),
dimension(:) :: stage
695 end subroutine dfw_fn
697 function qcalc(this, n, m, stage_n, stage_m, ipos)
result(qnm)
699 class(SwfDfwType) :: this
700 integer(I4B),
intent(in) :: n
701 integer(I4B),
intent(in) :: m
702 real(DP),
intent(in) :: stage_n
703 real(DP),
intent(in) :: stage_m
704 integer(I4B),
intent(in) :: ipos
706 integer(I4B) :: isympos
713 isympos = this%dis%con%jas(ipos)
715 cl1 = this%dis%con%cl1(isympos)
716 cl2 = this%dis%con%cl2(isympos)
718 cl1 = this%dis%con%cl2(isympos)
719 cl2 = this%dis%con%cl1(isympos)
723 if (this%iswrcond == 0)
then
724 cond = this%get_cond(n, m, ipos, stage_n, stage_m, cl1, cl2)
725 else if (this%iswrcond == 1)
then
726 cond = this%get_cond_swr(n, m, ipos, stage_n, stage_m, cl1, cl2)
730 qnm = cond * (stage_m - stage_n)
735 function get_cond(this, n, m, ipos, stage_n, stage_m, cln, clm)
result(cond)
739 class(SwfDfwType) :: this
740 integer(I4B),
intent(in) :: n
741 integer(I4B),
intent(in) :: m
742 integer(I4B),
intent(in) :: ipos
743 real(DP),
intent(in) :: stage_n
744 real(DP),
intent(in) :: stage_m
745 real(DP),
intent(in) :: cln
746 real(DP),
intent(in) :: clm
754 real(DP) :: range = 1.d-6
756 real(DP) :: smooth_factor
757 real(DP) :: length_nm
765 length_nm = cln + clm
767 if (length_nm >
dprec)
then
770 depth_n = stage_n - this%dis%bot(n)
771 depth_m = stage_m - this%dis%bot(m)
774 if (this%is2d == 0)
then
775 dhds_n = abs(stage_m - stage_n) / (cln + clm)
778 dhds_n = this%grad_dhds_mag(n)
779 dhds_m = this%grad_dhds_mag(m)
783 if (this%icentral == 0)
then
785 if (stage_n > stage_m)
then
794 call squadratic(depth_n, range, dydx, smooth_factor)
795 depth_n = depth_n * smooth_factor
796 call squadratic(depth_m, range, dydx, smooth_factor)
797 depth_m = depth_m * smooth_factor
800 call this%dis%get_flow_width(n, m, ipos, width_n, width_m)
804 cn = this%get_cond_n(n, depth_n, cln, width_n, dhds_n)
805 cm = this%get_cond_n(m, depth_m, clm, width_m, dhds_m)
810 if ((cn + cm) >
dprec)
then
811 cond = cn * cm / (cn + cm)
818 end function get_cond
824 function get_cond_n(this, n, depth, dx, width, dhds)
result(c)
827 class(SwfDfwType) :: this
828 integer(I4B),
intent(in) :: n
829 real(DP),
intent(in) :: depth
830 real(DP),
intent(in) :: dx
831 real(DP),
intent(in) :: width
832 real(DP),
intent(in) :: dhds
838 real(DP) :: conveyance
841 rough = this%manningsn(n)
842 conveyance = this%cxs%get_conveyance(this%idcxs(n), width, depth, rough)
843 dhds_sqr = dhds**
dhalf
844 if (dhds_sqr <
dem10)
then
849 c = this%unitconv * conveyance / dx / dhds_sqr
851 end function get_cond_n
853 function get_cond_swr(this, n, m, ipos, stage_n, stage_m, cln, clm)
result(cond)
857 class(SwfDfwType) :: this
858 integer(I4B),
intent(in) :: n
859 integer(I4B),
intent(in) :: m
860 integer(I4B),
intent(in) :: ipos
861 real(DP),
intent(in) :: stage_n
862 real(DP),
intent(in) :: stage_m
863 real(DP),
intent(in) :: cln
864 real(DP),
intent(in) :: clm
874 real(DP) :: range = 1.d-6
876 real(DP) :: smooth_factor
877 real(DP) :: length_nm
881 real(DP) :: area_n, area_m, area_avg
882 real(DP) :: rhn, rhm, rhavg
890 length_nm = cln + clm
892 if (length_nm >
dprec)
then
895 depth_n = stage_n - this%dis%bot(n)
896 depth_m = stage_m - this%dis%bot(m)
899 if (this%icentral == 0)
then
901 if (stage_n > stage_m)
then
910 call squadratic(depth_n, range, dydx, smooth_factor)
911 depth_n = depth_n * smooth_factor
912 call squadratic(depth_m, range, dydx, smooth_factor)
913 depth_m = depth_m * smooth_factor
916 call this%dis%get_flow_width(n, m, ipos, width_n, width_m)
919 weight_n = clm / length_nm
920 weight_m =
done - weight_n
923 area_n = this%cxs%get_area(this%idcxs(n), width_n, depth_n)
924 area_m = this%cxs%get_area(this%idcxs(m), width_m, depth_m)
925 area_avg = weight_n * area_n + weight_m * area_m
928 if (this%is2d == 0)
then
929 rhn = this%cxs%get_hydraulic_radius(this%idcxs(n), width_n, &
931 rhm = this%cxs%get_hydraulic_radius(this%idcxs(m), width_m, &
933 rhavg = weight_n * rhn + weight_m * rhm
935 rhavg = area_avg / width_n
940 if (this%is2d == 0)
then
941 dhds_nm = abs(stage_m - stage_n) / (length_nm)
943 dhds_n = this%grad_dhds_mag(n)
944 dhds_m = this%grad_dhds_mag(m)
945 dhds_nm = weight_n * dhds_n + weight_m * dhds_m
947 dhds_sqr = dhds_nm**
dhalf
948 if (dhds_sqr <
dem10)
then
953 weight_n = cln / length_nm
954 weight_m =
done - weight_n
955 rough_n = this%cxs%get_roughness(this%idcxs(n), width_n, depth_n, &
956 this%manningsn(n), dhds_nm)
957 rough_m = this%cxs%get_roughness(this%idcxs(m), width_m, depth_m, &
958 this%manningsn(m), dhds_nm)
959 ravg = (weight_n + weight_m) / &
960 (weight_n / rough_n + weight_m / rough_m)
961 rinv_avg =
done / ravg
964 cond = this%unitconv * rinv_avg * area_avg * rhavg / dhds_sqr / length_nm
968 end function get_cond_swr
977 function get_flow_area_nm(this, n, m, stage_n, stage_m, cln, clm, &
978 ipos)
result(area_avg)
982 class(SwfDfwType) :: this
983 integer(I4B),
intent(in) :: n
984 integer(I4B),
intent(in) :: m
985 real(DP),
intent(in) :: stage_n
986 real(DP),
intent(in) :: stage_m
987 real(DP),
intent(in) :: cln
988 real(DP),
intent(in) :: clm
989 integer(I4B),
intent(in) :: ipos
999 real(DP) :: length_nm
1000 real(DP) :: range = 1.d-6
1002 real(DP) :: smooth_factor
1004 real(DP) :: area_avg
1007 depth_n = stage_n - this%dis%bot(n)
1008 depth_m = stage_m - this%dis%bot(m)
1011 if (this%icentral == 0)
then
1013 if (stage_n > stage_m)
then
1022 call squadratic(depth_n, range, dydx, smooth_factor)
1023 depth_n = depth_n * smooth_factor
1024 call squadratic(depth_m, range, dydx, smooth_factor)
1025 depth_m = depth_m * smooth_factor
1028 call this%dis%get_flow_width(n, m, ipos, width_n, width_m)
1031 length_nm = cln + clm
1032 weight_n = clm / length_nm
1033 weight_m =
done - weight_n
1036 area_n = this%cxs%get_area(this%idcxs(n), width_n, depth_n)
1037 area_m = this%cxs%get_area(this%idcxs(m), width_m, depth_m)
1038 area_avg = weight_n * area_n + weight_m * area_m
1040 end function get_flow_area_nm
1042 subroutine calc_dhds(this)
1046 class(SwfDfwType) :: this
1050 integer(I4B) :: ipos
1051 integer(I4B) :: isympos
1055 do n = 1, this%dis%nodes
1056 this%grad_dhds_mag(n) =
dzero
1057 do ipos = this%dis%con%ia(n) + 1, this%dis%con%ia(n + 1) - 1
1058 m = this%dis%con%ja(ipos)
1059 isympos = this%dis%con%jas(ipos)
1063 cl1 = this%dis%con%cl1(isympos)
1064 cl2 = this%dis%con%cl2(isympos)
1066 cl1 = this%dis%con%cl2(isympos)
1067 cl2 = this%dis%con%cl1(isympos)
1072 if (cl1 + cl2 >
dprec)
then
1073 this%dhdsja(isympos) = (this%hnew(m) - this%hnew(n)) / (cl1 + cl2)
1075 this%dhdsja(isympos) =
dzero
1085 end subroutine calc_dhds
1092 subroutine dfw_nur(this, neqmod, x, xtemp, dx, inewtonur, dxmax, locmax)
1094 class(SwfDfwType) :: this
1095 integer(I4B),
intent(in) :: neqmod
1096 real(DP),
dimension(neqmod),
intent(inout) :: x
1097 real(DP),
dimension(neqmod),
intent(in) :: xtemp
1098 real(DP),
dimension(neqmod),
intent(inout) :: dx
1099 integer(I4B),
intent(inout) :: inewtonur
1100 real(DP),
intent(inout) :: dxmax
1101 integer(I4B),
intent(inout) :: locmax
1109 do n = 1, this%dis%nodes
1110 if (this%ibound(n) < 1) cycle
1111 if (this%icelltype(n) > 0)
then
1112 botm = this%dis%bot(n)
1115 if (x(n) < botm)
then
1119 if (abs(dxx) > abs(dxmax))
then
1131 end subroutine dfw_nur
1133 subroutine dfw_cq(this, stage, stage_old, flowja)
1135 class(SwfDfwType) :: this
1136 real(DP),
intent(inout),
dimension(:) :: stage
1137 real(DP),
intent(inout),
dimension(:) :: stage_old
1138 real(DP),
intent(inout),
dimension(:) :: flowja
1140 integer(I4B) :: n, ipos, m
1144 do n = 1, this%dis%nodes
1145 do ipos = this%dis%con%ia(n) + 1, this%dis%con%ia(n + 1) - 1
1146 m = this%dis%con%ja(ipos)
1148 qnm = this%qcalc(n, m, stage(n), stage(m), ipos)
1150 flowja(this%dis%con%isym(ipos)) = -qnm
1157 end subroutine dfw_cq
1165 subroutine dfw_bd(this, isuppress_output, model_budget)
1169 class(SwfDfwType) :: this
1170 integer(I4B),
intent(in) :: isuppress_output
1171 type(BudgetType),
intent(inout) :: model_budget
1179 end subroutine dfw_bd
1183 subroutine dfw_save_model_flows(this, flowja, icbcfl, icbcun)
1185 class(SwfDfwType) :: this
1186 real(DP),
dimension(:),
intent(in) :: flowja
1187 integer(I4B),
intent(in) :: icbcfl
1188 integer(I4B),
intent(in) :: icbcun
1190 integer(I4B) :: ibinun
1194 if (this%ipakcb < 0)
then
1196 elseif (this%ipakcb == 0)
then
1199 ibinun = this%ipakcb
1201 if (icbcfl == 0) ibinun = 0
1204 if (ibinun /= 0)
then
1207 call this%dis%record_connection_array(flowja, ibinun, this%iout)
1211 if (this%isavvelocity /= 0)
then
1212 if (ibinun /= 0)
call this%sav_velocity(ibinun)
1217 end subroutine dfw_save_model_flows
1221 subroutine dfw_print_model_flows(this, ibudfl, flowja)
1226 class(SwfDfwType) :: this
1227 integer(I4B),
intent(in) :: ibudfl
1228 real(DP),
intent(inout),
dimension(:) :: flowja
1230 character(len=LENBIGLINE) :: line
1231 character(len=30) :: tempstr
1232 integer(I4B) :: n, ipos, m
1235 character(len=*),
parameter :: fmtiprflow = &
1236 &
"(/,4x,'CALCULATED INTERCELL FLOW FOR PERIOD ', i0, ' STEP ', i0)"
1238 if (ibudfl /= 0 .and. this%iprflow > 0)
then
1239 write (this%iout, fmtiprflow)
kper,
kstp
1240 do n = 1, this%dis%nodes
1242 call this%dis%noder_to_string(n, tempstr)
1243 line = trim(tempstr)//
':'
1244 do ipos = this%dis%con%ia(n) + 1, this%dis%con%ia(n + 1) - 1
1245 m = this%dis%con%ja(ipos)
1246 call this%dis%noder_to_string(m, tempstr)
1247 line = trim(line)//
' '//trim(tempstr)
1249 write (tempstr,
'(1pg15.6)') qnm
1250 line = trim(line)//
' '//trim(adjustl(tempstr))
1252 write (this%iout,
'(a)') trim(line)
1258 end subroutine dfw_print_model_flows
1262 subroutine dfw_da(this)
1268 class(SwfDfwType) :: this
1282 if (this%is2d == 1)
then
1301 call this%obs%obs_da()
1302 deallocate (this%obs)
1307 call this%NumericalPackageType%da()
1312 end subroutine dfw_da
1316 subroutine calc_velocity(this, flowja)
1320 class(SwfDfwType) :: this
1321 real(DP),
intent(in),
dimension(:) :: flowja
1325 integer(I4B) :: ipos
1326 integer(I4B) :: isympos
1352 real(DP),
allocatable,
dimension(:) :: vi
1353 real(DP),
allocatable,
dimension(:) :: di
1354 real(DP),
allocatable,
dimension(:) :: viz
1355 real(DP),
allocatable,
dimension(:) :: diz
1356 real(DP),
allocatable,
dimension(:) :: nix
1357 real(DP),
allocatable,
dimension(:) :: niy
1358 real(DP),
allocatable,
dimension(:) :: wix
1359 real(DP),
allocatable,
dimension(:) :: wiy
1360 real(DP),
allocatable,
dimension(:) :: wiz
1361 real(DP),
allocatable,
dimension(:) :: bix
1362 real(DP),
allocatable,
dimension(:) :: biy
1363 logical :: nozee = .true.
1367 if (this%icalcvelocity /= 0 .and. this%dis%con%ianglex == 0)
then
1368 call store_error(
'Error. ANGLDEGX not provided in '// &
1369 'discretization file. ANGLDEGX required for '// &
1370 'calculation of velocity.', terminate=.true.)
1375 do n = 1, this%dis%nodes
1378 ic = this%dis%con%ia(n + 1) - this%dis%con%ia(n) - 1
1381 do m = 1, this%nedges
1382 if (this%nodedge(m) == n)
then
1388 if (ic > nc) nc = ic
1405 do n = 1, this%dis%nodes
1417 do ipos = this%dis%con%ia(n) + 1, this%dis%con%ia(n + 1) - 1
1418 m = this%dis%con%ja(ipos)
1419 isympos = this%dis%con%jas(ipos)
1420 ihc = this%dis%con%ihc(isympos)
1422 call this%dis%connection_normal(n, m, ihc, xn, yn, zn, ipos)
1423 call this%dis%connection_vector(n, m, nozee,
done,
done, &
1424 ihc, xc, yc, zc, dltot)
1425 cl1 = this%dis%con%cl1(isympos)
1426 cl2 = this%dis%con%cl2(isympos)
1428 cl1 = this%dis%con%cl2(isympos)
1429 cl2 = this%dis%con%cl1(isympos)
1431 ooclsum =
done / (cl1 + cl2)
1434 di(ic) = dltot * cl1 * ooclsum
1435 area = this%get_flow_area_nm(n, m, this%hnew(n), this%hnew(m), &
1437 if (area >
dzero)
then
1438 vi(ic) = flowja(ipos) / area
1447 do m = 1, this%nedges
1448 if (this%nodedge(m) == n)
then
1451 ihc = this%ihcedge(m)
1452 area = this%propsedge(2, m)
1455 nix(ic) = -this%propsedge(3, m)
1456 niy(ic) = -this%propsedge(4, m)
1457 di(ic) = this%propsedge(5, m)
1458 if (area >
dzero)
then
1459 vi(ic) = this%propsedge(1, m) / area
1477 dsumz = dsumz + diz(iz)
1479 denom = (ncz -
done)
1481 dsumz = dsumz +
dem10 * dsumz
1483 if (dsumz >
dzero) wiz(iz) =
done - diz(iz) / dsumz
1485 wiz(iz) = wiz(iz) / denom
1493 vz = vz + wiz(iz) * viz(iz)
1502 wix(ic) = di(ic) * abs(nix(ic))
1503 wiy(ic) = di(ic) * abs(niy(ic))
1504 dsumx = dsumx + wix(ic)
1505 dsumy = dsumy + wiy(ic)
1512 dsumx = dsumx +
dem10 * dsumx
1513 dsumy = dsumy +
dem10 * dsumy
1515 wix(ic) = (dsumx - wix(ic)) * abs(nix(ic))
1516 wiy(ic) = (dsumy - wiy(ic)) * abs(niy(ic))
1523 bix(ic) = wix(ic) * sign(
done, nix(ic))
1524 biy(ic) = wiy(ic) * sign(
done, niy(ic))
1525 dsumx = dsumx + wix(ic) * abs(nix(ic))
1526 dsumy = dsumy + wiy(ic) * abs(niy(ic))
1533 bix(ic) = bix(ic) * dsumx
1534 biy(ic) = biy(ic) * dsumy
1535 axy = axy + bix(ic) * niy(ic)
1536 ayx = ayx + biy(ic) * nix(ic)
1549 vx = vx + (bix(ic) - axy * biy(ic)) * vi(ic)
1550 vy = vy + (biy(ic) - ayx * bix(ic)) * vi(ic)
1552 denom =
done - axy * ayx
1553 if (denom /=
dzero)
then
1558 this%vcomp(1, n) = vx
1559 this%vcomp(2, n) = vy
1560 this%vcomp(3, n) = vz
1561 this%vmag(n) = sqrt(vx**2 + vy**2 + vz**2)
1578 end subroutine calc_velocity
1585 subroutine increase_edge_count(this, nedges)
1587 class(SwfDfwType) :: this
1588 integer(I4B),
intent(in) :: nedges
1590 this%nedges = this%nedges + nedges
1594 end subroutine increase_edge_count
1598 subroutine set_edge_properties(this, nodedge, ihcedge, q, area, nx, ny, &
1601 class(SwfDfwType) :: this
1602 integer(I4B),
intent(in) :: nodedge
1603 integer(I4B),
intent(in) :: ihcedge
1604 real(DP),
intent(in) :: q
1605 real(DP),
intent(in) :: area
1606 real(DP),
intent(in) :: nx
1607 real(DP),
intent(in) :: ny
1608 real(DP),
intent(in) :: distance
1610 integer(I4B) :: lastedge
1612 this%lastedge = this%lastedge + 1
1613 lastedge = this%lastedge
1614 this%nodedge(lastedge) = nodedge
1615 this%ihcedge(lastedge) = ihcedge
1616 this%propsedge(1, lastedge) = q
1617 this%propsedge(2, lastedge) = area
1618 this%propsedge(3, lastedge) = nx
1619 this%propsedge(4, lastedge) = ny
1620 this%propsedge(5, lastedge) = distance
1624 if (this%lastedge == this%nedges) this%lastedge = 0
1628 end subroutine set_edge_properties
1632 subroutine sav_velocity(this, ibinun)
1634 class(SwfDfwType) :: this
1635 integer(I4B),
intent(in) :: ibinun
1637 character(len=16) :: text
1638 character(len=16),
dimension(3) :: auxtxt
1640 integer(I4B) :: naux
1643 text =
' DATA-VCOMP'
1645 auxtxt(:) = [
' vx',
' vy',
' vz']
1646 call this%dis%record_srcdst_list_header(text, this%name_model, &
1647 this%packName, this%name_model, &
1648 this%packName, naux, auxtxt, ibinun, &
1649 this%dis%nodes, this%iout)
1652 do n = 1, this%dis%nodes
1653 call this%dis%record_mf6_list_entry(ibinun, n, n,
dzero, naux, &
1659 end subroutine sav_velocity
1666 subroutine dfw_df_obs(this)
1668 class(SwfDfwType) :: this
1670 integer(I4B) :: indx
1674 call this%obs%StoreObsType(
'ext-outflow', .true., indx)
1675 this%obs%obsData(indx)%ProcessIdPtr => dfwobsidprocessor
1679 end subroutine dfw_df_obs
1681 subroutine dfwobsidprocessor(obsrv, dis, inunitobs, iout)
1683 type(ObserveType),
intent(inout) :: obsrv
1684 class(DisBaseType),
intent(in) :: dis
1685 integer(I4B),
intent(in) :: inunitobs
1686 integer(I4B),
intent(in) :: iout
1689 character(len=LINELENGTH) :: string
1692 string = obsrv%IDstring
1696 obsrv%NodeNumber = n
1698 errmsg =
'Error reading data from ID string'
1704 end subroutine dfwobsidprocessor
1711 subroutine dfw_bd_obs(this)
1713 class(SwfDfwType) :: this
1719 character(len=100) :: msg
1720 type(ObserveType),
pointer :: obsrv => null()
1723 if (this%obs%npakobs > 0)
then
1724 call this%obs%obs_bd_clear()
1725 do i = 1, this%obs%npakobs
1726 obsrv => this%obs%pakobs(i)%obsrv
1727 do j = 1, obsrv%indxbnds_count
1728 n = obsrv%indxbnds(j)
1730 select case (obsrv%ObsTypeId)
1732 msg =
'Unrecognized observation type: '//trim(obsrv%ObsTypeId)
1735 call this%obs%SaveOneSimval(obsrv, v)
1741 call this%parser%StoreErrorUnit()
1747 end subroutine dfw_bd_obs
1754 subroutine dfw_rp_obs(this)
1758 class(SwfDfwType),
intent(inout) :: this
1763 class(ObserveType),
pointer :: obsrv => null()
1770 do i = 1, this%obs%npakobs
1771 obsrv => this%obs%pakobs(i)%obsrv
1774 nn1 = obsrv%NodeNumber
1775 if (nn1 < 1 .or. nn1 > this%dis%nodes)
then
1776 write (
errmsg,
'(a,1x,a,1x,i0,1x,a,1x,i0,a)') &
1777 trim(adjustl(obsrv%ObsTypeId)), &
1778 'reach must be greater than 0 and less than or equal to', &
1779 this%dis%nodes,
'(specified value is ', nn1,
')'
1782 if (obsrv%indxbnds_count == 0)
then
1783 call obsrv%AddObsIndex(nn1)
1785 errmsg =
'Programming error in dfw_rp_obs'
1791 do j = 1, obsrv%indxbnds_count
1792 nn1 = obsrv%indxbnds(j)
1793 if (nn1 < 1 .or. nn1 > this%dis%nodes)
then
1794 write (
errmsg,
'(a,1x,a,1x,i0,1x,a,1x,i0,a)') &
1795 trim(adjustl(obsrv%ObsTypeId)), &
1796 'reach must be greater than 0 and less than or equal to', &
1797 this%dis%nodes,
'(specified value is ', nn1,
')'
1805 call this%parser%StoreErrorUnit()
1811 end subroutine dfw_rp_obs
1813 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
real(dp), parameter dnodata
real no data constant
integer(i4b), parameter lenbigline
maximum length of a big line
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
real(dp), parameter dem5
real constant 1e-5
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 dthree
real constant 3
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 memorylist_remove(component, subcomponent, context)
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
subroutine, public defaultobsidprocessor(obsrv, dis, inunitobs, iout)
@ brief Process IDstring provided for each observation
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
character(len=maxcharlen) warnmsg
warning message string
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 ...