28 public :: swfdfwtype, dfw_cr
33 integer(I4B),
pointer :: is2d => null()
34 integer(I4B),
pointer :: icentral => null()
35 integer(I4B),
pointer :: iswrcond => null()
36 real(DP),
pointer :: unitconv
37 real(DP),
pointer :: timeconv
38 real(DP),
pointer :: lengthconv
39 real(DP),
dimension(:),
pointer,
contiguous :: hnew => null()
40 real(DP),
dimension(:),
pointer,
contiguous :: manningsn => null()
41 integer(I4B),
dimension(:),
pointer,
contiguous :: idcxs => null()
42 integer(I4B),
dimension(:),
pointer,
contiguous :: ibound => null()
43 integer(I4B),
dimension(:),
pointer,
contiguous :: icelltype => null()
46 integer(I4B),
pointer :: icalcvelocity => null()
47 integer(I4B),
pointer :: isavvelocity => null()
48 real(DP),
dimension(:, :),
pointer,
contiguous :: vcomp => null()
49 real(DP),
dimension(:),
pointer,
contiguous :: vmag => null()
50 integer(I4B),
pointer :: nedges => null()
51 integer(I4B),
pointer :: lastedge => null()
52 integer(I4B),
dimension(:),
pointer,
contiguous :: nodedge => null()
53 integer(I4B),
dimension(:),
pointer,
contiguous :: ihcedge => null()
54 real(DP),
dimension(:, :),
pointer,
contiguous :: propsedge => null()
55 real(DP),
dimension(:),
pointer,
contiguous :: grad_dhds_mag => null()
56 real(DP),
dimension(:),
pointer,
contiguous :: dhdsja => null()
59 integer(I4B),
pointer :: inobspkg => null()
60 type(ObsType),
pointer :: obs => null()
63 type(SwfCxsType),
pointer :: cxs
68 procedure :: allocate_scalars
69 procedure :: allocate_arrays
71 procedure :: source_options
72 procedure :: log_options
73 procedure :: source_griddata
74 procedure :: log_griddata
79 procedure :: dfw_qnm_fc_nr
85 procedure :: dfw_save_model_flows
86 procedure :: dfw_print_model_flows
88 procedure :: dfw_df_obs
89 procedure :: dfw_rp_obs
90 procedure :: dfw_bd_obs
93 procedure :: get_cond_swr
94 procedure :: get_cond_n
95 procedure :: get_flow_area_nm
96 procedure :: calc_velocity
97 procedure :: sav_velocity
98 procedure,
public :: increase_edge_count
99 procedure,
public :: set_edge_properties
100 procedure :: calc_dhds
101 procedure :: write_cxs_tables
109 subroutine dfw_cr(dfwobj, name_model, input_mempath, inunit, iout, &
114 type(SwfDfwType),
pointer :: dfwobj
115 character(len=*),
intent(in) :: name_model
116 character(len=*),
intent(in) :: input_mempath
117 integer(I4B),
intent(in) :: inunit
118 integer(I4B),
intent(in) :: iout
119 type(SwfCxsType),
pointer,
intent(in) :: cxs
121 logical(LGP) :: found_fname
123 character(len=*),
parameter :: fmtheader = &
124 "(1x, /1x, 'DFW -- DIFFUSIVE WAVE (DFW) PACKAGE, VERSION 1, 9/25/2023', &
125 &' INPUT READ FROM MEMPATH: ', A, /)"
131 call dfwobj%set_names(1, name_model,
'DFW',
'DFW')
134 call dfwobj%allocate_scalars()
137 dfwobj%input_mempath = input_mempath
138 dfwobj%inunit = inunit
142 call mem_set_value(dfwobj%input_fname,
'INPUT_FNAME', dfwobj%input_mempath, &
149 call obs_cr(dfwobj%obs, dfwobj%inobspkg)
155 write (iout, fmtheader) input_mempath
159 end subroutine dfw_cr
163 subroutine dfw_df(this, dis)
165 class(SwfDfwType) :: this
166 class(DisBaseType),
pointer,
intent(inout) :: dis
168 character(len=10) :: distype =
''
174 call this%dis%get_dis_type(distype)
175 if (distype ==
"DIS2D")
then
178 if (distype ==
"DISV2D")
then
187 call this%allocate_arrays()
194 end subroutine dfw_df
202 subroutine allocate_scalars(this)
205 class(SwfDfwtype) :: this
208 call this%NumericalPackageType%allocate_scalars()
212 call mem_allocate(this%icentral,
'ICENTRAL', this%memoryPath)
213 call mem_allocate(this%iswrcond,
'ISWRCOND', this%memoryPath)
214 call mem_allocate(this%unitconv,
'UNITCONV', this%memoryPath)
215 call mem_allocate(this%lengthconv,
'LENGTHCONV', this%memoryPath)
216 call mem_allocate(this%timeconv,
'TIMECONV', this%memoryPath)
217 call mem_allocate(this%inobspkg,
'INOBSPKG', this%memoryPath)
218 call mem_allocate(this%icalcvelocity,
'ICALCVELOCITY', this%memoryPath)
219 call mem_allocate(this%isavvelocity,
'ISAVVELOCITY', this%memoryPath)
220 call mem_allocate(this%nedges,
'NEDGES', this%memoryPath)
221 call mem_allocate(this%lastedge,
'LASTEDGE', this%memoryPath)
227 this%lengthconv =
done
230 this%icalcvelocity = 0
231 this%isavvelocity = 0
235 end subroutine allocate_scalars
239 subroutine allocate_arrays(this)
241 class(SwfDfwType) :: this
247 'MANNINGSN', this%memoryPath)
249 'IDCXS', this%memoryPath)
251 'ICELLTYPE', this%memoryPath)
254 call mem_allocate(this%nodedge, 0,
'NODEDGE', this%memoryPath)
255 call mem_allocate(this%ihcedge, 0,
'IHCEDGE', this%memoryPath)
256 call mem_allocate(this%propsedge, 0, 0,
'PROPSEDGE', this%memoryPath)
259 call mem_allocate(this%vcomp, 3, 0,
'VCOMP', this%memoryPath)
260 call mem_allocate(this%vmag, 0,
'VMAG', this%memoryPath)
262 do n = 1, this%dis%nodes
263 this%manningsn(n) =
dzero
265 this%icelltype(n) = 1
269 if (this%is2d == 1)
then
271 'GRAD_DHDS_MAG', this%memoryPath)
273 'DHDSJA', this%memoryPath)
274 do n = 1, this%dis%nodes
275 this%grad_dhds_mag(n) =
dzero
277 do n = 1, this%dis%njas
278 this%dhdsja(n) =
dzero
282 end subroutine allocate_arrays
286 subroutine dfw_load(this)
288 class(SwfDfwType) :: this
291 call this%source_options()
292 call this%source_griddata()
294 end subroutine dfw_load
298 subroutine source_options(this)
306 class(SwfDfwType) :: this
308 integer(I4B) :: isize
309 type(SwfDfwParamFoundType) :: found
310 type(CharacterStringType),
dimension(:),
pointer, &
311 contiguous :: obs6_fnames
315 this%input_mempath, found%icentral)
317 this%input_mempath, found%iswrcond)
319 this%input_mempath, found%lengthconv)
321 this%input_mempath, found%timeconv)
323 this%input_mempath, found%iprflow)
325 this%input_mempath, found%ipakcb)
327 this%input_mempath, found%isavvelocity)
330 if (found%icentral) this%icentral = 1
331 if (found%ipakcb) this%ipakcb = -1
334 this%unitconv = this%lengthconv**
donethird
335 this%unitconv = this%unitconv * this%timeconv
338 if (found%isavvelocity) this%icalcvelocity = this%isavvelocity
341 call get_isize(
'OBS6_FILENAME', this%input_mempath, isize)
345 errmsg =
'Multiple OBS6 keywords detected in OPTIONS block.'// &
346 ' Only one OBS6 entry allowed.'
351 call mem_setptr(obs6_fnames,
'OBS6_FILENAME', this%input_mempath)
353 found%obs6_filename = .true.
354 this%obs%inputFilename = obs6_fnames(1)
355 this%obs%active = .true.
357 this%obs%inUnitObs = this%inobspkg
358 call openfile(this%inobspkg, this%iout, this%obs%inputFilename,
'OBS')
359 call this%obs%obs_df(this%iout, this%packName, this%filtyp, this%dis)
360 call this%dfw_df_obs()
364 if (this%iout > 0)
then
365 call this%log_options(found)
368 end subroutine source_options
372 subroutine log_options(this, found)
374 class(SwfDfwType) :: this
375 type(SwfDfwParamFoundType),
intent(in) :: found
377 write (this%iout,
'(1x,a)')
'Setting DFW Options'
379 if (found%lengthconv)
then
380 write (this%iout,
'(4x,a, G0)')
'Mannings length conversion value &
381 &specified as ', this%lengthconv
384 if (found%timeconv)
then
385 write (this%iout,
'(4x,a, G0)')
'Mannings time conversion value &
386 &specified as ', this%timeconv
389 if (found%lengthconv .or. found%timeconv)
then
390 write (this%iout,
'(4x,a, G0)')
'Mannings conversion value calculated &
391 &from user-provided length_conversion and &
392 &time_conversion is ', this%unitconv
395 if (found%iprflow)
then
396 write (this%iout,
'(4x,a)')
'Cell-by-cell flow information will be printed &
397 &to listing file whenever ICBCFL is not zero.'
400 if (found%ipakcb)
then
401 write (this%iout,
'(4x,a)')
'Cell-by-cell flow information will be printed &
402 &to listing file whenever ICBCFL is not zero.'
405 if (found%obs6_filename)
then
406 write (this%iout,
'(4x,a)')
'Observation package is active.'
409 if (found%isavvelocity) &
410 write (this%iout,
'(4x,a)')
'Velocity will be calculated at cell &
411 ¢ers and written to DATA-VCOMP in budget &
412 &file when requested.'
414 if (found%iswrcond)
then
415 write (this%iout,
'(4x,a, G0)')
'Conductance will be calculated using &
416 &the SWR development option.'
419 write (this%iout,
'(1x,a,/)')
'End Setting DFW Options'
421 end subroutine log_options
425 subroutine source_griddata(this)
433 class(SwfDfwType) :: this
435 character(len=LENMEMPATH) :: idmMemoryPath
436 type(SwfDfwParamFoundType) :: found
437 integer(I4B),
dimension(:),
pointer,
contiguous :: map
444 if (this%dis%nodes < this%dis%nodesuser) map => this%dis%nodeuser
448 idmmemorypath, map, found%manningsn)
449 call mem_set_value(this%idcxs,
'IDCXS', idmmemorypath, map, found%idcxs)
452 if (.not. found%manningsn)
then
453 write (errmsg,
'(a)')
'Error in GRIDDATA block: MANNINGSN not found.'
458 call store_error_filename(this%input_fname)
462 if (this%iout > 0)
then
463 call this%log_griddata(found)
466 end subroutine source_griddata
470 subroutine log_griddata(this, found)
472 class(SwfDfwType) :: this
473 type(SwfDfwParamFoundType),
intent(in) :: found
475 write (this%iout,
'(1x,a)')
'Setting DFW Griddata'
477 if (found%manningsn)
then
478 write (this%iout,
'(4x,a)')
'MANNINGSN set from input file'
481 if (found%idcxs)
then
482 write (this%iout,
'(4x,a)')
'IDCXS set from input file'
485 call this%write_cxs_tables()
487 write (this%iout,
'(1x,a,/)')
'End Setting DFW Griddata'
489 end subroutine log_griddata
491 subroutine write_cxs_tables(this)
494 class(SwfDfwType) :: this
507 end subroutine write_cxs_tables
511 subroutine dfw_ar(this, ibound, hnew)
514 class(SwfDfwType) :: this
515 integer(I4B),
dimension(:),
pointer,
contiguous :: ibound
516 real(DP),
dimension(:),
pointer,
contiguous,
intent(inout) :: hnew
521 this%ibound => ibound
524 if (this%icalcvelocity == 1)
then
525 call mem_reallocate(this%vcomp, 3, this%dis%nodes,
'VCOMP', this%memoryPath)
526 call mem_reallocate(this%vmag, this%dis%nodes,
'VMAG', this%memoryPath)
527 call mem_reallocate(this%nodedge, this%nedges,
'NODEDGE', this%memoryPath)
528 call mem_reallocate(this%ihcedge, this%nedges,
'IHCEDGE', this%memoryPath)
529 call mem_reallocate(this%propsedge, 5, this%nedges,
'PROPSEDGE', &
531 do n = 1, this%dis%nodes
532 this%vcomp(:, n) =
dzero
538 call this%obs%obs_ar()
540 end subroutine dfw_ar
544 subroutine dfw_rp(this)
547 class(SwfDfwType) :: this
550 call this%dfw_rp_obs()
552 end subroutine dfw_rp
556 subroutine dfw_ad(this, irestore)
557 class(SwfDfwType) :: this
558 integer(I4B),
intent(in) :: irestore
561 call this%obs%obs_ad()
563 end subroutine dfw_ad
571 subroutine dfw_fc(this, kiter, matrix_sln, idxglo, rhs, stage, stage_old)
574 class(SwfDfwType) :: this
575 integer(I4B) :: kiter
576 class(MatrixBaseType),
pointer :: matrix_sln
577 integer(I4B),
intent(in),
dimension(:) :: idxglo
578 real(DP),
intent(inout),
dimension(:) :: rhs
579 real(DP),
intent(inout),
dimension(:) :: stage
580 real(DP),
intent(inout),
dimension(:) :: stage_old
584 if (this%is2d == 1)
then
585 call this%calc_dhds()
589 call this%dfw_qnm_fc_nr(kiter, matrix_sln, idxglo, rhs, stage, stage_old)
591 end subroutine dfw_fc
596 subroutine dfw_qnm_fc_nr(this, kiter, matrix_sln, idxglo, rhs, stage, stage_old)
600 class(SwfDfwType) :: this
601 integer(I4B) :: kiter
602 class(MatrixBaseType),
pointer :: matrix_sln
603 integer(I4B),
intent(in),
dimension(:) :: idxglo
604 real(DP),
intent(inout),
dimension(:) :: rhs
605 real(DP),
intent(inout),
dimension(:) :: stage
606 real(DP),
intent(inout),
dimension(:) :: stage_old
608 integer(I4B) :: n, m, ii, idiag
615 do n = 1, this%dis%nodes
618 idiag = this%dis%con%ia(n)
621 do ii = this%dis%con%ia(n) + 1, this%dis%con%ia(n + 1) - 1
624 if (this%dis%con%mask(ii) == 0) cycle
627 m = this%dis%con%ja(ii)
630 qnm = this%qcalc(n, m, stage(n), stage(m), ii)
631 rhs(n) = rhs(n) - qnm
635 qeps = this%qcalc(n, m, stage(n) + eps, stage(m), ii)
636 derv = (qeps - qnm) / eps
637 call matrix_sln%add_value_pos(idxglo(idiag), derv)
638 rhs(n) = rhs(n) + derv * stage(n)
642 qeps = this%qcalc(n, m, stage(n), stage(m) + eps, ii)
643 derv = (qeps - qnm) / eps
644 call matrix_sln%add_value_pos(idxglo(ii), derv)
645 rhs(n) = rhs(n) + derv * stage(m)
650 end subroutine dfw_qnm_fc_nr
654 subroutine dfw_fn(this, kiter, matrix_sln, idxglo, rhs, stage)
656 class(SwfDfwType) :: this
657 integer(I4B) :: kiter
658 class(MatrixBaseType),
pointer :: matrix_sln
659 integer(I4B),
intent(in),
dimension(:) :: idxglo
660 real(DP),
intent(inout),
dimension(:) :: rhs
661 real(DP),
intent(inout),
dimension(:) :: stage
668 end subroutine dfw_fn
672 function qcalc(this, n, m, stage_n, stage_m, ipos)
result(qnm)
674 class(SwfDfwType) :: this
675 integer(I4B),
intent(in) :: n
676 integer(I4B),
intent(in) :: m
677 real(DP),
intent(in) :: stage_n
678 real(DP),
intent(in) :: stage_m
679 integer(I4B),
intent(in) :: ipos
681 integer(I4B) :: isympos
688 isympos = this%dis%con%jas(ipos)
690 cl1 = this%dis%con%cl1(isympos)
691 cl2 = this%dis%con%cl2(isympos)
693 cl1 = this%dis%con%cl2(isympos)
694 cl2 = this%dis%con%cl1(isympos)
698 if (this%iswrcond == 0)
then
699 cond = this%get_cond(n, m, ipos, stage_n, stage_m, cl1, cl2)
700 else if (this%iswrcond == 1)
then
701 cond = this%get_cond_swr(n, m, ipos, stage_n, stage_m, cl1, cl2)
705 qnm = cond * (stage_m - stage_n)
714 function get_cond(this, n, m, ipos, stage_n, stage_m, cln, clm)
result(cond)
718 class(SwfDfwType) :: this
719 integer(I4B),
intent(in) :: n
720 integer(I4B),
intent(in) :: m
721 integer(I4B),
intent(in) :: ipos
722 real(DP),
intent(in) :: stage_n
723 real(DP),
intent(in) :: stage_m
724 real(DP),
intent(in) :: cln
725 real(DP),
intent(in) :: clm
733 real(DP) :: range = 1.d-6
735 real(DP) :: smooth_factor
736 real(DP) :: length_nm
744 length_nm = cln + clm
746 if (length_nm >
dprec)
then
749 depth_n = stage_n - this%dis%bot(n)
750 depth_m = stage_m - this%dis%bot(m)
753 if (this%is2d == 0)
then
754 dhds_n = abs(stage_m - stage_n) / (cln + clm)
757 dhds_n = this%grad_dhds_mag(n)
758 dhds_m = this%grad_dhds_mag(m)
762 if (this%icentral == 0)
then
764 if (stage_n > stage_m)
then
773 call squadratic(depth_n, range, dydx, smooth_factor)
774 depth_n = depth_n * smooth_factor
775 call squadratic(depth_m, range, dydx, smooth_factor)
776 depth_m = depth_m * smooth_factor
779 call this%dis%get_flow_width(n, m, ipos, width_n, width_m)
783 cn = this%get_cond_n(n, depth_n, cln, width_n, dhds_n)
784 cm = this%get_cond_n(m, depth_m, clm, width_m, dhds_m)
789 if ((cn + cm) >
dprec)
then
790 cond = cn * cm / (cn + cm)
797 end function get_cond
803 function get_cond_n(this, n, depth, dx, width, dhds)
result(c)
806 class(SwfDfwType) :: this
807 integer(I4B),
intent(in) :: n
808 real(DP),
intent(in) :: depth
809 real(DP),
intent(in) :: dx
810 real(DP),
intent(in) :: width
811 real(DP),
intent(in) :: dhds
817 real(DP) :: conveyance
820 rough = this%manningsn(n)
821 conveyance = this%cxs%get_conveyance(this%idcxs(n), width, depth, rough)
822 dhds_sqr = dhds**
dhalf
823 if (dhds_sqr <
dem10)
then
828 c = this%unitconv * conveyance / dx / dhds_sqr
830 end function get_cond_n
838 function get_cond_swr(this, n, m, ipos, stage_n, stage_m, cln, clm)
result(cond)
842 class(SwfDfwType) :: this
843 integer(I4B),
intent(in) :: n
844 integer(I4B),
intent(in) :: m
845 integer(I4B),
intent(in) :: ipos
846 real(DP),
intent(in) :: stage_n
847 real(DP),
intent(in) :: stage_m
848 real(DP),
intent(in) :: cln
849 real(DP),
intent(in) :: clm
859 real(DP) :: range = 1.d-6
861 real(DP) :: smooth_factor
862 real(DP) :: length_nm
866 real(DP) :: area_n, area_m, area_avg
867 real(DP) :: rhn, rhm, rhavg
875 length_nm = cln + clm
877 if (length_nm >
dprec)
then
880 depth_n = stage_n - this%dis%bot(n)
881 depth_m = stage_m - this%dis%bot(m)
884 if (this%icentral == 0)
then
886 if (stage_n > stage_m)
then
895 call squadratic(depth_n, range, dydx, smooth_factor)
896 depth_n = depth_n * smooth_factor
897 call squadratic(depth_m, range, dydx, smooth_factor)
898 depth_m = depth_m * smooth_factor
901 call this%dis%get_flow_width(n, m, ipos, width_n, width_m)
904 weight_n = clm / length_nm
905 weight_m =
done - weight_n
908 area_n = this%cxs%get_area(this%idcxs(n), width_n, depth_n)
909 area_m = this%cxs%get_area(this%idcxs(m), width_m, depth_m)
910 area_avg = weight_n * area_n + weight_m * area_m
913 if (this%is2d == 0)
then
914 rhn = this%cxs%get_hydraulic_radius(this%idcxs(n), width_n, &
916 rhm = this%cxs%get_hydraulic_radius(this%idcxs(m), width_m, &
918 rhavg = weight_n * rhn + weight_m * rhm
920 rhavg = area_avg / width_n
925 if (this%is2d == 0)
then
926 dhds_nm = abs(stage_m - stage_n) / (length_nm)
928 dhds_n = this%grad_dhds_mag(n)
929 dhds_m = this%grad_dhds_mag(m)
930 dhds_nm = weight_n * dhds_n + weight_m * dhds_m
932 dhds_sqr = dhds_nm**
dhalf
933 if (dhds_sqr <
dem10)
then
938 weight_n = cln / length_nm
939 weight_m =
done - weight_n
940 rough_n = this%cxs%get_roughness(this%idcxs(n), width_n, depth_n, &
941 this%manningsn(n), dhds_nm)
942 rough_m = this%cxs%get_roughness(this%idcxs(m), width_m, depth_m, &
943 this%manningsn(m), dhds_nm)
944 ravg = (weight_n + weight_m) / &
945 (weight_n / rough_n + weight_m / rough_m)
946 rinv_avg =
done / ravg
949 cond = this%unitconv * rinv_avg * area_avg * rhavg / dhds_sqr / length_nm
953 end function get_cond_swr
961 function get_flow_area_nm(this, n, m, stage_n, stage_m, cln, clm, &
962 ipos)
result(area_avg)
966 class(SwfDfwType) :: this
967 integer(I4B),
intent(in) :: n
968 integer(I4B),
intent(in) :: m
969 real(DP),
intent(in) :: stage_n
970 real(DP),
intent(in) :: stage_m
971 real(DP),
intent(in) :: cln
972 real(DP),
intent(in) :: clm
973 integer(I4B),
intent(in) :: ipos
983 real(DP) :: length_nm
984 real(DP) :: range = 1.d-6
986 real(DP) :: smooth_factor
991 depth_n = stage_n - this%dis%bot(n)
992 depth_m = stage_m - this%dis%bot(m)
995 if (this%icentral == 0)
then
997 if (stage_n > stage_m)
then
1006 call squadratic(depth_n, range, dydx, smooth_factor)
1007 depth_n = depth_n * smooth_factor
1008 call squadratic(depth_m, range, dydx, smooth_factor)
1009 depth_m = depth_m * smooth_factor
1012 call this%dis%get_flow_width(n, m, ipos, width_n, width_m)
1015 length_nm = cln + clm
1016 weight_n = clm / length_nm
1017 weight_m =
done - weight_n
1020 area_n = this%cxs%get_area(this%idcxs(n), width_n, depth_n)
1021 area_m = this%cxs%get_area(this%idcxs(m), width_m, depth_m)
1022 area_avg = weight_n * area_n + weight_m * area_m
1024 end function get_flow_area_nm
1032 subroutine calc_dhds(this)
1036 class(SwfDfwType) :: this
1040 integer(I4B) :: ipos
1041 integer(I4B) :: isympos
1045 do n = 1, this%dis%nodes
1046 this%grad_dhds_mag(n) =
dzero
1047 do ipos = this%dis%con%ia(n) + 1, this%dis%con%ia(n + 1) - 1
1048 m = this%dis%con%ja(ipos)
1049 isympos = this%dis%con%jas(ipos)
1053 cl1 = this%dis%con%cl1(isympos)
1054 cl2 = this%dis%con%cl2(isympos)
1056 cl1 = this%dis%con%cl2(isympos)
1057 cl2 = this%dis%con%cl1(isympos)
1062 if (cl1 + cl2 >
dprec)
then
1063 this%dhdsja(isympos) = (this%hnew(m) - this%hnew(n)) / (cl1 + cl2)
1065 this%dhdsja(isympos) =
dzero
1075 end subroutine calc_dhds
1080 subroutine dfw_nur(this, neqmod, x, xtemp, dx, inewtonur, dxmax, locmax)
1082 class(SwfDfwType) :: this
1083 integer(I4B),
intent(in) :: neqmod
1084 real(DP),
dimension(neqmod),
intent(inout) :: x
1085 real(DP),
dimension(neqmod),
intent(in) :: xtemp
1086 real(DP),
dimension(neqmod),
intent(inout) :: dx
1087 integer(I4B),
intent(inout) :: inewtonur
1088 real(DP),
intent(inout) :: dxmax
1089 integer(I4B),
intent(inout) :: locmax
1097 do n = 1, this%dis%nodes
1098 if (this%ibound(n) < 1) cycle
1099 if (this%icelltype(n) > 0)
then
1100 botm = this%dis%bot(n)
1103 if (x(n) < botm)
then
1107 if (abs(dxx) > abs(dxmax))
then
1117 end subroutine dfw_nur
1121 subroutine dfw_cq(this, stage, stage_old, flowja)
1123 class(SwfDfwType) :: this
1124 real(DP),
intent(inout),
dimension(:) :: stage
1125 real(DP),
intent(inout),
dimension(:) :: stage_old
1126 real(DP),
intent(inout),
dimension(:) :: flowja
1128 integer(I4B) :: n, ipos, m
1131 do n = 1, this%dis%nodes
1132 do ipos = this%dis%con%ia(n) + 1, this%dis%con%ia(n + 1) - 1
1133 m = this%dis%con%ja(ipos)
1135 qnm = this%qcalc(n, m, stage(n), stage(m), ipos)
1137 flowja(this%dis%con%isym(ipos)) = -qnm
1141 end subroutine dfw_cq
1145 subroutine dfw_bd(this, isuppress_output, model_budget)
1149 class(SwfDfwType) :: this
1150 integer(I4B),
intent(in) :: isuppress_output
1151 type(BudgetType),
intent(inout) :: model_budget
1156 end subroutine dfw_bd
1160 subroutine dfw_save_model_flows(this, flowja, icbcfl, icbcun)
1162 class(SwfDfwType) :: this
1163 real(DP),
dimension(:),
intent(in) :: flowja
1164 integer(I4B),
intent(in) :: icbcfl
1165 integer(I4B),
intent(in) :: icbcun
1167 integer(I4B) :: ibinun
1170 if (this%ipakcb < 0)
then
1172 elseif (this%ipakcb == 0)
then
1175 ibinun = this%ipakcb
1177 if (icbcfl == 0) ibinun = 0
1180 if (ibinun /= 0)
then
1182 call this%dis%record_connection_array(flowja, ibinun, this%iout)
1186 if (this%isavvelocity /= 0)
then
1187 if (ibinun /= 0)
call this%sav_velocity(ibinun)
1190 end subroutine dfw_save_model_flows
1194 subroutine dfw_print_model_flows(this, ibudfl, flowja)
1199 class(SwfDfwType) :: this
1200 integer(I4B),
intent(in) :: ibudfl
1201 real(DP),
intent(inout),
dimension(:) :: flowja
1203 character(len=LENBIGLINE) :: line
1204 character(len=30) :: tempstr
1205 integer(I4B) :: n, ipos, m
1208 character(len=*),
parameter :: fmtiprflow = &
1209 &
"(/,4x,'CALCULATED INTERCELL FLOW FOR PERIOD ', i0, ' STEP ', i0)"
1212 if (ibudfl /= 0 .and. this%iprflow > 0)
then
1213 write (this%iout, fmtiprflow)
kper,
kstp
1214 do n = 1, this%dis%nodes
1216 call this%dis%noder_to_string(n, tempstr)
1217 line = trim(tempstr)//
':'
1218 do ipos = this%dis%con%ia(n) + 1, this%dis%con%ia(n + 1) - 1
1219 m = this%dis%con%ja(ipos)
1220 call this%dis%noder_to_string(m, tempstr)
1221 line = trim(line)//
' '//trim(tempstr)
1223 write (tempstr,
'(1pg15.6)') qnm
1224 line = trim(line)//
' '//trim(adjustl(tempstr))
1226 write (this%iout,
'(a)') trim(line)
1230 end subroutine dfw_print_model_flows
1234 subroutine dfw_da(this)
1240 class(SwfDfwType) :: this
1254 if (this%is2d == 1)
then
1273 call this%obs%obs_da()
1274 deallocate (this%obs)
1279 call this%NumericalPackageType%da()
1284 end subroutine dfw_da
1290 subroutine calc_velocity(this, flowja)
1293 class(SwfDfwType) :: this
1294 real(DP),
intent(in),
dimension(:) :: flowja
1298 integer(I4B) :: ipos
1299 integer(I4B) :: isympos
1325 real(DP),
allocatable,
dimension(:) :: vi
1326 real(DP),
allocatable,
dimension(:) :: di
1327 real(DP),
allocatable,
dimension(:) :: viz
1328 real(DP),
allocatable,
dimension(:) :: diz
1329 real(DP),
allocatable,
dimension(:) :: nix
1330 real(DP),
allocatable,
dimension(:) :: niy
1331 real(DP),
allocatable,
dimension(:) :: wix
1332 real(DP),
allocatable,
dimension(:) :: wiy
1333 real(DP),
allocatable,
dimension(:) :: wiz
1334 real(DP),
allocatable,
dimension(:) :: bix
1335 real(DP),
allocatable,
dimension(:) :: biy
1336 logical :: nozee = .true.
1340 if (this%icalcvelocity /= 0 .and. this%dis%con%ianglex == 0)
then
1341 call store_error(
'Error. ANGLDEGX not provided in '// &
1342 'discretization file. ANGLDEGX required for '// &
1343 'calculation of velocity.', terminate=.true.)
1348 do n = 1, this%dis%nodes
1351 ic = this%dis%con%ia(n + 1) - this%dis%con%ia(n) - 1
1354 do m = 1, this%nedges
1355 if (this%nodedge(m) == n)
then
1361 if (ic > nc) nc = ic
1378 do n = 1, this%dis%nodes
1390 do ipos = this%dis%con%ia(n) + 1, this%dis%con%ia(n + 1) - 1
1391 m = this%dis%con%ja(ipos)
1392 isympos = this%dis%con%jas(ipos)
1393 ihc = this%dis%con%ihc(isympos)
1395 call this%dis%connection_normal(n, m, ihc, xn, yn, zn, ipos)
1396 call this%dis%connection_vector(n, m, nozee,
done,
done, &
1397 ihc, xc, yc, zc, dltot)
1398 cl1 = this%dis%con%cl1(isympos)
1399 cl2 = this%dis%con%cl2(isympos)
1401 cl1 = this%dis%con%cl2(isympos)
1402 cl2 = this%dis%con%cl1(isympos)
1404 ooclsum =
done / (cl1 + cl2)
1407 di(ic) = dltot * cl1 * ooclsum
1408 area = this%get_flow_area_nm(n, m, this%hnew(n), this%hnew(m), &
1410 if (area >
dzero)
then
1411 vi(ic) = flowja(ipos) / area
1420 do m = 1, this%nedges
1421 if (this%nodedge(m) == n)
then
1424 ihc = this%ihcedge(m)
1425 area = this%propsedge(2, m)
1428 nix(ic) = -this%propsedge(3, m)
1429 niy(ic) = -this%propsedge(4, m)
1430 di(ic) = this%propsedge(5, m)
1431 if (area >
dzero)
then
1432 vi(ic) = this%propsedge(1, m) / area
1450 dsumz = dsumz + diz(iz)
1452 denom = (ncz -
done)
1454 dsumz = dsumz +
dem10 * dsumz
1456 if (dsumz >
dzero) wiz(iz) =
done - diz(iz) / dsumz
1458 wiz(iz) = wiz(iz) / denom
1466 vz = vz + wiz(iz) * viz(iz)
1475 wix(ic) = di(ic) * abs(nix(ic))
1476 wiy(ic) = di(ic) * abs(niy(ic))
1477 dsumx = dsumx + wix(ic)
1478 dsumy = dsumy + wiy(ic)
1485 dsumx = dsumx +
dem10 * dsumx
1486 dsumy = dsumy +
dem10 * dsumy
1488 wix(ic) = (dsumx - wix(ic)) * abs(nix(ic))
1489 wiy(ic) = (dsumy - wiy(ic)) * abs(niy(ic))
1496 bix(ic) = wix(ic) * sign(
done, nix(ic))
1497 biy(ic) = wiy(ic) * sign(
done, niy(ic))
1498 dsumx = dsumx + wix(ic) * abs(nix(ic))
1499 dsumy = dsumy + wiy(ic) * abs(niy(ic))
1506 bix(ic) = bix(ic) * dsumx
1507 biy(ic) = biy(ic) * dsumy
1508 axy = axy + bix(ic) * niy(ic)
1509 ayx = ayx + biy(ic) * nix(ic)
1522 vx = vx + (bix(ic) - axy * biy(ic)) * vi(ic)
1523 vy = vy + (biy(ic) - ayx * bix(ic)) * vi(ic)
1525 denom =
done - axy * ayx
1526 if (denom /=
dzero)
then
1531 this%vcomp(1, n) = vx
1532 this%vcomp(2, n) = vy
1533 this%vcomp(3, n) = vz
1534 this%vmag(n) = sqrt(vx**2 + vy**2 + vz**2)
1549 end subroutine calc_velocity
1556 subroutine increase_edge_count(this, nedges)
1558 class(SwfDfwType) :: this
1559 integer(I4B),
intent(in) :: nedges
1561 this%nedges = this%nedges + nedges
1563 end subroutine increase_edge_count
1569 subroutine set_edge_properties(this, nodedge, ihcedge, q, area, nx, ny, &
1572 class(SwfDfwType) :: this
1573 integer(I4B),
intent(in) :: nodedge
1574 integer(I4B),
intent(in) :: ihcedge
1575 real(DP),
intent(in) :: q
1576 real(DP),
intent(in) :: area
1577 real(DP),
intent(in) :: nx
1578 real(DP),
intent(in) :: ny
1579 real(DP),
intent(in) :: distance
1581 integer(I4B) :: lastedge
1583 this%lastedge = this%lastedge + 1
1584 lastedge = this%lastedge
1585 this%nodedge(lastedge) = nodedge
1586 this%ihcedge(lastedge) = ihcedge
1587 this%propsedge(1, lastedge) = q
1588 this%propsedge(2, lastedge) = area
1589 this%propsedge(3, lastedge) = nx
1590 this%propsedge(4, lastedge) = ny
1591 this%propsedge(5, lastedge) = distance
1595 if (this%lastedge == this%nedges) this%lastedge = 0
1597 end subroutine set_edge_properties
1603 subroutine sav_velocity(this, ibinun)
1605 class(SwfDfwType) :: this
1606 integer(I4B),
intent(in) :: ibinun
1608 character(len=16) :: text
1609 character(len=16),
dimension(3) :: auxtxt
1611 integer(I4B) :: naux
1614 text =
' DATA-VCOMP'
1616 auxtxt(:) = [
' vx',
' vy',
' vz']
1617 call this%dis%record_srcdst_list_header(text, this%name_model, &
1618 this%packName, this%name_model, &
1619 this%packName, naux, auxtxt, ibinun, &
1620 this%dis%nodes, this%iout)
1623 do n = 1, this%dis%nodes
1624 call this%dis%record_mf6_list_entry(ibinun, n, n,
dzero, naux, &
1628 end subroutine sav_velocity
1633 subroutine dfw_df_obs(this)
1635 class(SwfDfwType) :: this
1637 integer(I4B) :: indx
1641 call this%obs%StoreObsType(
'ext-outflow', .true., indx)
1642 this%obs%obsData(indx)%ProcessIdPtr => dfwobsidprocessor
1644 end subroutine dfw_df_obs
1646 subroutine dfwobsidprocessor(obsrv, dis, inunitobs, iout)
1648 type(ObserveType),
intent(inout) :: obsrv
1649 class(DisBaseType),
intent(in) :: dis
1650 integer(I4B),
intent(in) :: inunitobs
1651 integer(I4B),
intent(in) :: iout
1654 character(len=LINELENGTH) :: string
1657 string = obsrv%IDstring
1661 obsrv%NodeNumber = n
1663 errmsg =
'Error reading data from ID string'
1668 end subroutine dfwobsidprocessor
1673 subroutine dfw_bd_obs(this)
1675 class(SwfDfwType) :: this
1681 character(len=100) :: msg
1682 type(ObserveType),
pointer :: obsrv => null()
1685 if (this%obs%npakobs > 0)
then
1686 call this%obs%obs_bd_clear()
1687 do i = 1, this%obs%npakobs
1688 obsrv => this%obs%pakobs(i)%obsrv
1689 do j = 1, obsrv%indxbnds_count
1690 n = obsrv%indxbnds(j)
1692 select case (obsrv%ObsTypeId)
1694 msg =
'Unrecognized observation type: '//trim(obsrv%ObsTypeId)
1697 call this%obs%SaveOneSimval(obsrv, v)
1707 end subroutine dfw_bd_obs
1712 subroutine dfw_rp_obs(this)
1716 class(SwfDfwType),
intent(inout) :: this
1721 class(ObserveType),
pointer :: obsrv => null()
1727 do i = 1, this%obs%npakobs
1728 obsrv => this%obs%pakobs(i)%obsrv
1731 nn1 = obsrv%NodeNumber
1732 if (nn1 < 1 .or. nn1 > this%dis%nodes)
then
1733 write (
errmsg,
'(a,1x,a,1x,i0,1x,a,1x,i0,a)') &
1734 trim(adjustl(obsrv%ObsTypeId)), &
1735 'reach must be greater than 0 and less than or equal to', &
1736 this%dis%nodes,
'(specified value is ', nn1,
')'
1739 if (obsrv%indxbnds_count == 0)
then
1740 call obsrv%AddObsIndex(nn1)
1742 errmsg =
'Programming error in dfw_rp_obs'
1748 do j = 1, obsrv%indxbnds_count
1749 nn1 = obsrv%indxbnds(j)
1750 if (nn1 < 1 .or. nn1 > this%dis%nodes)
then
1751 write (
errmsg,
'(a,1x,a,1x,i0,1x,a,1x,i0,a)') &
1752 trim(adjustl(obsrv%ObsTypeId)), &
1753 'reach must be greater than 0 and less than or equal to', &
1754 this%dis%nodes,
'(specified value is ', nn1,
')'
1767 end subroutine dfw_rp_obs
1769 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 memorystore_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 ...