The Toric Component

At this point, the Toric component is a work in progress, so this page details the physics and software development issues currently being addressed. This material is intended primarily for FACETS developers, so it may not be easy to follow.

Development Strategy

Creating the Toric component is going to require more than just wrapper code. It's going to involve editing and potentially refactoring the original Toric source code. For example, Toric has hard coded references to MPI_COMM_WORLD, and FACETS expects to provide the communicator. For FACETS, the hard coded references will be changed to a reference to a global variable reference.

There are other issues. For example, the code for reading the toric.inp configuration file appears to be mixed in with the computational code. The FACETS design calls for configuration to be separate from computation.

Question: Will we be attempting to feed our changes back to the Toric development team? Should the goal be to minimize changes to the original Toric code?

JRC: Our goal should be to minimize code changes. In this case, since TORIC is not a dynamic component, one can even just have one call, "update". TGWE: Some changes are going to be deep such as MPI_COMM_WORLD.

The Toric Parameters

Like all components, the Toric component must following the FACETS interface naming conventions. At the outset, these are the quantities that must be exposed. This  Wikipedia reference helps me keep toroidal and poloidal straight.

The Toric Inputs

After talking with Scott Kruger, the Toric inputs seem a little more extensive than our initial list. Basically, the Toric inputs includes everything that is currently being read from the I2MEX file.

ntheta ::

Integer number of poloidal rays plus one. Also described in toric_man as the number of theta points. The value from the I2MEX seems to be ignored, and the value from the gfreadinp namelist is used instead.

nmhd
Integer number of radial grid points. In toric_man}}, it's described as the number of psi surfaces. The value from the I2MEX seems to be ignored, and the value from the {{{gfreadinp namelist is used instead.
psipol(1:nmhd)
Original radial poloidal flux grid (1-D array of doubles). Toric gets this from a call to i2mex_getOriPsi(nmhd, psipol, ierr).
thetapol(1:ntheta)
Original poloidal grid (1-D array of doubles). Toric gets this from a call to i2mex_getOriT(ntheta, thetapol, ierr).
rtorm_gf
Major radius (scalar double). The major radius is defined as the average of Xout and Xin, where Xin and Xout are the plasma dounbary ponits intersecting the mid plane. Toric reads this with i2mex_get_Rmajor(rtorm_gf, ierr), but it appears to ignore the value returned.
r_axis_gf
R of magnetic axis (scalar double). The magnetic radius position. Toric reads this with i2mex_getRmagnetic(r_axis_gf, ierr), but it appears to ignore the value returned.
zaxis
Z of magnetic axis (scalar double). The magnetic Z position. Toric reads this with i2mex_getZmagnetic(zaxis,ierr). zaxis is stored in a public module variable, but nothing appears to read it.
b_zero_gf
Central magnetic field (scalar double). The vacuum magnetic field at the major radius position. Toric reads this with i2mex_getB0(b_zero_gf, ierr), but it never reads the value.
GBcov(1:nmhd)
Covariant component of B field (1-D array of doubles). The covariant toroidal magnetic field component on the psipol mesh. Toric reads this with i2mex_getG(nmhd, psipol, GBcov, ierr), but it never reads the value.
qq_gf(1:nmhd)
q profile (1-D array of doubles). This is q on the psipol mesh. Toric reads this with i2mex_getQ(nmhd, psipol, qq_gf, ierr).

Input Parameters

R the major radius.

TORIC should return the power profile as a 1D array, and somehow should return a 1D array of rho values corresponding to those array values. For all of these, we will implement as a set*Array description. We need to update the wiki, and then also perhaps FacetsIfc??

rho_CS
This is a one-dimensional array of doubles that is the coordinate system used by the core solver. It typically refers to a normalized toroidal flux, so is unitless.

Toric uses a psi_normal as its coordinate system so we will probably need to figure out the best way of handling this interface so we should probably pass the psi_normal grid (which the core solver has).

