PPTEST Version 2: User Manual

PPTEST Version 2: User Manual
PPTEST: A Multi‐Species Reactive Transport Model to Estimate Biogeochemical Rates Based on Single‐Well Push‐Pull Test Data User Manual Report Number: 2010ENE­01 Mantha S. Phanikumar Department of Civil & Environmental Engineering Michigan State University, East Lansing, MI 48824, USA Email: [email protected] Summer 2010 PPTEST: User Manual
Version 2.0
July 23, 2010
Errata
This user manual is written to describe the PPTEST model (Phanikumar and McGuire, 2010) in more
detail . In the original paper, two typographical errors were not corrected at the proofs stage. These
are described below.
1. In equation (12) on page 999, the last term should appear as shown below:
½
+··· +
kN −1 Ci nN −1
0
tN −1 ∗ ≤ t < tN ∗
otherwise
¾
2. On page 999 (below equation 1), the sentence ”N is the total number of reaction constants”
should read ” (N − 1) is the total number of reaction constants”.
Phanikumar, M.S. and J.T. McGuire, A multi-species reactive transport model to estimate biogeochemical rates based on single-well push-pull test data, Computers & Geosciences, Vol. 36, No. 8, pp.
997-1004 (August 2010)
1
PPTEST: User Manual
1
Introduction
PPTEST is a one-dimensional, radial-coordiante, finite-differene model to analyze data obtained from
a variety of single-well push-pull tests. The model allows the simulation of multiple species, arbitrary
reaction order kinetics and multiple reaction rates to describe the observed data. A number of sorption
models have been built into the model and additional user-defined models can be easily incorporated
into the code. This document describes the theory and the numerical details and provides examples
to illustrate the application of PPTEST. This document is organized as follows. In the next section,
we present the governing equations, boundary and initial conditions. In section 3 details of the
computational meshes and numerical schemes are discussed. PPTEST prompts the user for a text file
that contains the input parameters. In section4 we describe the input parameters. Examples and
sample input files are presented in section 5. The program listing is given in section 6. The source
code can be compiled using any FORTRAN compiler although results reported in the paper were
obtained using the Intel Fortran Compiler version 11. The code was compiled using the following
command:
>> ifort ppt.f90
For the data and analyses reported in this manual, PPTEST took less than a minute to run - typical
running times are a few seconds. Performance can be further improved using high-level / processorspecific optimizations (e.g., Intel, 2008). Since the present method of analysis relies on numerical
solutions (as opposed to analytical solutions), two points are probably worth mentioning. First, care
should be exercised to ensure that the numerical solutions are accurate and do not suffer from excessive
numerical dispersion since the schemes used are second-order accurate at best. By refining the grid and
rerunning PPTEST, one can get an idea about the errors involved and the resolution required for a given
problem. The second point is related to the input parameter idiag which controls the node number
for which concentration versus time information is generated (e.g., for comparison with observed data).
It is important to keep in mind that when the number of grid points changes, idiag corresponding to
a radial coordinate r also changes. Therefore, to compare solutions obtained using two different grids
at the same radial location, different idiag values should be used. When the program terminates
successfully, several output files will be created - a mesh.txt with three columns for j, ∆rj and rj and
files that contain the time versus concentration information (the number of files created is equal to
the number of species simulated). Filenames have the form out1.dat, out2.dat. The mesh.txt file
is useful for understanding how the idiag value changes as the mesh-related parameters are changed.
PPTEST can handle upto a maximum of 10001 grid points, 10 species and 10 reaction constants without
requiring any changes to the source code. To increase these numbers, the parameter statements on
lines 8, 95, 460, 514, 583, 599, 616 and 647 should be changed and the code recompiled.
Figure 1: Schematic showing the different phases in a typical push-pull test.
2
Governing Equations
PPTEST can solve an arbitrary number of partial differential equations (similar to equations 1 and 2
below) for tracer (denoted by c(1,i) in the program) and reactive species (c(2,i), c(3,i), · · · in
the code). Symbols are explained in the nomenclature section at the end of the manual. The equations
can have complex source and sink terms and coupled to other equations (e.g., to describe microbial
processes such as growth on a substrate etc). Equation (1) for the tracer is a special case of equation
(2), therefore we focus on equation (2) for the i-th species.
2
PPTEST: User Manual
∂CT
∂CT
∂ 2 CT
+v
= αL |v|
∂t
∂r
∂r2
(1)
N −1
∂Ci ρb ∂Si
∂Ci
∂ 2 Ci X
+
+v
= αL |v|
−
[H (t − tj ∗ ) − H (t − tj+1 ∗ )] kj Ci nj ± Fi
∂t
θ ∂t
∂r
∂r2
(2)
j=1
Here Ci and Si are the aqueous and sorbed phase concentrations respectively and Fi denotes source/sink
terms specified using the user-defined reactions module (described later). The second term on the right
hand side of equation (2) allows the user to describe the data using a series of piece-wise linear or
non-linear approximations (see Figure 4) and can be thought of as a special case of the more general
user-defined module Fi . In (2), H denotes the Heaviside step function, kj and nj are the reaction
constants and orders respectively, N denotes the total number of ”control points” - times (t∗1 , t∗2 etc.)
at which the slope changes in Figure 4 or N (minus one) is the total number of reaction constants
used to describe the data and t∗j are the times at which there is a change in the reaction constats or
orders or both (see Fig. 4). Since the Heaviside step function H operating on a function f (x) turns
the function ”on” or ”off” according to the following property:

0
if t ≤ tj ∗

∗
∗
f (x)
if tj ∗ < t < tj+1 ∗
[H (t − tj ) − H (t − tj+1 )] f (x) =

0
if t > tj+1 ∗
the second term on the right hand side of equation (2) can be written as shown below:
½
¾
½
¾
NP
−1
k1 Ci n1 t1 ∗ ≤ t < t2 ∗
k2 Ci n2 t2 ∗ ≤ t < t3 ∗
nj
∗
∗
[H (t − tj ) − H (t − tj+1 )] kj Ci =
+
0
otherwise
0
otherwise
j=1
¾
½
kN −1 Ci nN −1 tN −1 ∗ ≤ t < tN ∗
+··· +
0
otherwise
The pore water velocity near the well is given by:
v=
Q
2πbθr
(3)
In equation (3), the regional groundwater velocity is assumed to have negligible effect compared to the
effects of imposed pumping, a reasonable assumption close to the test well. Before solving equation (2)
for the reactive component, we need to invoke a sorption model. PPTEST allows five different sorption
models as shown below. In what follows, we focus on equation (2) and drop the suffix i with the
understanding that C = Ci and S = Si .
Linear equilibrium sorption : S = Kd C
1
Freundlich isotherm : S = aC m
Langmuir isotherm : S =
One − site kinetic sorption :
pqC
1 + pC
∂S
= α (Kd C − S)
∂t
(4)
(5)
(6)
(7)
∂S
= α [(1 − f )Kd C − S]
(8)
∂t
More details about the one-site and two-site sorption models can be found in van Genuchten and
Wagenet (1989). For the isotherm-based models, if equations (4), (5) or (6) are differentiated with
Two − site kinetic sorption :
3
PPTEST: User Manual
respect to time and substituted into equation (2), then we obtain a single equation for the aqueous
phase concentration with a retardation factor multiplying the unsteady term as shown below.
¯ ¯ 2
−1
¯ A ¯ ∂ Ci NX
∂Ci A ∂Ci
+
= αL ¯¯ ¯¯
−
[H (t − tj ∗ ) − H (t − tj+1 ∗ )] kj Ci nj ± Fi
Ri
∂t
r ∂r
r ∂r2
j=1
where the retardation factor for the i-th species is given by:
Ri = 1 +
ρb ∂Si
θ ∂Ci
The retardation factors corresponding to the isotherm models (equations 4-6) appear as shown below.
R=1+
ρb
Kd
θ
ρb mC m−1
θ
¶
µ
ρb
pq
RL = 1 +
θ (1 + pC)2
RF = 1 +
(9)
(10)
(11)
In equations (9-11) R, RF and RL denote the retardation factors corresponding to the linear, Freundlich and Langmuir isotherms respectively. All three isotherms (4-6) are linear for low concentrations; however, the Freundlich and Langmuir isotherms change slope at higher concentrations. The
main difference between the Freundlich and Langmuir isotherms is that there is no capacity term
(upper limit for sorption) in the Freundlich model while there is an upper limit in the Langmuir model
(the term q denotes the capacity term).
Initial conditions for the tracer and the reactive components can be specified either as a zero initial
condition or as a background value. Depending on the sorption model used, an additional equation
needs to be solved for S. Therefore boundary and initial conditions are shown for both aqueous and
sorbed-phase concentrations.
C(r, t = 0) = Cb : r > rw
(12)
S(r, t = 0) = Sb : r > rw
(13)
If Cb and Sb are non-zero, they can be specified in lines 193-199 in the program (code should be
recompiled). Boundary conditions are different for the injection, rest and extraction phases as shown
below (see Figure 1).
Injection of Test Solution:
µ
¶
∂C
−αL
+C
= C0 : 0 < t < tinj
(14)
∂r
r=rw
S(rw , t) = S0 : 0 < t < tinj
∂C(r → ∞, t)
=0
∂r
∂S(r → ∞, t)
=0
∂r
Cr=rw = C0 : 0 < t < tinj
(15)
(16)
(17)
(18)
The value of S0 is calculated inside the code based on the sorption model used. In some cases
equation(18) can be used for the boundary condition near the well casing instead of equation (14).
Both forms (18 and 14) are implemented in PPTEST although equation (14) is the default condition
4
PPTEST: User Manual
used. To use the Robin boundary condition, lines 311 and 320 should be activated (uncommented)
and lines 304-309 and 313-318 should be commented. This change requires compilation of the source
code.
Injection of Chaser:
The mathematical form of the boundary conditions is identical to those for the injection of a test
solution (equations 14 - 18) except that C0 and S0 in equations (14) and (15) are replaced with the
concentrations for the chaser solution (C1 and S1 ) for each species simulated.
µ
¶
∂C
−αL
+C
= C1 : tinj < t < (tinj + tchaser )
(19)
∂r
r=rw
S(rw , t) = S1 : tinj < t < (tinj + tchaser )
Cr=rw
∂C(r → ∞, t)
=0
∂r
∂S(r → ∞, t)
=0
∂r
= C1 : tinj < t < (tinj + tchaser )
Equation (19) can be replaced by equation (23) in the code. Both forms are implemented.
Rest Period:
µ
¶
∂C
−αL
+C
= 0 : (tinj + tchaser ) < t < (tinj + tchaser + trest )
∂r
r=rw
∂S(rw , t)
= 0 : (tinj + tchaser ) < t < (tinj + tchaser + trest )
∂r
∂C(r → ∞, t)
=0
∂r
∂S(r → ∞, t)
=0
∂r
Extraction:
∂C(rw , t)
= 0 : (tinj + tchaser + trest ) < t < tmax
∂r
∂S(rw , t)
= 0 : (tinj + tchaser + trest ) < t < tmax
∂r
C(r → ∞, t) → 0 : t > 0
S(r → ∞, t) → 0 : t > 0
(20)
(21)
(22)
(23)
(24)
(25)
(26)
(27)
(28)
(29)
(30)
(31)
In equations (28) and (29) tmax = (tinj + tchaser + trest + text ). While using the kinetic or two-site
sorption model, boundary conditions for the sorbed-phase concentration (equations 15, 20) S0 and S1
need to be specified. If we assume that the sorbed-phase is locally in equilibrium with the aquesous
phase, then the following conditions can be used (f = 1 for the one-site kinetic model).
S0 = (1 − f )Kd C0
(32)
S1 = (1 − f )Kd C1
(33)
Equations (32) and (33) appear in lines 222 and 223 in the source code. These lines can be changed
to specify different conditions for S0 and S1 .
5
PPTEST: User Manual
3
Numerical Methods
Computational grids with variable step sizes can be generated using two methods. In the first method,
geometrically varying step sizes can be generated. If this method is used, then the user specifies the
number of points n and the desired resolution (step size) near the well (∆r1 ). rmax can be calculated
using equation (34). The geometric ratio λ that produces a desired rmax can be easily calculated by
taking the logarithms on both sides of equation (34).
rmax =
∆r1 (λnr − 1)
(λ − 1)
λ>1
(34)
In the second method, variable grids can be generated using a nonlinear transform (equations 35 and
36) to obtain refined grid spacing around an arbitrary location rc .
´ 
³

