The Open FUSION Toolkit 1.0.0-8905cc5
Modeling tools for plasma and fusion research and engineering
Loading...
Searching...
No Matches
Marklin Example: Inhomogeneous Ideal MHD Equilibria

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
!---Runtime
!---Grid
!---Linear Algebra
!
!---Lagrange FE space
!---H1 FE space (Grad(H^1) subspace)
!---Full H(Curl) FE space
!---Taylor state
!---Tracing
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

!---Lagrange mass solver
CLASS(oft_matrix), POINTER :: lmop => null()
CLASS(oft_solver), POINTER :: lminv => null()
!---Fixed constants
INTEGER(i4), PARAMETER :: order = 2
INTEGER(i4), PARAMETER :: nh=2
REAL(r8), PARAMETER :: fr = 6
!---Local variables
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.

!---Initialize enviroment
!---Setup grid
CALL multigrid_construct(mg_mesh)
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.

!--- Lagrange
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)
CALL lag_setup_interp(hmodes%ML_lagrange)
!--- Grad(H^1) subspace
ALLOCATE(ff_obj%ML_H1)
CALL oft_h1_setup(mg_mesh,order+1,ff_obj%ML_H1)
CALL h1_setup_interp(ff_obj%ML_H1)
!--- H(Curl) subspace
ALLOCATE(hmodes%ML_hcurl)
ff_obj%ML_hcurl=>hmodes%ML_hcurl
CALL oft_hcurl_setup(mg_mesh,order,hmodes%ML_hcurl)
CALL hcurl_setup_interp(hmodes%ML_hcurl)
CALL hcurl_mloptions(hmodes%ML_hcurl)
!--- Full H(Curl) space
ALLOCATE(ff_obj%ML_hcurl_grad,ff_obj%ML_h1grad)
CALL oft_hcurl_grad_setup(hmodes%ML_hcurl,ff_obj%ML_H1,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
CALL taylor_hmodes(hmodes,1)
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.

!--- X-Injector
hcpc(:,1)=(/.0,.0,-.6/)
hcpv(:,1)=(/-5.,.0,.0/)
htags(1)='Xinj'
!--- Y-Injector
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)
CALL taylor_vacuum(ff_obj,hmodes=hmodes)
CALL taylor_injectors(ff_obj,hmodes,hmodes%hlam(1,hmodes%ML_hcurl%level))
!---Setup field interpolation object
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.

