28 character(len=LENBUDTXT),
dimension(NBDITEMS) ::
budtxt
29 data budtxt/
' STORAGE-AQUEOUS',
' DECAY-AQUEOUS', &
30 ' STORAGE-SORBED',
' DECAY-SORBED'/
41 real(dp),
dimension(:),
pointer,
contiguous :: porosity => null()
42 real(dp),
dimension(:),
pointer,
contiguous :: thetam => null()
43 real(dp),
dimension(:),
pointer,
contiguous :: volfracim => null()
44 real(dp),
dimension(:),
pointer,
contiguous :: ratesto => null()
47 integer(I4B),
pointer :: idcy => null()
48 real(dp),
dimension(:),
pointer,
contiguous :: decay => null()
49 real(dp),
dimension(:),
pointer,
contiguous :: decay_sorbed => null()
50 real(dp),
dimension(:),
pointer,
contiguous :: ratedcy => null()
51 real(dp),
dimension(:),
pointer,
contiguous :: decaylast => null()
52 real(dp),
dimension(:),
pointer,
contiguous :: decayslast => null()
55 integer(I4B),
pointer :: isrb => null()
56 integer(I4B),
pointer :: ioutsorbate => null()
57 real(dp),
dimension(:),
pointer,
contiguous :: bulk_density => null()
58 real(dp),
dimension(:),
pointer,
contiguous :: distcoef => null()
59 real(dp),
dimension(:),
pointer,
contiguous :: sp2 => null()
60 real(dp),
dimension(:),
pointer,
contiguous :: ratesrb => null()
61 real(dp),
dimension(:),
pointer,
contiguous :: ratedcys => null()
62 real(dp),
dimension(:),
pointer,
contiguous :: csrb => null()
65 integer(I4B),
dimension(:),
pointer,
contiguous :: ibound => null()
102 subroutine mst_cr(mstobj, name_model, inunit, iout, fmi)
105 character(len=*),
intent(in) :: name_model
106 integer(I4B),
intent(in) :: inunit
107 integer(I4B),
intent(in) :: iout
114 call mstobj%set_names(1, name_model,
'MST',
'MST')
117 call mstobj%allocate_scalars()
120 mstobj%inunit = inunit
125 call mstobj%parser%Initialize(mstobj%inunit, mstobj%iout)
138 integer(I4B),
dimension(:),
pointer,
contiguous :: ibound
141 character(len=*),
parameter :: fmtmst = &
142 "(1x,/1x,'MST -- MOBILE STORAGE AND TRANSFER PACKAGE, VERSION 1, &
143 &7/29/2020 INPUT READ FROM UNIT ', i0, //)"
146 write (this%iout, fmtmst) this%inunit
149 call this%read_options()
153 this%ibound => ibound
156 call this%allocate_arrays(dis%nodes)
159 call this%read_data()
167 subroutine mst_fc(this, nodes, cold, nja, matrix_sln, idxglo, cnew, &
172 integer,
intent(in) :: nodes
173 real(DP),
intent(in),
dimension(nodes) :: cold
174 integer(I4B),
intent(in) :: nja
176 integer(I4B),
intent(in),
dimension(nja) :: idxglo
177 real(DP),
intent(inout),
dimension(nodes) :: rhs
178 real(DP),
intent(in),
dimension(nodes) :: cnew
179 integer(I4B),
intent(in) :: kiter
183 call this%mst_fc_sto(nodes, cold, nja, matrix_sln, idxglo, rhs)
186 if (this%idcy /= 0)
then
187 call this%mst_fc_dcy(nodes, cold, cnew, nja, matrix_sln, idxglo, &
192 if (this%isrb /= 0)
then
193 call this%mst_fc_srb(nodes, cold, nja, matrix_sln, idxglo, rhs, cnew)
197 if (this%isrb /= 0 .and. this%idcy /= 0)
then
198 call this%mst_fc_dcy_srb(nodes, cold, nja, matrix_sln, idxglo, rhs, &
208 subroutine mst_fc_sto(this, nodes, cold, nja, matrix_sln, idxglo, rhs)
213 integer,
intent(in) :: nodes
214 real(DP),
intent(in),
dimension(nodes) :: cold
215 integer(I4B),
intent(in) :: nja
217 integer(I4B),
intent(in),
dimension(nja) :: idxglo
218 real(DP),
intent(inout),
dimension(nodes) :: rhs
220 integer(I4B) :: n, idiag
222 real(DP) :: hhcof, rrhs
223 real(DP) :: vnew, vold
229 do n = 1, this%dis%nodes
232 if (this%ibound(n) <= 0) cycle
235 vnew = this%dis%area(n) * (this%dis%top(n) - this%dis%bot(n)) * &
236 this%fmi%gwfsat(n) * this%thetam(n)
238 if (this%fmi%igwfstrgss /= 0) vold = vold + this%fmi%gwfstrgss(n) *
delt
239 if (this%fmi%igwfstrgsy /= 0) vold = vold + this%fmi%gwfstrgsy(n) *
delt
243 rrhs = -vold * tled * cold(n)
244 idiag = this%dis%con%ia(n)
245 call matrix_sln%add_value_pos(idxglo(idiag), hhcof)
246 rhs(n) = rhs(n) + rrhs
255 subroutine mst_fc_dcy(this, nodes, cold, cnew, nja, matrix_sln, &
261 integer,
intent(in) :: nodes
262 real(DP),
intent(in),
dimension(nodes) :: cold
263 real(DP),
intent(in),
dimension(nodes) :: cnew
264 integer(I4B),
intent(in) :: nja
266 integer(I4B),
intent(in),
dimension(nja) :: idxglo
267 real(DP),
intent(inout),
dimension(nodes) :: rhs
268 integer(I4B),
intent(in) :: kiter
270 integer(I4B) :: n, idiag
271 real(DP) :: hhcof, rrhs
274 real(DP) :: decay_rate
277 do n = 1, this%dis%nodes
280 if (this%ibound(n) <= 0) cycle
283 vcell = this%dis%area(n) * (this%dis%top(n) - this%dis%bot(n))
284 swtpdt = this%fmi%gwfsat(n)
287 idiag = this%dis%con%ia(n)
288 if (this%idcy == 1)
then
292 hhcof = -this%decay(n) * vcell * swtpdt * this%thetam(n)
293 call matrix_sln%add_value_pos(idxglo(idiag), hhcof)
294 elseif (this%idcy == 2)
then
299 kiter, cold(n), cnew(n),
delt)
300 this%decaylast(n) = decay_rate
301 rrhs = decay_rate * vcell * swtpdt * this%thetam(n)
302 rhs(n) = rhs(n) + rrhs
313 subroutine mst_fc_srb(this, nodes, cold, nja, matrix_sln, idxglo, rhs, &
319 integer,
intent(in) :: nodes
320 real(DP),
intent(in),
dimension(nodes) :: cold
321 integer(I4B),
intent(in) :: nja
323 integer(I4B),
intent(in),
dimension(nja) :: idxglo
324 real(DP),
intent(inout),
dimension(nodes) :: rhs
325 real(DP),
intent(in),
dimension(nodes) :: cnew
327 integer(I4B) :: n, idiag
329 real(DP) :: hhcof, rrhs
330 real(DP) :: swt, swtpdt
341 do n = 1, this%dis%nodes
344 if (this%ibound(n) <= 0) cycle
347 vcell = this%dis%area(n) * (this%dis%top(n) - this%dis%bot(n))
348 swtpdt = this%fmi%gwfsat(n)
349 swt = this%fmi%gwfsatold(n,
delt)
350 idiag = this%dis%con%ia(n)
351 const1 = this%distcoef(n)
353 if (this%isrb > 1) const2 = this%sp2(n)
354 volfracm = this%get_volfracm(n)
355 rhobm = this%bulk_density(n)
356 call mst_srb_term(this%isrb, volfracm, rhobm, vcell, tled, cnew(n), &
357 cold(n), swtpdt, swt, const1, const2, &
358 hcofval=hhcof, rhsval=rrhs)
361 call matrix_sln%add_value_pos(idxglo(idiag), hhcof)
362 rhs(n) = rhs(n) + rrhs
372 subroutine mst_srb_term(isrb, volfracm, rhobm, vcell, tled, cnew, cold, &
373 swnew, swold, const1, const2, rate, hcofval, rhsval)
376 integer(I4B),
intent(in) :: isrb
377 real(DP),
intent(in) :: volfracm
378 real(DP),
intent(in) :: rhobm
379 real(DP),
intent(in) :: vcell
380 real(DP),
intent(in) :: tled
381 real(DP),
intent(in) :: cnew
382 real(DP),
intent(in) :: cold
383 real(DP),
intent(in) :: swnew
384 real(DP),
intent(in) :: swold
385 real(DP),
intent(in) :: const1
386 real(DP),
intent(in) :: const2
387 real(DP),
intent(out),
optional :: rate
388 real(DP),
intent(out),
optional :: hcofval
389 real(DP),
intent(out),
optional :: rhsval
402 term = -volfracm * rhobm * vcell * tled * const1
403 if (
present(hcofval)) hcofval = term * swnew
404 if (
present(rhsval)) rhsval = term * swold * cold
405 if (
present(rate)) rate = term * swnew * cnew - term * swold * cold
409 cavg =
dhalf * (cold + cnew)
417 else if (isrb == 3)
then
425 term = -volfracm * rhobm * vcell * tled
426 cbaravg = (cbarold + cbarnew) *
dhalf
427 swavg = (swnew + swold) *
dhalf
428 if (
present(hcofval))
then
429 hcofval = term * derv * swavg
431 if (
present(rhsval))
then
432 rhsval = term * derv * swavg * cold - term * cbaravg * (swnew - swold)
434 if (
present(rate))
then
435 rate = term * derv * swavg * (cnew - cold) &
436 + term * cbaravg * (swnew - swold)
452 integer,
intent(in) :: nodes
453 real(DP),
intent(in),
dimension(nodes) :: cold
454 integer(I4B),
intent(in) :: nja
456 integer(I4B),
intent(in),
dimension(nja) :: idxglo
457 real(DP),
intent(inout),
dimension(nodes) :: rhs
458 real(DP),
intent(in),
dimension(nodes) :: cnew
459 integer(I4B),
intent(in) :: kiter
461 integer(I4B) :: n, idiag
462 real(DP) :: hhcof, rrhs
470 real(DP) :: decay_rate
475 do n = 1, this%dis%nodes
478 if (this%ibound(n) <= 0) cycle
483 vcell = this%dis%area(n) * (this%dis%top(n) - this%dis%bot(n))
484 swnew = this%fmi%gwfsat(n)
485 distcoef = this%distcoef(n)
486 idiag = this%dis%con%ia(n)
487 volfracm = this%get_volfracm(n)
488 rhobm = this%bulk_density(n)
489 term = this%decay_sorbed(n) * volfracm * rhobm * swnew * vcell
492 if (this%idcy == 1)
then
494 if (this%isrb == 1)
then
498 hhcof = -term * distcoef
499 else if (this%isrb == 2)
then
504 else if (this%isrb == 3)
then
510 elseif (this%idcy == 2)
then
514 if (distcoef >
dzero)
then
516 if (this%isrb == 1)
then
517 csrbold = cold(n) * distcoef
518 csrbnew = cnew(n) * distcoef
519 else if (this%isrb == 2)
then
522 else if (this%isrb == 3)
then
528 this%decayslast(n), &
529 kiter, csrbold, csrbnew,
delt)
530 this%decayslast(n) = decay_rate
531 rrhs = decay_rate * volfracm * rhobm * swnew * vcell
537 call matrix_sln%add_value_pos(idxglo(idiag), hhcof)
538 rhs(n) = rhs(n) + rrhs
548 subroutine mst_cq(this, nodes, cnew, cold, flowja)
552 integer(I4B),
intent(in) :: nodes
553 real(DP),
intent(in),
dimension(nodes) :: cnew
554 real(DP),
intent(in),
dimension(nodes) :: cold
555 real(DP),
dimension(:),
contiguous,
intent(inout) :: flowja
559 call this%mst_cq_sto(nodes, cnew, cold, flowja)
562 if (this%idcy /= 0)
then
563 call this%mst_cq_dcy(nodes, cnew, cold, flowja)
567 if (this%isrb /= 0)
then
568 call this%mst_cq_srb(nodes, cnew, cold, flowja)
572 if (this%isrb /= 0 .and. this%idcy /= 0)
then
573 call this%mst_cq_dcy_srb(nodes, cnew, cold, flowja)
577 if (this%isrb /= 0)
then
578 call this%mst_calc_csrb(cnew)
592 integer(I4B),
intent(in) :: nodes
593 real(DP),
intent(in),
dimension(nodes) :: cnew
594 real(DP),
intent(in),
dimension(nodes) :: cold
595 real(DP),
dimension(:),
contiguous,
intent(inout) :: flowja
598 integer(I4B) :: idiag
601 real(DP) :: vnew, vold
602 real(DP) :: hhcof, rrhs
609 this%ratesto(n) =
dzero
612 if (this%ibound(n) <= 0) cycle
615 vnew = this%dis%area(n) * (this%dis%top(n) - this%dis%bot(n)) * &
616 this%fmi%gwfsat(n) * this%thetam(n)
618 if (this%fmi%igwfstrgss /= 0) vold = vold + this%fmi%gwfstrgss(n) *
delt
619 if (this%fmi%igwfstrgsy /= 0) vold = vold + this%fmi%gwfstrgsy(n) *
delt
623 rrhs = -vold * tled * cold(n)
624 rate = hhcof * cnew(n) - rrhs
625 this%ratesto(n) = rate
626 idiag = this%dis%con%ia(n)
627 flowja(idiag) = flowja(idiag) + rate
641 integer(I4B),
intent(in) :: nodes
642 real(DP),
intent(in),
dimension(nodes) :: cnew
643 real(DP),
intent(in),
dimension(nodes) :: cold
644 real(DP),
dimension(:),
contiguous,
intent(inout) :: flowja
647 integer(I4B) :: idiag
650 real(DP) :: hhcof, rrhs
652 real(DP) :: decay_rate
660 this%ratedcy(n) =
dzero
661 if (this%ibound(n) <= 0) cycle
664 vcell = this%dis%area(n) * (this%dis%top(n) - this%dis%bot(n))
665 swtpdt = this%fmi%gwfsat(n)
671 if (this%idcy == 1)
then
672 hhcof = -this%decay(n) * vcell * swtpdt * this%thetam(n)
673 elseif (this%idcy == 2)
then
675 0, cold(n), cnew(n),
delt)
676 rrhs = decay_rate * vcell * swtpdt * this%thetam(n)
678 rate = hhcof * cnew(n) - rrhs
679 this%ratedcy(n) = rate
680 idiag = this%dis%con%ia(n)
681 flowja(idiag) = flowja(idiag) + rate
696 integer(I4B),
intent(in) :: nodes
697 real(DP),
intent(in),
dimension(nodes) :: cnew
698 real(DP),
intent(in),
dimension(nodes) :: cold
699 real(DP),
dimension(:),
contiguous,
intent(inout) :: flowja
702 integer(I4B) :: idiag
705 real(DP) :: swt, swtpdt
719 this%ratesrb(n) =
dzero
722 if (this%ibound(n) <= 0) cycle
725 vcell = this%dis%area(n) * (this%dis%top(n) - this%dis%bot(n))
726 swtpdt = this%fmi%gwfsat(n)
727 swt = this%fmi%gwfsatold(n,
delt)
728 volfracm = this%get_volfracm(n)
729 rhobm = this%bulk_density(n)
730 const1 = this%distcoef(n)
732 if (this%isrb > 1) const2 = this%sp2(n)
733 call mst_srb_term(this%isrb, volfracm, rhobm, vcell, tled, cnew(n), &
734 cold(n), swtpdt, swt, const1, const2, &
736 this%ratesrb(n) = rate
737 idiag = this%dis%con%ia(n)
738 flowja(idiag) = flowja(idiag) + rate
753 integer(I4B),
intent(in) :: nodes
754 real(DP),
intent(in),
dimension(nodes) :: cnew
755 real(DP),
intent(in),
dimension(nodes) :: cold
756 real(DP),
dimension(:),
contiguous,
intent(inout) :: flowja
759 integer(I4B) :: idiag
761 real(DP) :: hhcof, rrhs
771 real(DP) :: decay_rate
778 this%ratedcys(n) =
dzero
781 if (this%ibound(n) <= 0) cycle
786 vcell = this%dis%area(n) * (this%dis%top(n) - this%dis%bot(n))
787 swnew = this%fmi%gwfsat(n)
788 distcoef = this%distcoef(n)
789 volfracm = this%get_volfracm(n)
790 rhobm = this%bulk_density(n)
791 term = this%decay_sorbed(n) * volfracm * rhobm * swnew * vcell
794 if (this%idcy == 1)
then
796 if (this%isrb == 1)
then
800 hhcof = -term * distcoef
801 else if (this%isrb == 2)
then
806 else if (this%isrb == 3)
then
812 elseif (this%idcy == 2)
then
816 if (distcoef >
dzero)
then
817 if (this%isrb == 1)
then
818 csrbold = cold(n) * distcoef
819 csrbnew = cnew(n) * distcoef
820 else if (this%isrb == 2)
then
823 else if (this%isrb == 3)
then
828 this%decayslast(n), &
829 0, csrbold, csrbnew,
delt)
830 rrhs = decay_rate * volfracm * rhobm * swnew * vcell
835 rate = hhcof * cnew(n) - rrhs
836 this%ratedcys(n) = rate
837 idiag = this%dis%con%ia(n)
838 flowja(idiag) = flowja(idiag) + rate
848 real(DP),
intent(in),
dimension(:) :: cnew
857 if (this%ibound(n) > 0)
then
858 distcoef = this%distcoef(n)
859 if (this%isrb == 1)
then
860 csrb = cnew(n) * distcoef
861 else if (this%isrb == 2)
then
863 else if (this%isrb == 3)
then
874 subroutine mst_bd(this, isuppress_output, model_budget)
880 integer(I4B),
intent(in) :: isuppress_output
881 type(
budgettype),
intent(inout) :: model_budget
888 call model_budget%addentry(rin, rout,
delt,
budtxt(1), &
889 isuppress_output, rowlabel=this%packName)
892 if (this%idcy /= 0)
then
894 call model_budget%addentry(rin, rout,
delt,
budtxt(2), &
895 isuppress_output, rowlabel=this%packName)
899 if (this%isrb /= 0)
then
901 call model_budget%addentry(rin, rout,
delt,
budtxt(3), &
902 isuppress_output, rowlabel=this%packName)
906 if (this%isrb /= 0 .and. this%idcy /= 0)
then
908 call model_budget%addentry(rin, rout,
delt,
budtxt(4), &
909 isuppress_output, rowlabel=this%packName)
921 integer(I4B),
intent(in) :: icbcfl
922 integer(I4B),
intent(in) :: icbcun
924 integer(I4B) :: ibinun
925 integer(I4B) :: iprint, nvaluesp, nwidthp
926 character(len=1) :: cdatafmp =
' ', editdesc =
' '
930 if (this%ipakcb < 0)
then
932 elseif (this%ipakcb == 0)
then
937 if (icbcfl == 0) ibinun = 0
940 if (ibinun /= 0)
then
945 call this%dis%record_array(this%ratesto, this%iout, iprint, -ibinun, &
946 budtxt(1), cdatafmp, nvaluesp, &
947 nwidthp, editdesc, dinact)
950 if (this%idcy /= 0) &
951 call this%dis%record_array(this%ratedcy, this%iout, iprint, -ibinun, &
952 budtxt(2), cdatafmp, nvaluesp, &
953 nwidthp, editdesc, dinact)
956 if (this%isrb /= 0) &
957 call this%dis%record_array(this%ratesrb, this%iout, iprint, -ibinun, &
958 budtxt(3), cdatafmp, nvaluesp, &
959 nwidthp, editdesc, dinact)
962 if (this%isrb /= 0 .and. this%idcy /= 0) &
963 call this%dis%record_array(this%ratedcys, this%iout, iprint, -ibinun, &
964 budtxt(4), cdatafmp, nvaluesp, &
965 nwidthp, editdesc, dinact)
974 integer(I4B),
intent(in) :: idvsave
976 character(len=1) :: cdatafmp =
' ', editdesc =
' '
977 integer(I4B) :: ibinun
978 integer(I4B) :: iprint
979 integer(I4B) :: nvaluesp
980 integer(I4B) :: nwidthp
984 if (this%ioutsorbate /= 0)
then
989 if (idvsave == 0) ibinun = 0
992 if (ibinun /= 0)
then
995 if (this%ioutsorbate /= 0)
then
996 ibinun = this%ioutsorbate
997 call this%dis%record_array(this%csrb, this%iout, iprint, ibinun, &
998 ' SORBATE', cdatafmp, nvaluesp, &
999 nwidthp, editdesc, dinact)
1017 if (this%inunit > 0)
then
1036 this%ibound => null()
1043 call this%NumericalPackageType%da()
1059 call this%NumericalPackageType%allocate_scalars()
1063 call mem_allocate(this%ioutsorbate,
'IOUTSORBATE', this%memoryPath)
1068 this%ioutsorbate = 0
1083 integer(I4B),
intent(in) :: nodes
1089 call mem_allocate(this%porosity, nodes,
'POROSITY', this%memoryPath)
1090 call mem_allocate(this%thetam, nodes,
'THETAM', this%memoryPath)
1091 call mem_allocate(this%volfracim, nodes,
'VOLFRACIM', this%memoryPath)
1092 call mem_allocate(this%ratesto, nodes,
'RATESTO', this%memoryPath)
1095 if (this%idcy == 0)
then
1096 call mem_allocate(this%ratedcy, 1,
'RATEDCY', this%memoryPath)
1097 call mem_allocate(this%decay, 1,
'DECAY', this%memoryPath)
1098 call mem_allocate(this%decaylast, 1,
'DECAYLAST', this%memoryPath)
1100 call mem_allocate(this%ratedcy, this%dis%nodes,
'RATEDCY', this%memoryPath)
1101 call mem_allocate(this%decay, nodes,
'DECAY', this%memoryPath)
1102 call mem_allocate(this%decaylast, nodes,
'DECAYLAST', this%memoryPath)
1104 if (this%idcy /= 0 .and. this%isrb /= 0)
then
1105 call mem_allocate(this%ratedcys, this%dis%nodes,
'RATEDCYS', &
1107 call mem_allocate(this%decayslast, this%dis%nodes,
'DECAYSLAST', &
1110 call mem_allocate(this%ratedcys, 1,
'RATEDCYS', this%memoryPath)
1111 call mem_allocate(this%decayslast, 1,
'DECAYSLAST', this%memoryPath)
1113 call mem_allocate(this%decay_sorbed, 1,
'DECAY_SORBED', &
1117 if (this%isrb == 0)
then
1118 call mem_allocate(this%bulk_density, 1,
'BULK_DENSITY', this%memoryPath)
1120 call mem_allocate(this%distcoef, 1,
'DISTCOEF', this%memoryPath)
1121 call mem_allocate(this%ratesrb, 1,
'RATESRB', this%memoryPath)
1122 call mem_allocate(this%csrb, 1,
'CSRB', this%memoryPath)
1124 call mem_allocate(this%bulk_density, nodes,
'BULK_DENSITY', this%memoryPath)
1125 call mem_allocate(this%distcoef, nodes,
'DISTCOEF', this%memoryPath)
1126 call mem_allocate(this%ratesrb, nodes,
'RATESRB', this%memoryPath)
1127 call mem_allocate(this%csrb, nodes,
'CSRB', this%memoryPath)
1128 if (this%isrb == 1)
then
1131 call mem_allocate(this%sp2, nodes,
'SP2', this%memoryPath)
1137 this%porosity(n) =
dzero
1138 this%thetam(n) =
dzero
1139 this%volfracim(n) =
dzero
1140 this%ratesto(n) =
dzero
1142 do n = 1,
size(this%decay)
1143 this%decay(n) =
dzero
1144 this%ratedcy(n) =
dzero
1145 this%decaylast(n) =
dzero
1147 do n = 1,
size(this%bulk_density)
1148 this%bulk_density(n) =
dzero
1149 this%distcoef(n) =
dzero
1150 this%ratesrb(n) =
dzero
1151 this%csrb(n) =
dzero
1153 do n = 1,
size(this%sp2)
1156 do n = 1,
size(this%ratedcys)
1157 this%ratedcys(n) =
dzero
1158 this%decayslast(n) =
dzero
1174 character(len=LINELENGTH) :: keyword
1175 character(len=LINELENGTH) :: sorption
1176 character(len=MAXCHARLEN) :: fname
1177 integer(I4B) :: ierr
1178 logical :: isfound, endOfBlock
1180 character(len=*),
parameter :: fmtisvflow = &
1181 "(4x,'CELL-BY-CELL FLOW INFORMATION WILL BE SAVED TO BINARY FILE &
1182 &WHENEVER ICBCFL IS NOT ZERO.')"
1183 character(len=*),
parameter :: fmtlinear = &
1184 &
"(4x,'LINEAR SORPTION IS ACTIVE. ')"
1185 character(len=*),
parameter :: fmtfreundlich = &
1186 &
"(4x,'FREUNDLICH SORPTION IS ACTIVE. ')"
1187 character(len=*),
parameter :: fmtlangmuir = &
1188 &
"(4x,'LANGMUIR SORPTION IS ACTIVE. ')"
1189 character(len=*),
parameter :: fmtidcy1 = &
1190 &
"(4x,'FIRST-ORDER DECAY IS ACTIVE. ')"
1191 character(len=*),
parameter :: fmtidcy2 = &
1192 &
"(4x,'ZERO-ORDER DECAY IS ACTIVE. ')"
1193 character(len=*),
parameter :: fmtfileout = &
1194 "(4x,'MST ',1x,a,1x,' WILL BE SAVED TO FILE: ',a,/4x,&
1195 &'OPENED ON UNIT: ',I7)"
1198 call this%parser%GetBlock(
'OPTIONS', isfound, ierr, blockrequired=.false., &
1199 supportopenclose=.true.)
1203 write (this%iout,
'(1x,a)')
'PROCESSING MOBILE STORAGE AND TRANSFER OPTIONS'
1205 call this%parser%GetNextLine(endofblock)
1206 if (endofblock)
exit
1207 call this%parser%GetStringCaps(keyword)
1208 select case (keyword)
1211 write (this%iout, fmtisvflow)
1213 call store_error(
'SORBTION is not a valid option. Use &
1214 &SORPTION instead.')
1215 call this%parser%StoreErrorUnit()
1217 call this%parser%GetStringCaps(sorption)
1218 select case (sorption)
1221 write (this%iout, fmtlinear)
1224 write (this%iout, fmtfreundlich)
1227 write (this%iout, fmtlangmuir)
1229 call store_error(
'Unknown sorption type was specified ' &
1230 & //
'('//trim(adjustl(sorption))//
').'// &
1231 &
' Sorption must be specified as LINEAR, &
1232 &FREUNDLICH, or LANGMUIR.')
1233 call this%parser%StoreErrorUnit()
1235 case (
'FIRST_ORDER_DECAY')
1237 write (this%iout, fmtidcy1)
1238 case (
'ZERO_ORDER_DECAY')
1240 write (this%iout, fmtidcy2)
1242 call this%parser%GetStringCaps(keyword)
1243 if (keyword ==
'FILEOUT')
then
1244 call this%parser%GetString(fname)
1246 call openfile(this%ioutsorbate, this%iout, fname,
'DATA(BINARY)', &
1248 write (this%iout, fmtfileout) &
1249 'SORBATE', fname, this%ioutsorbate
1251 errmsg =
'Optional SORBATE keyword must be '// &
1252 'followed by FILEOUT.'
1256 write (
errmsg,
'(a,a)')
'Unknown MST option: ', trim(keyword)
1258 call this%parser%StoreErrorUnit()
1261 write (this%iout,
'(1x,a)')
'END OF MOBILE STORAGE AND TRANSFER OPTIONS'
1277 character(len=LINELENGTH) :: keyword
1278 character(len=:),
allocatable :: line
1279 integer(I4B) :: istart, istop, lloc, ierr, n
1280 logical :: isfound, endOfBlock
1281 logical,
dimension(6) :: lname
1282 character(len=24),
dimension(6) :: aname
1285 data aname(1)/
' MOBILE DOMAIN POROSITY'/
1286 data aname(2)/
' BULK DENSITY'/
1287 data aname(3)/
'DISTRIBUTION COEFFICIENT'/
1288 data aname(4)/
' DECAY RATE'/
1289 data aname(5)/
' DECAY SORBED RATE'/
1290 data aname(6)/
' SECOND SORPTION PARAM'/
1297 call this%parser%GetBlock(
'GRIDDATA', isfound, ierr)
1299 write (this%iout,
'(1x,a)')
'PROCESSING GRIDDATA'
1301 call this%parser%GetNextLine(endofblock)
1302 if (endofblock)
exit
1303 call this%parser%GetStringCaps(keyword)
1304 call this%parser%GetRemainingLine(line)
1306 select case (keyword)
1308 call this%dis%read_grid_array(line, lloc, istart, istop, this%iout, &
1309 this%parser%iuactive, this%porosity, &
1312 case (
'BULK_DENSITY')
1313 if (this%isrb == 0) &
1315 'BULK_DENSITY', trim(this%memoryPath))
1316 call this%dis%read_grid_array(line, lloc, istart, istop, this%iout, &
1317 this%parser%iuactive, &
1318 this%bulk_density, aname(2))
1321 if (this%isrb == 0) &
1323 trim(this%memoryPath))
1324 call this%dis%read_grid_array(line, lloc, istart, istop, this%iout, &
1325 this%parser%iuactive, this%distcoef, &
1329 if (this%idcy == 0) &
1331 trim(this%memoryPath))
1332 call this%dis%read_grid_array(line, lloc, istart, istop, this%iout, &
1333 this%parser%iuactive, this%decay, &
1336 case (
'DECAY_SORBED')
1338 'DECAY_SORBED', trim(this%memoryPath))
1339 call this%dis%read_grid_array(line, lloc, istart, istop, this%iout, &
1340 this%parser%iuactive, &
1341 this%decay_sorbed, aname(5))
1344 if (this%isrb < 2) &
1346 trim(this%memoryPath))
1347 call this%dis%read_grid_array(line, lloc, istart, istop, this%iout, &
1348 this%parser%iuactive, this%sp2, &
1352 write (
errmsg,
'(a,a)')
'Unknown GRIDDATA tag: ', trim(keyword)
1354 call this%parser%StoreErrorUnit()
1357 write (this%iout,
'(1x,a)')
'END PROCESSING GRIDDATA'
1359 write (
errmsg,
'(a)')
'Required GRIDDATA block not found.'
1361 call this%parser%StoreErrorUnit()
1365 if (.not. lname(1))
then
1366 write (
errmsg,
'(a)')
'POROSITY not specified in GRIDDATA block.'
1371 if (this%isrb > 0)
then
1372 if (.not. lname(2))
then
1373 write (
errmsg,
'(a)')
'Sorption is active but BULK_DENSITY &
1374 ¬ specified. BULK_DENSITY must be specified in GRIDDATA block.'
1377 if (.not. lname(3))
then
1378 write (
errmsg,
'(a)')
'Sorption is active but distribution &
1379 &coefficient not specified. DISTCOEF must be specified in &
1383 if (this%isrb > 1)
then
1384 if (.not. lname(6))
then
1385 write (
errmsg,
'(a)')
'Freundlich or langmuir sorption is active &
1386 &but SP2 not specified. SP2 must be specified in &
1393 write (
warnmsg,
'(a)')
'Sorption is not active but &
1394 &BULK_DENSITY was specified. BULK_DENSITY will have no affect on &
1395 &simulation results.'
1397 write (this%iout,
'(1x,a)')
'WARNING. '//
warnmsg
1400 write (
warnmsg,
'(a)')
'Sorption is not active but &
1401 &distribution coefficient was specified. DISTCOEF will have &
1402 &no affect on simulation results.'
1404 write (this%iout,
'(1x,a)')
'WARNING. '//
warnmsg
1407 write (
warnmsg,
'(a)')
'Sorption is not active but &
1408 &SP2 was specified. SP2 will have &
1409 &no affect on simulation results.'
1411 write (this%iout,
'(1x,a)')
'WARNING. '//
warnmsg
1416 if (this%idcy > 0)
then
1417 if (.not. lname(4))
then
1418 write (
errmsg,
'(a)')
'First or zero order decay is &
1419 &active but the first rate coefficient is not specified. DECAY &
1420 &must be specified in GRIDDATA block.'
1423 if (.not. lname(5))
then
1427 if (this%isrb > 0)
then
1428 write (
errmsg,
'(a)')
'DECAY_SORBED not provided in GRIDDATA &
1429 &block but decay and sorption are active. Specify DECAY_SORBED &
1430 &in GRIDDATA block.'
1436 write (
warnmsg,
'(a)')
'First- or zero-order decay &
1437 &is not active but decay was specified. DECAY will &
1438 &have no affect on simulation results.'
1440 write (this%iout,
'(1x,a)')
'WARNING. '//
warnmsg
1443 write (
warnmsg,
'(a)')
'First- or zero-order decay &
1444 &is not active but DECAY_SORBED was specified. &
1445 &DECAY_SORBED will have no affect on simulation results.'
1447 write (this%iout,
'(1x,a)')
'WARNING. '//
warnmsg
1453 call this%parser%StoreErrorUnit()
1457 do n = 1,
size(this%porosity)
1458 this%thetam(n) = this%porosity(n)
1472 real(DP),
dimension(:),
intent(in) :: volfracim
1477 do n = 1, this%dis%nodes
1478 this%volfracim(n) = this%volfracim(n) + volfracim(n)
1483 do n = 1, this%dis%nodes
1484 this%thetam(n) = this%get_volfracm(n) * this%porosity(n)
1497 integer(I4B),
intent(in) :: node
1499 real(dp) :: volfracm
1501 volfracm =
done - this%volfracim(node)
1511 real(dp),
intent(in) :: conc
1512 real(dp),
intent(in) :: kf
1513 real(dp),
intent(in) :: a
1517 if (conc >
dzero)
then
1531 real(dp),
intent(in) :: conc
1532 real(dp),
intent(in) :: kl
1533 real(dp),
intent(in) :: sbar
1537 if (conc >
dzero)
then
1538 cbar = (kl * sbar * conc) / (
done + kl * conc)
1551 real(dp),
intent(in) :: conc
1552 real(dp),
intent(in) :: kf
1553 real(dp),
intent(in) :: a
1557 if (conc >
dzero)
then
1558 derv = kf * a * conc**(a -
done)
1571 real(dp),
intent(in) :: conc
1572 real(dp),
intent(in) :: kl
1573 real(dp),
intent(in) :: sbar
1577 if (conc >
dzero)
then
1578 derv = (kl * sbar) / (
done + kl * conc)**
dtwo
1588 real(dp),
intent(in) :: conc
1589 real(dp),
intent(in) :: kf
1590 real(dp),
intent(in) :: a
1594 if (conc >
dzero)
then
1595 kd = kf * conc**(a -
done)
1605 real(dp),
intent(in) :: conc
1606 real(dp),
intent(in) :: kl
1607 real(dp),
intent(in) :: sbar
1611 if (conc >
dzero)
then
1612 kd = (kl * sbar) / (
done + kl * conc)
1627 cold, cnew, delt)
result(decay_rate)
1629 real(dp),
intent(in) :: decay_rate_usr
1630 real(dp),
intent(in) :: decay_rate_last
1631 integer(I4B),
intent(in) :: kiter
1632 real(dp),
intent(in) :: cold
1633 real(dp),
intent(in) :: cnew
1634 real(dp),
intent(in) :: delt
1636 real(dp) :: decay_rate
1639 if (decay_rate_usr <
dzero)
then
1642 decay_rate = decay_rate_usr
1648 if (kiter == 1)
then
1649 decay_rate = min(decay_rate_usr, cold / delt)
1651 decay_rate = decay_rate_last
1652 if (cnew <
dzero)
then
1653 decay_rate = decay_rate_last + cnew / delt
1654 else if (cnew > cold)
then
1655 decay_rate = decay_rate_last + cnew / delt
1657 decay_rate = min(decay_rate_usr, decay_rate)
1659 decay_rate = max(decay_rate,
dzero)
This module contains the BudgetModule.
subroutine, public rate_accumulator(flow, rin, rout)
@ brief Rate accumulator subroutine
This module contains simulation constants.
integer(i4b), parameter linelength
maximum length of a standard line
@ mnormal
normal output mode
real(dp), parameter dhnoflo
real no flow constant
real(dp), parameter dhalf
real constant 1/2
real(dp), parameter dzero
real constant zero
integer(i4b), parameter maxcharlen
maximum length of char string
real(dp), parameter dtwo
real constant 2
integer(i4b), parameter lenbudtxt
maximum length of a budget component names
real(dp), parameter done
real constant 1
– @ brief Mobile Storage and Transfer (MST) Module
subroutine mst_srb_term(isrb, volfracm, rhobm, vcell, tled, cnew, cold, swnew, swold, const1, const2, rate, hcofval, rhsval)
@ brief Calculate sorption terms
subroutine mst_cq_srb(this, nodes, cnew, cold, flowja)
@ brief Calculate sorption terms for package
subroutine mst_calc_csrb(this, cnew)
@ brief Calculate sorbed concentration
subroutine addto_volfracim(this, volfracim)
@ brief Add volfrac values to volfracim
real(dp) function get_zero_order_decay(decay_rate_usr, decay_rate_last, kiter, cold, cnew, delt)
@ brief Calculate zero-order decay rate and constrain if necessary
character(len=lenbudtxt), dimension(nbditems) budtxt
subroutine mst_cq(this, nodes, cnew, cold, flowja)
@ brief Calculate flows for package
subroutine mst_bd(this, isuppress_output, model_budget)
@ brief Calculate budget terms for package
subroutine allocate_arrays(this, nodes)
@ brief Allocate arrays for package
real(dp) function get_freundlich_derivative(conc, kf, a)
@ brief Calculate sorption derivative using Freundlich
real(dp) function get_langmuir_kd(conc, kl, sbar)
@ brief Get effective Langmuir distribution coefficient
subroutine mst_cq_dcy_srb(this, nodes, cnew, cold, flowja)
@ brief Calculate decay-sorption terms for package
real(dp) function get_freundlich_conc(conc, kf, a)
@ brief Calculate sorption concentration using Freundlich
real(dp) function get_volfracm(this, node)
@ brief Return mobile domain volume fraction
subroutine mst_ot_dv(this, idvsave)
Save sorbate concentration array to binary file.
subroutine mst_ot_flow(this, icbcfl, icbcun)
@ brief Output flow terms for package
subroutine read_options(this)
@ brief Read options for package
subroutine mst_ar(this, dis, ibound)
@ brief Allocate and read method for package
subroutine mst_fc_srb(this, nodes, cold, nja, matrix_sln, idxglo, rhs, cnew)
@ brief Fill sorption coefficient method for package
subroutine mst_cq_dcy(this, nodes, cnew, cold, flowja)
@ brief Calculate decay terms for package
subroutine read_data(this)
@ brief Read data for package
subroutine allocate_scalars(this)
@ brief Allocate scalar variables for package
subroutine mst_fc_dcy_srb(this, nodes, cold, nja, matrix_sln, idxglo, rhs, cnew, kiter)
@ brief Fill sorption-decay coefficient method for package
subroutine mst_da(this)
@ brief Deallocate
subroutine mst_fc_dcy(this, nodes, cold, cnew, nja, matrix_sln, idxglo, rhs, kiter)
@ brief Fill decay coefficient method for package
integer(i4b), parameter nbditems
subroutine mst_fc(this, nodes, cold, nja, matrix_sln, idxglo, cnew, rhs, kiter)
@ brief Fill coefficient method for package
real(dp) function get_freundlich_kd(conc, kf, a)
@ brief Get effective Freundlich distribution coefficient
subroutine mst_fc_sto(this, nodes, cold, nja, matrix_sln, idxglo, rhs)
@ brief Fill storage coefficient method for package
real(dp) function get_langmuir_derivative(conc, kl, sbar)
@ brief Calculate sorption derivative using Langmuir
subroutine, public mst_cr(mstobj, name_model, inunit, iout, fmi)
@ brief Create a new package object
subroutine mst_cq_sto(this, nodes, cnew, cold, flowja)
@ brief Calculate storage terms for package
real(dp) function get_langmuir_conc(conc, kl, sbar)
@ brief Calculate sorption concentration using Langmuir
This module defines variable data types.
This module contains the base numerical package type.
This module contains simulation methods.
subroutine, public store_warning(msg, substring)
Store warning message.
subroutine, public store_error(msg, terminate)
Store an error message.
integer(i4b) function, public count_errors()
Return number of errors.
This module contains simulation variables.
character(len=maxcharlen) errmsg
error message string
character(len=maxcharlen) warnmsg
warning message string
real(dp), pointer, public delt
length of the current time step
Derived type for the Budget object.
@ brief Mobile storage and transfer