28 character(len=LENBUDTXT),
dimension(NBDITEMS) ::
budtxt
29 data budtxt/
' STORAGE-AQUEOUS',
' DECAY-AQUEOUS', &
30 ' STORAGE-SORBED',
' DECAY-SORBED'/
53 real(dp),
dimension(:),
pointer,
contiguous :: porosity => null()
54 real(dp),
dimension(:),
pointer,
contiguous :: thetam => null()
55 real(dp),
dimension(:),
pointer,
contiguous :: volfracim => null()
56 real(dp),
dimension(:),
pointer,
contiguous :: ratesto => null()
59 integer(I4B),
pointer :: idcy => null()
60 real(dp),
dimension(:),
pointer,
contiguous :: decay => null()
61 real(dp),
dimension(:),
pointer,
contiguous :: decay_sorbed => null()
62 real(dp),
dimension(:),
pointer,
contiguous :: ratedcy => null()
63 real(dp),
dimension(:),
pointer,
contiguous :: decaylast => null()
64 real(dp),
dimension(:),
pointer,
contiguous :: decayslast => null()
67 integer(I4B),
pointer :: isrb => null()
68 integer(I4B),
pointer :: ioutsorbate => null()
69 real(dp),
dimension(:),
pointer,
contiguous :: bulk_density => null()
70 real(dp),
dimension(:),
pointer,
contiguous :: distcoef => null()
71 real(dp),
dimension(:),
pointer,
contiguous :: sp2 => null()
72 real(dp),
dimension(:),
pointer,
contiguous :: ratesrb => null()
73 real(dp),
dimension(:),
pointer,
contiguous :: ratedcys => null()
74 real(dp),
dimension(:),
pointer,
contiguous :: csrb => null()
77 integer(I4B),
dimension(:),
pointer,
contiguous :: ibound => null()
113 subroutine mst_cr(mstobj, name_model, inunit, iout, fmi)
116 character(len=*),
intent(in) :: name_model
117 integer(I4B),
intent(in) :: inunit
118 integer(I4B),
intent(in) :: iout
125 call mstobj%set_names(1, name_model,
'MST',
'MST')
128 call mstobj%allocate_scalars()
131 mstobj%inunit = inunit
136 call mstobj%parser%Initialize(mstobj%inunit, mstobj%iout)
148 integer(I4B),
dimension(:),
pointer,
contiguous :: ibound
151 character(len=*),
parameter :: fmtmst = &
152 "(1x,/1x,'MST -- MOBILE STORAGE AND TRANSFER PACKAGE, VERSION 1, &
153 &7/29/2020 INPUT READ FROM UNIT ', i0, //)"
156 write (this%iout, fmtmst) this%inunit
159 call this%read_options()
163 this%ibound => ibound
166 call this%allocate_arrays(dis%nodes)
169 call this%read_data()
176 subroutine mst_fc(this, nodes, cold, nja, matrix_sln, idxglo, cnew, &
181 integer,
intent(in) :: nodes
182 real(DP),
intent(in),
dimension(nodes) :: cold
183 integer(I4B),
intent(in) :: nja
185 integer(I4B),
intent(in),
dimension(nja) :: idxglo
186 real(DP),
intent(inout),
dimension(nodes) :: rhs
187 real(DP),
intent(in),
dimension(nodes) :: cnew
188 integer(I4B),
intent(in) :: kiter
191 call this%mst_fc_sto(nodes, cold, nja, matrix_sln, idxglo, rhs)
195 call this%mst_fc_dcy(nodes, cold, cnew, nja, matrix_sln, idxglo, &
201 call this%mst_fc_srb(nodes, cold, nja, matrix_sln, idxglo, rhs, cnew)
206 call this%mst_fc_dcy_srb(nodes, cold, nja, matrix_sln, idxglo, rhs, &
215 subroutine mst_fc_sto(this, nodes, cold, nja, matrix_sln, idxglo, rhs)
220 integer,
intent(in) :: nodes
221 real(DP),
intent(in),
dimension(nodes) :: cold
222 integer(I4B),
intent(in) :: nja
224 integer(I4B),
intent(in),
dimension(nja) :: idxglo
225 real(DP),
intent(inout),
dimension(nodes) :: rhs
227 integer(I4B) :: n, idiag
229 real(DP) :: hhcof, rrhs
230 real(DP) :: vnew, vold
236 do n = 1, this%dis%nodes
239 if (this%ibound(n) <= 0) cycle
242 vnew = this%dis%area(n) * (this%dis%top(n) - this%dis%bot(n)) * &
243 this%fmi%gwfsat(n) * this%thetam(n)
245 if (this%fmi%igwfstrgss /= 0) vold = vold + this%fmi%gwfstrgss(n) *
delt
246 if (this%fmi%igwfstrgsy /= 0) vold = vold + this%fmi%gwfstrgsy(n) *
delt
250 rrhs = -vold * tled * cold(n)
251 idiag = this%dis%con%ia(n)
252 call matrix_sln%add_value_pos(idxglo(idiag), hhcof)
253 rhs(n) = rhs(n) + rrhs
261 subroutine mst_fc_dcy(this, nodes, cold, cnew, nja, matrix_sln, &
267 integer,
intent(in) :: nodes
268 real(DP),
intent(in),
dimension(nodes) :: cold
269 real(DP),
intent(in),
dimension(nodes) :: cnew
270 integer(I4B),
intent(in) :: nja
272 integer(I4B),
intent(in),
dimension(nja) :: idxglo
273 real(DP),
intent(inout),
dimension(nodes) :: rhs
274 integer(I4B),
intent(in) :: kiter
276 integer(I4B) :: n, idiag
277 real(DP) :: hhcof, rrhs
280 real(DP) :: decay_rate
283 do n = 1, this%dis%nodes
286 if (this%ibound(n) <= 0) cycle
289 vcell = this%dis%area(n) * (this%dis%top(n) - this%dis%bot(n))
290 swtpdt = this%fmi%gwfsat(n)
293 idiag = this%dis%con%ia(n)
294 select case (this%idcy)
299 if (cnew(n) >
dzero)
then
300 hhcof = -this%decay(n) * vcell * swtpdt * this%thetam(n)
301 call matrix_sln%add_value_pos(idxglo(idiag), hhcof)
308 kiter, cold(n), cnew(n),
delt)
309 this%decaylast(n) = decay_rate
310 rrhs = decay_rate * vcell * swtpdt * this%thetam(n)
311 rhs(n) = rhs(n) + rrhs
321 subroutine mst_fc_srb(this, nodes, cold, nja, matrix_sln, idxglo, rhs, &
327 integer,
intent(in) :: nodes
328 real(DP),
intent(in),
dimension(nodes) :: cold
329 integer(I4B),
intent(in) :: nja
331 integer(I4B),
intent(in),
dimension(nja) :: idxglo
332 real(DP),
intent(inout),
dimension(nodes) :: rhs
333 real(DP),
intent(in),
dimension(nodes) :: cnew
335 integer(I4B) :: n, idiag
337 real(DP) :: hhcof, rrhs
338 real(DP) :: swt, swtpdt
349 do n = 1, this%dis%nodes
352 if (this%ibound(n) <= 0) cycle
355 vcell = this%dis%area(n) * (this%dis%top(n) - this%dis%bot(n))
356 swtpdt = this%fmi%gwfsat(n)
357 swt = this%fmi%gwfsatold(n,
delt)
358 idiag = this%dis%con%ia(n)
359 const1 = this%distcoef(n)
364 volfracm = this%get_volfracm(n)
365 rhobm = this%bulk_density(n)
366 call mst_srb_term(this%isrb, volfracm, rhobm, vcell, tled, cnew(n), &
367 cold(n), swtpdt, swt, const1, const2, &
368 hcofval=hhcof, rhsval=rrhs)
371 call matrix_sln%add_value_pos(idxglo(idiag), hhcof)
372 rhs(n) = rhs(n) + rrhs
381 subroutine mst_srb_term(isrb, volfracm, rhobm, vcell, tled, cnew, cold, &
382 swnew, swold, const1, const2, rate, hcofval, rhsval)
384 integer(I4B),
intent(in) :: isrb
385 real(DP),
intent(in) :: volfracm
386 real(DP),
intent(in) :: rhobm
387 real(DP),
intent(in) :: vcell
388 real(DP),
intent(in) :: tled
389 real(DP),
intent(in) :: cnew
390 real(DP),
intent(in) :: cold
391 real(DP),
intent(in) :: swnew
392 real(DP),
intent(in) :: swold
393 real(DP),
intent(in) :: const1
394 real(DP),
intent(in) :: const2
395 real(DP),
intent(out),
optional :: rate
396 real(DP),
intent(out),
optional :: hcofval
397 real(DP),
intent(out),
optional :: rhsval
410 term = -volfracm * rhobm * vcell * tled * const1
411 if (
present(hcofval)) hcofval = term * swnew
412 if (
present(rhsval)) rhsval = term * swold * cold
413 if (
present(rate)) rate = term * swnew * cnew - term * swold * cold
417 cavg =
dhalf * (cold + cnew)
434 term = -volfracm * rhobm * vcell * tled
435 cbaravg = (cbarold + cbarnew) *
dhalf
436 swavg = (swnew + swold) *
dhalf
437 if (
present(hcofval))
then
438 hcofval = term * derv * swavg
440 if (
present(rhsval))
then
441 rhsval = term * derv * swavg * cold - term * cbaravg * (swnew - swold)
443 if (
present(rate))
then
444 rate = term * derv * swavg * (cnew - cold) &
445 + term * cbaravg * (swnew - swold)
460 integer,
intent(in) :: nodes
461 real(DP),
intent(in),
dimension(nodes) :: cold
462 integer(I4B),
intent(in) :: nja
464 integer(I4B),
intent(in),
dimension(nja) :: idxglo
465 real(DP),
intent(inout),
dimension(nodes) :: rhs
466 real(DP),
intent(in),
dimension(nodes) :: cnew
467 integer(I4B),
intent(in) :: kiter
469 integer(I4B) :: n, idiag
470 real(DP) :: hhcof, rrhs
478 real(DP) :: decay_rate
483 do n = 1, this%dis%nodes
486 if (this%ibound(n) <= 0) cycle
491 vcell = this%dis%area(n) * (this%dis%top(n) - this%dis%bot(n))
492 swnew = this%fmi%gwfsat(n)
493 distcoef = this%distcoef(n)
494 idiag = this%dis%con%ia(n)
495 volfracm = this%get_volfracm(n)
496 rhobm = this%bulk_density(n)
497 term = this%decay_sorbed(n) * volfracm * rhobm * swnew * vcell
500 select case (this%idcy)
502 select case (this%isrb)
507 if (cnew(n) >
dzero)
then
508 hhcof = -term * distcoef
525 if (distcoef >
dzero)
then
526 select case (this%isrb)
528 csrbold = cold(n) * distcoef
529 csrbnew = cnew(n) * distcoef
539 this%decayslast(n), &
540 kiter, csrbold, csrbnew,
delt)
541 this%decayslast(n) = decay_rate
542 rrhs = decay_rate * volfracm * rhobm * swnew * vcell
547 call matrix_sln%add_value_pos(idxglo(idiag), hhcof)
548 rhs(n) = rhs(n) + rrhs
557 subroutine mst_cq(this, nodes, cnew, cold, flowja)
560 integer(I4B),
intent(in) :: nodes
561 real(DP),
intent(in),
dimension(nodes) :: cnew
562 real(DP),
intent(in),
dimension(nodes) :: cold
563 real(DP),
dimension(:),
contiguous,
intent(inout) :: flowja
566 call this%mst_cq_sto(nodes, cnew, cold, flowja)
570 call this%mst_cq_dcy(nodes, cnew, cold, flowja)
575 call this%mst_cq_srb(nodes, cnew, cold, flowja)
580 call this%mst_cq_dcy_srb(nodes, cnew, cold, flowja)
585 call this%mst_calc_csrb(cnew)
598 integer(I4B),
intent(in) :: nodes
599 real(DP),
intent(in),
dimension(nodes) :: cnew
600 real(DP),
intent(in),
dimension(nodes) :: cold
601 real(DP),
dimension(:),
contiguous,
intent(inout) :: flowja
604 integer(I4B) :: idiag
607 real(DP) :: vnew, vold
608 real(DP) :: hhcof, rrhs
615 this%ratesto(n) =
dzero
618 if (this%ibound(n) <= 0) cycle
621 vnew = this%dis%area(n) * (this%dis%top(n) - this%dis%bot(n)) * &
622 this%fmi%gwfsat(n) * this%thetam(n)
624 if (this%fmi%igwfstrgss /= 0) vold = vold + this%fmi%gwfstrgss(n) *
delt
625 if (this%fmi%igwfstrgsy /= 0) vold = vold + this%fmi%gwfstrgsy(n) *
delt
629 rrhs = -vold * tled * cold(n)
630 rate = hhcof * cnew(n) - rrhs
631 this%ratesto(n) = rate
632 idiag = this%dis%con%ia(n)
633 flowja(idiag) = flowja(idiag) + rate
646 integer(I4B),
intent(in) :: nodes
647 real(DP),
intent(in),
dimension(nodes) :: cnew
648 real(DP),
intent(in),
dimension(nodes) :: cold
649 real(DP),
dimension(:),
contiguous,
intent(inout) :: flowja
652 integer(I4B) :: idiag
655 real(DP) :: hhcof, rrhs
657 real(DP) :: decay_rate
665 this%ratedcy(n) =
dzero
666 if (this%ibound(n) <= 0) cycle
669 vcell = this%dis%area(n) * (this%dis%top(n) - this%dis%bot(n))
670 swtpdt = this%fmi%gwfsat(n)
677 if (cnew(n) >
dzero)
then
678 hhcof = -this%decay(n) * vcell * swtpdt * this%thetam(n)
682 0, cold(n), cnew(n),
delt)
683 rrhs = decay_rate * vcell * swtpdt * this%thetam(n)
685 rate = hhcof * cnew(n) - rrhs
686 this%ratedcy(n) = rate
687 idiag = this%dis%con%ia(n)
688 flowja(idiag) = flowja(idiag) + rate
702 integer(I4B),
intent(in) :: nodes
703 real(DP),
intent(in),
dimension(nodes) :: cnew
704 real(DP),
intent(in),
dimension(nodes) :: cold
705 real(DP),
dimension(:),
contiguous,
intent(inout) :: flowja
708 integer(I4B) :: idiag
711 real(DP) :: swt, swtpdt
725 this%ratesrb(n) =
dzero
728 if (this%ibound(n) <= 0) cycle
731 vcell = this%dis%area(n) * (this%dis%top(n) - this%dis%bot(n))
732 swtpdt = this%fmi%gwfsat(n)
733 swt = this%fmi%gwfsatold(n,
delt)
734 volfracm = this%get_volfracm(n)
735 rhobm = this%bulk_density(n)
736 const1 = this%distcoef(n)
741 call mst_srb_term(this%isrb, volfracm, rhobm, vcell, tled, cnew(n), &
742 cold(n), swtpdt, swt, const1, const2, &
744 this%ratesrb(n) = rate
745 idiag = this%dis%con%ia(n)
746 flowja(idiag) = flowja(idiag) + rate
760 integer(I4B),
intent(in) :: nodes
761 real(DP),
intent(in),
dimension(nodes) :: cnew
762 real(DP),
intent(in),
dimension(nodes) :: cold
763 real(DP),
dimension(:),
contiguous,
intent(inout) :: flowja
766 integer(I4B) :: idiag
768 real(DP) :: hhcof, rrhs
778 real(DP) :: decay_rate
785 this%ratedcys(n) =
dzero
788 if (this%ibound(n) <= 0) cycle
793 vcell = this%dis%area(n) * (this%dis%top(n) - this%dis%bot(n))
794 swnew = this%fmi%gwfsat(n)
795 distcoef = this%distcoef(n)
796 volfracm = this%get_volfracm(n)
797 rhobm = this%bulk_density(n)
798 term = this%decay_sorbed(n) * volfracm * rhobm * swnew * vcell
801 select case (this%idcy)
805 select case (this%isrb)
810 if (cnew(n) >
dzero)
then
811 hhcof = -term * distcoef
828 if (distcoef >
dzero)
then
829 select case (this%isrb)
831 csrbold = cold(n) * distcoef
832 csrbnew = cnew(n) * distcoef
841 this%decayslast(n), &
842 0, csrbold, csrbnew,
delt)
843 rrhs = decay_rate * volfracm * rhobm * swnew * vcell
848 rate = hhcof * cnew(n) - rrhs
849 this%ratedcys(n) = rate
850 idiag = this%dis%con%ia(n)
851 flowja(idiag) = flowja(idiag) + rate
861 real(DP),
intent(in),
dimension(:) :: cnew
870 if (this%ibound(n) > 0)
then
871 distcoef = this%distcoef(n)
872 select case (this%isrb)
874 csrb = cnew(n) * distcoef
888 subroutine mst_bd(this, isuppress_output, model_budget)
894 integer(I4B),
intent(in) :: isuppress_output
895 type(
budgettype),
intent(inout) :: model_budget
902 call model_budget%addentry(rin, rout,
delt,
budtxt(1), &
903 isuppress_output, rowlabel=this%packName)
908 call model_budget%addentry(rin, rout,
delt,
budtxt(2), &
909 isuppress_output, rowlabel=this%packName)
915 call model_budget%addentry(rin, rout,
delt,
budtxt(3), &
916 isuppress_output, rowlabel=this%packName)
922 call model_budget%addentry(rin, rout,
delt,
budtxt(4), &
923 isuppress_output, rowlabel=this%packName)
934 integer(I4B),
intent(in) :: icbcfl
935 integer(I4B),
intent(in) :: icbcun
937 integer(I4B) :: ibinun
938 integer(I4B) :: iprint, nvaluesp, nwidthp
939 character(len=1) :: cdatafmp =
' ', editdesc =
' '
943 if (this%ipakcb < 0)
then
945 elseif (this%ipakcb == 0)
then
950 if (icbcfl == 0) ibinun = 0
953 if (ibinun /= 0)
then
958 call this%dis%record_array(this%ratesto, this%iout, iprint, -ibinun, &
959 budtxt(1), cdatafmp, nvaluesp, &
960 nwidthp, editdesc, dinact)
964 call this%dis%record_array(this%ratedcy, this%iout, iprint, -ibinun, &
965 budtxt(2), cdatafmp, nvaluesp, &
966 nwidthp, editdesc, dinact)
970 call this%dis%record_array(this%ratesrb, this%iout, iprint, -ibinun, &
971 budtxt(3), cdatafmp, nvaluesp, &
972 nwidthp, editdesc, dinact)
976 call this%dis%record_array(this%ratedcys, this%iout, iprint, -ibinun, &
977 budtxt(4), cdatafmp, nvaluesp, &
978 nwidthp, editdesc, dinact)
987 integer(I4B),
intent(in) :: idvsave
989 character(len=1) :: cdatafmp =
' ', editdesc =
' '
990 integer(I4B) :: ibinun
991 integer(I4B) :: iprint
992 integer(I4B) :: nvaluesp
993 integer(I4B) :: nwidthp
997 if (this%ioutsorbate /= 0)
then
1002 if (idvsave == 0) ibinun = 0
1005 if (ibinun /= 0)
then
1008 if (this%ioutsorbate /= 0)
then
1009 ibinun = this%ioutsorbate
1010 call this%dis%record_array(this%csrb, this%iout, iprint, ibinun, &
1011 ' SORBATE', cdatafmp, nvaluesp, &
1012 nwidthp, editdesc, dinact)
1029 if (this%inunit > 0)
then
1048 this%ibound => null()
1055 call this%NumericalPackageType%da()
1069 call this%NumericalPackageType%allocate_scalars()
1073 call mem_allocate(this%ioutsorbate,
'IOUTSORBATE', this%memoryPath)
1078 this%ioutsorbate = 0
1092 integer(I4B),
intent(in) :: nodes
1098 call mem_allocate(this%porosity, nodes,
'POROSITY', this%memoryPath)
1099 call mem_allocate(this%thetam, nodes,
'THETAM', this%memoryPath)
1100 call mem_allocate(this%volfracim, nodes,
'VOLFRACIM', this%memoryPath)
1101 call mem_allocate(this%ratesto, nodes,
'RATESTO', this%memoryPath)
1105 call mem_allocate(this%ratedcy, 1,
'RATEDCY', this%memoryPath)
1106 call mem_allocate(this%decay, 1,
'DECAY', this%memoryPath)
1107 call mem_allocate(this%decaylast, 1,
'DECAYLAST', this%memoryPath)
1109 call mem_allocate(this%ratedcy, this%dis%nodes,
'RATEDCY', this%memoryPath)
1110 call mem_allocate(this%decay, nodes,
'DECAY', this%memoryPath)
1111 call mem_allocate(this%decaylast, nodes,
'DECAYLAST', this%memoryPath)
1114 call mem_allocate(this%ratedcys, this%dis%nodes,
'RATEDCYS', &
1116 call mem_allocate(this%decayslast, this%dis%nodes,
'DECAYSLAST', &
1119 call mem_allocate(this%ratedcys, 1,
'RATEDCYS', this%memoryPath)
1120 call mem_allocate(this%decayslast, 1,
'DECAYSLAST', this%memoryPath)
1122 call mem_allocate(this%decay_sorbed, 1,
'DECAY_SORBED', &
1127 call mem_allocate(this%bulk_density, 1,
'BULK_DENSITY', this%memoryPath)
1129 call mem_allocate(this%distcoef, 1,
'DISTCOEF', this%memoryPath)
1130 call mem_allocate(this%ratesrb, 1,
'RATESRB', this%memoryPath)
1131 call mem_allocate(this%csrb, 1,
'CSRB', this%memoryPath)
1133 call mem_allocate(this%bulk_density, nodes,
'BULK_DENSITY', this%memoryPath)
1134 call mem_allocate(this%distcoef, nodes,
'DISTCOEF', this%memoryPath)
1135 call mem_allocate(this%ratesrb, nodes,
'RATESRB', this%memoryPath)
1136 call mem_allocate(this%csrb, nodes,
'CSRB', this%memoryPath)
1140 call mem_allocate(this%sp2, nodes,
'SP2', this%memoryPath)
1146 this%porosity(n) =
dzero
1147 this%thetam(n) =
dzero
1148 this%volfracim(n) =
dzero
1149 this%ratesto(n) =
dzero
1151 do n = 1,
size(this%decay)
1152 this%decay(n) =
dzero
1153 this%ratedcy(n) =
dzero
1154 this%decaylast(n) =
dzero
1156 do n = 1,
size(this%bulk_density)
1157 this%bulk_density(n) =
dzero
1158 this%distcoef(n) =
dzero
1159 this%ratesrb(n) =
dzero
1160 this%csrb(n) =
dzero
1162 do n = 1,
size(this%sp2)
1165 do n = 1,
size(this%ratedcys)
1166 this%ratedcys(n) =
dzero
1167 this%decayslast(n) =
dzero
1182 character(len=LINELENGTH) :: keyword
1183 character(len=LINELENGTH) :: sorption
1184 character(len=MAXCHARLEN) :: fname
1185 integer(I4B) :: ierr
1186 logical :: isfound, endOfBlock
1188 character(len=*),
parameter :: fmtisvflow = &
1189 "(4x,'CELL-BY-CELL FLOW INFORMATION WILL BE SAVED TO BINARY FILE &
1190 &WHENEVER ICBCFL IS NOT ZERO.')"
1191 character(len=*),
parameter :: fmtlinear = &
1192 &
"(4x,'LINEAR SORPTION IS ACTIVE. ')"
1193 character(len=*),
parameter :: fmtfreundlich = &
1194 &
"(4x,'FREUNDLICH SORPTION IS ACTIVE. ')"
1195 character(len=*),
parameter :: fmtlangmuir = &
1196 &
"(4x,'LANGMUIR SORPTION IS ACTIVE. ')"
1197 character(len=*),
parameter :: fmtidcy1 = &
1198 &
"(4x,'FIRST-ORDER DECAY IS ACTIVE. ')"
1199 character(len=*),
parameter :: fmtidcy2 = &
1200 &
"(4x,'ZERO-ORDER DECAY IS ACTIVE. ')"
1201 character(len=*),
parameter :: fmtfileout = &
1202 "(4x,'MST ',1x,a,1x,' WILL BE SAVED TO FILE: ',a,/4x,&
1203 &'OPENED ON UNIT: ',I7)"
1206 call this%parser%GetBlock(
'OPTIONS', isfound, ierr, blockrequired=.false., &
1207 supportopenclose=.true.)
1211 write (this%iout,
'(1x,a)')
'PROCESSING MOBILE STORAGE AND TRANSFER OPTIONS'
1213 call this%parser%GetNextLine(endofblock)
1214 if (endofblock)
exit
1215 call this%parser%GetStringCaps(keyword)
1216 select case (keyword)
1219 write (this%iout, fmtisvflow)
1221 call store_error(
'SORBTION is not a valid option. Use &
1222 &SORPTION instead.')
1223 call this%parser%StoreErrorUnit()
1225 call this%parser%GetStringCaps(sorption)
1226 select case (sorption)
1229 write (this%iout, fmtlinear)
1232 write (this%iout, fmtfreundlich)
1235 write (this%iout, fmtlangmuir)
1237 call store_error(
'Unknown sorption type was specified ' &
1238 & //
'('//trim(adjustl(sorption))//
').'// &
1239 &
' Sorption must be specified as LINEAR, &
1240 &FREUNDLICH, or LANGMUIR.')
1241 call this%parser%StoreErrorUnit()
1243 case (
'FIRST_ORDER_DECAY')
1245 write (this%iout, fmtidcy1)
1246 case (
'ZERO_ORDER_DECAY')
1248 write (this%iout, fmtidcy2)
1250 call this%parser%GetStringCaps(keyword)
1251 if (keyword ==
'FILEOUT')
then
1252 call this%parser%GetString(fname)
1254 call openfile(this%ioutsorbate, this%iout, fname,
'DATA(BINARY)', &
1256 write (this%iout, fmtfileout) &
1257 'SORBATE', fname, this%ioutsorbate
1259 errmsg =
'Optional SORBATE keyword must be '// &
1260 'followed by FILEOUT.'
1264 write (
errmsg,
'(a,a)')
'Unknown MST option: ', trim(keyword)
1266 call this%parser%StoreErrorUnit()
1269 write (this%iout,
'(1x,a)')
'END OF MOBILE STORAGE AND TRANSFER OPTIONS'
1284 character(len=LINELENGTH) :: keyword
1285 character(len=:),
allocatable :: line
1286 integer(I4B) :: istart, istop, lloc, ierr, n
1287 logical :: isfound, endOfBlock
1288 logical,
dimension(6) :: lname
1289 character(len=24),
dimension(6) :: aname
1291 data aname(1)/
' MOBILE DOMAIN POROSITY'/
1292 data aname(2)/
' BULK DENSITY'/
1293 data aname(3)/
'DISTRIBUTION COEFFICIENT'/
1294 data aname(4)/
' DECAY RATE'/
1295 data aname(5)/
' DECAY SORBED RATE'/
1296 data aname(6)/
' SECOND SORPTION PARAM'/
1303 call this%parser%GetBlock(
'GRIDDATA', isfound, ierr)
1305 write (this%iout,
'(1x,a)')
'PROCESSING GRIDDATA'
1307 call this%parser%GetNextLine(endofblock)
1308 if (endofblock)
exit
1309 call this%parser%GetStringCaps(keyword)
1310 call this%parser%GetRemainingLine(line)
1312 select case (keyword)
1314 call this%dis%read_grid_array(line, lloc, istart, istop, this%iout, &
1315 this%parser%iuactive, this%porosity, &
1318 case (
'BULK_DENSITY')
1321 'BULK_DENSITY', trim(this%memoryPath))
1322 call this%dis%read_grid_array(line, lloc, istart, istop, this%iout, &
1323 this%parser%iuactive, &
1324 this%bulk_density, aname(2))
1329 trim(this%memoryPath))
1330 call this%dis%read_grid_array(line, lloc, istart, istop, this%iout, &
1331 this%parser%iuactive, this%distcoef, &
1337 trim(this%memoryPath))
1338 call this%dis%read_grid_array(line, lloc, istart, istop, this%iout, &
1339 this%parser%iuactive, this%decay, &
1342 case (
'DECAY_SORBED')
1344 'DECAY_SORBED', trim(this%memoryPath))
1345 call this%dis%read_grid_array(line, lloc, istart, istop, this%iout, &
1346 this%parser%iuactive, &
1347 this%decay_sorbed, aname(5))
1352 trim(this%memoryPath))
1353 call this%dis%read_grid_array(line, lloc, istart, istop, this%iout, &
1354 this%parser%iuactive, this%sp2, &
1358 write (
errmsg,
'(a,a)')
'Unknown GRIDDATA tag: ', trim(keyword)
1360 call this%parser%StoreErrorUnit()
1363 write (this%iout,
'(1x,a)')
'END PROCESSING GRIDDATA'
1365 write (
errmsg,
'(a)')
'Required GRIDDATA block not found.'
1367 call this%parser%StoreErrorUnit()
1371 if (.not. lname(1))
then
1372 write (
errmsg,
'(a)')
'POROSITY not specified in GRIDDATA block.'
1379 if (.not. lname(2))
then
1380 write (
errmsg,
'(a)')
'Sorption is active but BULK_DENSITY &
1381 ¬ specified. BULK_DENSITY must be specified in GRIDDATA block.'
1384 if (.not. lname(3))
then
1385 write (
errmsg,
'(a)')
'Sorption is active but distribution &
1386 &coefficient not specified. DISTCOEF must be specified in &
1391 if (.not. lname(6))
then
1392 write (
errmsg,
'(a)')
'Freundlich or langmuir sorption is active &
1393 &but SP2 not specified. SP2 must be specified in &
1400 write (
warnmsg,
'(a)')
'Sorption is not active but &
1401 &BULK_DENSITY was specified. BULK_DENSITY will have no affect on &
1402 &simulation results.'
1404 write (this%iout,
'(1x,a)')
'WARNING. '//
warnmsg
1407 write (
warnmsg,
'(a)')
'Sorption is not active but &
1408 &distribution coefficient was specified. DISTCOEF will have &
1409 &no affect on simulation results.'
1411 write (this%iout,
'(1x,a)')
'WARNING. '//
warnmsg
1414 write (
warnmsg,
'(a)')
'Sorption is not active but &
1415 &SP2 was specified. SP2 will have &
1416 &no affect on simulation results.'
1418 write (this%iout,
'(1x,a)')
'WARNING. '//
warnmsg
1424 if (.not. lname(4))
then
1425 write (
errmsg,
'(a)')
'First or zero order decay is &
1426 &active but the first rate coefficient is not specified. DECAY &
1427 &must be specified in GRIDDATA block.'
1430 if (.not. lname(5))
then
1436 write (
errmsg,
'(a)')
'DECAY_SORBED not provided in GRIDDATA &
1437 &block but decay and sorption are active. Specify DECAY_SORBED &
1438 &in GRIDDATA block.'
1444 write (
warnmsg,
'(a)')
'First- or zero-order decay &
1445 &is not active but decay was specified. DECAY will &
1446 &have no affect on simulation results.'
1448 write (this%iout,
'(1x,a)')
'WARNING. '//
warnmsg
1451 write (
warnmsg,
'(a)')
'First- or zero-order decay &
1452 &is not active but DECAY_SORBED was specified. &
1453 &DECAY_SORBED will have no affect on simulation results.'
1455 write (this%iout,
'(1x,a)')
'WARNING. '//
warnmsg
1461 call this%parser%StoreErrorUnit()
1465 do n = 1,
size(this%porosity)
1466 this%thetam(n) = this%porosity(n)
1478 real(DP),
dimension(:),
intent(in) :: volfracim
1483 do n = 1, this%dis%nodes
1484 this%volfracim(n) = this%volfracim(n) + volfracim(n)
1489 do n = 1, this%dis%nodes
1490 this%thetam(n) = this%get_volfracm(n) * this%porosity(n)
1501 integer(I4B),
intent(in) :: node
1503 real(dp) :: volfracm
1505 volfracm =
done - this%volfracim(node)
1514 real(dp),
intent(in) :: conc
1515 real(dp),
intent(in) :: kf
1516 real(dp),
intent(in) :: a
1520 if (conc >
dzero)
then
1533 real(dp),
intent(in) :: conc
1534 real(dp),
intent(in) :: kl
1535 real(dp),
intent(in) :: sbar
1539 if (conc >
dzero)
then
1540 cbar = (kl * sbar * conc) / (
done + kl * conc)
1552 real(dp),
intent(in) :: conc
1553 real(dp),
intent(in) :: kf
1554 real(dp),
intent(in) :: a
1558 if (conc >
dzero)
then
1559 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
integer(i4b), parameter izero
integer constant zero
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
@ decay_zero_order
Zeroth-order decay.
@ decay_first_order
First-order decay.
@ sorption_freund
Freundlich sorption between aqueous and solid phases.
@ sorption_lang
Langmuir sorption between aqueous and solid phases.
@ sorption_linear
Linear sorption between aqueous and solid phases.
@ decay_off
Decay (or production) of mass inactive (default)
@ sorption_off
Sorption is inactive (default)
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