Content
- Introduction
- Files provided
- Running a test example
- Structure of the command files
- Storing EIRENE triangular grids in IMAS
- Structure of EIRENE files keeping the grid
- Presentation of EIRENE grid in GGD
- Module triangular_grid_modile
- Module triangular_grid_ids_io
- Template files save_grid.f90 and recover_grid.f90
- Storing the EIRENE input
- Things to be done
1. Introduction
The Fortran routines described herein are intended to become a part of interface between the code EIRENE and the IMAS data structure. In its current form, they provide ???
The structure of this document is as follows. ???
2. Files provided
The files listed below can be found in the public directory ~g2yyakov/public/eirene/version0.9.
!!! To be updated
FILES | CONTENT |
---|---|
triangular_grid_module.f90 | Module that supports reading, writing and processing triangular grids |
triangular_grid_ids_io.f90 | Module supporing the storage of triangular grids in IMAS |
imas_data_io.f90 | Module supporing the storage of physical quantities (tallies) in IMAS |
eirene_data_io.f90 | Module supporing reading / writing of EIRENE data files |
edge_profiles_io.f90 | Module that supports placing the data to the 'edge_profiles' IDS |
equilibrium_io.f90 | Module that supports placing the data to the 'equilibrium' IDS |
imas_controls_for_input.f90 | |
global_parameters.f90 | |
save_input_main.f90 | Program that takes a set of EIRENE input files and puts their content to IMAS |
provide_input_main.f90 | Program that extracts EIRENE input from IMAS, providing it in EIRENE native format |
Makefile | Used to compile the programs |
save_input.par | |
provide_input.par | |
soledge3x.npco_char | Triangular grid example received from the EIRENE team |
soledge3x.elemente | Another file of this example |
soledge3x.neighbor | Another file of this example |
README.txt | Brief description of how to compile and run |
user_guide.pdf | PDF version of this document |
3. Running a test example
You can use the prepared data files (the files soledge3x.npco_char, soledge3x.elemente, soledge3x.neighbor, and the files with the suffix '.dat'). Admittedly, the dat-files have no physical sense and were created with the only aim to check the corectness of input/output operations.
- Copy the files to your directory.
- If you wish to test the programs with your own files, copy them to the same direcctory. Do not forget to put the correct names to the command file save_input.par.
- Load the IMAS library by typing:
module load imasenv/3.37.0
- Create the IMAS database entry:
imasdb eirene
- Now you can compile the examples. Type
make clean
make save_input
- Run the program:
./save_input.exe
The program puts the grid stored in the files soledge3x.* and the content of the dat-files into the IMAS databaseeirene
. - Type
make provide_input
- Run the program:
./provide_input.exe
- Compare the new files
eirene.*
with the original filessoledge3x.*
and the original data files with the new files (their names end with '_input.dat').
4. Structure of the command files
The program save_input.exe takes parameters from the file save_input.cmd. ????????????????????????????
5. Storing EIRENE triangular grids in IMAS
The Fortran routines described herein take files containing the description of a triangular grid in native EIRENE format and store this grid in an IMAS IDS; on the other hand, they extract a stored grid description from IMAS and provide it in EIRENE format. At present, these routines have been tested only with the IDS's edge_profiles
and equilibrium.
The grid is stored in the IMAS subsystem called GGD (General Grid Description). This subsystem consists of two data sub-trees available in most IMAS IDS: grid_ggd
and ggd
. The former contains the description of the grid itself; the latter, all quantities given with reference to this grid (for, value of electron temperature at all grid nodes, values of energy flux at all nodes at the divertor surface etc.). A more detailed description will be given in section 5.
The files provided are intended to support storing triangular 2D grids in the grid_ggd
structure. In the future (if required), they can be upgraded to support work with 3D grids consisting of a triangular 2D grid in the poloidal plane and a grid in the toroidal direction.
5.1. Structure of EIRENE files keeping the grid
There are three files describing the triangular grid used in EIRENE.
The file defining the grid nodes and their coordinates (soledge3x.npco_char
in the provided example) starts with the number of nodes in the line 1. The rest of lines contain 3 number each:
node index, R (or X) coordinate (cm), Z (or Y) coordinate (cm).
The file defining the triangles in terms of its vertices (soledge3x.elemente
in the provided example) has the following structure. The line 1 contains the number of triangles. Each following line contains 4 integers:
triangle index, index of vertex 1 (in the grid node list), index of vertex 2, index of vertex 3.
The file describing the boundaries and neighbours of the triangles in terms of its vertices (soledge3x.neighbor
in the provided example) has the following structure. The line 1 contains the number of triangles. Each following line contains 12 integers:
triangle index, N1, S1, M1, N2, S2, M2, N3, S3, M3, ixtri
, iytri
.
Here Ni is the index of the neighbouring triangle on side i, Si is the index of this side in the triangle Ni, Mi is the ‘material property’ of the side i, ixtri
and iytri
are not used now (they are zeros in this example). Note that side 1 connects vertices 1 and 2; side 2, vertices 2 and 3; side 3, vertices 3 and 1. The material property (MP) is an index referring to a surface model defined in the main EIRENE file. In particular, MP is 0 for transparent (i.e., internal) grid edges. The MP of boundary edges can have different positive values. In the provides example, there are boundary edges with MP = 1, 2, 3.
5.2. Presentation of EIRENE grid in GGD
We begin with brief overview of general principles of presentation of grids in the grid_ggd
structure.
We will follow the terminology of the GGD manual. The IMAS data dictionary is a hierarchical tree-like structure consisting of substructures. The following terms will be used:
- A node is any element of the tree.
- A simple node is a regular single node.
- An array of structures node (AOS) is a 1D array of structures under the same node label.
- A leaf is and endpoint of the tree. It holds data in specified format.
- The parent of a node is the element one level above this node.
- A child of a node is an element one level below this node.
- A sibling of a node is a node having the same parent.
First of all, grid_ggd
is AOS whose elements correspond to different time slices of the IDS. If the grid does not depend on time, this array can contain only one element.
Each element of grid_ggd
has (inter alia) two children AOS’s: spaces and grid subsets.
The spaces are used to contain the description of geometric objects constituting the grid, including their location in space. Let us consider a rectangular grid in 2D space as an example. To describe it, we can introduce one 2D space, provide the coordinates of all nodes and then describe the other grid elements (edges and cells) in terms of the nodes they consist of. However, it may be easier to choose another way. We can organize two 1D spaces, put the nodes along each coordinate and (if required) describe edges connecting these nodes.
It seems that for EIRENE in 3D geometry, it will be worthwhile to introduce 2 spaces: a 2D space in the poloidal plane and a 1D space in the toroidal direction. At present, only the poloidal 2D space is implemented.
The main child of each element of the space
AOS is the objects_per_dimension
AOS, each element of this AOS having only one child – the object
AOS.
The element objects_per_dimension(1)
contains information about the 0D objects of the space – the grid nodes. In each element of the object
AOS, only one child – the geometry(:)
real array containing the spatial coordinates of the node – is actually filled.
The 2nd and 3rd elements of objects_per_dimension
hold information about 1D and 2D objects, respectively. For each 1D object (edge), we store the indices of the 2 nodes that the edge connects. They are stored in the nodes(:)
child of each object. For a 2D object (triangle), we fill its children nodes(:) (with 3 elements) and boundary. In the AOS boundary
, we fill the index
child leaf (the index of the bounding edge) and one element of the neighbours
child AOS (the index of the neighbouring triangle).
Each grid subset is an arbitrary set of grid elements of the same dimensionality. For examples, all grid nodes, all grid edges, all grid cells, all boundary grid edges, all cells situated in SOL can be examples of subsets. Each subset provided in the grid_ggd
branch can be used in the ggd
branch of the IDS in order to save a distribution of some physical quantity on this subset. For example, if we have organized the subset of all boundary edges in 2D, we can save in ggd
the flux of particles through these edges as a 1D array. By giving a reference to this grid subset, we establish relation between the flux values and the edges.
To describe a subset, we can refer to objects from several spaces. Let us consider again the example of a 2D rectangular grid represented via two 1D grid spaces. The subset of all grid nodes can be organized as follows. The grid_subset
AOS has a child element, holding information about all subset elements. In our case, the elements are the grid nodes. Each node can be described as a combination of one node of the x-grid and one node of the y-grid. So, each element in the element
AOS has the only child – the object
AOS. Each element of the object
AOS has three leaves: space
(the index of the space from which it is taken), dimension
(its dimensionality index), and index
(its index in the list of objects of this dimensionality). In our case, the elements are grid nodes. Each node (element) can be described as a combination of one node of the x-grid (0-dimensional object of the x-space) and one node of the y-grid (0-dimensional object of the x-space).
The subsets can be distinguished by their identifiers. The identifier
node has three leaves:
name
contains the name given to the subset.index
contains the integer identifier given to the subset (the list of standard integer identifiers can be found in the GGD manual).description
contains a verbose description.
For the triangular EIRENE grid, the following subsets are created (this list can be extended if required or shortened if some subsets are not needed):
- Subset of all nodes in the poloidal plane (the subset name is
'pol1'
, the integer identifier is 1). - Subset of all edges in the poloidal plane (the subset name is
'pol2'
, the integer identifier is 2). - Subset of all 2D cells (triangles) in the poloidal plane (the subset name is
'pol3'
). - Several subsets of edges with a certain MP in the poloidal plane (the subset names are
'MPnnnn'
, where nnnn is the material property value). - Special subset with no objects for storing averages in
ggd_fast
(the subset name is 'average'). - Subset of all nodes in 3D space.
- Subset of all 3D cells (trigonal prisms).
At present, only items 1-4 of this lists are implemented.
5.3. Module triangular_grid_module
The module contains a data type for storing the information about all elements of a triangular grid and a library of methods (subroutines and functions). The methods solve the following tasks:
- Reading and writing files in the EIRENE format
- Checking the grid description for sanity
- Building the missing parts of the information from available parts
The last item is important because the information set in the EIRENE files and the information set in GGD are different. In particular, the EIRENE files do not contain information about edges.
The module depends on the IMAS module ids_types
(uses the constant IDS_real
– the kind of real variables in IMAS).
5.3.1. Data types provided
The following data types are provided:
type triangular_grid
type(coordinates_2d), allocatable, dimension(:) :: vertex
type(triangle_structure), allocatable, dimension(:) :: triangle
type(edge_structure), allocatable, dimension(:) :: edge
end type triangular_grid
The type triangular_grid
is intended for storing the description of a triangular grid, its components keeping information about the grid vertices, the grid cells (triangles), and the grid edges, respectively.
type coordinates_2d
real(IDS_real) :: x, y
end type coordinates_2d
The type coordinates_2d
is intended for storing the grid point coordinates in the poloidal plane.
type triangle_structure
integer :: vertex(3)
integer :: neighbor(3) = (/0,0,0/)
integer :: neighbors_side(3) = (/0,0,0/)
integer :: side(3)
integer :: material_property(3)=(/0,0,0/)
integer :: ixtri=0, iytri=0
end type triangle_structure
The type triangle_structure
is intended for storing information about a grid triangle, including the information about neighbouring triangles available in the EIRENE files. The integer child array vertex holds indices of the triangle vertices in triangular_grid%vertex
. The child arrays side
and material_property
hold indices of the sides in triangular_grid%edges
and their MPs, respectively (side 1 connects vertices 1 and 2; side 2, vertices 2 and 3; side 3, vertices 3 and 1). The child arrays neighbor
and neighbors_side
hold indices of the corresponding neighbouring triangles Ni in triangular_grid%triangle
and the indices of the separating edge in Ni. The child leaves ixtri
and iytri
will be used later (maybe).
type edge_structure
integer :: vertex(2)
integer :: material_property=0
integer :: adjacent(2)=(/0,0/)
end type edge_structure
The type edge_structure
is intended for information about an edge. The integer child array vertex
holds indices of the edge vertices in triangular_grid%vertex
. The leaf material_property
holds the MP of the edge. The child array adjacent
holds the indices of the neighbouring triangles in triangular_grid%triangle
.
5.3.2. Methods provided
The module member routines are as follows:
function read_eirene_grid
Read information about a triangular grid from EIRENE-format files and generate a list of grid edges;subroutine write_eirene_grid
Write information about a triangular grid into EIRENE-format files;subroutine provide_grid_object_lists
Provide lists of objects (nodes, edges and cells); nodes are characterized by their coordinates; edges and cells, by indices of nodes they consist of;subroutine arrange_neighbors
Build information about neighboring cells necessary the EIRENE file format;integer, allocatable, dimension(:) function give_edges_with_mat_property
Provide list of all MP values available in the grid;subroutine deallocate_grid
Deallocate the structure child arrays.
Service routines:
subroutine read_vertices
subroutine read_triangles
subroutine read_neighbors
subroutine write_vertices
subroutine write_triangles
subroutine write_neighbors
subroutine find_neighboring_triangles
integer function find_side
subroutine write_edges
subroutine check_edges
subroutine check_vertices
subroutine grid_statistics
integer function neighboring_triangle_index
integer function edge_index
Detailed description of the methods:
function read_eirene_grid (coord_file, triangles_file, neighbors_file, do_tests, io_unit) result (grid)
Read information about a triangular grid from EIRENE-format files and generate a list of grid edges (using the method build_edges
).
Argument / result | Type | Intent | Description |
---|---|---|---|
grid | type(triangular_grid) | result | Grid structure holding the content of the files |
coord_file | character(len=*) | in | Name of the file holding grid node coordinates |
triangles_file | character(len=*) | in | Name of the file holding indices of triangle vertices |
neighbors_file | character(len=*) | in | Name of the file holding information about neighbours of triangles |
do_tests | logical | in | Turns on/off sanity checks |
io_unit | integer, optional | in | Number of the i/o unit used (equals to 69 by default) |
subroutine write_eirene_grid (grid, coord_file, triangles_file, neighbors_file, do_tests, io_unit)
Write information about a triangular grid into EIRENE-format files;
Argument | Type | Intent | Description |
---|---|---|---|
grid | type(triangular_grid) | in | Grid structure |
coord_file | character(len=*) | in | Name of the file to hold grid node coordinates |
triangles_file | character(len=*) | in | Name of the file to hold indices of triangle vertices |
neighbors_file | character(len=*) | in | Name of the file to hold information about neighbours of triangles |
do_tests | logical | in | Turns on/off sanity checks |
io_unit | integer, optional | in | Number of the i/o unit used (equals to 69 by default) |
subroutine provide_grid_object_lists (grid, coordinates, edge_connect, cell_connect)
Given a grid stucture, the subroutine provides three arrays:
coordinates
, real 2D array containing the coordinates for all grid nodes;edge_connect
, integer 2D array containing indices of vertices for all edges;cell_connect
, integer 2D array containing indices of vertices for all cells (triangles).
This subroutine is no longer used in the module triangular_grid_ids_io.f90
.
Argument | Type | Intent | Description |
---|---|---|---|
grid | type(triangular_grid) | in | Grid structure |
coordinates | real(IDS_real), dimension(:,:) | out | Array containing the coordinates of all vertices |
edge_connect | integer, dimension(:,:) | out | Array containing indices of vertices for all edges |
cell_connect | integer, dimension(:,:) | out | Array containing indices of vertices for all triangles |
subroutine arrange_neighbors (grid)
Process a grid structure taken from IMAS, filling up the missing components of grid%triangle
(information about neighbouring edges and triangles).
Argument | Type | Intent | Description |
---|---|---|---|
grid | type(triangular_grid) | inout | Grid structure to be completed |
subroutine build_edges (grid)
Process a grid structure, building the missing substructure grid % edge
. The order of the edges in the substructure is as follows: side 1 of triange 1, side 2 of triange 1, side 3 of triange 1, side 1 of triangle 2 (if not accounted for earlier), side 2 of triangle 2 (if not accounted for earlier), and so on.
Argument | Type | Intent | Description |
---|---|---|---|
grid | type(triangular_grid) | inout | Grid structure to be completed |
function give_edges_with_mat_property (grid, mat_property)
Return a list of edges with a given value of MP.
Argument | Type | Intent | Description |
---|---|---|---|
grid | type(triangular_grid) | in | Grid structure |
mat_property | integer | in | MP value |
result | integer, allocatable, dimension(:) | result | List of edge indices in grid % edge |
subroutine deallocate_grid (grid)
Deallocate all grid components.
Argument | Type | Intent | Description |
---|---|---|---|
grid | type(triangular_grid) | in | Grid structure |
For description of service routines (some of them are no longer used), see comments in the module file.
5.4. Module triangular_grid_ids_io
The module contains routines that support writing a grid having the type(triangular_grid)
form to IMAS IDS's and, vice versa, reading a grid from IMAS and putting it into the type(triangular_grid)
form. It depends on the module triangular_grid_module
and the IMAS modules ids_schemas
and ids_routines
.
The module contains the following routines:
get_triangular_grid_from_ids
Read a triangular grid contained in a given space of a GGD grid and transform it into atype(triangular_grid)
-structure.put_eirene_grids_to_ids
Save a triangular grid given as atype(triangular_grid)
-structure ingrid_ggd
, invoking other routines of this module (arrange_triangular_grid_space
,arrange_standard_2d_subset
, andarrange_mat_property_subset
).arrange_triangular_grid_space
Put a triangular grid given as atype(triangular_grid)
-structure to a desiredgrid_ggd
space.arrange_standard_2d_subset
Arrange a "standard" subset in the poloidal space (subset of all nodes, all edges, or all triangular cells).arrange_mat_property_subset
Arrange a subset of edges with a certain value of MP.
Detailed description of the methods:
function get_triangular_grid_from_ids (grid_ggd, space_index) result (eirene_grid)
Read data about a triangular grid from a given space of GGD grid, put it into a type(triangular_grid)
-structure and call the function arrange_neighbors
(from triangular_grid_module
) to build the missing parts of the structure.
Argument | Type | Intent | Description |
---|---|---|---|
eirene_grid | type(triangular_grid) | result | The retrieved grid |
grid_ggd | type(ids_generic_grid_aos3_root), pointer | pointer | Pointer to the grid_ggd AOS element containing the grid |
space_index | integer | in | Index of the triangular grid in space AOS |
subroutine put_eirene_grids_to_ids (eirene_grid, coord_type, grid_ggd, nSpaces, eirene_space_index, grid_name, grid_description, eirene_space_name, eirene_space_description)
Allocate the space AOS in a given grid_ggd
element with a given number of grid spaces, put a triangular grid given as a type(triangular_grid)
-structure into a desired element of the space
AOS, and organize necessary grid subsets.
Argument | Type | Intent | Description |
---|---|---|---|
eirene_grid | type(triangular_grid) | in | The grid to be saved |
grid_ggd | type(ids_generic_grid_aos3_root), pointer | pointer | Pointer to the grid_ggd AOS element to hold the grid |
coord_type | integer | in | To be done |
nSpaces | integer | in | The dimension of |
eirene_space_index | integer | in | Index of the triangular grid space in |
grid_name | character(len=*) | in | Name assigned to the |
grid_description | character(len=*) | in | Verbose description of the |
eirene_space_name | character(len=*) | in | Name assigned to the triangular grid space |
eirene_space_description | character(len=*) | in | Verbose description of the triangular grid space |
subroutine arrange_triangular_grid_space (space, grid, space_name, space_description)
Put a triangular grid into a given element of the space
AOS. The grid information is taken from a type(triangular_grid)
-structure.
Argument | Type | Intent | Description |
---|---|---|---|
space | type(ids_generic_grid_dynamic_space), pointer | pointer | Pointer to the space AOS element to hold the space |
grid | type(triangular_grid) | in | The grid to be saved |
space_name | character(len=*) | in | Name assigned to the triangular grid space |
space_description | character(len=*) | in | Verbose description of the triangular grid space |
subroutine arrange_standard_2d_subset(subset, space, space_index, dimensionality, subset_id)
Arrange a "standard" subset in the poloidal space – a subset of all nodes, edges, or triangular cells (depending on the dimensionality, 1, 2, or 3, respectively). The subset gets the name 'poln', where n is the dimensionality.
Argument | Type | Intent | Description |
---|---|---|---|
subset | type(ids_generic_grid_dynamic_grid_subset), pointer | pointer | Pointer to the |
space | type(ids_generic_grid_dynamic_space), pointer | pointer | Pointer to the |
space_index | integer | in | Index of the triangular grid space in the |
dimensionality | integer | in | Dimensionality of subset objects (1 for nodes, 2 for edges etc.) |
subset_id | integer | in | Integer identifier of the subset |
subroutine arrange_mat_property_subset (subset, space, space_index, grid, mat_property, subset_id)
Arrange a subset for edges with a certain value of MP. The subset gets the name 'MPnnnn', where nnnn is the MP value.
Argument | Type | Intent | Description |
---|---|---|---|
subset | type(ids_generic_grid_dynamic_grid_subset), pointer | pointer | Pointer to the |
space | type(ids_generic_grid_dynamic_space), pointer | pointer | Pointer to the |
space_index | integer | in | Index of the triangular grid space in the |
grid | type(triangular_grid) | in | The grid being saved |
mat_property | integer | in | MP value |
subset_id | integer | in | Integer identifier of the subset |
6. Storing EIRENE input
Only a part of input quantities are now processed.
6.1. Structure of EIRENE input files
6.2. Module ???
6.3. Main files save_input_main.f90
and provide_input_main
.f90
The program contained in the file save_grid.f90
performs the following actions:
- Initializes an instance of the
edge_profiles
IDS in the code memory (with writing some mandatory fields), using the subroutinesetIDSFundamentals
(module ids_utility). - Writes some labels to the IDS.
- Allocates the
grid_ggd
AOS with only one element. - Reads information about the grid from files and establishes grid edges, using the
read_eirene_grid
function (moduletriangular_grid_module
). - Puts the grid information into the IDS, using the
put_triangular_grid_to_ids
subroutine (moduletriangular_grid_ids_io
). - Creates the corresponding IDS in an IMAS database, using the
createIDS
subroutine (moduleids_utility
). - Writes the IDS prepared in the code memory to the IMAS database and closes the database, using the subroutine
putIDS
(moduleids_utility
).
The program contained in the file recover_grid.f90
performs the following actions:
- Opens the IMAS database by calling the subroutine
imas_open_env
. - Reads the IMAS IDS
edge_profiles
, using the subroutineids_get
. - Extracts the information about the grid from the IDS and puts it into a
type(triangular_grid)
-structure, using the subroutineget_triangular_grid_from_ids
(moduletriangular_grid_ids_io
). - Writes the grid to EIRENE-format files (subroutine
write_eirene_grid
, moduletriangular_grid_module
). - Closes the IMAS database.
7. Things to be done
- Code parameters
- Extend the list of input quantities
- IMASification of EIRENE output
- Try to adjust the processing of exceptions to GSL practices (if worth while)