rc
γ − 1)
1
+
(e
rmax
1
³
´ 0 < γ < ∞
B=
ln 
(35)
rc
2γ
−γ
1 + (e − 1)
rmax
½
¾
sinh [γ (r0 − B)]
r = rc 1 +
sinh(γB)
(36)
The first and second derivatives in equations (1) and (2) can be approximated using the following
expressions (Phanikumar and Mahajan, 1998) for variable grid spacing (Figure 2).
¯
βj Cj−1
(∆rj − ∆rj−1 )
Cj+1
∂C ¯¯
−
+
Cj
(37)
=
¯
∂r j
βj (∆rj + ∆rj−1 ) (∆rj + ∆rj−1 )
(∆rj · ∆rj−1 )
¯
·
¸
Cj+1
Cj−1
2Cj
∂ 2 C ¯¯
2
+
−
=
¯
2
∂r j
(∆rj + ∆rj−1 ) ∆rj
∆rj−1
(∆rj · ∆rj−1 )
µ
¶
∆rj
β=
∆rj−1
(38)
(39)
In the above equations the suffix j denotes the spatial location (this should not be confused with the
summation index j in equation (2). PPTEST uses (first and second-order accurate) upwind difference
schemes to approximate the advection terms. Depending on the direction of velocity, the first-order
accurate upwind scheme uses either forward or backward differences to evaluate the first derivative
in the advection term. The following equations summarize the second-order accurate upwind scheme.
More details of this scheme can be found in Roache (1998).
vR CR − vL CL
∂
(vC) =
∂r
∆
1
(vj+1 + vj )
2
1
vL = (vj + vj−1 )
2
vR =
CR = Cj if
CR = Cj+1
CL = Cj−1
CL = Cj if
vR > 0
if vR < 0
if vL > 0
vL < 0
(40)
(41)
(42)







(43)
6
PPTEST: User Manual
The above conditions can be combined into one single equation with four switches ψ1 ,ψ2 ,ψ3 and ψ4
as shown below.
vR ψ1 Cj+1 + vR ψ2 Cj + vL ψ3 Cj + vL ψ4 Cj−1
∂
(vC) =
(44)
∂x
∆
Using the above approximations, the implicit finite-difference representation of equation (2) appears
as shown below.
Ã
!
µ ¶
`+1
`+1
Cj`+1 − Cj` ρb ∂S `
ψ1 vR Cj+1
+ ψ2 vR Cj`+1 + ψ3 vL Cj`+1 + ψ4 vL Cj−1
+
+
∆t
θ
∂t j
∆
(
=
αL |v|`j
#
" `+1
)
`+1
Cj−1
2Cj`+1
Cj+1
2
−
−
−
(∆rj + ∆rj−1 ) ∆rj
∆rj−1
(∆rj · ∆rj−1 )
N
−1
X
³
´ni
[H (t − ti ∗ ) − H (t − ti+1 ∗ )] ki Cj l+1
± Fj`
(45)
i=1
In the above equation, the superscripts ` + 1 and ` denote the new and old time levels respectively.
The summation index j in equation (2) is replaced with i in the above equation to avoid confusion
with the spatial index j. If the above equation is written once for every grid node, then we obtain a
system of algebraic equations in the following form:
`+1
`+1
−Ej Cj−1
+ Fj Cj`+1 − Gj Cj+1
= Rj
(46)
If we assume that the two-site sorption model is used, then the coefficients appear as shown below.
Ej = −
Fj =
2αL |v|
vR ψ 1
+
R∆
(∆rj + ∆rj−1 )R∆rj
vR ψ2 + vL ψ3
2αL |v|
ki ¡ ` ¢ni −1
1
ρb
+
+
+
Cj
+ δ α(1 − f )Kd
∆t
R∆
(∆rj ∆rj−1 )R R
θ
Gj = −
vL ψ4
2αL |v|
+
∆R
(∆rj + ∆rj−1 )∆rj−1 R
(47)
(48)
(49)
Cj`
ρb
+ δ αSj` ± Fj`
(50)
∆t
θ
For the sake of illustration, the above system of equations gives rise to the following tridiagonal matrix
system for the case of five grid nodes.

  `+1  

C1
R1
F1 G1


 E2 F2 G2
C2`+1 
 
 R2 




`+1
 C

E3 F3 G3
(51)
=  R3 

 3 

 
`+1




R4
E4 F4 G4  C4 
R5
E5 F5
C5`+1
Rj =
In equations (47-50), ∆ is an appropriate step size (∆rj or ∆rj−1 ) depending on the direction of
velocity and R is a retardation coefficient (=R, RF or RL ) that depends on the sorption model. If
the kinetic or two-site sorption models are used, then R = 1. If the nonlinear equilibrium models are
used (i.e., R 6= 1), then δ = 0 in equations (48) and (50). In equation (48), the reaction term was
linearized and approximated as:
7
PPTEST: User Manual
ki ¡ `+1 ¢ni
ki h¡ ` ¢ni −1 ¡ `+1 ¢i
Cj
Cj
· Cj
(52)
=
R
R
Other approximations are possible (e.g., Crank-Nicholson approximation). The two-site sorption
model can be represented as shown below.
Sj`+1 − Sj`
= α(1 − f )Kd Cj` − Sj`
(53)
∆t
Rearranging the equation in the form (46), we get the following coeffcients for the tridiagonal matrix:
Ej = 0
Fj =
1
+1
∆t
Gj = 0
Rj =
Sj`
+ α(1 − f )Kd Cj`
∆t
(54)
(55)
(56)
(57)
Figure 2: Nomenclature for the finite-difference stencil
Examples of a variable grids generated using equations (35-36) is shown in Figure 3. The step size
decreases as we approch rc and increases away from it. To identify the tuning parameter β that
produces the desired resolution at a given location rc , the following matlab script can be used.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
clear; clc;
rw=0.104;
rmax=50.0;
nr=3001;
tau=10.0; % this is gamma in eqs. (35-36)
rc=0.36-rw;
rmax=rmax-rw;
%Calculate constants
anr = 1.0 + (exp(tau)-1.0)*(rc/rmax);
adr = 1.0 + (exp(-tau)-1.0)*(rc/rmax);
b = (1.0/(2.0*tau))*log(anr/adr);
%First generate a uniform mesh
del=1/(nr-1);
%del=1.0/(nr-1);
rr(1)=0;
for i=2:nr
%rr(i)=b+(1.0/tau)*asinh((rat-1.0d0)*dsinh(tau*b));
rr(i)=rr(i-1)+del;
8
PPTEST: User Manual
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
end
%Now generate the variable mesh:
r(1)=0;
for i=2:nr
anum = sinh(tau*(rr(i)-b));
aden = sinh(tau*b);
r(i)=1.0 + anum/aden;
r(i)=rc*r(i);
end
for i=1:nr
r(i)=r(i)+rw;
end
for i=2:nr
dr(i-1)=r(i)-r(i-1);
end
dr(nr)=dr(nr-1);
[r(1) dr(1)]
figure(1);
i=1:nr;
loglog(r,dr,’-’);
xlabel(’Radial distance from well casing, r_{j}’);
ylabel(’Step size, \Delta r_{j}’);
grid on;
Figure 3: Examples of variable meshes generated by equations (35-36) for different values of the tuning
parameter, γ. The resolution around the radial location rc increases with γ. Note the logarithmic
scale for both axes.
The solution of the above system of simultaneous equations (equation 46) can be obtained efficiently
using the well-known Thomas algorithm (Roache, 1998).
9
PPTEST: User Manual
4
Input Parameters
The number of parameters needed to run PPTEST depends on the sorption and reaction models used.
The number and type of parameters will also change depending on whether a uniform or variable mesh
is desired. Any consistent system of units can be used as there are no unit conversions inside the code.
Line 1: rmax, nr, dt
Line 2: imesh
Line 3: drone,grat
Line 3: tau, rdiag
Line 4: iadvect
Line 5: idiag
Line 6: ichasr
Line 7: qinj, qext, tinj, trest, text, baquifer,por,alphal,rhob,rw
Line 8: qinj2, tinj2
Line 9: numsp, nseg
Line 10: c0
Line 11: korder
Line 12: tcrit
Line 13: k
Line 14: c1
Line 15: isorp
Line 16: kd
Line 16: a,b
Line 16: a,b
Line 16: alpha,kd
Line 16: alpha,frac,kd
Line 17: usrxn
A detailed explanation of these input parameters is given below.
Line 1: rmax, nr, dt
1. rmax: Distance from the well casing to the outer boundary (rmax )
2. nr: Number grid points n
3. dt: Time step ∆t
Line 2: imesh
This parameter is used to select a method for generating the computational mesh. If imesh = 1, then
a uniform mesh is generated and the next line (in which parameters are specified for generating a
variable grid) is not required.
Line 3:
If imesh = 2, then a variable mesh in which the step size increases geometrically from the well casing
will be generated. Parameters drone,grat (∆r1 , λ) will be read from line 3.
If imesh = 3, then a variable mesh will be generated such that fine grids will be placed near an
arbitrary (user-specified) radial location rc . Parameters γ, rc (called tau and rdiag in the code) will
be read from line 3. Here γ is a tuning parameter (described earlier).
Line 4: iadvect
This parameter specifies the advection scheme. The current version of PPTEST allows the user to use
either a first-order or a second-order accurate upwind scheme. Future versions of PPTEST will include
other advection schemes.
10
PPTEST: User Manual
iadvect = 1: First-order accurate upwind scheme iadvect = 3: Second-order accurate upwind
scheme. iadvect = 3 is the recommended option for most applications.
Line 5: idiag
Diagnostic node number. Concentration(s) versus time information will be saved to a textfile for the
diagnostic node.
Line 6: ichasr
This is a flag (1 = yes, 0 = no) that determines whether the injection period is followed by the injection
of a chaser solution. If ichaser = 1, then the user is expected to provide details of the chaser injection
in separate lines (lines 8 and 14 of the input file).
Line 7: qinj, qext, tinj, trest, text, baquifer,por,alphal,rhob,rw
1. qinj: Pumping rate during injection
2. qext: Pumping rate during extraction
3. tinj: Duration of the injection period
4. trest: Duration of the rest period
5. text: Duration of the extraction period
6. baquifer: Aquifer thickness (b)
7. por: Aquifer porosity (θ)
8. alphal: Longitudinal dispersivity (αL )
9. rhob: Density (ρb )
10. rw: Radius of the well casing (rw )
Line 8: qinj2, tinj2
This line is required only if ichasr = 1.
1. qinj2: Pumping rate (injection) for the chaser
2. tinj2: Duration of the injection period (chaser)
Line 9: numsp, nseg
Number of species to be simulated (isp = 1 corresponds to a conservative tracer). nseg is the number
of segments used to describe the data.
Line 10: c0
Injection concentrations for all the species simulated separated by commas (read in the order c0(i), i =
1, numsp)
Line 11: korder
Order of the reaction for the j-th segment, nj . A total of nseg values are expected. PPTEST allows
multiple reaction rates to be used to describe the data as shown in Figure 4. Here, Cr = c2/c20 and
Ctr = c/c10 are the normalized concentrations of the reactive component and the tracer respectively.
The concentrations are plotted following the simplified method of push-pull test data analysis proposed
by Haggerty et al. (1998). In Figure 4, t∗1 , t∗2 and t∗3 are the times tcrit(1), tcrit(2) and tcrit(3)
at which reaction rates (and possibly orders) change. An arbitrary number of reaction rates (and
reaction orders) can be simulated although most applications may require zero, one or two reaction
rates. Input files for examples 1 through 4 illustrate how to specify these parameters. If the user
decides to describe reactions using the more general user-defined reactions module, then it is possible
to set nseg = 0 in line 9, then lines 11, 12 and 13 for korder, tcrit and k are not needed.
11
PPTEST: User Manual
Line 12: tcrit
The times t∗j at which slopes change as shown in Figure 4. A total of nseg values are needed. t∗1 = 0
Line 13: k
The reaction rates kj used to describe the different segments as shown in Figure 4. A total of nseg
values is needed. If there is a lag phase for the reaction, then k1 = 0.
k
k
2
ln ( C Ctr )
r
1
Lag Phase
t1*
t2*
t3*
k
3
n=1
Experiment
Model
Time since injection ended (hours)
Figure 4: The presence of a lag phase, multiple reaction rates and potentially complex reaction order
could complicate the interpretation of rates. PPTEST can simulate situations such as the one shown
above.
Line 14: c1
If a second injection period (chaser solution) is simulated, then concentrations of all species during
this period need to be specified on this line separated by commas.
Line 15: isorp
This parameter can take values from 0 to 5 and is used to select a sorption model. If isorp = 0, then
sorption is not simulated and the next line (in which model-specific sorption parameters are specified)
is not required.
Line 16:
If isorp = 1, then linear equilibrium sorption is simulated. The distribution coefficient kd is read
from line 16.
If isorp = 2, then the Freundlich isotherm is used. Two parameters a, b (equation 5) are read from
line 16.
If isorp = 3, then the Langmuir isotherm is simulated. Two parameters a, b (equation 6) are read
from line 16.
If isorp = 4, then the one-site kinetic sorption model is used. Two parameters alpha, kd (equation
7) are read from line 16.
If isorp = 5, then the two-site kinetic sorption model is used. For this case, three parameters alpha,
frac, kd (equation 8) are read from line 16.
12
PPTEST: User Manual
Figure 5: Comparison of numerical results obtained from PPTEST with the approximate analytical
solution of Gelhar & Collins (1971). A uniform grid of 1000 points was used to compute the solution.
Other parameters are shown in the input file above.
Line 17: usrxn
This is a flag (1 = Yes, 0 = No) to determine if user-defined reactions are simulated. If usrxn = 1,
then the subroutine reactions is called. Example 4 illustrates the use of this subroutine.
5
Examples
In this section we provide several examples to illustrate the application of PPTEST. These examples
are discussed in Phanikumar and McGuire (2010).
5.1
Example1: Comparison with the analytical solution of Gelhar & Collins (1971)
Gelhar & Collins (1971) provided the following approximate analytical solution for the radial dispersion
problem:


³
´
V


Vinj − 1
C
1


= erfc  ½ ³
(58)

µ
¶¾
1/2
¯
¯
´
³
´
C0
2


1/2
¯
αL
16
V ¯
V
2 − ¯1 − Vinj ¯
1 − Vinj
3
rmax
r
rmax =
Qtinj
πbθR
(59)
where V denotes the cumulative extracted volume (= |Qext | t) , Vinj = Qinj .tinj and tinj denotes the
duration of the injection period. The retardation factor R = 1. Any set of parameters can be used
to compare with the analytical solution, however, an upper limit for the applicability of the above
equation is ² ¿ 0.01 where ε = αL /2rmax . A numerical solution was computed using PPTEST for the
following set of paramters. The analytical solution is computed using the matlab script.
13
PPTEST: User Manual
1
2
3
4
5
6
7
8
9
10
10.0, 1001, 0.1
1
3
2
0
2.587, 2.282, 94.32, 0.0, 405.6, 8.0, 0.38, 0.064, 1.7, 0.052
1, 0
1.0
0
0
matlab script to compare the numerical solution with the analytical solution of Gelhar & Collins
(1971):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
%----------parameters------------------qinj = 2.587; qext=2.282;b=8.0; por=0.38;
rw= 0.052;tinj=94.32;text=405.6; trest=0.00;alphal=0.064;
%---------------------------------------vinj=qinj*tinj;
rmax = sqrt(vinj/(pi*b*por));
epsilon = alphal/(2.0*rmax)
load out1.dat;
time=out1(:,2);
nt=length(time);
Cnum=out1(:,3);
%-----------Compute Approximate Analytical Solution-----------------tt = time; % this is extr_vol_by_inj_vol in PPTEST
term1 = (tt-1.0);
term2 = (abs(1.0-tt)).^0.5;
term2 = term2.*(1.0-tt);
term2 = (2.0-term2);
term2 = ((16.0/3.0)*(alphal/rmax)).*term2;
term2 = term2.^0.5;
!del a1.dat
C = 0.5*erfc(term1./term2);
out = [tt Cnum C];
save -ascii a1.dat out;
plot(tt,C,’b--’);
hold on;
plot (tt,Cnum,’r-’);
legend(’Analytical (Gelhar & Collins (1971)’,’Numerical’);legend boxoff;
xlabel(’V/V_{inj}’,’fontweight’,’bold’,’fontsize’,12); ylabel(’C/C0’,’rotation’,0);
set(gca,’xlim’, [0 3]);
%----------------------------------------------------------
5.2
Example 2: Estimation of dispersion and sorption parameters
Pickens et al. (1981)conducted push-pull tests in a sandy aquifer to understand the sorption of
85 Sr using 131 I as a non-reactive tracer. Tracer breakthrough curves were obtained at several radial
distances (r = 0.36, 0.66 and 2.06) and depths using multi-level sampling devices during the injection
period. During the extraction period samples were collected from the well discharge line. Schroth
et al. (2001) compared the results of a simplified method of analysis with the data of Pickens et al.
(1981) and determined αL = 6.4 cm and Kd = 2.33 ml/g. The input file used for the comparison is
14
PPTEST: User Manual
Observed: 131I
1
Simulated: 131I
0.8
Observed:
85
Simulated:
85
Sr
Sr
C/C0 0.6
0.4
0.2
0
0
0.5
1
1.5
Extracted Volume/Injected Volume
2
2.5
Figure 6: Comparison of numerical results obtained from PPTEST with the observations of Pickens et
al. (2002). A variable grid of 5000 points with fine grids clustered around rc = 0.36, a time step of 0.1
and rmax = 10 were used. Grid clustering was accomplished using a tuning parameter β = 15. 85 Sr
was described using the linear equilibrium sorption model (isorp = 1).
shown below and uses the same values of αL and Kd . Comparisons between the observed data and
the numerical solutions are shown in Figure 6.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
10.0, 5001, 0.1
3
15.0, 0.36
3
2
0
2.587, 2.282, 94.32, 0.0, 405.6, 8.0, 0.38, 0.064, 1.7, 0.052
2, 3
1.0, 1.0
1.0,1.0, 1.0
0.0, 7000.0, 7000.0
0.0, 0.0, 0.0
0,1
2.33
0
The output generated using the above parameters is shown below (out1.dat and out2.dat).
out1.dat:
0.08000
0.18000
0.28000
0.38000
0.48000
0.58000
0.00075
0.00168
0.00262
0.00355
0.00449
0.00542
0.10000E+0001
0.10000E+0001
0.10000E+0001
0.10000E+0001
0.10000E+0001
0.10000E+0001
15
PPTEST: User Manual
0.68000
0.78000
0.88000
0.98000
1.08000
1.18000
1.28000
1.38000
1.48000
1.58000
1.68000
1.78000
1.88000
1.98000
2.08000
2.18000
------79.08000
79.18000
79.28000
79.38000
79.48000
79.58000
79.68000
79.78000
79.88000
79.98000
80.08000
80.18000
80.28000
80.38000
80.48000
80.58000
80.68000
80.78000
80.88000
80.98000
81.08000
81.18000
81.28000
81.38000
81.48000
81.58000
81.68000
81.78000
81.88000
-------
0.00636
0.00729
0.00823
0.00917
0.01010
0.01104
0.01197
0.01291
0.01384
0.01478
0.01571
0.01665
0.01758
0.01852
0.01945
0.02039
------0.73957
0.74051
0.74145
0.74238
0.74332
0.74425
0.74519
0.74612
0.74706
0.74799
0.74893
0.74986
0.75080
0.75173
0.75267
0.75360
0.75454
0.75547
0.75641
0.75734
0.75828
0.75921
0.76015
0.76108
0.76202
0.76296
0.76389
0.76483
0.76576
-------
0.10000E+0001
0.10000E+0001
0.10000E+0001
0.10000E+0001
0.10000E+0001
0.10000E+0001
0.10000E+0001
0.10000E+0001
0.10000E+0001
0.10000E+0001
0.10000E+0001
0.10000E+0001
0.10000E+0001
0.10000E+0001
0.10000E+0001
0.10000E+0001
------0.83199E+0000
0.83091E+0000
0.82983E+0000
0.82875E+0000
0.82766E+0000
0.82657E+0000
0.82548E+0000
0.82438E+0000
0.82328E+0000
0.82217E+0000
0.82106E+0000
0.81995E+0000
0.81884E+0000
0.81772E+0000
0.81660E+0000
0.81548E+0000
0.81435E+0000
0.81322E+0000
0.81208E+0000
0.81095E+0000
0.80981E+0000
0.80866E+0000
0.80752E+0000
0.80637E+0000
0.80521E+0000
0.80406E+0000
0.80290E+0000
0.80174E+0000
0.80057E+0000
------16
PPTEST: User Manual
403.78000
403.88000
403.98000
404.08000
404.18000
404.28000
404.38000
404.48000
404.58000
404.68000
404.78000
404.88000
404.98000
405.08000
405.18000
405.28000
405.38000
405.48000
405.58000
405.68000
3.77625
3.77718
3.77812
3.77905
3.77999
3.78092
3.78186
3.78279
3.78373
3.78466
3.78560
3.78653
3.78747
3.78840
3.78934
3.79027
3.79121
3.79214
3.79308
3.79401
0.95051E-0008
0.94429E-0008
0.93811E-0008
0.93198E-0008
0.92588E-0008
0.91982E-0008
0.91380E-0008
0.90782E-0008
0.90188E-0008
0.89598E-0008
0.89012E-0008
0.88429E-0008
0.87851E-0008
0.87276E-0008
0.86705E-0008
0.86138E-0008
0.85574E-0008
0.85015E-0008
0.84459E-0008
0.83906E-0008
out2.dat:
0.08000
0.18000
0.28000
0.38000
0.48000
0.58000
0.68000
0.78000
0.88000
0.98000
1.08000
1.18000
------70.58000
70.68000
70.78000
70.88000
70.98000
71.08000
71.18000
71.28000
71.38000
71.48000
71.58000
71.68000
71.78000
71.88000
0.00075
0.00168
0.00262
0.00355
0.00449
0.00542
0.00636
0.00729
0.00823
0.00917
0.01010
0.01104
------0.66008
0.66102
0.66195
0.66289
0.66382
0.66476
0.66569
0.66663
0.66756
0.66850
0.66943
0.67037
0.67130
0.67224
0.10000E+0001
0.10000E+0001
0.10000E+0001
0.10000E+0001
0.10000E+0001
0.10000E+0001
0.10000E+0001
0.10000E+0001
0.10000E+0001
0.10000E+0001
0.10000E+0001
0.99999E+0000
------0.74186E+0000
0.74101E+0000
0.74016E+0000
0.73931E+0000
0.73846E+0000
0.73761E+0000
0.73676E+0000
0.73591E+0000
0.73506E+0000
0.73420E+0000
0.73335E+0000
0.73249E+0000
0.73164E+0000
0.73078E+0000
17
PPTEST: User Manual
71.98000
72.08000
72.18000
72.28000
72.38000
72.48000
72.58000
72.68000
72.78000
72.88000
72.98000
73.08000
------404.68000
404.78000
404.88000
404.98000
405.08000
405.18000
405.28000
405.38000
405.48000
405.58000
405.68000
5.3
0.67317
0.67411
0.67504
0.67598
0.67691
0.67785
0.67879
0.67972
0.68066
0.68159
0.68253
0.68346
------3.78466
3.78560
3.78653
3.78747
3.78840
3.78934
3.79027
3.79121
3.79214
3.79308
3.79401
0.72993E+0000
0.72907E+0000
0.72821E+0000
0.72736E+0000
0.72650E+0000
0.72564E+0000
0.72478E+0000
0.72392E+0000
0.72306E+0000
0.72220E+0000
0.72134E+0000
0.72048E+0000
------0.44595E-0003
0.44491E-0003
0.44387E-0003
0.44284E-0003
0.44180E-0003
0.44078E-0003
0.43975E-0003
0.43872E-0003
0.43770E-0003
0.43668E-0003
0.43566E-0003
Example3: Estimation of reaction rates
McGuire, et al. (2002) conducted a series of modified push-pull tests at the former Wurtsmith Air
Force Base in Michigan. Their study was aimed at quantifying the rates of biogeochemical reactions
when recharge water comes in contact with a reduced aquifer. Details of the test conditions are
described in McGuire, et al. (2002). Here we use PPTEST to describe the data using a uniform grid
of 500 points. Sorption is not simulated for the reactive component (sulfate). The input file is shown
below and results are shown in Figure 5.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
10.0, 501, 0.01
1
3
8
1
0.0333, 0.011, 0.6, 0.0333, 3.6,
0.0255,0.067
2, 3
100.0, 20.0
1.0,1.0, 1.0
0.0, 1.0, 2.5
0.0, 0.25,1.5
10.0, 2.0
0,0
0
0.1, 0.33, 0.001, 1.7, 0.0125
18
PPTEST: User Manual
The output (written to the files out1.dat and out2.dat) generated by running PPTEST with the above
input is shown below. The first column is time since injection ended, the second column is the ratio of
volume extracted to the volume injected and the third column is the concentration. If an additional
equation is solved for the sorbed-phase concentration, then a fourth column for S appears in the
output file(s).
out1.dat:
0.00300
0.01300
0.02300
0.03300
0.04300
0.05300
0.06300
0.07300
0.08300
0.09300
0.10300
0.11300
0.12300
0.13300
0.14300
0.15300
0.16300
0.17300
0.18300
0.19300
0.20300
------3.57300
3.58300
3.59300
3.60300
3.61300
3.62300
3.63300
3.64300
0.00152
0.00659
0.01167
0.01674
0.02181
0.02688
0.03195
0.03702
0.04210
0.04717
0.05224
0.05731
0.06238
0.06746
0.07253
0.07760
0.08267
0.08774
0.09281
0.09789
0.10296
------1.81216
1.81723
1.82230
1.82737
1.83245
1.83752
1.84259
1.84766
0.81999E+0002
0.81999E+0002
0.81999E+0002
0.81999E+0002
0.83525E+0002
0.84917E+0002
0.86188E+0002
0.87348E+0002
0.88408E+0002
0.89375E+0002
0.90260E+0002
0.91068E+0002
0.91806E+0002
0.92481E+0002
0.93097E+0002
0.93661E+0002
0.94176E+0002
0.94647E+0002
0.95077E+0002
0.95469E+0002
0.95827E+0002
------0.16269E+0001
0.15941E+0001
0.15619E+0001
0.15304E+0001
0.14994E+0001
0.14691E+0001
0.14393E+0001
0.14101E+0001
out2.dat:
0.00300
0.01300
0.02300
0.03300
0.04300
0.05300
0.06300
0.07300
0.08300
0.09300
0.00152
0.00659
0.01167
0.01674
0.02181
0.02688
0.03195
0.03702
0.04210
0.04717
0.16400E+0002
0.16400E+0002
0.16400E+0002
0.16400E+0002
0.16705E+0002
0.16983E+0002
0.17238E+0002
0.17470E+0002
0.17682E+0002
0.17875E+0002
19
PPTEST: User Manual
0.10300
0.11300
0.12300
0.13300
0.14300
0.15300
0.16300
0.17300
0.18300
0.19300
------3.52300
3.53300
3.54300
3.55300
3.56300
3.57300
3.58300
3.59300
3.60300
3.61300
3.62300
3.63300
3.64300
0.05224
0.05731
0.06238
0.06746
0.07253
0.07760
0.08267
0.08774
0.09281
0.09789
------1.78680
1.79187
1.79694
1.80201
1.80709
1.81216
1.81723
1.82230
1.82737
1.83245
1.83752
1.84259
1.84766
0.18052E+0002
0.18214E+0002
0.18361E+0002
0.18496E+0002
0.18619E+0002
0.18732E+0002
0.18835E+0002
0.18929E+0002
0.19015E+0002
0.19094E+0002
------0.63321E-0001
0.61154E-0001
0.59059E-0001
0.57035E-0001
0.55079E-0001
0.53190E-0001
0.51364E-0001
0.49600E-0001
0.47896E-0001
0.46250E-0001
0.44659E-0001
0.43122E-0001
0.41638E-0001
120
Observed (Cl)
Simulated (Cl)
Observed (SO4)
100
Concentration (mg/L)
Simulated (SO4)
80
n = 3001, αL=1 cm
60
40
n = 501, αL = 0.1 cm
20
0
0
0.5
1
1.5
2
2.5
Time (hours)
3
3.5
4
Figure 7: Comparison of numerical results obtained from PPTEST with the observations of McGuire et
al. (2002). Two grid sizes (with 501 and 3001 grid points) were used to obtain the results. Both grids
used an rmax of 10 and a porosity of 0.33. The diagnostic node was placed at a radial distance of 0.15
(idiag=8 for n=501 and idiag=43 for n=3001). Both simulations used a time step ∆t = 0.01 hours.
20
PPTEST: User Manual
5.4
Example 4: Monod Kinetics / User-Defined Reactions
To illustrate the application of the user-defined reactions module, we consider the following set of coupled differential equations with source terms. Equation (61) has a degradation term based on Monod
kinetics (k is a degradation rate and kS denotes a half-saturation coefficient). The analytical solutions
for this coupled system of equations were obtained using the method of manufactured solutions described in Roache (2009). Maple 13 (Waterloo Maple, 2009) was used to simplify the source terms S1
and S2 and to generate the Fortran code in the subroutine reactions.
¯ ¯ 2
¯ A ¯ ∂ C1
∂C1 A ∂C1
+ S1
(60)
+
= αL ¯¯ ¯¯
∂t
r ∂r
r ∂r2
¯ ¯ 2
µ
¶
¯ A ¯ ∂ C2
C1
∂C2 A ∂C2
¯
¯
−k
C2 + S2
(61)
+
= αL ¯ ¯
∂t
r ∂r
r ∂r2
kS + C1
¯ ¯
¯ ¯
µ
¶
¯A¯
¯ A ¯ 2√
1 −√rt
2
S1 = − 3/2 e
4 r + 2 At + α ¯¯ ¯¯ t + α ¯¯ ¯¯ t r
(62)
r
r
4r
√
"µ
¯ ¯
¯ ¯
rt
¶³
√ ´
¯A¯
¯ A ¯ 2√
e− 2π
2
− rt
¯
¯
¯
¯
√ ¢
¡
S2 = −
8
r
π
+
4
Atπ
+
2
α
tπ
+
α
t
r
k
+
e
S
¯r¯
¯r¯
16π 2 r3/2 kS + e− rt
#
−16 ke−
√
rt 2 3/2
π r
(63)
The above system of equations has the following analytical solutions:
√
C1 = e−t
C2 = e
r
√
−t r
2π
(64)
(65)
The input file for simulating the above system is shown below. The source terms and the Monod term
are included in the subroutine reactions. The last line of the input file sets the flag usrxns = 1
which invokes the user-defined reaction module.
1
2
3
4
5
6
7
8
9
10
11
12
13
2.0, 1001, 0.01
1
3
2
0
2.0,0.1, 1.0,0.0,10.0,0.1, 0.33, 0.01, 1.7,
2, 1
1.0, 1.0
0
0.0
0.0
0, 0
1
0.01
Comparisons shown in Figure 8 indicate that PPTEST has the ability to simulate coupled system of
equations such as (60-61) based on Monod or Michelis-Menten kinetics. The user-defined module can
also be used to simulate transport based approaches such as the mobile-immobile or residence time distribution (RTD) modeling. Additional examples illustrating the application of PPTEST will be included
in future versions of this document (available at the site: http://www.egr.msu.edu/∼phani/pptest).
21
PPTEST: User Manual
Concentration (c1 or c2 )
1.2
1.0
0.8
0.6
c1 (Numerical)
c1 (Analytical)
0.4
c2 (Numerical)
c2 (Analytical)
0.2
0
2
4
6
8
10
12
Time
Figure 8: Comparison of numerical results obtained from PPTEST with the analytical solutions for the
system of equations (58-62)
6
Program Listing
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
program ppt
implicit real *8 (a-h,o-z)
!There are 5 lines similar to the one below in the code. Change the numbers here
!if you want to increase the grid size (mr), the number of components simulated (ns)
!or the number of piecewise-linear segments used to describe the data
! on a plot of log(c_r/c_tr) versus time since injection. Here c_r is the reactive component
!and c_tr is the tracer.
PARAMETER (mr=10001,ncomp=10, ns=10)
!------------------------------------------------------------------------!Written by Mantha Phanikumar, Michigan State Univervity ([email protected])
!DISCLAIMER: This software is distributed in the hope that it will be useful.
!Author makes no warranty that the software will meet your requirements
!and shall not be held liable for any damages resulting from the correct
!or incorrect use of the software. The software and its documentation
!could include technical or other mistakes, inaccuracies or typographical
!errors. Efforts will be made to correct any errors in future versions.
!------------------------------------------------------------------------! use any consistent system of units. no unit conversions in code.
19
20
21
real *8 kd, k, korder, kprime, canaly(10)
integer isorp, nr, i, iadvect, userxn
character *80 filnam
22
23
24
25
26
common/param1/r(mr),dr(mr),c(ncomp,mr),cold(ncomp,mr),z1(mr),z2(mr),aa(mr),bb(mr),cc(mr),&
dd(mr),s(ncomp,mr),sold(ncomp,mr),v(mr), vt(mr), d(mr),dtracer(mr),qinj,qext,&
tinj, trest, text, baquifer, por, rhob, rw,rmax,dt,qinj2,tinj2,tmax,&
kd(ncomp), a(ncomp),b(ncomp), alpha(ncomp), frac(ncomp), drone,grat,tau,rdiag,alphal,&
c0(ncomp), c1(ncomp),kprime, k(ns),korder(ns),tcrit(ns),time,time_since_inj,&
22
PPTEST: User Manual
27
28
29
30
31
32
33
34
35
36
37
38
39
vol_extr_by_vol_inj, Ak, cone, am, q1r, qmr, pi, flag, flag2, q, retard
common/param2/nr,idiag, ichasr,isorp(ncomp),imesh,numsp, nseg,i,isp,itr,iadvect,nt,l1,lm,userxn
common/userdefparam/uk(10)
write (*,*) ’what is the name of the file (input parameters will be read from this file)?’
read (*,*) filnam
open(unit=1,file=filnam)
!------------------------------------! Read mesh-related parameters
!------------------------------------drone=0.0d0; grat=0.0d0; tau=0.0d0; rdiag=0.0d0;
do i=1,ncomp
isorp(i)=0
enddo
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
read (1,*) rmax, nr, dt
read (1,*) imesh
if (imesh.eq.2) read (1,*) drone,grat
if (imesh.eq.3) read (1,*) tau, rdiag
read (1,*) iadvect
read (1,*) idiag
read (1,*) ichasr
!----------------------------------------!Injection, extraction and other parametrs
!-----------------------------------------read (1,*) qinj, qext, tinj, trest, text, baquifer,por,alphal,rhob,rw
if(ichasr.eq.1) then
read (1,*) qinj2, tinj2
else
qinj2=0.0d0
tinj2=0.0d0
endif
!----------------------------------------!Number of species, number of piece-wise linear segments
read (1,*) numsp, nseg
!-----------------------------------------if (numsp.eq.0) then
write(*,*) ’Number of species is zero! STOP.’
STOP
endif
65
66
67
68
69
70
read (1,*) (c0(i), i=1,numsp)
if (nseg.gt.0) then
read (1,*) (korder(i),i=1,nseg)
read (1,*) (tcrit(i), i=1,nseg)
read (1,*) (k(i), i=1,nseg)
endif
71
72
73
74
75
76
77
78
!----------------------------------------!input chaser concentration
if(ichasr.eq.1) then
read (1,*) (c1(i), i=1,numsp)
endif
!-----------------------------------------a=0.0d0; b=0.0d0; alpha=0.0d0; frac=0.0d0;
read (1,*) (isorp(i),i=1,numsp)
23
PPTEST: User Manual
79
80
81
82
83
84
85
do i = 1,numsp
if (isorp(i).eq.1)
if (isorp(i).eq.2)
if (isorp(i).eq.3)
if (isorp(i).eq.4)
if (isorp(i).eq.5)
enddo
86
read (1,*) userxn
87
close(unit=1)
88
89
!isp is the species number (goes from 1 to nsp). It will be updated inside pptest
call pptest
read
read
read
read
read
(1,*)
(1,*)
(1,*)
(1,*)
(1,*)
kd(i)
a(i),b(i)
a(i),b(i)
alpha(i),kd(i)
alpha(i),frac(i),kd(i)
!linear sorption
!freundlich isotherm
!langmuir isotherm
!one-site kinetic sorption
!two-site kinetic sorption
90
91
92
93
94
95
96
97
98
99
100
stop
end
!
subroutine pptest
implicit real *8 (a-h,o-z)
PARAMETER (mr=10001,ncomp=10, ns=10)
integer isorp, nr, i, iadvect, userxn
real *8 k,korder,tcrit, kd, kprime, canaly(10)
character *80 filnam
character *3 cisp
character *20 fname
101
102
103
104
105
106
107
108
109
110
111
112
common/param1/ r(mr),dr(mr),c(ncomp,mr),cold(ncomp,mr),z1(mr),z2(mr), aa(mr),bb(mr),cc(mr),&
dd(mr), s(ncomp,mr),sold(ncomp,mr),v(mr),vt(mr),d(mr),dtracer(mr),qinj,qext,&
tinj, trest, text, baquifer, por, rhob, rw,rmax, dt, qinj2, tinj2,tmax,&
kd(ncomp), a(ncomp),b(ncomp), alpha(ncomp), frac(ncomp), drone,grat,tau, rdiag, alphal,&
c0(ncomp), c1(ncomp),kprime, k(ns),korder(ns), tcrit(ns), time, time_since_inj,&
vol_extr_by_vol_inj, Ak, cone, am, q1r, qmr, pi, flag, flag2, q, retard
common/param2/nr,idiag, ichasr,isorp(ncomp),imesh,numsp,nseg,i,isp, itr,iadvect,nt,l1,lm,userxn
common/userdefparam/uk(10)
!c--------------------------------------------------------!the times tcrit(1) and tcrit(2) where slopes change (on a plot of
![log(c_r/c_tr) vs t]) are counted from the beginning of injection.
pi = 4.0d0*datan(1.0d0)
113
114
!Generate a log file with all input data
open(unit=1, file = ’log.txt’)
115
116
117
118
119
120
121
122
123
124
125
126
127
write (1,*) ’rmax, nr, dt:’, rmax, nr, dt
write (1,*) ’imesh:’, imesh
if (imesh.eq.2) write (1,*) ’drone,grat:’, drone,grat
if (imesh.eq.3) write (1,*) ’tau, rdiag:’, tau, rdiag
write (1,*) ’iadvect:’, iadvect
write (1,*) ’idiag:’, idiag
write (1,*) ’ichasr:’, ichasr
write (1,*) ’qinj, qext, tinj, trest, text, baquifer,por,alphal,rhob,rw:’
write (1,*) qinj, qext, tinj, trest, text, baquifer,por,alphal,rhob,rw
if(ichasr.eq.1) then
write (1,*) ’qinj2, tinj2:’
write (1,*) qinj2, tinj2
endif
24
PPTEST: User Manual
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
write (1,*) ’numsp, nseg:’
write (1,*) numsp, nseg
!-----------------------------------------write(1,*) ’c0 values for all species:’
write(1,*) (c0(i), i=1,numsp)
if (nseg.gt.0) then
write (1,*) ’korder for all piece-wise linear segments:’
write (1,*) (korder(i),i=1,nseg)
write (1,*) ’times (tcrit) at which slopes change for all segments (tcrit(1) = 0):’
write (1,*) (tcrit(i), i=1,nseg)
write(1,*) ’reaction ks for all segments:’
write (1,*) (k(i), i=1,nseg)
endif
!input chaser concentration
if(ichasr.eq.1) then
write(1,*) ’chaser concentration for all species:’
write (1,*) (c1(i), i=1,numsp)
endif
write (1,*) ’Sorption-related parameters:’
write(1,*) ’isorp for all species:’
write (1,*) (isorp(i),i=1,ncomp)
do i=1,numsp
if (isorp(i).eq.1)then
write (1,*) ’isp, isorp(isp), kd(isp): ’, i,isorp(i),kd(i)
endif
if (isorp(i).eq.2) then
write (1,*) ’isp, isorp(isp), a(isp), b(isp):’, i, isorp(i),a(i),b(i)
endif
if (isorp(i).eq.3) then
write (1,*) ’isp, isorp(isp), a(isp), b(isp):’, i, isorp(i),a(i),b(i)
endif
if (isorp(i).eq.4) then
write (1,*) ’isp, isorp(isp), alpha(isp), kd(isp):’,i,isorp(i),alpha(i),kd(i)
endif
if (isorp(i).eq.5) then
write (1,*) ’isp, isorp(isp), alpha(isp), frac(isp), kd(isp):’,i,isorp(i),alpha(i),frac(i),kd(i)
endif
enddo
close(1)
if (rw.eq.0.0) then
write(*,*)
write(*,*) ’error: radius of well casing is zero (rw = 0). stop’
write(*,*)
stop
endif
if (ichasr.eq.0) then
qinj2=0.0d0
tinj2=0.0d0
endif
tinjtotal = tinj + tinj2
nrr=nr-1
iref = 2
if (imesh.eq.1) then
call umesh(rw,nr,rmax,dr,r)
elseif (imesh.eq.2) then
call gmesh(rw,drone,grat,nr,dr,r)
25
PPTEST: User Manual
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
elseif (imesh.eq.3) then
call vmesh(rw, tau,rmax,rdiag,nr,dr,r)
endif
open (unit=3, file=’mesh.txt’)
do i=1,nr
write(3,*) i,dr(i),r(i)
enddo
close(3)
!c---------initialize variables-------------------do isp=1,numsp
do 16 i=2,nr
c(isp,i)=0
cold(isp,i)=0
s(isp,i)=0.0d0
sold(isp,i)=0.0d0
16
continue
enddo
itr=0
time = 0.0d0
ls = 0
tmax = tinjtotal + trest + text
nt= (tmax/dt) + 1
do j = 1,nseg
tcrit(j)=tinjtotal+trest+tcrit(j)
enddo
209
210
211
212
213
214
1
continue
kount=kount+1
itr=itr+1
time = time + dt
time_since_inj = (time-tinjtotal)
vol_extr_by_vol_inj = time_since_inj*qext/(qinj*tinj + qinj2*tinj2)
215
do isp = 1,numsp
216
217
218
219
if
if
if
if
220
221
222
223
224
if (isorp(isp).ge.4) then
retard = 1.0d0
s0=(1.0d0-frac(isp))*kd(isp)*c0(isp) ! c0 is conc. for first injection
s1=(1.0d0-frac(isp))*kd(isp)*c1(isp) ! c1 is conc. for chaser
endif
225
226
227
!c-----------------------------------------------------------!c
specify boundary-conditions:
! Here c is the aq. phase and s is the sorbed phase
228
229
230
231
232
233
if(time.le.tinj) then
c(isp,1)=c0(isp)
cold(isp,1)=c0(isp)
cone = c0(isp)
c(isp,nr)=c(isp,nrr)
cold(isp,nr)=cold(isp,nrr)
!Solve for all species
((isorp(isp).eq.0).or.(isorp(isp).ge.4)) retard = 1.0d0
(isorp(isp).eq.1) retard = 1.0d0 + rhob*kd(isp)/por
(isorp(isp).eq. 4) frac(isp) = 1.0d0
(isp.eq.1) retard = 1.0d0
! neumann conditon
26
PPTEST: User Manual
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
if(isorp(isp).ge.4) then
s(isp,1)=s0
sold(isp,1)=s0
s(isp,nr)=s(isp,nrr)
sold(isp,nr)=sold(isp,nrr)
endif
flag=1.0d0
q=qinj
flag2=1.0d0
elseif ((((time.gt.tinj).and.(time.lt.tinjtotal)).and.(ichasr.eq.1))) then
c(isp,1)=c1(isp)
cold(isp,1)=c1(isp)
cone = c1(isp)
c(isp,nr)=c(isp,nrr)
! neumann conditon
cold(isp,nr)=cold(isp,nrr)
if(isorp(isp).ge.4) then
s(isp,1)=s1
sold(isp,1)=s1
s(isp,nr)=s(isp,nrr)
sold(isp,nr)=sold(isp,nrr)
endif
flag=1.0d0
q=qinj2
flag2=1.0d0
elseif ((time.gt.tinjtotal).and.(time.lt.(trest+tinjtotal))) then
ss=alphal/dr(1)
! using mixed boundary conditions (c(1) = cold(2)*ss/(1+ss))
c(isp,1)=c(isp,2)*(ss/(1.0d0+ss))
!cold(isp,1)=cold(isp,2)*(ss/(1.0d0+ss))
c(isp,nr)=c(isp,nrr)
cold(isp,nr)=cold(isp,nrr)
if(isorp(isp).ge.4) then
s(isp,nr)=s(isp,nrr)
!sold(isp,nr)=sold(isp,nrr)
endif
q=0.0d0 !check
flag = 0.0d0
flag2=0.0d0
elseif ((time.gt.(trest+tinjtotal)).and.(time.le.tmax)) then
c(isp,1)=c(isp,2)
!cold(isp,1)=cold(isp,2)
c(isp,nr)=c(isp,nrr)
! neumann conditon
!cold(isp,nr)=cold(isp,nrr)
if(isorp(isp).ge.4) then
s(isp,1)=s(isp,2)
!sold(isp,1)=sold(isp,2)
s(isp,nr)=s(isp,nrr)
!sold(isp,nr)=sold(isp,nrr)
endif
flag = -1.0d0
q=qext
flag2=1.0d0
endif
286
287
288
!uncomment these lines for example 4 in the paper
!(user-defined reactions with source terms: analytical solution)
!flag = 1.0d0;
27
PPTEST: User Manual
289
290
!flag2=1.0d0;
!q=qinj;
291
Ak = flag*q/(2.0d0*pi*baquifer*por)
292
293
294
295
296
297
298
299
do i=1,nr
if (isorp(isp).eq.2) retard = 1.0d0 + rhob*a(isp)*b(isp)*c(isp,i)**(b(isp)-1.0d0)/por
if (isorp(isp).eq.3) retard = 1.0d0 + (rhob/por)*(a(isp)*b(isp)/(1.0d0+a(isp)*c(isp,i))**2)
vt(i)=Ak/r(i)
v(i)=vt(i)/retard
dtracer(i)=flag2*alphal*dabs(vt(i))
d(i)=flag2*alphal*dabs(v(i))
enddo
300
301
302
!------------------------------------------------!
boundary conditions
!-------------------------------------------------
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
if(time.le.tinj) then
l1=1
cone=c0(isp)
lm=2
am=0.0d0
q1r=c0(isp)
qmr=0.0d0
!injection, dirichlet bc
! Third-type BCs can be used at the well during injection by activating the following line:
!l1=3; cone=ss;cone2=ss; lm=2; am=0.0d0; q1t=c10;qmt=0.0d0;q1r=c20;qmr=0.0d0
elseif ((((time.gt.tinj).and.(time.le.tinjtotal)).and.(ichasr.eq.1))) then
l1=1;
cone=c1(isp);
lm=2;
am=0.0d0;
q1r=c1(isp);
qmr=0.0d0
!injection, chaser, dirichlet
! Third-type BCs:
!l1=3; cone=ss;cone2=ss; lm=2; am=0.0d0; q1=c110;qm=0.0d0;q1r=c220;qmr=0.0d0
elseif ((time.gt.tinjtotal).and.(time.le.(trest+tinjtotal))) then
l1=3;
cone=ss;
lm=2;
am=0.0d0;
q1r=0.0d0;
qmr=0.0d0
!rest:
elseif ((time.gt.(trest+tinjtotal)).and.(time.le.tmax)) then
l1=2;
cone=0.0d0;
lm=1;
am=0.0d0;
q1r=0.0d0;
qmr=0.0d0
endif
336
337
338
339
!------------------------------------------------!
solve for concentrations:
!------------------------------------------------do 882 i=2,nrr
28
PPTEST: User Manual
340
341
342
343
344
345
346
347
348
349
350
if(nseg.gt.0) then
do 8822 j=1,nseg-1
if((time.gt.tcrit(j)).and.(time.le.tcrit(j+1))) then
kprime = (k(j)/retard)*(c(isp,i))**(korder(j) - 1.0d0)
elseif((time.gt.tcrit(nseg))) then
kprime=(k(nseg)/retard)*(c(isp,i))**(korder(nseg) - 1.0d0)
endif
8822 continue
else
kprime = 0.0d0
endif
351
if(isp.eq.1) kprime=0 ! isp=1 is always a tracer
352
353
354
355
356
357
358
359
360
361
362
363
!first-order upwind differencing:
if(iadvect.eq.1) then
call coef1
! elseif (iadvect.eq.2) then
! central differncing - not available in this version
! call coef2
elseif (iadvect.eq.3) then
call coef3
else
write(*,*) ’iadvect value out of range! STOP.’
STOP
endif
364
882 continue
365
366
367
368
call thomas(aa,bb,cc,dd,nr,z1,l1,cone,lm,am,q1r,qmr)
do 883 jj=1,nr
c(isp,jj)=z1(jj)
883 continue
369
370
371
!-------------------------------------------! Depending on the sorption model solve for the sorbed-phase concentration:
!--------------------------------------------
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
if (isorp(isp).ge.4) then
do i = 2,nrr
aa(i)=0.0d0
bb(i)=1.0d0 + (1.0d0/dt)
cc(i)=0.0d0
dd(i)= (1.0d0/dt)*s(isp,i) + alpha(isp)*(1.0d0-frac(isp))*kd(isp)*c(isp,i)
enddo
if(time.le.tinj) then
l1=1; sone=s0; lm=2; am=0.0d0; q1=0.0d0; qm=0.0d0
elseif ((((time.gt.tinj).and.(time.le.tinjtotal)).and.(ichasr.eq.1))) then
l1=1; sone=s1; lm=2; am=0.0d0 ; q1=0.0d0; qm=0.0d0
elseif ((time.gt.tinjtotal).and.(time.le.(trest+tinjtotal))) then
l1=2; sone=0.0d0;lm=2; am=0.0d0 ; q1=0.0d0; qm=0.0d0
elseif ((time.gt.(trest+tinjtotal)).and.(time.le.tmax)) then
l1=2; sone=0.0d0; lm=1; am=0.0d0 ; q1=0.0d0; qm=0.0d0
endif
call thomas (aa,bb,cc,dd,nr,z2,l1,sone,lm,am,q1,qm)
do jj=1,nr
29
PPTEST: User Manual
390
391
392
s(isp,jj)=z2(jj)
enddo
endif
393
394
395
396
397
398
!==================================================
!
writing the output file
!==================================================
!following 2 lines useful to generate the analytical solution in example 4
!canaly(1) = dexp(-dsqrt(r(idiag))*time)
!canaly(2) = dexp(-dsqrt(r(idiag))*time/pi/0.2D1)
399
400
401
402
! The following logic creates as many output files as there are number of species
!(one file for each species):
write(cisp, ’(i3)’) isp
fname = ’out’//trim(adjustl(cisp))//’.dat’
403
404
405
406
407
408
409
410
411
open(unit=3,file=fname, access=’append’)
if (time_since_inj.ge.0.0d0) then
if (isorp(isp).ge.4) then
write(3,11) time_since_inj, vol_extr_by_vol_inj, c(isp,idiag),
else
write(3,12) time_since_inj, vol_extr_by_vol_inj, c(isp,idiag)
endif
11
format(f12.5,1x,f12.5, 2x, e15.5e4,2x,e15.5e4)
12
format(f12.5,1x,f12.5, 2x, e15.5e4)
412
413
414
415
416
endif
close(unit=3)
do 289 i=1,nr
cold(isp,i)=c(isp,i)
289 continue
417
418
419
420
421
if (isorp(isp).ge.4) then
do 290 i=1,nr
sold(isp,i)=s(isp,i)
290 continue
endif
422
enddo ! this is where the isp loop ends
423
424
425
426
427
428
429
if (itr.ge.nt) then
ls = 1
itr=0
else
endif
if(ls.eq. 1) goto 2992
goto 1
430
431
432
433
434
435
436
437
2992 stop
end
!------------------------------------------------subroutine thomas(e,f,g,r,nr,phi,lbc1,valbc1,lbcn,valbcn,q1,qm)
implicit real *8 (a-h,o-z)
dimension e(nr),f(nr),g(nr),r(nr),a(nr),b(nr),phi(nr)
if(lbc1.eq.1) a(1)=0.0d0
if(lbc1.eq.1) b(1)=valbc1
s(isp,idiag)
30
PPTEST: User Manual
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
if(lbc1.eq.2) a(1)=1.0d0
if(lbc1.eq.2) b(1)=-valbc1
if(lbc1.eq.3) a(1)=valbc1/(valbc1-1.0d0)
if(lbc1.eq.3) b(1)=q1/(1.0d0-valbc1)
nrr=nr-1
do 1 i=2,nrr
dd=1.0d0/(f(i)-g(i)*a(i-1))
a(i)=e(i)*dd
1 b(i)=(r(i)+g(i)*b(i-1))*dd
if(lbcn.eq.1) phi(nr)=valbcn
if(lbcn.eq.2) phi(nr)=(b(nrr)+valbcn)/(1.0d0-a(nrr))
if(lbcn.eq.3) phi(nr)=(b(mm)+qm/valbcn)/((1.0d0+valbcn)/valbcn-a(nrr))
do ii=1,nrr
m=nr-ii
phi(m)=a(m)*phi(m+1)+b(m)
enddo
return
end
!------------------------------------------------subroutine coef1
!first-order upwind differencing:
implicit real *8 (a-h,o-z)
PARAMETER (mr=10001,ncomp=10, ns=10)
real *8 k1,k2, kd, kprime, kprime2
integer isorp, nr, i, iadvect, userxn
463
464
465
466
467
468
469
470
common/param1/ r(mr),dr(mr),c(ncomp,mr),cold(ncomp,mr),z1(mr),z2(mr),aa(mr),bb(mr),cc(mr),&
dd(mr),s(ncomp,mr),sold(ncomp,mr),v(mr), vt(mr), d(mr),dtracer(mr), qinj, qext,&
tinj, trest, text, baquifer, por, rhob, rw,rmax,dt,qinj2,tinj2,tmax,&
kd(ncomp), a(ncomp),b(ncomp), alpha(ncomp), frac(ncomp), drone,grat,tau,rdiag,alphal,&
c0(ncomp), c1(ncomp),kprime, k(ns),korder(ns),tcrit(ns),time,time_since_inj,&
vol_extr_by_vol_inj, Ak, cone, am, q1r, qmr, pi, flag, flag2, q, retard
common/param2/nr,idiag, ichasr,isorp(ncomp),imesh,numsp, nseg,i,isp,itr,iadvect,nt,l1,lm,userxn
common/userdefparam/uk(10)
471
472
473
474
475
if (userxn.eq.1) then
call reactions(rxn)
else
rxn = 0.0d0
endif
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
if (v(i).ge.0.0d0) then
s1=0.0d0
s2=1.0d0
s3=-1.0d0
del = dr(i-1)
vv= v(i)
vvt=vt(i)
else
del = dr(i)
s1=1.0d0
s2=-1.0d0
s3=0.0d0
vv= v(i)
vvt=vt(i)
endif
31
PPTEST: User Manual
491
492
drs=dr(i)+dr(i-1)
drp=dr(i)*dr(i-1)
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
!------------------------------------------------!
simultaneous equations
!------------------------------------------------if (isp.eq.1) then
aa(i)=-vvt*s1/del + 2.0d0*dtracer(i)/(drs*dr(i))
bb(i)=1.0d0/dt + vvt*s2/del + 2.0d0*dtracer(i)/drp
cc(i)=-vvt*s3/del + 2.0d0*dtracer(i)/(drs*dr(i-1))
else
aa(i)=-vv*s1/del + 2.0d0*d(i)/(drs*dr(i))
bb(i)=1.0d0/dt + vv*s2/del + 2.0d0*d(i)/drp + kprime
cc(i)=-vv*s3/del + 2.0d0*d(i)/(drs*dr(i-1))
endif
dd(i)=c(isp,i)/dt + rxn ! This is where the user-defined reactions go ...
!(the coefficient D of the Thomas Algorithm)
if (isorp(isp).ge.4) dd(i)=dd(i) + (rhob/por)*alpha(isp)*s(isp,i)
if (isorp(isp).ge.4) bb(i)=bb(i) + (rhob/por)*alpha(isp)*((1.0d0-frac(isp))*kd(isp))
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
return
end
!------------------------------------------------subroutine coef3
implicit real *8 (a-h,o-z)
PARAMETER (mr=10001,ncomp=10, ns=10)
real *8 k1,k2, kd, kprime, kprime2,rxn, uk
integer isorp, nr, i, iadvect, userxn
common/param1/ r(mr),dr(mr),c(ncomp,mr),cold(ncomp,mr),z1(mr),z2(mr),aa(mr),bb(mr),cc(mr),&
dd(mr),s(ncomp,mr),sold(ncomp,mr),v(mr), vt(mr), d(mr),dtracer(mr), qinj, qext,&
tinj, trest, text, baquifer, por, rhob, rw,rmax,dt,qinj2,tinj2,tmax,&
kd(ncomp), a(ncomp),b(ncomp), alpha(ncomp), frac(ncomp), drone,grat,tau,rdiag,alphal,&
c0(ncomp), c1(ncomp),kprime, k(ns),korder(ns),tcrit(ns),time,time_since_inj,&
vol_extr_by_vol_inj, Ak, cone, am, q1r, qmr, pi, flag, flag2, q, retard
common/param2/nr,idiag, ichasr,isorp(ncomp),imesh,numsp, nseg,i,isp,itr,iadvect,nt,l1,lm,userxn
common/userdefparam/uk(10)
525
526
527
528
529
if (userxn.eq.1) then
call reactions(rxn)
else
rxn = 0.0d0
endif
530
531
532
533
534
535
536
537
538
539
540
541
542
vr=0.5d0*(v(i)+v(i+1))
vl=0.5d0*(v(i)+v(i-1))
vrt=0.5d0*(vt(i)+vt(i+1))
vlt=0.5d0*(vt(i)+vt(i-1))
if ((vr.gt.0.0d0).and.(vl.gt.0.0d0)) then
s1=0.0d0
s2=1.0d0
s3=0.0d0
s4=-1.0d0
del = dr(i-1)
!0.5d0*(dr(i-1)+dr(i))
vv= vr
vvt= vrt
elseif ((vr.lt.0.0d0).and.(vl.lt.0.0d0)) then
32
PPTEST: User Manual
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
del = dr(i)
s1=1.0d0
s2=0.0d0
s3=-1.0d0
s4=0.0d0
vv= vl
vvt= vlt
else
del = dr(i)
s1=1.0d0
s2=0.0d0
s3=-1.0d0
s4=0.0d0
vv= vl
vvt= vlt
endif
!0.5d0*(dr(i+1)+dr(i))
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
drs=dr(i)+dr(i-1)
drp=dr(i)*dr(i-1)
!-------------------------------------------! Setup the simultaneous equations
!-------------------------------------------if (isp.eq.1) then
aa(i)=-vvt*s1/del + 2.0d0*dtracer(i)/(drs*dr(i))
bb(i)=1.0d0/dt + vvt*s2/del + vvt*s3/del + 2.0d0*dtracer(i)/drp
cc(i)=-vvt*s4/del + 2.0d0*dtracer(i)/(drs*dr(i-1))
else
aa(i)=-vv*s1/del + 2.0d0*d(i)/(drs*dr(i))
bb(i)=1.0d0/dt + vv*s2/del + vv*s3/del + 2.0d0*d(i)/drp + kprime
cc(i)=-vv*s4/del + 2.0d0*d(i)/(drs*dr(i-1))
endif
dd(i)=c(isp,i)/dt + rxn ! This is where the user-defined reactions go
574
575
if (isorp(isp).ge.4) dd(i)=dd(i) + (rhob/por)*alpha(isp)*s(isp,i)
if (isorp(isp).ge.4) bb(i)=bb(i) + (rhob/por)*alpha(isp)*((1.0d0-frac(isp))*kd(isp))
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
return
end
!------------------------------------------------!
uniform mesh
!------------------------------------------------subroutine umesh(rw,n,ymax,dy,y)
implicit real *8 (a-h,o-z)
PARAMETER (mr=10001,ncomp=10, ns=10)
dimension dy(mr),y(mr)
del=ymax/float(n-1)
y(1)=rw
dy(1)=del
do 1 i=2,n
dy(i)=del
y(i)=y(i-1)+del
1 continue
return
end
!------------------------------------------------!
non-uniform mesh : geometrically varying
!0.5d0*(dr(i+1)+dr(i))
33
PPTEST: User Manual
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
!------------------------------------------------subroutine gmesh(rw,drone,grat,nr,dr,r)
implicit real *8 (a-h,o-z)
PARAMETER (mr=10001,ncomp=10, ns=10)
dimension dr(mr),r(mr)
r(1)=rw
nrr=nr-1
dr(1)=drone
rinf=r(1)+drone*(grat**nrr-1.0d0)/(grat-1.0d0)
do 1 j=2,nr
dr(j)=grat*dr(j-1)
1 continue
do 3 j=2,nr
3 r(j)=r(j-1)+dr(j-1)
return
end
!------------------------------------------------subroutine vmesh(rw,tau,rmax,rc,nr,dr,r)
!generates a variable mesh according to equation (16) in the paper
implicit real *8 (a-h,o-z)
PARAMETER (mr=10001,ncomp=10, ns=10)
dimension drr(mr),rr(mr), dr(mr), r(mr)
rmax=rmax-rw
rc=rc-rw
del=1.0d0/dfloat(nr-1)
rr(1)=0;
anr = 1.0d0 + (dexp(tau)-1.0d0)*(rc/rmax)
adr = 1.0d0 + (exp(-tau)-1.0d0)*(rc/rmax)
b = (1.0d0/(2.0d0*tau))*dlog(anr/adr)
do i=2,nr
rr(i)=rr(i-1)+del
enddo
r(1)=0.0d0
do i=2,nr
anum = dsinh(tau*(rr(i)-b))
aden = dsinh(tau*b)
r(i)=1.0 + anum/aden
r(i)=rc*r(i)
enddo
do i=1,nr
r(i)=r(i)+rw
enddo
do i=2,nr
dr(i-1)=r(i)-r(i-1)
enddo
return
end
!------------------------------------------------subroutine reactions(rxn)
! User-defined reactions can be specified using this module.
implicit real *8 (a-h,o-z)
PARAMETER (mr=10001,ncomp=10, ns=10)
integer isorp, nr, i, iadvect, userxn
real *8 k,korder,tcrit, kd, kprime, rxn, uk
character *80 filnam
character *3 cisp
34
PPTEST: User Manual
652
character
*20 fname
653
654
655
656
657
658
659
660
common/param1/ r(mr),dr(mr),c(ncomp,mr),cold(ncomp,mr),z1(mr),z2(mr),aa(mr),bb(mr),cc(mr),&
dd(mr),s(ncomp,mr),sold(ncomp,mr),v(mr), vt(mr), d(mr),dtracer(mr), qinj, qext,&
tinj, trest, text, baquifer, por, rhob, rw,rmax,dt,qinj2,tinj2,tmax,&
kd(ncomp), a(ncomp),b(ncomp), alpha(ncomp), frac(ncomp), drone,grat,tau,rdiag,alphal,&
c0(ncomp), c1(ncomp),kprime, k(ns),korder(ns),tcrit(ns),time,time_since_inj,&
vol_extr_by_vol_inj, Ak, cone, am, q1r, qmr, pi, flag, flag2, q, retard
common/param2/nr,idiag, ichasr,isorp(ncomp),imesh,numsp, nseg,i,isp,itr,iadvect,nt,l1,lm,userxn
common/userdefparam/uk(10)
661
real *8 ks, kk
662
663
664
rxn = 0.0d0
ks = 0.1d0
kk = 0.2d0
665
666
uk(1)=kk;
uk(2)=ks;
667
668
rr=r(i)
t=time
669
670
671
!following code generated using MAPLE version 13:
if(isp.eq.1) rxn = -dexp(-dsqrt(rr)*t)*rr**(-0.3D1/0.2D1)*(0.4D1*rr**2 &
+ 0.2D1*Ak*t + alphal*dabs(Ak/rr)*t + alphal*dabs(Ak/rr)*t**2*dsqrt(rr))/0.4D1
672
if(isp.eq.2)
673
674
675
676
677
678
679
680
if(isp.eq.2) rxn = rxn -dexp(-dsqrt(rr)*t/pi/0.2D1)*rr**(-0.3D1/0.2D1)* &
(0.8D1*rr**2*pi*ks+0.8D1*rr**2*pi*dexp(-dsqrt(rr)*t) + &
0.4D1*Ak*t*pi*ks + 0.4D1*Ak*t*pi*dexp(-dsqrt(rr)*t) &
+ 0.2D1*alphal*dabs(Ak/rr)*t*pi*ks + 0.2D1*alphal*dabs(Ak/rr) &
*t*pi*dexp(-dsqrt(rr)*t) + alphal*dabs(Ak/rr)*t**2* &
dsqrt(rr)*ks + alphal*dabs(Ak/rr)*t**2*dsqrt(rr)*dexp(-dsqrt( &
rr)*t) - 0.16D2*kk*dexp(-dsqrt(rr)*t)*pi**2*rr**(0.3D1 /&
0.2D1))/pi**2/(ks + dexp(-dsqrt(rr)*t))/0.16D2
681
682
683
684
!Override the default boundary conditions here if desired:
! this is an analytical solution with function values specified on both ends (Dirichlet BCs)
! so we want to override the boundary conditions specified in the code
! if this is not needed, comment the following lines
685
686
687
688
689
690
conc1rw = dexp(-dsqrt(rw)*time);
conc2rw = dexp(-dsqrt(rw)*time/pi/0.2D1)
c0(1)=conc1rw
c0(2)=conc2rw
conc1nr = dexp(-dsqrt(r(nr))*time);
conc2nr = dexp(-dsqrt(r(nr))*time/pi/0.2D1)
691
692
693
694
695
if(isp.eq.1) then
concnr=conc1nr
c(isp,nr)=conc1nr
c(isp,1)=c0(isp)
cold(isp,1)=c0(isp)
rxn = -kk*(c(1,i)/(ks + c(1,i)))*c(2,i) !Monod reaction term
35
PPTEST: User Manual
696
697
698
699
700
701
702
703
704
cold(isp,nr)=conc1nr
elseif (isp.eq.2) then
concnr=conc2nr
c(isp,nr)=conc2nr
c(isp,1)=c0(isp)
cold(isp,1)=c0(isp)
cold(isp,nr)=conc2nr
else
endif
705
706
707
708
l1=1
cone=c0(isp)
lm=1
am=c(isp,nr)
709
710
return
end
7
Nomenclature
a
B
b
C0
C20
CT
Cb
C
E, F, G
f
H
Kd
m
n
nr
N
p, q
Q
r
r0
rc
rw
rmax
R
R, RF , RL
S
S1 · · · S4
S0
S20
Coefficient in the Freundlich isotherm, equation (5)
Parameter for mesh generation, rq. (35-36)
Aquifer thickness
Concentration (eq. 2) near the well casing during injection (boundary condition)
Concentration (eq. 2) near the well casing during chaser injection (boundary condition)
Concentration of tracer
Background concentration in the aquifer before the ”push” phase
Concentration of the reactive component
Coefficients of the tridiagonal matrix, equation (46)
Fraction of sites in equilibrium for the kinetic and two-site sorption models
Heaviside step function. H(t − a) = 1 if t ≥ a and zero otherwise
Distribution Coefficient
Coefficient in the Freundlich isotherm, equation (5)
Order of the reaction, equation (2)
Number of grid points
Total number of reaction rates in equation (2)
Coefficients in the Langmuir isotherm, equation (6)
Pumping rate
Radial coordinate
A uniform grid coordinate used in equation (36) r0 = 1/nr
Radial coordinate where details need to be resolved using fine grids
Radius of the well casing
Size of the computational domain (distance between well casing and the outer domain)
Right hand side of the linear system of equations, equation (46)
Retardation coefficients for the linear equilibrium, Freundlich and Langmuir isotherms
Sorbed-phase concentration
Switches (variables that can take only integer values -1, 0, +1) in equation (44)
Sorbed-phase concentration near the well casing during injection (boundary condition)
Sorbed-phase concentration (boundary condition) during chaser injection
36
PPTEST: User Manual
t
t∗i
tinj
tchaser
trest
text
v
v R , vL
α
αL
γ
∆rj
∆t
λ
ρb
Time
Times (since injection) when reaction rates (and possibly oders) change
Duration of the injection period for the test solution
Duration of the injection period for the chaser solution
Duration of the rest period
Duration of the extraction period
Pore water velocity
Velocity at the right and left faces of a control volume around node j . See figure 2
First-order kinetic rate parameter, equations (7) and (8)
Longitudinal dispersivity
Mesh tuning parameter. As γ increases, fine grids are placed around rc
Step size at the spatial / grid location denoted by j
Time step
Mesh expansion ratio for the geometric grid (ratio of the geometric progression) eq. (34)
Bulk density
Subscripts & Superscripts
`
L, R
j
8
Time-level. ` + 1 and ` denote the new and old time-levels respectively
Denote left and right relative to the grid node located at j
Index denoting the spatial location
References
Haggerty, R., M.H. Schroth, J.D. Istok, Simplified method of ”Push-Pull” test data analysis for
determining in situ reaction rate coefficients. Ground Water, 36(2), 314-324 (1998)
Intelr Whitepaper, Quick-Reference Guide to Optimization with Intelr Compilers version 11
For IA-32 processors, Intelr 64 processors and IA-64 processors, Intel Corporation, Santa Clara, CA
(2008)
McGuire, J. T., D.T. Long, M.J. Klug, S.K. Haack, D.W. Hyndman, Evaluating the behavior of
oxygen, nitrate, and sulfate during recharge and quantifying reduction rates in a contaminated aquifer,
Environmental Science and Technology, 36(12), 2693-2700 (2002)
Pickens, J. F., R.E. Jackson, K.J. Inch, Measurement of distribution coefficients using a radial
injection dual-tracer test, Water Resources Research, 17(3), 529-544 (1981)
Phanikumar, M.S. and R.L. Mahajan, Numerical analysis of unsteady thermosolutal convection
over a horizontal, isothermal circular cylinder, Numerical Heat Transfer - Part A: Applications, Vol.
33, pp. 673-700 (1998)
Phanikumar, M.S. and J.T. McGuire, A multi-species reactive transport model to estimate biogeochemical rates based on single-well push-pull test data, Computers & Geosciences, Vol. 36, No. 8,
pp. 997-1004 (2010)
Roache, P.J. Computational Fluid Dynamics, Hermosa Publishers, Albuquerque, NM (1998)
Roache, P.J. Fundamentals of Verification and Validation, Hermosa Publishers, Albuquerque, NM
(2009)
Schroth, M. H., Istok, J. D., Haggerty, R. In situ evaluation of solute retardation using single-well
push-pull tests, Advances in Water Resources, 24, 105-117 (2001)
Tannehill, J. C., D.A. Anderson, R.H. Pletcher, Computational Fluid Mechanics and Heat Transfer,
337 pp., Taylor & Francis, Washington D.C. (1997).
37
PPTEST: User Manual
Van Genuchten, M. Th., R.J. Wagenet, Two-Site/two-region models for pesticide transport and
degradation: theoretical development and analytical solutions. Soil Science Society of America Journal, 53(5), 1303-1310 (1989).
Waterloo Maple Inc., Maple 13, User Manual, pp. 524 (2009)
If you have questions/comments or if you would like to request new features or report bugs, please
e-mail: [email protected]
38
Was this manual useful for you? yes no
Thank you for your participation!

* Your assessment is very important for improving the work of artificial intelligence, which forms the content of this project

Download PDF

advertisement