The Open FUSION Toolkit 1.0.0-8905cc5
Modeling tools for plasma and fusion research and engineering
Loading...
Searching...
No Matches
API Example 2: Multi-Grid Preconditioners

This program expands on doc_ex1 by solving the Poisson's equation, but replaces diagonal scaling with a more efficient Multi-Grid preconditioner to accelerate the solver. It also introduces how to handle cases where Native ane PETSc implementations will differ. Although, PETSc matrices will work with almost all Native solvers, they do not currently work with the Jacobi smoothers used here. Additionally, it is desirable to use the PETSc solver implementations for any complicated nested operation, such as Multi-Grid preconditioning. In order to make the code portable preprocessor gaurds are added to select the appropriate implementation depending on the existence of PETSc during build.

Code Walk Through

There are many similarities between this example and the previous example. As a result only the differences and elements relating directly to MG will be discussed here. Please refer to ex1 for the basic program outline and I/O.

Module Includes

In order to construct MG preconditioners we must include the MG constructor create_mlpre.

PROGRAM example2
!---Runtime
!---Grid
!---Linear Algebra
!---Lagrange FE space
IMPLICIT NONE
Base FEM class and functions for construction of FE linkage.
Definition fem_base.F90:20
Classes and infrastructure for composite FE representations.
Definition fem_composite.F90:14
Multigrid initialization using nested meshes.
Definition multigrid_build.F90:14
subroutine multigrid_construct(mg_mesh, grnd_pt)
Construct multi-level mesh.
Definition multigrid_build.F90:440
Multi-Level grid implementation using nested meshes.
Definition multigrid.F90:14
Base environment functions and aliases for Open FUSION Toolkit.
Definition oft_base.F90:23
HDF5 file manipulation for output and restart data.
Definition oft_io.F90:19
Abstract vector and matrix interfaces.
Definition lin_alg_base.F90:20
Base Lagrange FE class and basis evaluation.
Definition lagrange_basis.F90:22
subroutine oft_lag_setup(mg_mesh, order, ml_lag_obj, ml_blag_obj, ml_vlag_obj, minlev)
Construct lagrange scalar FE on each mesh level.
Definition lagrange_basis.F90:317
Lagrange FE operator definitions.
Definition lagrange_operators.F90:25
real(r8), dimension(fem_max_levels) df_lop
Definition lagrange_operators.F90:156
subroutine lag_base_push(self, afine, acors)
Transfer a MPI level Lagrange scalar field to the base level.
Definition lagrange_operators.F90:1975
subroutine lag_base_pop(self, acors, afine)
Transfer a base level Lagrange scalar field to the next MPI level.
Definition lagrange_operators.F90:1953
subroutine oft_lag_getlop(fe_rep, mat, bc)
Construct laplacian matrix for Lagrange scalar representation.
Definition lagrange_operators.F90:884
integer(i4), dimension(fem_max_levels) nu_lop
Definition lagrange_operators.F90:155
subroutine oft_lag_getmop(fe_rep, mat, bc)
Construct mass matrix for Lagrange scalar representation.
Definition lagrange_operators.F90:770
subroutine lag_mloptions()
Read-in options for the basic Lagrange ML preconditioners.
Definition lagrange_operators.F90:168
subroutine lag_setup_interp(ml_lag_rep, ml_vlag_rep)
Construct interpolation matrices on each MG level.
Definition lagrange_operators.F90:1503
Abstract solver interfaces and select native implementations.
Definition solver_base.F90:32
Matrix and vector management routines.
Definition solver_utils.F90:14
subroutine create_mlpre(pre, mats, levels, nlevels, ml_vecspace, bc, stype, df, nu, xml_root)
Construct Multi-Grid preconditioner.
Definition solver_utils.F90:44
subroutine create_cg_solver(solver, force_native)
Needs docs.
Definition solver_utils.F90:437
Needs docs.
Definition fem_base.F90:174
Needs docs.
Definition fem_base.F90:146
Multi-level composite FE type.
Definition fem_composite.F90:73
Multigrid meshes and ML context structure.
Definition multigrid.F90:44
Information for XDMF plotting groups in HDF5 plot file.
Definition oft_io.F90:77
Matrix pointer.
Definition lin_alg_base.F90:606
Abstract matrix class.
Definition lin_alg_base.F90:566
Abstract vector class.
Definition lin_alg_base.F90:69
Zero Lagrange FE vector at all global boundary nodes.
Definition lagrange_operators.F90:111
Base class for OFT solvers.
Definition solver_base.F90:99

Variable Definitions