!---Construct operator
NULLIFY(lmop)
CALL oft_lag_vgetmop(ml_vlagrange%current_level,lmop,'none')
!---Setup solver
CALL create_cg_solver(lminv)
lminv%A=>lmop
lminv%its=-2
CALL create_diag_pre(lminv%pre) ! Setup Preconditioner
!---Create solver fields
CALL ml_vlagrange%vec_create(u)
CALL ml_vlagrange%vec_create(v)
!---Setup field interpolation
CALL bfield%setup(hmodes%ML_hcurl%current_level,ff_obj%ML_H1%current_level)
!---Project field
CALL oft_lag_vproject(hmodes%ML_lagrange%current_level,bfield,v)
CALL u%set(0.d0)
CALL lminv%apply(u,v)
!---Retrieve local values and save
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.
!---Setup tracer
CALL create_tracer(tracer,1)
tracer%tol=1.d-9
tracer%maxsteps=1e5
tracer%maxtrans=2e3
tracer%B=>bfield
!---Create launch point list
npts=20
ALLOCATE(pts(3,npts))
DO i=1,npts
pts(:,i)=(/0.d0,.33d0,-.3d0 + .6d0*i/real(npts,8)/)
END DO
!---Perform tracing
CALL tracing_poincare(tracer,pts,npts,'Example4.poin')
!---Finalize enviroment
END PROGRAM example4
void oft_finalize()

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
!---Runtime
!---Grid
!---Linear Algebra
!
!---Lagrange FE space
!---H1 FE space (Grad(H^1) subspace)
!---Full H(Curl) FE space
!---Taylor state
!---Tracing
IMPLICIT NONE
#include "local.h"
!------------------------------------------------------------------------------
! Variable Definitions
!------------------------------------------------------------------------------
!---Lagrange mass solver
CLASS(oft_matrix), POINTER :: lmop => null()
CLASS(oft_solver), POINTER :: lminv => null()
!---Fixed constants
INTEGER(i4), PARAMETER :: order = 2
INTEGER(i4), PARAMETER :: nh=2
REAL(r8), PARAMETER :: fr = 6
!---Local variables
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
!------------------------------------------------------------------------------
!---Initialize enviroment
!---Setup grid
CALL multigrid_construct(mg_mesh)
CALL plot_file%setup("Example4")
CALL mg_mesh%mesh%setup_io(plot_file,order)
!------------------------------------------------------------------------------
! Setup FE Types
!------------------------------------------------------------------------------
!--- Lagrange
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)
CALL lag_setup_interp(hmodes%ML_lagrange)
!--- Grad(H^1) subspace
ALLOCATE(ff_obj%ML_H1)
CALL oft_h1_setup(mg_mesh,order+1,ff_obj%ML_H1)
CALL h1_setup_interp(ff_obj%ML_H1)
!--- H(Curl) subspace
ALLOCATE(hmodes%ML_hcurl)
ff_obj%ML_hcurl=>hmodes%ML_hcurl
CALL oft_hcurl_setup(mg_mesh,order,hmodes%ML_hcurl)
CALL hcurl_setup_interp(hmodes%ML_hcurl)
CALL hcurl_mloptions(hmodes%ML_hcurl)
!--- Full H(Curl) space
ALLOCATE(ff_obj%ML_hcurl_grad,ff_obj%ML_h1grad)
CALL oft_hcurl_grad_setup(hmodes%ML_hcurl,ff_obj%ML_H1,ff_obj%ML_hcurl_grad,ff_obj%ML_h1grad)
!------------------------------------------------------------------------------
! Compute Taylor state
!------------------------------------------------------------------------------
hmodes%minlev=1
IF(oft_env%nprocs>1)hmodes%minlev=2
ff_obj%minlev=hmodes%minlev
CALL taylor_hmodes(hmodes,1)
!------------------------------------------------------------------------------
! Injector Cut Planes
!------------------------------------------------------------------------------
!--- X-Injector
hcpc(:,1)=(/.0,.0,-.6/)
hcpv(:,1)=(/-5.,.0,.0/)
htags(1)='Xinj'
!--- Y-Injector
hcpc(:,2)=(/.0,.0,.6/)
hcpv(:,2)=(/.0,-5.,.0/)
htags(2)='Yinj'
!------------------------------------------------------------------------------
! Compute Inhomogeneous state
!------------------------------------------------------------------------------
CALL ff_obj%setup(nh,hcpc,hcpv,htags)
CALL taylor_vacuum(ff_obj,hmodes=hmodes)
CALL taylor_injectors(ff_obj,hmodes,hmodes%hlam(1,hmodes%ML_hcurl%level))
!---Setup field interpolation object
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
!------------------------------------------------------------------------------
!---Construct operator
NULLIFY(lmop)
CALL oft_lag_vgetmop(ml_vlagrange%current_level,lmop,'none')
!---Setup solver
CALL create_cg_solver(lminv)
lminv%A=>lmop
lminv%its=-2
CALL create_diag_pre(lminv%pre) ! Setup Preconditioner
!---Create solver fields
CALL ml_vlagrange%vec_create(u)
CALL ml_vlagrange%vec_create(v)
!---Setup field interpolation
CALL bfield%setup(hmodes%ML_hcurl%current_level,ff_obj%ML_H1%current_level)
!---Project field
CALL oft_lag_vproject(hmodes%ML_lagrange%current_level,bfield,v)
CALL u%set(0.d0)
CALL lminv%apply(u,v)
!---Retrieve local values and save
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
!------------------------------------------------------------------------------
!---Setup tracer
CALL create_tracer(tracer,1)
tracer%tol=1.d-9
tracer%maxsteps=1e5
tracer%maxtrans=2e3
tracer%B=>bfield
!---Create launch point list
npts=20
ALLOCATE(pts(3,npts))
DO i=1,npts
pts(:,i)=(/0.d0,.33d0,-.3d0 + .6d0*i/real(npts,8)/)
END DO
!---Perform tracing
CALL tracing_poincare(tracer,pts,npts,'Example4.poin')
!---Finalize enviroment
END PROGRAM example4
subroutine oft_finalize()
Finalize Open FUSION Toolkit environment.
Definition oft_base.F90:356