This example introduces the Taylor State physics module. The Taylor module is used to compute Ideal MHD force-free states with uniform \( \lambda \). This example computes the Taylor state in a oblate cylinder. The T3D interface is used to generate a mesh for the cylinder and provide boundary information for the setup of a quadratic spatial mapping. This example also demonstrates the steps required to output a vector field for plotting.
Code Walk Through
Module Includes
The Taylor module requires the Lagrange and H(Curl) finite element representations.
PROGRAM example3
IMPLICIT NONE
#include "local.h"
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
Base H(Curl) FE class and basis evaluation.
Definition hcurl_basis.F90:22
subroutine oft_hcurl_setup(mg_mesh, order, ml_hcurl_obj, ml_bhcurl_obj, minlev)
Construct H(Curl) FE basis on each mesh level.
Definition hcurl_basis.F90:104
H(Curl) FE operator definitions.
Definition hcurl_operators.F90:29
subroutine hcurl_setup_interp(ml_hcurl_rep)
Construct interpolation matrices on each MG level.
Definition hcurl_operators.F90:1108
subroutine hcurl_mloptions(ml_hcurl_obj)
Read-in options for the basic H(Curl) ML preconditioners.
Definition hcurl_operators.F90:147
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
subroutine lag_mloptions()
Read-in options for the basic Lagrange ML preconditioners.
Definition lagrange_operators.F90:168
subroutine oft_lag_vproject(fe_rep, field, x)
Project a vector field onto a lagrange basis.
Definition lagrange_operators.F90:1402
subroutine oft_lag_vgetmop(vlag_rep, mat, bc)
Construct mass matrix for Lagrange vector representation.
Definition lagrange_operators.F90:1229
subroutine lag_setup_interp(ml_lag_rep, ml_vlag_rep)
Construct interpolation matrices on each MG level.
Definition lagrange_operators.F90:1503
subroutine lag_lop_eigs(ml_lag_rep, minlev)
Compute eigenvalues and smoothing coefficients for the operator LAG::LOP.
Definition lagrange_operators.F90:2012
Abstract solver interfaces and select native implementations.
Definition solver_base.F90:32
Matrix and vector management routines.
Definition solver_utils.F90:14
subroutine create_diag_pre(pre)
Needs docs.
Definition solver_utils.F90:619
subroutine create_cg_solver(solver, force_native)
Needs docs.
Definition solver_utils.F90:437
Subroutines and fields for Taylor state calculations using mimetic operators.
Definition taylor.F90:21
subroutine taylor_hmodes(self, nm, rst_filename)
Compute 'taylor_nm' Force-Free eignemodes.
Definition taylor.F90:295
Multi-level composite FE type.
Definition fem_composite.F90:73
Multigrid meshes and ML context structure.
Definition multigrid.F90:44
Interpolate of a H(Curl) field.
Definition hcurl_operators.F90:88
Information for XDMF plotting groups in HDF5 plot file.
Definition oft_io.F90:77
Abstract matrix class.
Definition lin_alg_base.F90:566
Abstract vector class.
Definition lin_alg_base.F90:69
Base class for OFT solvers.
Definition solver_base.F90:99
Force-free, uniform eigenmode object.
Definition taylor.F90:75
Variable Definitions
Although the core solvers are contained within the taylor_hmodes subroutine an additional solver is required for the field projection. A simple diagonally scaled CG solver is used for this purpose as the mass matrix is not especially stiff. We also declare a field interpolation object to evalute the curl of the vector potential computed by taylor_hmodes.
CLASS(oft_matrix), POINTER :: lmop => null()
CLASS(oft_solver), POINTER :: lminv => null()
INTEGER(i4) :: i,ierr
INTEGER(i4), PARAMETER :: order = 3
REAL(r8), POINTER, DIMENSION(:) :: vals => null()
REAL(r8), ALLOCATABLE, TARGET, DIMENSION(:,:) :: bvout
CLASS(oft_vector), POINTER :: u,v,check
TYPE(oft_hcurl_cinterp) :: Bfield
TYPE(xdmf_plot_file) :: plot_file
TYPE(multigrid_mesh) :: mg_mesh
TYPE(oft_ml_fem_comp_type) :: ML_vlagrange
TYPE(oft_taylor_hmodes) :: taylor_states
Setup Grid
As in the previous examples the runtime environment, grid and plotting files must be setup before the FE setup begins.
CALL plot_file%setup("Example3")
CALL mg_mesh%mesh%setup_io(plot_file,order)
subroutine oft_init(nthreads)
Initializes Open FUSION Toolkit run environment.
Definition oft_base.F90:193
Setup FE Types
As in example 2 we construct the finite element space, MG vector cache, and interpolation operators. In this case the setup procedure is done for each required finite element space.
ALLOCATE(taylor_states%ML_lagrange)
CALL oft_lag_setup(mg_mesh,order,taylor_states%ML_lagrange,ml_vlag_obj=ml_vlagrange)
ALLOCATE(taylor_states%ML_hcurl)
Compute Taylor state
The eigenstate is now computed using the taylor_hmodes subroutine. The number of eigenstates computed is controlled by an optional parameter to this subroutine. In this case we are only computing the lowest eigenvalue (Spheromak state) so the default number of modes (1) is used. The taylor_hmodes subroutine uses MG preconditioning as constructed by the hcurl_getwop_pre subroutine. The number of levels used is set by specifying the minimum level with the variable taylor_minlev.
- Note
- For our parallel example we increase the minimum level by 1 to use distributed levels only.
taylor_states%minlev=1
IF(
oft_env%nprocs>1)taylor_states%minlev=2
type(oft_env_type) oft_env
Global container for environment information.
Definition oft_base.F90:145
Project Solution for Plotting
In order to output the solution for plotting the field must be converted to a nodal, Lagrange, representation. This is done by projecting the solution on to a Lagrange basis by integrating the field against Lagrange test functions. The result is the then multiplied by the inverse of the Lagrange metric matrix to produce the projected field. This field can then be exported for plotting in VisIt.
Integration is performed by the oft_lag_vproject subroutine, which takes a general interpolation object that is used to evaluate the field. The result of taylor_hmodes is the vector potential taylor_hffa in H(Curl) form so the oft_hcurl_cinterp object is used to provide evaluation of \( B = \nabla \times A \).
NULLIFY(lmop)
lminv%A=>lmop
lminv%its=-2
CALL ml_vlagrange%vec_create(u)
CALL ml_vlagrange%vec_create(v)
bfield%u=>taylor_states%hffa(1,taylor_states%ML_hcurl%level)%f
CALL bfield%setup(taylor_states%ML_hcurl%current_level)
CALL u%set(0.d0)
CALL lminv%apply(u,v)
ALLOCATE(bvout(3,u%n/3))
vals=>bvout(1,:)
CALL u%get_local(vals,1)
vals=>bvout(2,:)
CALL u%get_local(vals,2)
vals=>bvout(3,:)
CALL u%get_local(vals,3)
call mg_mesh%mesh%save_vertex_vector(bvout,plot_file,'B')
END PROGRAM example3
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. For this example we also introduce the use of curved tetrahedrons on the boundary. High order tetrahedra can be constructed to provide a more accurate boundary using the runtime option grid_order
in the mesh_options
group. This option causes OFT to generate a quadratic representation for all boundary elements using the available CAD information.
&runtime_options
ppn=1
debug=0
/
&mesh_options
meshname='cylinder'
cad_type=0
nlevels=1
nbase=1
grid_order=2
/
&native_mesh_options
filename='cyl.h5'
/
&lag_op_options
df_lop=1.,.830,.619
nu_lop=64,2,1
/
&hcurl_op_options
df_wop=.689,.390,.316
nu_wop=64,2,1
/
Parallel input file
The input file below will provide the same preconditioner as the serial example, but can be run in parallel.
&runtime_options
ppn=1
debug=0
/
&mesh_options
meshname='cylinder'
cad_type=0
nlevels=2
nbase=1
grid_order=2
/
&native_mesh_options
filename='cyl.h5'
/
&lag_op_options
df_lop=0.,1.,.830,.619
nu_lop=0,64,2,1
/
&hcurl_op_options
df_wop=0.,.689,.390,.316
nu_wop=0,64,2,1
/
Mesh Creation
A mesh file cyl.h5
is provided with this example. Instructions to generate your own mesh for the geometry using CUBIT and GMSH.
Meshing with CUBIT
A suitable mesh for this example, with radius of 1m and height of 2m, can be created using the CUBIT script below.
reset
create Cylinder height 1 radius 1
volume 1 scheme Tetmesh
set tetmesher interior points on
set tetmesher optimize level 3 optimize overconstrained off sliver off
set tetmesher boundary recovery off
volume 1 size .2
mesh volume 1
set duplicate block elements off
block 1 add volume 1
block 1 element type tetra10
set large exodus file on
export Genesis "cyl.g" overwrite block 1
Once complete the mesh should be converted into the native mesh format using the convert_cubit.py
script as below. The script is located in bin
following installation or src/utilities
in the base repo.
~$ python convert_cubit.py --in_file=cyl.g
Meshing with Gmsh
If the CUBIT mesh generation codes is not avilable the mesh can be created using the Gmsh code and the geometry script below.
Coherence;
Point(1) = {0, 0, 0, 1.0};
Point(2) = {1, 0, 0, 1.0};
Point(3) = {0, 1, 0, 1.0};
Point(4) = {-1, 0, 0, 1.0};
Point(5) = {0, -1, 0, 1.0};
Circle(1) = {2, 1, 3};
Circle(2) = {3, 1, 4};
Circle(3) = {4, 1, 5};
Circle(4) = {5, 1, 2};
Line Loop(5) = {2, 3, 4, 1};
Plane Surface(6) = {5};
Extrude {0, 0, 1} {
Surface{6};
}
To generate a mesh, with resolution matching the Cubit example above, place the script contents in a file called cyl.geo
and run the following command.
~$ gmsh -3 -format mesh -optimize -clscale .2 -order 2 -o cyl.mesh cyl.geo
Once complete the mesh should be converted into the native mesh format using the convert_gmsh.py
script as below. The script is located in bin
following installation or src/utilities
in the base repo.
~$ python convert_gmsh.py --in_file=cyl.mesh
Complete Source
PROGRAM example3
IMPLICIT NONE
#include "local.h"
CLASS(oft_matrix), POINTER :: lmop => null()
CLASS(oft_solver), POINTER :: lminv => null()
INTEGER(i4) :: i,ierr
INTEGER(i4), PARAMETER :: order = 3
REAL(r8), POINTER, DIMENSION(:) :: vals => null()
REAL(r8), ALLOCATABLE, TARGET, DIMENSION(:,:) :: bvout
CLASS(oft_vector), POINTER :: u,v,check
TYPE(oft_hcurl_cinterp) :: Bfield
TYPE(xdmf_plot_file) :: plot_file
TYPE(multigrid_mesh) :: mg_mesh
TYPE(oft_ml_fem_comp_type) :: ML_vlagrange
TYPE(oft_taylor_hmodes) :: taylor_states
CALL plot_file%setup("Example3")
CALL mg_mesh%mesh%setup_io(plot_file,order)
ALLOCATE(taylor_states%ML_lagrange)
CALL oft_lag_setup(mg_mesh,order,taylor_states%ML_lagrange,ml_vlag_obj=ml_vlagrange)
ALLOCATE(taylor_states%ML_hcurl)
taylor_states%minlev=1
IF(
oft_env%nprocs>1)taylor_states%minlev=2
NULLIFY(lmop)
lminv%A=>lmop
lminv%its=-2
CALL ml_vlagrange%vec_create(u)
CALL ml_vlagrange%vec_create(v)
bfield%u=>taylor_states%hffa(1,taylor_states%ML_hcurl%level)%f
CALL bfield%setup(taylor_states%ML_hcurl%current_level)
CALL u%set(0.d0)
CALL lminv%apply(u,v)
ALLOCATE(bvout(3,u%n/3))
vals=>bvout(1,:)
CALL u%get_local(vals,1)
vals=>bvout(2,:)
CALL u%get_local(vals,2)
vals=>bvout(3,:)
CALL u%get_local(vals,3)
call mg_mesh%mesh%save_vertex_vector(bvout,plot_file,'B')
END PROGRAM example3