This example shows how to use the Taylor State physics module and mesh cut planes to compute Inhomogeneous Ideal MHD Equilibria with uniform \( \lambda \). The code computes a composite Taylor state in HIT-SI with a flux ratio of 6.
Code Walk Through
Module Includes
PROGRAM example4
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 scalar H^1 FE class and basis evaluation.
Definition h1_basis.F90:22
subroutine oft_h1_setup(mg_mesh, order, ml_h1_obj, ml_bh1_obj, minlev)
Construct H^1 scalar FE on each mesh level.
Definition h1_basis.F90:99
H^1 FE operator definitions.
Definition h1_operators.F90:22
subroutine h1_setup_interp(ml_h1_rep)
Construct interpolation matrices for transfer between H^1 finite element spaces.
Definition h1_operators.F90:551
subroutine h1_mloptions
Read-in options for the basic H^1 ML preconditioners.
Definition h1_operators.F90:99
Base H(Curl) FE class and basis evaluation.
Definition hcurl_basis.F90:22
subroutine oft_hcurl_grad_setup(ml_hcurl_obj, ml_h1_obj, ml_hcurl_grad_obj, ml_h1grad_obj, minlev)
Construct a vector FE space for H(Curl) and it's compliment ( )
Definition hcurl_basis.F90:176
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_injectors(self, hmodes, lambda, rst_filename)
Compute force-free plasma response to external fields generated by taylor_injectors.
Definition taylor.F90:853
integer(i4), parameter taylor_tag_size
Size of jump planes character tags.
Definition taylor.F90:91
subroutine taylor_vacuum(self, energy, hmodes, rst_filename)
Generate vacuum fields for specified handle (cut planes)
Definition taylor.F90:531
subroutine taylor_hmodes(self, nm, rst_filename)
Compute 'taylor_nm' Force-Free eignemodes.
Definition taylor.F90:295
Tracing implementation for the Open FUSION Toolkit.
Definition tracing.F90:17
subroutine create_tracer(tracer, type)
Create tracer object.
Definition tracing.F90:257
subroutine tracing_poincare(tracer, pts, n, filename, offset, pcoord, qfile)
Advance a group of tracers while accumulating crossing of the yz-plane into a poincare section.
Definition tracing.F90:433
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
Force-free, uniform field object (inhomogeneous BCs)
Definition taylor.F90:99
Interpolate a Taylor state field.
Definition taylor.F90:54
Abstract class for OFT tracers.
Definition tracing.F90:29
Variable Definitions
CLASS(oft_matrix), POINTER :: lmop => null()
CLASS(oft_solver), POINTER :: lminv => null()
INTEGER(i4), PARAMETER :: order = 2
INTEGER(i4), PARAMETER :: nh=2
REAL(r8), PARAMETER :: fr = 6
INTEGER(i4) :: i,npts,ierr
REAL(r8) :: fluxes(nh),hcpc(3,nh),hcpv(3,nh)
CHARACTER(LEN=taylor_tag_size) :: htags(nh)
REAL(r8), POINTER, DIMENSION(:) :: vals => null()
REAL(r8), ALLOCATABLE, TARGET, DIMENSION(:,:) :: bvout,pts
CLASS(oft_vector), POINTER :: u,v,check
TYPE(oft_taylor_rinterp), TARGET :: Bfield
CLASS(oft_tracer), POINTER :: tracer
TYPE(xdmf_plot_file) :: plot_file
TYPE(multigrid_mesh) :: mg_mesh
TYPE(oft_ml_fem_comp_type) :: ML_vlagrange
TYPE(oft_taylor_hmodes) :: hmodes
TYPE(oft_taylor_ifield) :: ff_obj
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("Example4")
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(hmodes%ML_lagrange)
ff_obj%ML_lagrange=>hmodes%ML_lagrange
CALL oft_lag_setup(mg_mesh,order,hmodes%ML_lagrange,ml_vlag_obj=ml_vlagrange)
ALLOCATE(ff_obj%ML_H1)
ALLOCATE(hmodes%ML_hcurl)
ff_obj%ML_hcurl=>hmodes%ML_hcurl
ALLOCATE(ff_obj%ML_hcurl_grad,ff_obj%ML_h1grad)
Compute Taylor state
For composite Taylor states the lowest eigenmode is used used in addition to the injector fields. This is possible in HIT-SI due to decoupling of the injector vacuum field and lowest eigenmode. The lowest eigenmode is computed as in example 3 using taylor_hmodes.
hmodes%minlev=1
IF(
oft_env%nprocs>1)hmodes%minlev=2
ff_obj%minlev=hmodes%minlev
type(oft_env_type) oft_env
Global container for environment information.
Definition oft_base.F90:145
Injector Cut Planes
The ideal MHD equilibrium solvers with inhomogeneous source terms require vacuum fields to use as the external source term. For HIT-SI the taylor_vacuum can be used to compute vacuum fields for the injectors from cut planes in the mesh. Cut planes are identified by specifying the cut plane center (hcpc
) and normal direction (hcpv
) for each jump. The jump is also localized to a circular region around the center point, defined by the magnitude of hcpv
, such that \( \left( \vec{r}
- \vec{r}_{hcpc} \right) \cdot \vec{r}_{hcpv} \leq 1 \). Each jump can also be given a character identifier which is used here to indicate the naming convention on HIT-SI.
hcpc(:,1)=(/.0,.0,-.6/)
hcpv(:,1)=(/-5.,.0,.0/)
htags(1)='Xinj'
hcpc(:,2)=(/.0,.0,.6/)
hcpv(:,2)=(/.0,-5.,.0/)
htags(2)='Yinj'
Compute Inhomogeneous state
With cut planes specified, the injector equilibrium can then be compute using the taylor_vacuum and taylor_injectors subroutines. taylor_injectors computes the plasma response using the vacuum fields computed for the cut planes with unit fluxes for a specified \( \lambda \). Since we are interested in composite Taylor states \( \lambda \) must be equal to the value for the lowest homogeneous eigenmode (Taylor state).
Once the plasma response and vacuum fields have been computed the composite field can be projected for plotting. The full field is defined as \(\vec{B} = \vec{B}_{hffa} + flux^i \left( \vec{B}^i_{hvac} + \vec{B}^i_{gffa} \right)\), where \( \vec{B}_{hffa} \) is the field for the lowest eigenmode, \( \vec{B}^i_{hvac} \) is the vacuum field for the injector, and \( \vec{B}^i_{gffa} \) is the plasma component of the inhomogeneous equilibrium field. The interpolation object oft_taylor_rinterp is designed to support this type of field and is populated once the subfields are computed.
CALL ff_obj%setup(nh,hcpc,hcpv,htags)
fluxes=(/1.d0,0.d0/)
CALL ff_obj%ML_hcurl_grad%vec_create(bfield%uvac)
DO i=1,nh
CALL bfield%uvac%add(1.d0,fluxes(i),ff_obj%hvac(i)%f)
END DO
CALL hmodes%ML_hcurl%vec_create(bfield%ua)
CALL bfield%ua%add(0.d0,fr/hmodes%htor(1,hmodes%ML_hcurl%level),hmodes%hffa(1,hmodes%ML_hcurl%level)%f)
DO i=1,nh
CALL bfield%ua%add(1.d0,fluxes(i),ff_obj%gffa(i)%f)
END DO
Project Solution for Plotting
With the interpolation operator defined the field can be projected to a Lagrange basis for plotting as in example 3.
NULLIFY(lmop)
CALL oft_lag_vgetmop(ml_vlagrange%current_level,lmop,'none')
CALL create_cg_solver(lminv)
lminv%A=>lmop
lminv%its=-2
CALL create_diag_pre(lminv%pre)
CALL ml_vlagrange%vec_create(u)
CALL ml_vlagrange%vec_create(v)
CALL bfield%setup(hmodes%ML_hcurl%current_level,ff_obj%ML_H1%current_level)
CALL oft_lag_vproject(hmodes%ML_lagrange%current_level,bfield,v)
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')
Create Poincare section
Poincare sections can be created using the subroutine tracing_poincare. This subroutine requires a tracing object, which is used to advance the streamline ODE and a list of launch points for each streamline. The tracing object is used as a template to spawn additional tracers that are advanced in parallel. Tracing objects can be created using the create_tracer subroutine. Once the tracer has been created basic properties are set including the tracing tolerance, maximum number of steps, maximum number of domain transfers and the field interpolation object.
For this example a line of points in the xz-plane are used, positioned at the radius of the magnetic axis of the Taylor state. The resulting puncture list is stored in the file 'Example4.poin'.
- Note
- Poincare tracing requires the Open FUSION Toolkit (OFT) to be built with OpenMP enabled. A single thread may still be used for execution by setting the environment variable "OMP_NUM_THREADS=1", and a second thread will be used only during tracing.
CALL create_tracer(tracer,1)
tracer%tol=1.d-9
tracer%maxsteps=1e5
tracer%maxtrans=2e3
tracer%B=>bfield
npts=20
ALLOCATE(pts(3,npts))
DO i=1,npts
pts(:,i)=(/0.d0,.33d0,-.3d0 + .6d0*i/real(npts,8)/)
END DO
CALL tracing_poincare(tracer,pts,npts,'Example4.poin')
END PROGRAM example4
Input file
Below is an input file which can be used with this example in a serial environment.
&runtime_options
ppn=1
debug=0
/
&mesh_options
meshname='hitsi'
cad_type=1
nlevels=1
nbase=1
grid_order=2
/
&t3d_options
filename='hitsi_rs.t3d'
inpname='hitsi_rs.inp'
reflect='xy'
/
&lag_op_options
df_lop=1.,.837,.613
nu_lop=64,2,1
/
&h1_op_options
df_lop=.98,.564,.441,.363
nu_lop=64,4,2,1
/
&hcurl_op_options
df_wop=.680,.384,.321
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='hitsi'
cad_type=1
nlevels=2
nbase=1
grid_order=2
/
&t3d_options
filename='hitsi_rs.t3d'
inpname='hitsi_rs.inp'
reflect='xy'
/
&lag_op_options
df_lop=0.,1.,.837,.613
nu_lop=0,64,2,1
/
&h1_op_options
df_lop=0.,.98,.564,.441,.363
nu_lop=0,64,4,2,1
/
&hcurl_op_options
df_wop=0.,.680,.384,.321
nu_wop=0,64,2,1
/
Complete Source
PROGRAM example4
IMPLICIT NONE
#include "local.h"
CLASS(oft_matrix), POINTER :: lmop => null()
CLASS(oft_solver), POINTER :: lminv => null()
INTEGER(i4), PARAMETER :: order = 2
INTEGER(i4), PARAMETER :: nh=2
REAL(r8), PARAMETER :: fr = 6
INTEGER(i4) :: i,npts,ierr
REAL(r8) :: fluxes(nh),hcpc(3,nh),hcpv(3,nh)
CHARACTER(LEN=taylor_tag_size) :: htags(nh)
REAL(r8), POINTER, DIMENSION(:) :: vals => null()
REAL(r8), ALLOCATABLE, TARGET, DIMENSION(:,:) :: bvout,pts
CLASS(oft_vector), POINTER :: u,v,check
TYPE(oft_taylor_rinterp), TARGET :: Bfield
CLASS(oft_tracer), POINTER :: tracer
TYPE(xdmf_plot_file) :: plot_file
TYPE(multigrid_mesh) :: mg_mesh
TYPE(oft_ml_fem_comp_type) :: ML_vlagrange
TYPE(oft_taylor_hmodes) :: hmodes
TYPE(oft_taylor_ifield) :: ff_obj
CALL plot_file%setup("Example4")
CALL mg_mesh%mesh%setup_io(plot_file,order)
ALLOCATE(hmodes%ML_lagrange)
ff_obj%ML_lagrange=>hmodes%ML_lagrange
CALL oft_lag_setup(mg_mesh,order,hmodes%ML_lagrange,ml_vlag_obj=ml_vlagrange)
ALLOCATE(ff_obj%ML_H1)
ALLOCATE(hmodes%ML_hcurl)
ff_obj%ML_hcurl=>hmodes%ML_hcurl
ALLOCATE(ff_obj%ML_hcurl_grad,ff_obj%ML_h1grad)
hmodes%minlev=1
IF(
oft_env%nprocs>1)hmodes%minlev=2
ff_obj%minlev=hmodes%minlev
hcpc(:,1)=(/.0,.0,-.6/)
hcpv(:,1)=(/-5.,.0,.0/)
htags(1)='Xinj'
hcpc(:,2)=(/.0,.0,.6/)
hcpv(:,2)=(/.0,-5.,.0/)
htags(2)='Yinj'
CALL ff_obj%setup(nh,hcpc,hcpv,htags)
fluxes=(/1.d0,0.d0/)
CALL ff_obj%ML_hcurl_grad%vec_create(bfield%uvac)
DO i=1,nh
CALL bfield%uvac%add(1.d0,fluxes(i),ff_obj%hvac(i)%f)
END DO
CALL hmodes%ML_hcurl%vec_create(bfield%ua)
CALL bfield%ua%add(0.d0,fr/hmodes%htor(1,hmodes%ML_hcurl%level),hmodes%hffa(1,hmodes%ML_hcurl%level)%f)
DO i=1,nh
CALL bfield%ua%add(1.d0,fluxes(i),ff_obj%gffa(i)%f)
END DO
NULLIFY(lmop)
lminv%A=>lmop
lminv%its=-2
CALL ml_vlagrange%vec_create(u)
CALL ml_vlagrange%vec_create(v)
CALL bfield%setup(hmodes%ML_hcurl%current_level,ff_obj%ML_H1%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')
tracer%tol=1.d-9
tracer%maxsteps=1e5
tracer%maxtrans=2e3
tracer%B=>bfield
npts=20
ALLOCATE(pts(3,npts))
DO i=1,npts
pts(:,i)=(/0.d0,.33d0,-.3d0 + .6d0*i/real(npts,8)/)
END DO
END PROGRAM example4
subroutine oft_finalize()
Finalize Open FUSION Toolkit environment.
Definition oft_base.F90:356