This module is provided to assist in the generation and solution of preconditioner
matrices for problems arising from reaction-transport systems. More specifically, the
routines pjac_rbdpre, and psol_rbdpre are intended as auxiliary routines for
the user-supplied routines pjac
and psol
called by daskr when the Krylov method
is selected.
These routines are meant for a DAE system obtained from a system of reaction-transport PDEs, in which some of the PDE variables obey differential equations, and the rest obey algebraic equations [2, section 4]. It is assumed that the right-hand sides of all the equations have the form of a sum of a reaction term and a transport term , that the transport term is discretized by finite differences, and that in the spatial discretization the PDE variables at each spatial point are kept together. Thus, the DAE system function, in terms of a dependent variable vector , has the form:
where is the identity matrix with zeros in the positions corresponding to the algebraic components and ones in those for the differential components, denotes the reaction terms (spatial coupling absent), and denotes the spatial transport terms.
As shown in Brown et al. [2], two possible preconditioners for such a system are:
The routines given here can be used to compute the reaction-based factor . More
precisely, they provide an approximation to . The matrix is
block-diagonal, with each block corresponding to one spatial point. In , we
compute each block by difference quotient approximations, by way of calls to a
user-supplied subroutine rblock
, that evaluates the reaction terms at a single spatial
point. has one such block for each spatial point in the mesh. For a more
economical approximation, see daskr_rbgpre which uses block-grouping in .
The routines given here are specialized to the case of a 2D problem on a rectangular mesh in the x-y plane. However, they can be easily modified for a different problem geometry. It is also assumed that the PDE variables are ordered so that the differential variables appear first, followed by the algebraic variables.
Warning
This module uses module variables to share the mesh and block-group parameters among routines and is, thus, thread unsafe.
To use these routines in conjunction with daskr, the following steps are needed:
Set info(12) = 1
to select the Krylov iterative method and info(15) = 1
to indicate
that a pjac
routine exists.
Call setup_rbdpre to set mesh-related inputs.
Include a pjac
routine, as prescribed by the daskr instructions, which calls
pjac_rbdpre, and does any other Jacobian-related preprocessing needed for
preconditioning. The latter routine takes as argument r0
the current value of the
reaction vector . This can be done, for example, by taking r0
to be rpar
,
and loading rpar
with the vector in the last call to the res
routine; in
that case, the calling program must declare rpar
to have length at least neq
.
Alternatively, insert a call to rblock
within the loop over mesh points inside
pjac_rbdpre.
Include a psol
routine, as prescribed by the daskr instructions, which calls
psol_rbdpre for the solution of systems , and does any other linear
system solving required by the preconditioner.
The program example_web demonstrates the use of this preconditioner.
This routine sets the mesh parameters needed to use the routines pjac_rbdpre and
psol_rbdpre, assuming a 2D rectangular problem. Additionally, it loads the lengths
lrwp
and liwp
in array iwork
.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
integer, | intent(in) | :: | mx |
Number of mesh points in x-direction. |
||
integer, | intent(in) | :: | my |
Number of mesh points in y-direction. |
||
integer, | intent(in) | :: | ns |
Number of PDE variables, the size of each block in the block-diagonal preconditioner matrix . |
||
integer, | intent(in) | :: | nsd |
Number of differential PDE variables. In the DAE system, the first |
||
integer, | intent(in) | :: | lid |
Flag indicating whether to load the ID array in |
||
integer, | intent(inout) | :: | iwork(*) |
Integer work array. |
This routine generates and preprocesses a block-diagonal preconditioner matrix, based
on the part of the Jacobian corresponding to the reaction terms of the problem.
It generates a matrix of the form . It calls dgefa
from LINPACK to do the LU decomposition of each diagonal block. The computation of the
diagonal blocks uses the mesh information in the module variables. One block per
spatial point is computed. The Jacobian elements are generated by difference quotients.
This routine calls a user routine rblock
to compute the block (jx,jy)
of .
Type | Intent | Optional | Attributes | Name | ||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
real(kind=rk), | intent(in) | :: | t |
Current independent variable. |
||||||||||||||||||||||||||||||||||||||||||||
real(kind=rk), | intent(inout) | :: | u(*) |
Current dependent variables. |
||||||||||||||||||||||||||||||||||||||||||||
real(kind=rk), | intent(in) | :: | r0(*) |
Current value of the vector . |
||||||||||||||||||||||||||||||||||||||||||||
private subroutine rblock(t, jx, jy, uxy, rxy)User routine that computes a single block of . Arguments
|
||||||||||||||||||||||||||||||||||||||||||||||||
real(kind=rk), | intent(inout) | :: | r1(*) |
Real work space available to this subroutine. |
||||||||||||||||||||||||||||||||||||||||||||
real(kind=rk), | intent(in) | :: | rewt(*) |
Reciprocal error weights. |
||||||||||||||||||||||||||||||||||||||||||||
real(kind=rk), | intent(in) | :: | cj |
Scalar used in forming the system Jacobian. |
||||||||||||||||||||||||||||||||||||||||||||
real(kind=rk), | intent(out) | :: | bd(*) |
LU factors of the diagonal blocks. |
||||||||||||||||||||||||||||||||||||||||||||
integer, | intent(out) | :: | ipbd(*) |
Pivots for the LU factorizations. |
||||||||||||||||||||||||||||||||||||||||||||
integer, | intent(inout) | :: | ierr |
Error flag.
|
This routine solves a linear system , using the LU factors of the diagonal blocks computed in pjac_rbdpre and mesh parameters passed as module variables. The solution is carried out by dgesl from LINPACK.
Type | Intent | Optional | Attributes | Name | ||
---|---|---|---|---|---|---|
real(kind=rk), | intent(inout) | :: | b(*) |
Right-hand side vector on entry and solution vector on return. |
||
real(kind=rk), | intent(in) | :: | bd(*) |
LU factors of the diagonal blocks. |
||
integer, | intent(in) | :: | ipbd(*) |
Pivots for the LU factorizations. |