!---Solver objects
CLASS(oft_solver), POINTER :: linv
!--- ML structures for MG-preconditioner
TYPE(oft_matrix_ptr), POINTER, DIMENSION(:) :: ml_int => null()
TYPE(oft_matrix_ptr), POINTER, DIMENSION(:) :: ml_lop => null()
INTEGER(i4), ALLOCATABLE, DIMENSION(:) :: levels
INTEGER(i4), ALLOCATABLE, DIMENSION(:) :: nu
REAL(r8), ALLOCATABLE, DIMENSION(:) :: df
!---Local variables
CLASS(oft_vector), POINTER :: u,v
CLASS(oft_matrix), POINTER :: lop => null()
CLASS(oft_matrix), POINTER :: mop => null()
REAL(r8) :: uu
REAL(r8), POINTER, DIMENSION(:) :: vtmp => null()
INTEGER(i4) :: i,nlevels
INTEGER(i4), PARAMETER :: order = 3
TYPE(xdmf_plot_file) :: plot_file
TYPE(multigrid_mesh) :: mg_mesh
TYPE(oft_ml_fem_type), TARGET :: ML_oft_lagrange,ML_oft_blagrange
TYPE(oft_ml_fem_comp_type), TARGET :: ML_oft_vlagrange
TYPE(oft_lag_zerob) :: lag_zerob
TYPE(oft_ml_fe_vecspace) :: ml_vecspace

Setup Lagrange FE

When MG is used it is also desirable to construct field caches for each FE representation to be used. This is done with the *_vcache subroutines in each of the corresponding FE *_fields modules. These subroutines create a field cache which prevents the recreation of internal field lists, which are otherwise recreated each time a new vector is created using *_create routines. See mat_vec_vconst for more information.

!---Initialize enviroment
!---Setup grid
CALL multigrid_construct(mg_mesh)
CALL plot_file%setup("Example2")
CALL mg_mesh%mesh%setup_io(plot_file,order)
!---Construct FE levels
CALL oft_lag_setup(mg_mesh,order,ml_oft_lagrange,ml_oft_blagrange,ml_oft_vlagrange)
CALL lag_setup_interp(ml_oft_lagrange)
lag_zerob%ML_lag_rep=>ml_oft_lagrange
subroutine oft_init(nthreads)
Initializes Open FUSION Toolkit run environment.
Definition oft_base.F90:193

Construct ML structures

To form a MG preconditioner the approximate matrices corresponding to each level must be constructed and passed to form the preconditioner. The transfer level is skipped by setting the level to the negative of the true FE level. This causes the preconditioner to skip smoothing and only interpolate/inject on this level.

nlevels=ml_oft_lagrange%nlevels
ALLOCATE(ml_lop(nlevels),ml_int(nlevels-1))
ALLOCATE(df(nlevels),nu(nlevels),levels(nlevels))
DO i=1,nlevels
CALL ml_oft_lagrange%set_level(i)
levels(i)=i
IF(i==ml_oft_lagrange%blevel+1)levels(i)=-levels(i)
df(i)=df_lop(i)
nu(i)=nu_lop(i)
!---
NULLIFY(ml_lop(i)%M)
CALL oft_lag_getlop(ml_oft_lagrange%current_level,ml_lop(i)%M,'zerob')
IF(i>1)ml_int(i-1)%M=>ml_oft_lagrange%interp_matrices(i)%m !oft_lagrange_ops%interp
END DO
CALL ml_oft_lagrange%set_level(ml_oft_lagrange%nlevels)

Setup solver fields

!---Create solver fields
CALL ml_oft_lagrange%vec_create(u)
CALL ml_oft_lagrange%vec_create(v)
!---Get FE operators
lop=>ml_lop(nlevels)%M
CALL oft_lag_getmop(ml_oft_lagrange%current_level,mop,'none')

Setup linear solver

CALL create_cg_solver(linv)
linv%its=-3
linv%A=>lop
!---Setup MG preconditioner
ml_vecspace%ML_FE_rep=>ml_oft_lagrange
ml_vecspace%base_pop=>lag_base_pop
ml_vecspace%base_push=>lag_base_push
CALL create_mlpre(linv%pre,ml_lop,levels,nlevels=nlevels,ml_vecspace=ml_vecspace, &
bc=lag_zerob,stype=1,df=df,nu=nu)

Solve linear system

CALL u%set(1.d0)
CALL mop%apply(u,v)
CALL lag_zerob%apply(v)
CALL u%set(0.d0)
CALL linv%apply(u,v)
CALL u%get_local(vtmp)
CALL mg_mesh%mesh%save_vertex_scalar(vtmp,plot_file,'T')
DEALLOCATE(vtmp)
!---Finalize enviroment
END PROGRAM example2
subroutine oft_finalize()
Finalize Open FUSION Toolkit environment.
Definition oft_base.F90:356

Input file

Below is an input file which can be used with this example in a serial environment. The lag_op_options group has been added over the groups in ex1 to set parameters used by the multigrid preconditioner. In this case we are setting the smoother coefficient df and number of iterations nu used by the Jacobi smoother on each level.

&runtime_options
 ppn=1
 debug=0
/

&mesh_options
 meshname='cube'
 cad_type=92
 nlevels=4
 nbase=4
/

&lag_op_options
 df_lop=1.,1.,1.,1.,.826,.645
 nu_lop=10,64,8,4,2,1
/

Parallel input file

The number of grid levels changes when you got to a parallel environment, as there is now a transfer level in addition to the refinement levels, see Example 1. As a result you must modify the preconditioner options to take this into account. The input file below will provide the same preconditioner as the serial example, but can be run in parallel.

