Developers can add completely new smoother and/or solver classes derived from the base objects in the library (see Remark 2 in Section 6.2), without recompiling the library itself.
To do so, it is necessary first to select the base type to be extended. In our experience, it is quite likely that the new application needs only the definition of a ``solver'' object, which is almost always acting only on the local part of the distributed matrix. The parallel actions required to connect the various solver objects are most often already provided by the block-Jacobi or the additive Schwarz smoothers. To define a new solver, the developer will then have to define its components and methods, perhaps taking one of the predefined solvers as a starting point, if possible.
Once the new smoother/solver class has been developed, to use it in the context of the multilevel preconditioners it is necessary to:
set
routine as in the
following:
call p%set(smoother,info [,ilev,ilmax,pos])
call p%set(solver,info [,ilev,ilmax,pos])
It is possible to define new values for the keyword WHAT
in the
set
routine; if the library code does not recognize a keyword,
it passes it down the composition hierarchy (levels containing
smoothers containing in turn solvers), so that it can be eventually caught by
the new solver.
An example is provided in the source code distribution under the
folder tests/newslv
. In this example we are implementing a new
incomplete factorization variant (which is simply the ILU(0)
factorization under a new name). Because of the specifics of this case, it is
possible to reuse the basic structure of the ILU solver, with its
L/D/U components and the methods needed to apply the solver; only a
few methods, such as the description and most importantly the build,
need to be ovverridden (rewritten).
The interfaces for the calls shown above are defined using
smoother |
class(mld_x_base_smoother_type) |
The user-defined new smoother to be employed in the preconditioner. | |
solver |
class(mld_x_base_solver_type) |
The user-defined new solver to be employed in the preconditioner. |
tests/newslv
code we define a new object of type mld_d_tlu_solver_type
, and
we pass it as follows:
! sparse matrix and preconditioner type(psb_dspmat_type) :: a type(mld_dprec_type) :: prec type(mld_d_tlu_solver_type) :: tlusv ...... ! ! prepare the preconditioner: an ML with defaults, but with TLU solver at ! intermediate levels. All other parameters are at default values. ! call prec%init('ML', info) call prec%hierarchy_build(a,desc_a,info) nlv = prec%get_nlevs() call prec%set(tlusv, info,ilev=1,ilmax=max(1,nlv-1)) call prec%smoothers_build(a,desc_a,info)