This is an input to Toric set by the framework using a call like source->setDoubleArray("rho_CS", rho(:) ).

density_CS_electron
This is a one-dimensional array of doubles that holds the electron density in 1/m3. Toric takes this quantity as an input to its calculations, and the framework set this using source->setDoubleArray("density_CS_electron", value);.
density_CS_H2p1
This is a one-dimensional array of doubles that holds the H2+ density in 1/m3. Toric takes this quantity as an input to its calculations, and the framework sets this using source->setDoublearray("ptclSource_CS_H2p1", 1, idx, value);.
temperature_CS_electron
This is a one-dimensional array of doubles that holds the electron temperature in eV. Toric takes this quantity as an input to its calculations, and the framework set this using source->setDoubleAtIndex("temperature_CS_electron", 1, idx, value);. Question: Is idx related to the poloidal or toroidal dimension?
temperature_CS_H2p1
This is a one-dimensional array of doubles that holds the H2+ temperature in eV. Toric takes this quantity as an input to its calculations, and the framework sets this using source->setDoubleAtIndex("temperature_CS_H2p1", 1, idx, value);. Question: Is idx related to the poloidal or toroidal dimension?

JRC: I think we need to modify our interface so that these are all just calls to setDoubleArray or some such. Alex Pletzer should comment on what he did for nubeam.

Output Parameters

<P> flux surface averaged power deposition (a function of Psi)

<jparallel_rf> flux surface average driven current (a function of Psi)

ptclSource_CS_electron
This is a one-dimensional array of doubles that holds the electron particle source in 1/m3/s. Toric calculates this, and the framework reads this using source->getDoubleAtIndex("ptclSource_CS_electron", 1, idx, value);. Question: Is idx related to the poloidal or toroidal dimension?
ptclSource_CS_H2p1
This is a one-dimensional array of doubles that holds the H2+ particle source in 1/m3/s. Toric calculates this, and the framework reads this using source->getDoubleAtIndex("ptclSource_CS_H2p1", 1, idx, value);. Question: Is idx related to the poloidal or toroidal dimension?
energySource_CS_electron
This is a one-dimensional array of doubles that holds the electron energy source in J/m3/s. Toric calculates this, and the framework reads this using source->getDoubleAtIndex("energySource_CS_electron", 1, idx, value);. Question: Is idx related to the poloidal or toroidal dimension?
energySource_CS_H2p1
This is a one-dimensional array of doubles that holds the H2+ energy source in J/m3/s. Toric calculates this, and the framework reads this using source->getDoubleAtIndex("energySource_CS_H2p1", 1, idx, value);. Question: Is idx related to the poloidal or toroidal dimension?
angularMomentumSource_CS_electron
This is a one-dimensional array of doubles that holds the electron angular momentum source in kg/m2/s2. Toric calculates this, and the framework reads this using source->getDoubleAtIndex("angularMomentumSource_CS_electron", 1, idx, value);. Note: initially this will just return zero because FACETS doesn't need it right now. Question: Is idx related to the poloidal or toroidal dimension?
angularMomentumSource_CS_H2p1
This is a one-dimensional array of doubles that holds the H2+ angular momentum source in kg/m2/s2}}}. Toric calculates this, and the framework reads this using source->getDoubleAtIndex("angularMomentumSource_CS_H2p1", 1, idx, value);. Note: initially this will just return zero because FACETS doesn't need it right now. Question: Is idx related to the poloidal or toroidal dimension?

Differences Between Meshes

Toric's grid is not expected to coincide with the core's grid. The expectation is that the Toric glue code will interpolate source values in geometric space to provide values at the points required by the client. I assume this will involve a call to source->getDoubleAtLoc("ptclSource_CS_electron", 1, coord, value); where coord is a one-dimension double giving the geometric location where the framework requires a value. Question: Are the units and values of coord common across components?

Parallel Toric