Note
The smoother coefficient and number of iterations are set to zero for the transfer level. This is only for clarity of the input file however, as smoothing is skipped altogether on the transfer level.
&runtime_options
 ppn=1
 debug=0
/

&mesh_options
 meshname='cube'
 cad_type=92
 nlevels=5
 nbase=3
/

&lag_op_options
 df_lop=1.,1.,1.,0.,1.,.826,.645
 nu_lop=10,64,8,0,4,2,1
/

Complete Source

PROGRAM example2
!---Runtime
!---Grid
!---Linear Algebra
!---Lagrange FE space
IMPLICIT NONE
!------------------------------------------------------------------------------
! Variable Definitions
!------------------------------------------------------------------------------
!---Solver objects
CLASS(oft_solver), POINTER :: linv
!--- ML structures for MG-preconditioner
TYPE(oft_matrix_ptr), POINTER, DIMENSION(:) :: ml_int => null()
TYPE(oft_matrix_ptr), POINTER, DIMENSION(:) :: ml_lop => null()
INTEGER(i4), ALLOCATABLE, DIMENSION(:) :: levels
INTEGER(i4), ALLOCATABLE, DIMENSION(:) :: nu
REAL(r8), ALLOCATABLE, DIMENSION(:) :: df
!---Local variables
CLASS(oft_vector), POINTER :: u,v
CLASS(oft_matrix), POINTER :: lop => null()
CLASS(oft_matrix), POINTER :: mop => null()
REAL(r8) :: uu
REAL(r8), POINTER, DIMENSION(:) :: vtmp => null()
INTEGER(i4) :: i,nlevels
INTEGER(i4), PARAMETER :: order = 3
TYPE(xdmf_plot_file) :: plot_file
TYPE(multigrid_mesh) :: mg_mesh
TYPE(oft_ml_fem_type), TARGET :: ML_oft_lagrange,ML_oft_blagrange
TYPE(oft_ml_fem_comp_type), TARGET :: ML_oft_vlagrange
TYPE(oft_lag_zerob) :: lag_zerob
TYPE(oft_ml_fe_vecspace) :: ml_vecspace
!------------------------------------------------------------------------------
! Setup Lagrange FE
!------------------------------------------------------------------------------
!---Initialize enviroment
!---Setup grid
CALL multigrid_construct(mg_mesh)
CALL plot_file%setup("Example2")
CALL mg_mesh%mesh%setup_io(plot_file,order)
!---Construct FE levels
CALL oft_lag_setup(mg_mesh,order,ml_oft_lagrange,ml_oft_blagrange,ml_oft_vlagrange)
CALL lag_setup_interp(ml_oft_lagrange)
lag_zerob%ML_lag_rep=>ml_oft_lagrange
!------------------------------------------------------------------------------
! Construct ML structures
!------------------------------------------------------------------------------
nlevels=ml_oft_lagrange%nlevels
ALLOCATE(ml_lop(nlevels),ml_int(nlevels-1))
ALLOCATE(df(nlevels),nu(nlevels),levels(nlevels))
DO i=1,nlevels
CALL ml_oft_lagrange%set_level(i)
levels(i)=i
IF(i==ml_oft_lagrange%blevel+1)levels(i)=-levels(i)
df(i)=df_lop(i)
nu(i)=nu_lop(i)
!---
NULLIFY(ml_lop(i)%M)
CALL oft_lag_getlop(ml_oft_lagrange%current_level,ml_lop(i)%M,'zerob')
IF(i>1)ml_int(i-1)%M=>ml_oft_lagrange%interp_matrices(i)%m !oft_lagrange_ops%interp
END DO
CALL ml_oft_lagrange%set_level(ml_oft_lagrange%nlevels)
!------------------------------------------------------------------------------
! Setup solver fields
!------------------------------------------------------------------------------
!---Create solver fields
CALL ml_oft_lagrange%vec_create(u)
CALL ml_oft_lagrange%vec_create(v)
!---Get FE operators
lop=>ml_lop(nlevels)%M
CALL oft_lag_getmop(ml_oft_lagrange%current_level,mop,'none')
!------------------------------------------------------------------------------
! Setup linear solver
!------------------------------------------------------------------------------
CALL create_cg_solver(linv)
linv%its=-3
linv%A=>lop
!---Setup MG preconditioner
ml_vecspace%ML_FE_rep=>ml_oft_lagrange
ml_vecspace%base_pop=>lag_base_pop
ml_vecspace%base_push=>lag_base_push
CALL create_mlpre(linv%pre,ml_lop,levels,nlevels=nlevels,ml_vecspace=ml_vecspace, &
bc=lag_zerob,stype=1,df=df,nu=nu)
!------------------------------------------------------------------------------
! Solve linear system
!------------------------------------------------------------------------------
CALL u%set(1.d0)
CALL mop%apply(u,v)
CALL lag_zerob%apply(v)
CALL u%set(0.d0)
CALL linv%apply(u,v)
CALL u%get_local(vtmp)
CALL mg_mesh%mesh%save_vertex_scalar(vtmp,plot_file,'T')
DEALLOCATE(vtmp)
!---Finalize enviroment
END PROGRAM example2