Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.


Info
titleQuote of the day

"You’re a man looking at the world through a keyhole,
and you’ve spent your whole life trying to widen that keyhole, to see more, to know more,
and now, on hearing that it can be widened, in ways you can’t imagine you reject the possibility."

The Ancient One - Doctor Strange

Table of Contents

Info

code parameters allow to store varaibles and parameters outside of actor code in elegant way.

The IMAS environment has specially dedicated library - xmllib to handle it.

Accessing code parameters from pure IMAS code

Prepare your environment:

Code Block
$ module load imasenv/3.24.0/rc
$ mkdir -p $ITMWORK/projects
$ cd $ITMWORK/projects
$ cp -r $SWIMASDIR/resources/tutorials/2019-10-PSNC/code_parameters .


Info

Before proceeding any further, make sure you have configured your Kepler environment. Take a look here 00. Initial setup or here 05.3. IMAS - basic topics - environment set-up(POZ'19Oct)

The structure of your working directory should look like this:

Code Block
$ cd code_parameters
$ tree
.
├── input_test_xmllib_pathquery.xml
├── input_test_xmllib_pathquery.xsd
├── Makefile						# instructions on how to compile
├── sample_default.xml
├── sample.f90						# code with accessing code parameters
├── sample.xml						# file with parameters
└── sample.xsd						# defining the structure of an XML document

A sample xml file containing information in the form of parameters for an actor:

Code Block
titlesample.xml
<?xml version="1.0"?>

<?xml-stylesheet type="text/xsl" href="./ets.xsl" charset="ISO-8859-1"?>

<parameters>

  <input>
    <shot_in>              4     </shot_in>          <!-- shot number -->
    <run_in>               1     </run_in>           <!-- run number -->
    <interpol>             1     </interpol>         <!-- interpolation index -->
    <time_dep_input>       0     </time_dep_input>   <!-- 1 implies time dependence in input data -->
  </input>


  <output>
    <shot_out>             5     </shot_out>         <!-- shot number -->
    <run_out>              2     </run_out>          <!-- run number -->
    <tau_out>         0.0003    </tau_out>          <!-- output frequency -->
    <db_out>         mdsplus     </db_out>           <!-- output database format -->
  </output>


  <dims>
    <nrho>                50     </nrho>             <!-- NRHO,  number of radial points -->
    <npsi>                100    </npsi>             <!-- NPSI,  number of equilibrium points -->
    <neq_dim1>            100    </neq_dim1>         <!-- NDIM1, number of points for 2-D equilibrium signals in R direction -->
    <neq_dim2>            100    </neq_dim2>         <!-- NDIM2, number of points for 2-D equilibrium signals in Z direction -->
    <neq_max_npoints>     100    </neq_max_npoints>  <!-- MAX_NPOINTS,  number of equilibrium boundary points -->
  </dims>

...

  <experimental>
    <option>              -1     </option>           <!-- option #: 0: disabled -->
  </experimental>

</parameters>

The first 35 lines of this code show how you can handle reading of the xml file in which the actor's parameters are saved:

Code Block
titlesample.f90
linenumberstrue
!> Test program Christian Konz version of xmllib.
program sample

  use xml_file_reader, only: fill_param
  use xml2eg_mdl
  use xmllib_parser, only: element, tree, xmllib_parse, destroy_xml_tree
  use string_manipulation_tools

  implicit none

  ! Input parameters, read from file
  character(132), pointer :: param_xml(:)     => NULL()
  character(132), pointer :: param_xsd(:)     => NULL()
  character(132), pointer :: param_default(:) => NULL()

  ! Input file names:
  character(132) :: fn_xml = 'sample.xml'
  character(132) :: fn_xml_default = 'sample.xml'
  character(132) :: fn_xsd = 'sample.xsd'

  ! Representation of xml parameters
  TYPE(tree) :: parameter_list
  TYPE(element), POINTER :: temp_pointer => null()
  character(len = 132) :: cname

  ! Values parser from xml
  integer :: shot_in, run_in
  integer(4) :: nparm
  real(8) :: geo_ax

  call fill_param(param_xml, param_default, param_xsd, fn_xml, fn_xml_default, fn_xsd)

  CALL XMLLIB_PARSE(param_xml, param_xsd, param_default, nparm, parameter_list)

  temp_pointer => parameter_list%first

  outer: do

     write(*,*)'Next xml element: ',temp_pointer%cname
     cname = char2str(temp_pointer%cname)   ! necessary for AIX
     !write(0,*)'RFOF_input::RFOF_parse_xml_input_param, cname=',trim(cname)

     select case (cname)
	 ...
     end select

     do
        if (associated(temp_pointer%sibling)) then
           temp_pointer => temp_pointer%sibling
           exit
        end if
        if (associated(temp_pointer%parent, parameter_list%first )) &
             exit outer
        if (associated(temp_pointer%parent)) then
           temp_pointer => temp_pointer%parent
        else
           write(0, *) 'ERROR: broken list.'
           stop
        end if
     end do
  end do outer

  !-- destroy tree
  call destroy_xml_tree(parameter_list)

end program sample


Run an example:

Code Block
$ module load imasenv/3.24.0/rc		# load environment if not set
$ make
ifort  -fPIC -g  -I/gw/swimas/extra/xmllib/3.2.0/intel/17.0/include/xmllib -I/usr/include/libxml2   -c -o sample.o sample.f90
ifort -fPIC -g  -o sample.exe sample.o  -L/gw/swimas/extra/xmllib/3.2.0/intel/17.0/lib -lxmllib -lxml2
./sample.exe
 Next xml element: parameters
 Next xml element: input
 Next xml element: shot_in
 Read shot_in=           4
 Next xml element: run_in
 Read shot_in=           1
 Next xml element: interpol
 Next xml element: time_dep_input
 Next xml element: output
 Next xml element: dims
 Next xml element: compositions
 Next xml element: startup
 Next xml element: boundary
 Next xml element: equilibrium
 Next xml element: geo_ax
 Read geo_ax=   2.86000000000000
 Next xml element: plasma_ax
 Next xml element: amin
 Next xml element: elong
 Next xml element: tria_up
 Next xml element: tria_low
 Next xml element: solver
 Next xml element: experimental

Compare result with data inside sample.xml file.

Accessing code parameters from FC2K actor

Info

Before proceeding any further, make sure you have configured your Kepler environment. Take a look here 00. Initial setup or here 05.3. IMAS - basic topics - environment set-up(POZ'19Oct)

Prepare your environment:

Code Block
$ module load imasenv/3.24.0/rc
$ mkdir -p $ITMWORK/projects
$ cd $ITMWORK/projects
$ git clone ssh://git@git.iter.org/imex/fc2k-testing-framework.git
  
# OR copy from this location
$ cp -r $SWIMASDIR/resources/tutorials/2019-10-PSNC/fc2k-testing-framework .

The structure of your working directory should look like this:

Code Block
$ cd fc2k-testing-framework/primitives_param/fortran/
$ tree
.
├── clean.sh
├── Makefile
├── primitives_param.f90			# FC2K actor with accessing code parameters
├── primitivesparam_fc2k.xml		# FC2K configuration file
├── primitivesparam_workflow.xml	# example workflow  
├── run_test.sh						# script for run example
├── sample_default.xml
├── sample.xml						# XML file with parameters
└── sample.xsd						# defining the structure of an XML document


Let's see what the xml file looks like with the parameters.
Suppose we want to download an "i" parameter from this file.

Code Block
titlesample.xml
<?xml version="1.0"?>
<parameters>
  <r> 3.141592 </r>
  <i> 2 </i> 
  <boolean> True False </boolean>
  <realVec> 2.7e2  4.0 </realVec>
  <intVec> 13 7 </intVec>
  <booleanVec> True False </booleanVec>
</parameters>


Below is an example of the code that retrieves parameters/i value from an xml file:

Code Block
titleprimitives_param.f90
linenumberstrue
subroutine primitivesparam(in_input, out_output, user_in_codeparamstruct)

  use ids_schemas, only: ids_real, ids_int, ids_equilibrium, ids_core_profiles, ids_parameters_input
  use xml2eg_mdl, only: xml2eg_parse_memory, xml2eg_get, type_xml2eg_document, xml2eg_free_doc, set_verbose
  use iso_c_binding, only: c_int

  implicit none

  integer, intent(in)        :: in_input
  integer, intent(out)       :: out_output
  integer(ids_int)           :: value_int
  integer(c_int)             :: tmp_value_int

  type(ids_parameters_input) :: user_in_codeparamstruct
  type(type_xml2eg_document) :: doc

  ! Parse the "codeparam_string". This means that the data is put into a document "doc"
  call xml2eg_parse_memory( user_in_codeparamstruct%parameters_value, doc )
  call set_verbose(.TRUE.)

  ! Extract data in "doc" at position "parameters/i" and store it in "int_value"
  call xml2eg_get( doc , 'i' , tmp_value_int)

  value_int  = int( tmp_value_int, ids_int )

  ! Make sure to clean up after you!!
  ! When calling "xml2eg_parse_memory" memory was allocated in the "doc" object.
  ! This memory is freed by "xml2eg_free_doc(doc)"
  call xml2eg_free_doc(doc)

  out_output = in_input + value_int

  return

end subroutine



Run an example:

Code Block
$ module load imasenv/3.24.0/rc		# load environment if not set
$ ./run_test.sh
Compilation - OK
Skipping log removal
FC2K build for primitives with params - OK
Skipping log removal
Workflow execution: primitives with params - OK
Skipping log removal
Checking output - should be equal to '3' - OK
Skipping log removal

Investigate test.log file to find more detailed information on this example.