At the Toric componentization kickoff telecon, we discussed the conventions for parallel Toric runs. The expectation is that Toric is configured on MPI node 0 of its communicator. The parallelization scheme is responsible for scattering the configuration data to all Toric nodes, and after the calculation, the parallelization scheme is responsible for gathering the resulting data back to node 0. John Cary believe that Toric itself handles the scatter and gather operations.

John C. Wright (JCW) says TORIC inputs are read by all processors, they are not read in my process 0 and scattered - could be done but has not been a performance issue for us. Toric outputs are gathered to process 0 for output though.

Toric Notes (John C. Wright)

According to JCW, The ion composition is important for Toric. If FACETS does not track this normally, something will have to be added to specify the relative concentrations of the different ion species. Toric supports parametrically specified profiles as well and a numerical array.

Toric provides no momentum source calculation.

Toric provides a power profile or 2D power array for a heating rate to either individual ion species or electrons. Generally there is power in both electron and ion channels, different ions may be heated at different rates. The sum of powers is normalized to integrate to "1". For use as an input to another code it is normally scaled to the known coupled rf power.

TEMPEC is the central electron temperature. All density profiles are proportional to each other.

For inputs and internally, toric uses a uniform radial sqrt poloidal flux mesh normalized to one at the LCF.

Practical Series of Steps For Componentization

  1. Autotool your project. Easiest to external config directory and use its script to do this. [SEK]
  2. Add a C++ class derived from FacetsIfc?.h and implement the wrapper methods. [TE]
  3. Make sure you have an install target for your component and that you install your library and header files. [SEK]
  4. Modify the facetsall repo to external your component. Hook in your component into the bilder system. [SEK]
  5. Register your component in the FACETS framework so that it can be used. [TE/MM]

The items still remaining are the C++ wrapper class and component registration.

Linking FACETS Named Quantities to Their Toric Counterparts

This section is about the nuts and bolts of the Toric component. Toric as a code defines numerous quantities in its data structures, and ultimately, we have to map between the FACETS naming conventions and variables in Toric modules. Toric's design is to place all shared values as static data elements in Fortran modules. Many of the subroutines have no arguments. Data is shared between subroutines via using global data from shared Fortran modules.

The table below represents my initial best guess at finding the module variables corresponding to quantities set or read by FACETS. Note, these quantities may require units conversion, interpolation, or other calculations to be appropriate for FACETS.

rho_CS
Either rho_tor or rho_pol defined on line 334 of t4_mod_public.F. In t4_mod_ncdf.F:704, rho_tor is described as "Normal. Rho Toroidal for Power Profiles (coarse mesh)", and rho_pol is the poloidal counterpart (t4_mod_ncdf.F:713.
temperature_CS_electron
tempec from t4_mod_public.F:131 seems to be an electron temperature in eV, but it's only a scalar. I thought we were looking for a one-dimensional quantity.
temperature_CS_H2p1
This may be an element tempic from t4_mod_public.F:136; although, it's only a scalar (not 1-D).
density_CS_electron
denec from t4_mod_public.F:131 is described in the comments as the central electron density in cm-3.
density_CS_H2p1
Work in progress.
ptclSource_CS_electron
Work in progress.
ptclSource_CS_H2p1
Work in progress.
energySource_CS_electron
Work in progress.
energySource_CS_H2p1
Work in progress.
angularMomentumSource_CS_electron
Work in progress.
angularMomentumSource_CS_H2p1
Work in progress.

Basic Questions About How Toric Will Be Run

  1. Toric seems configurable with respect to the number of species. In the  "Using Toric" presentation, there is the NSPEC configuration parameter that controls the number of species, and ATM(i) seems to be the atomic mass number of species i. Similarly, AZI(i) is the atomic charge. What will be the species for a FACETS run? According to information above, it seems that FACETS is only concerned with electrons and H2+. It would be useful to put together the toric.inp file that FACETS will need. Species configuration seems like it will impact how some of the quantities defined above are determined.
  2. Toric has several run modes: equil, toric, sumnph, ssfpql, and diagns. Which of these run modes is FACETS going to use?