summaryrefslogtreecommitdiff
path: root/doc/IGE332/chapter1.tex
diff options
context:
space:
mode:
Diffstat (limited to 'doc/IGE332/chapter1.tex')
-rw-r--r--doc/IGE332/chapter1.tex7412
1 files changed, 7412 insertions, 0 deletions
diff --git a/doc/IGE332/chapter1.tex b/doc/IGE332/chapter1.tex
new file mode 100644
index 0000000..5e8a5ef
--- /dev/null
+++ b/doc/IGE332/chapter1.tex
@@ -0,0 +1,7412 @@
+\section{The GANLIB Version 5 architecture}
+
+The GANLIB is a small library that is linked to a software application in order to facilitate modularity,
+interoperability, and to bring generic capabilities in term of data transfer. The GANLIB is an application programming
+interface (API) made of subroutines that are called by the software application (e.g., a lattice code) or by
+the multi-physics surrounding application. In other words, the GANLIB acts as a standardized interface between the
+software application and the multi-physics application, as depicted in \Fig{multi}.
+
+\begin{figure}[htbp]
+\begin{center}
+\epsfxsize=9cm
+\centerline{ \epsffile{multiphysics.eps}}
+\parbox{12cm}{\caption{Implementing a multi-physics application.}\label{fig:multi}}
+\end{center}
+\end{figure}
+\goodbreak
+
+\vskip 0.08cm
+
+The GANLIB is made of two distinct and inter-related components:
+\begin{itemize}
+\item CLE--2000 is a compact supervisor responsible for the free-format recovery of input data, for the modularization
+of the software application and for the insertion of loops and control statements in the input data flow. CLE-2000
+permits the conception of {\sl computational schemes}, dedicated to specific engineering studies, without any need
+for recompilation of the software application.\cite{cle2000}
+\item LCM objects are data structures used to transfer data between modules of the software application and towards the
+multi-physics application. LCM objects are structures made of {\sl associative table} and {\sl heterogeneous lists}. These
+structures are either {\sl memory resident} or {\sl persistent} (i.e., stored in a file). The LCM object API is implemented
+with access efficiency as its first requirement, even for frequent calls with small chunks of data.\cite{lcm2002}
+\end{itemize}
+
+\vskip 0.08cm
+
+The GANLIB Version 5 is implemented in the ANSI~C programming language\cite{ansiC}, in order to maximize its compatibility
+in a multi-physics environment where different components are implemented in various programming languages (C++,
+Fortran, Java, etc.). The GANLIB Version 5 is {\sl 64-bit clean}, another benefit of using an ANSI~C implementation. This
+last property allows the execution of software applications with 32-bit integers and 64-bit addresses. Specific Fortran
+APIs are also available and are implemented according to the C interoperability mechanism,
+available in Fortran~2003 and standardized by the International Organization for Standardization (ISO). This architecture is 64-bit clean.\cite{fortran2003}
+
+\vskip 0.8cm
+
+\subsection {From Versions 3 or 4 to Version 5}
+
+The Version 3 and Version 4 software applications available at GAN are using a legacy GANLIB, implemented in FORTRAN~77,
+and relatively unchanged for more than 15~years.\cite{lcm1994} The only addition in Version~4 are the heterogeneous lists within LCM
+objects. This Fortran implementation is {\sl not} ISO standard and {\sl not} 64-bit clean. However, the corresponding API
+is mature and efficient, two qualities that we want to preserve.
+
+\vskip 0.08cm
+
+A software application is not 64-bit clean when 32-bit integers are used to store addresses (or differences between
+two addresses). This nasty operation is possible in ANSI~C but can always be avoided. Unfortunately, this operation
+is extensively used in software applications DRAGON, TRIVAC and DONJON Versions 3 or 4, due to design constraints
+related to the choice of FORTRAN~77 as programming language.
+
+\vskip 0.08cm
+
+Versions 3 or 4 software applications can be re-implemented around the Version~5 GANLIB in order to become ISO standard and 64-bit clean.
+However, the conversion process is not automatic and is time-consuming. Two major modifications must be done:
+\begin{enumerate}
+\item All variables containing addresses of LCM objects must be declared as {\tt TYPE(C\_PTR)} instead of been
+declared as {\tt INTEGER}. The intrinsic type {\tt TYPE(C\_PTR)} is available in Fortran~2003, as defined by ISO.
+\item Every call to the {\tt SETARA} subroutine of the GANLIB must be replaced by an {\tt ALLOCATE} statement and every call to the {\tt RLSARA}
+subroutine must be replaced by a {\tt DEALLOCATE} statement. Statements {\tt ALLOCATE} and {\tt DEALLOCATE} are
+available in Fortran~90, as defined by ISO. The {\tt ALLOCATABLE} attribute is used to identify allocated arrays. Blank common
+are no longer required as reference addresses. This modification
+is the more time-consuming of the two.
+\end{enumerate}
+
+\vskip 0.08cm
+
+Implementing software applications in Fortran 2003 offers the opportunity to use advanced features of this language, such
+as pointers, Fortran modules (not to be confused with CLE-2000 modules) and polymorphism. However, this is a programming
+style issue which is independent of the selection of GANLIB Version 5. It is possible, as a pragmatic choice, to keep the Fortran-77 programming style
+and just use the GANLIB Version~5, {\tt TYPE(C\_PTR)} types and {\tt ALLOCATABLE} arrays.
+
+\section {The ANSI C {\sc lcm} API}\label{sect:lcmapiC}
+
+LCM objects are data structures, implemented in ANSI~C, with characteristics of {\sl associative tables} (a.k.a., dictionaries or
+hash tables) and/or {\sl heterogeneous lists} (a.k.a., cell arrays). These data structures are either stored in memory or are persistent
+(i.e., stored in a file). These objects are primarily accessed via an API implemented in ANSI~C. Access by other languages is
+possible via {\sl specific bindings} that are also described in this report. Deep copy and serialization utilities are available.
+
+\vskip 0.08cm
+
+Persistence is implemented using XSM data structures, together with another API implemented in ANSI~C. {\sc xsm} files are used
+in this case. However, the XSM API
+is invoked from within LCM and a developer using the GANLIB never has to call it directly.
+
+\vskip 0.08cm
+
+The {\sc lcm} API was implemented in such a way that
+\begin{itemize}
+\item the access from ANSI~C or from Fortran is highly optimized, even for frequent calls with small chunks of data.
+\item the access from other languages (Matlab, Python, Java, or Objective~C) permits a complete read/write access
+of the totality of information contained in the object.
+\end{itemize}
+
+\vskip 0.08cm
+
+This technical report contains the precise description of each ANSI~C function available in the {\sc lcm} API and dedicated
+to a programmer using the GANLIB Version~5.
+
+\vskip 0.08cm
+
+A LCM object is a collection of the following elements:
+\vskip 0.08cm
+{\bf Associative tables} \\
+An associative table is equivalent to a Python dictionary or to a Java hash table. Each element of an associative table is an association between a 12-character name and a block of data. A block of data can be an array of some elementary type, another associative table or an heterogeneous list. Tree structures can be constructed that way.
+\vskip 0.08cm
+{\bf Heterogeneous list} \\
+An heterogeneous list is an ordered set of blocks of information (referred as ``0", ``1", ``2", etc. ). A block of data can be an array of some elementary type, another associative table or an heterogeneous list.
+\vskip 0.08cm
+{\bf Array of elementary type} \\
+An array of elementary type is a set of consecutive values in memory, all of the same type. The type is selected in the following table: \\
+\begin{tabular}{|c|c|c|}
+\hline
+index & array of ... & type\\
+\hline
+1 & 32-bit integer & int\_32 \\
+2 & 32-bit real & float\_32 \\
+3 & 4-character strings & \\
+4 & 64-bit real & double\_64 \\
+5 & 32-bit logical & int\_32 \\
+6 & 64-bit complex& \\
+\hline
+\end{tabular}
+
+\vskip 0.08cm
+
+Any ANSI~C function calling the {\sc lcm} API must use an include file of the form
+\begin{verbatim}
+#include "lcm.h"
+\end{verbatim}
+
+Each LCM object has a {\sl root associative table} from which the complete object is constructed.
+
+\clearpage
+
+\subsection{General utility functions}
+
+\subsubsection{strcut\_c\index{strcut\_c}}
+
+Copy {\tt n} characters from string {\tt ct} to {\tt s}. Eliminate leading {\tt ' '} and {\tt '}$\backslash${\tt 0'}
+characters in {\tt s}. Terminate {\tt s} with a {\tt '}$\backslash${\tt 0'}.
+
+\begin{verbatim}
+
+strcut_c(s, ct, n);
+\end{verbatim}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt ct} & {\it char*} & character variable of length {\tt n}. May not be null-terminated.\\
+\hline
+{\tt n} & {\it int\_32} & length of {\tt ct}. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameter:} \\
+\hline
+{\tt s} & {\it char*} & null terminated string. \\
+\hline
+\multicolumn{3}{|c|}{\bf value of the function:} \\
+\hline
+\multicolumn{2}{|l|}{\it void} & \\
+\hline
+\end{tabular}
+
+\subsubsection{strfil\_c\index{strfil\_c}}
+
+Copy {\tt n} characters from string {\tt ct} to {\tt s}. Eliminate {\tt '}$\backslash${\tt 0'} characters and
+pack with {\tt ' '}. Assume that {\tt ct} is null-terminated.
+
+\begin{verbatim}
+
+strfil_c(s, ct, n);
+\end{verbatim}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt ct} & {\it char*} & null-terminated character variable.\\
+\hline
+{\tt n} & {\it int\_32} & expected length of {\tt s}. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameter:} \\
+\hline
+{\tt s} & {\it char*} & character variable of length {\tt n} (not null-terminated). \\
+\hline
+\multicolumn{3}{|c|}{\bf value of the function:} \\
+\hline
+\multicolumn{2}{|l|}{\it void} & \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\subsection{Opening, closing and validation of LCM objects}
+
+\subsubsection{lcmop\_c\index{lcmop\_c}}
+
+Open an LCM object (either memory resident or persistent). Obtain the address of the LCM
+object if it is created. Note that CLE-2000 is responsible to perform the calls to
+{\tt lcmop\_c} for the LCM objects that are used as parameters of a CLE-2000 module. The use
+of {\tt lcmop\_c} is generally restricted to the use of temporary LCM objects created within a CLE-2000 module.
+
+\begin{verbatim}
+
+lcmop_c(iplist,namp,imp,medium,impx);
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt iplist} & {\it lcm**} & address of the LCM object if {\tt imp=1} or {\tt imp=2}. {\tt iplist} corresponds to the address of the root associative table. \\
+\hline
+{\tt namp} & {\it char[73]} & name of the LCM object if {\tt imp=0}. \\
+\hline
+{\tt imp} & {\it int\_32} & =0 to create a new LCM object ;
+ =1 to modify an existing LCM object;
+ =2 to access an existing LCM object in {\bf read-only} mode. \\
+\hline
+{\tt medium} & {\it int\_32} & =1 to use a memory-resident LCM object;
+ =2 to use an {\sc xsm} file to store the LCM object. \\
+\hline
+{\tt impx} & {\it int\_32} & print parameter. Equal to zero to suppress all printings. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameters:} \\
+\hline
+{\tt iplist} & {\it lcm**} & address of an LCM object if {\tt imp=0}. \\
+\hline
+{\tt namp} & {\it char*} & name of the LCM object if {\tt imp=1} or {\tt imp=2}. \\
+\hline
+\multicolumn{3}{|c|}{\bf value of the function:} \\
+\hline
+\multicolumn{2}{|l|}{\it void} & \\
+\hline
+\end{tabular}
+
+\subsubsection{lcmcl\_c\index{lcmcl\_c}}
+
+Close an LCM object (either memory resident or persistent). Note that CLE-2000 is responsible to perform the calls to
+{\tt lcmcl\_c} for the LCM objects that are used as parameters of a CLE-2000 module. The use
+of {\tt lcmcl\_c} is generally restricted to the use of temporary LCM objects created within a CLE-2000 module.
+
+\vskip 0.2cm
+
+A LCM object can only be closed if {\tt iplist} points towards its root directory.
+
+\begin{verbatim}
+
+lcmcl_c(iplist,iact);
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt iplist} & {\it lcm**} & address of the LCM object (address of the root directory of the LCM object). \\
+\hline
+{\tt iact} & {\it int\_32} & =1 close the LCM object without destroying it; =2 and destroying it; =3 erase and close the LCM object without destroying it. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameters:} \\
+\hline
+{\tt iplist} & {\it lcm**} & {\tt iplist=null} indicates that the LCM object is closed and destroyed. A memory-resident LCM object keeps the
+same address during its complete existence. A persistent LCM object is associated to an XSM file and is represented by a different
+value of {\tt iplist} each time it is reopened. \\
+\hline
+\multicolumn{3}{|c|}{\bf value of the function:} \\
+\hline
+\multicolumn{2}{|l|}{\it void} & \\
+\hline
+\end{tabular}
+
+\subsubsection{lcmval\_c\index{lcmval\_c}}
+
+Function to validate a single block of data in a LCM object or the totality of the LCM object,
+starting from the address of an associative table. This function has no effect if the object is
+persistent. The validation consists to verify the connections between the elements of the LCM
+object, to verify that each element of the object is defined and to check for possible memory corruptions.
+If an error is detected, the following message is issued:
+
+\begin{verbatim}
+LCMVAL_C: BLOCK xxx OF THE TABLE yyy HAS BEEN OVERWRITTEN.
+\end{verbatim}
+
+This function is called as
+
+\begin{verbatim}
+
+lcmval_c(iplist,namp);
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt iplist} & {\it lcm**} & address of the associative table or of the heterogeneous list. \\
+\hline
+{\tt namp} & {\it char*} & name of the block to validate in the associative table.
+If {\tt namp='~'}, all the blocks in the associative table are verified in a recursive way. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{4.0cm}|p{11cm}|}
+\hline
+\multicolumn{2}{|c|}{\bf value of the function:} \\
+\hline
+{\it void} & \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\subsection{Interrogation of LCM objects}
+
+The data structures in an LCM object are self-described. It is therefore possible to
+interrogate them in order to know their characteristics.
+
+\vskip 0.4cm
+
+\begin{center}
+\begin{tabular}{|c|l|l|l|}
+\cline{3-4}
+\multicolumn{2}{c|}{} & \multicolumn{2}{c|}{type of interrogation} \\
+\cline{3-4}
+\multicolumn{2}{c|}{} & father structure~~~~ & information block \\
+\hline
+father & associative table & {\tt lcminf\_c} & {\tt lcmlen\_c} \\
+ & & {\tt lcmnxt\_c} & \\
+\cline{2-4}
+ & heterogeneous list & {\tt lcminf\_c} & {\tt lcmlel\_c} \\
+\hline
+\end{tabular}
+\end{center}
+
+\subsubsection{lcmlen\_c\index{lcmlen\_c}}
+
+Function used to recover the length and type of an information block stored in an
+associative table (either memory-resident or persistent). The length is the number of
+elements in a daughter heterogeneous list or the number of elements in an array of elementary type.
+If {\tt itylcm=3}, the length is the number of four-character words. As an example, the length required
+to store an array of eight-character words is twice its dimension.
+
+\begin{verbatim}
+
+lcmlen_c(iplist,namp,ilong,itylcm);
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt iplist} & {\it lcm**} & address of the associative table. \\
+\hline
+{\tt namp} & {\it char*} & name of the block. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameters:} \\
+\hline
+{\tt ilong} & {\it int\_32*} & length of the block. =$-1$ for a daughter associative table;
+ =$N$ for a daughter heterogeneous list containing $N$ components;
+ =0 if the block does't exist. \\
+\hline
+{\tt itylcm} & {\it int\_32*} & type of information. =0 associative table; =1 32-bit integer;
+ =2 32-bit real; =3 4-character data;
+ =4 64-bit real; =5 32-bit logical; =6 64-bit complex; =10 heterogeneous list;
+ =99 undefined (99 is returned if the block does't exist). \\
+\hline
+\multicolumn{3}{|c|}{\bf value of the function:} \\
+\hline
+\multicolumn{2}{|l|}{\it void} & \\
+\hline
+\end{tabular}
+
+\subsubsection{lcminf\_c\index{lcminf\_c}}
+
+Function used to recover general information about a LCM object.
+
+\begin{verbatim}
+
+lcminf_c(iplist,namlcm,nammy,empty,ilong,lcm,access);
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameter:} \\
+\hline
+{\tt iplist} & {\it lcm**} & address of the associative table or of the heterogeneous list. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameters:} \\
+\hline
+{\tt namlcm} & {\it char[73]} & name of the LCM object. \\
+\hline
+{\tt nammy} & {\it char[13]} & name of the associative table at address {\tt iplist}. $=${\tt '/'} if the associative table
+is the root of the LCM object; $=${\tt ' '} if the associative table
+is an heterogeneous list component. \\
+\hline
+{\tt empty} & {\it int\_32*} & 32-bit integer variable set to $1$
+ if the associative table is empty
+ or set to $0$ otherwise. \\
+\hline
+{\tt ilong} & {\it int\_32*} & $=-1$: {\tt iplist} is an associative table; $>0$: number of components in the heterogeneous list {\tt iplist}. \\
+\hline
+{\tt lcm} & {\it int\_32*} & 32-bit integer variable set to $1$
+ if information is memory-resident or set to $0$ if information is persistent (stored in an XSM file). \\
+\hline
+{\tt access} & {\it int\_32*} & 32-bit integer variable set to the access mode of object. $=0$: the object
+is closed (only available for memory-resident LCM objects); $=1$: the object is open for modification;
+$=2$: the object is open in read-only mode.\\
+\hline
+\multicolumn{3}{|c|}{\bf value of the function:} \\
+\hline
+\multicolumn{2}{|l|}{\it void} & \\
+\hline
+\end{tabular}
+
+\subsubsection{lcmnxt\_c\index{lcmnxt\_c}}
+
+Function used to find the name of the next block of data in an associative table. Use
+of {\tt lcmnxt\_c} is forbidden if the associative table is empty. The order of names is
+arbitrary. The search cycle indefinitely.
+
+\begin{verbatim}
+
+lcmnxt_c(iplist,namp);
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt iplist} & {\it lcm**} & address of the associative table. \\
+\hline
+{\tt namp} & {\it char*} & name of an existing block.
+ {\tt namp=' '} can be used to obtain a first name to initiate the search. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameters:} \\
+\hline
+{\tt namp} & {\it char*} & name of the next block.
+ A call to {\tt xabort\_c} is performed if the associative table is empty. \\
+\hline
+\multicolumn{3}{|c|}{\bf value of the function:} \\
+\hline
+\multicolumn{2}{|l|}{\it void} & \\
+\hline
+\end{tabular}
+
+\subsubsection{lcmlel\_c\index{lcmlel\_c}}
+
+Function used to recover the length and type of an information block stored in an
+heterogeneous list (either memory-resident or persistent). The length is the number of
+elements in a daughter heterogeneous list or the number of elements in an array of elementary type.
+If {\tt itylcm=3}, the length is the number of four-character words. As an example, the length required
+to store an array of eight-character words is twice its dimension.
+
+\begin{verbatim}
+
+lcmlel_c(iplist,iset,ilong,itylcm);
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt iplist} & {\it lcm**} & address of the heterogeneous list. \\
+\hline
+{\tt iset} & {\it int\_32} & index of the block in the list.
+The first element of the list is located at index $0$. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameters:} \\
+\hline
+{\tt ilong} & {\it int\_32*} & length of the block. =0 if the block does't exist. \\
+\hline
+{\tt itylcm} & {\it int\_32*} & type of information. =0 associative table; =1 32-bit integer;
+ =2 32-bit real; =3 4-chatacter data;
+ =4 64-bit real; =5 32-bit logical; =6 64-bit complex; =10 heterogeneous list;
+ =99 undefined (99 is returned if the block does't exist). \\
+\hline
+\multicolumn{3}{|c|}{\bf value of the function:} \\
+\hline
+\multicolumn{2}{|l|}{\it void} & \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\subsection{Management of the array of elementary type}
+
+Management of the array of elementary type can be performed {\sl with} copy of the data ({\tt lcmput\_c}, {\tt lcmget\_c}, {\tt lcmpdl\_c} or
+{\tt lcmgdl\_c}) or {\sl without} copy ({\tt lcmppd\_c}, {\tt lcmgpd\_c}, {\tt lcmppl\_c} or
+{\tt lcmgpl\_c}).
+
+\vskip 0.4cm
+
+\begin{center}
+\begin{tabular}{|c|l|l|l|}
+\cline{3-4}
+\multicolumn{2}{c|}{} & \multicolumn{2}{c|}{type of operation} \\
+\cline{3-4}
+\multicolumn{2}{c|}{} & put~~~~~~~~~~~~~ & get~~~~~~~~~~~~~ \\
+\hline
+father & associative table & {\tt lcmput\_c} & {\tt lcmget\_c} \\
+ & & {\tt lcmppd\_c} & {\tt lcmgpd\_c} \\
+\cline{2-4}
+ & heterogeneous list & {\tt lcmpdl\_c} & {\tt lcmgdl\_c} \\
+ & & {\tt lcmppl\_c} & {\tt lcmgpl\_c} \\
+\hline
+\end{tabular}
+\end{center}
+
+\subsubsection{lcmget\_c\index{lcmget\_c}}
+
+Function used to recover an information block (array of elementary type) from an associative table and to copy
+this data into memory.
+
+\begin{verbatim}
+
+lcmget_c(iplist,namp,data);
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt iplist} & {\it lcm**} & address of the associative table. \\
+\hline
+{\tt namp} & {\it char*} & name of the block to recover.
+ A call to {\tt xabort\_c} is performed if the block does't exist. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameters:} \\
+\hline
+{\tt data} & {\it int\_32*} & array of dimension $\ge$ {\tt ilong} in which the block is copied. \\
+\hline
+\multicolumn{3}{|c|}{\bf value of the function:} \\
+\hline
+\multicolumn{2}{|l|}{\it void} & \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+Function {\tt lcmget\_c} can be used to recover information of type other than {\it int\_32*} by using a
+cast operation. Here is an example:
+
+\begin{verbatim}
+#include "lcm.h"
+ ...
+ float_32 data[5];
+ lcm *iplist;
+ iplist=... ;
+ lcmget_c(&iplist,namp,(int_32*)data);
+\end{verbatim}
+
+\vskip 0.2cm
+
+Function {\tt lcmget\_c} can also be used to recover character-string information available in a block
+of the LCM object. It is also possible to use function {\tt lcmgcd\_c} presented in \Sect{lcmgcdc}.
+In the following example, a block is stored in an associative table located at
+address {\tt iplist}. The block has a name {\tt namp} and a length equivalent to 5 32-bit words.
+The information is recovered into the integer array {\tt idata} and transformed into a null-terminated
+character string {\tt hname} using the {\tt strcut\_c} utility:
+
+\begin{verbatim}
+#include "lcm.h"
+ ...
+ char *namp="...", hname[21];
+ int_32 idata[5];
+ lcm *iplist;
+ iplist=... ;
+ lcmget_c(&iplist,namp,idata);
+ strcut_c(hname,(char *)idata,20);
+\end{verbatim}
+
+\subsubsection{lcmput\_c\index{lcmput\_c}}
+
+Function used to store a block of data (array of elementary type) into an associative table.
+The information is copied from memory towards the LCM object. If the block already exists, it is replaced;
+otherwise, it is created. This operation cannot be performed into a LCM object open in {\tt read-only} mode.
+
+\begin{verbatim}
+
+lcmput_c(iplist,namp,ilong,itylcm,data);
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt iplist} & {\it lcm**} & address of the associative table. \\
+\hline
+{\tt namp} & {\it char*} & name of the block. \\
+\hline
+{\tt ilong} & {\it int\_32} & length of the block. \\
+\hline
+{\tt itylcm} & {\it int\_32} & type of information. =1 32-bit integer;
+ =2 32-bit real; =3 4-character data;
+ =4 64-bit real; =5 32-bit logical; =6 64-bit complex; =99 undefined. \\
+\hline
+{\tt data} & {\it int\_32*} & array of dimension $\ge$ {\tt jlong} to be copied into the LCM object. {\tt jlong}={\tt 2*ilong} if {\tt itylcm}=4 or {\tt itylcm}=6;
+ {\tt jlong}={\tt ilong} otherwise.
+ Array elements {\tt data[0]} to {\tt data[jlong-1]}
+ must be initialized before the call to {\tt lcmput\_c}. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{4.0cm}|p{11cm}|}
+\hline
+\multicolumn{2}{|c|}{\bf value of the function:} \\
+\hline
+{\it void} & \\
+\hline
+\end{tabular}
+
+\vskip 0.4cm
+
+Function {\tt lcmput\_c} can be used to store information of type other than {\it int\_32*} by using a
+cast operation. Here is an example:
+
+\begin{verbatim}
+#include "lcm.h"
+ ...
+ float_32 data[5];
+ lcm *iplist;
+ int_32 i;
+ iplist=... ;
+ for (i=0;i<5;i++) {
+ data[i]=... ;
+ }
+ lcmput_c(&iplist,namp,5,2,(int_32*)data);
+\end{verbatim}
+
+\vskip 0.2cm
+
+Function {\tt lcmput\_c} can also be used to store character-string information in an associative table
+of a LCM object. It is also possible to use function {\tt lcmpcd\_c} presented in \Sect{lcmpcdc}. In the
+following example, a character string {\tt hname} is first transformed into an integer array {\tt idata}
+using the {\tt strfil\_c} utility. This array (block of data) is stored into the LCM object located at
+address {\tt iplist}, using {\tt lcmput\_c}. The block has a name {\tt namp}, a length equivalent
+to 5 32-bit words, and a type equal to 3.
+
+\begin{verbatim}
+#include "lcm.h"
+ ...
+ char *namp="...", hname[20];
+ int_32 idata[5], il=5, it=3;
+ lcm *iplist;
+ iplist=... ;
+ strfil_c((char *)idata,hname,20);
+ lcmput_c(&iplist,namp,il,it,idata);
+\end{verbatim}
+
+\subsubsection{lcmgpd\_c\index{lcmgpd\_c}}
+
+Function used to recover the memory address of an information block (array of elementary type) from an associative table,
+{\sl without} making a copy of the information. Use of this function must respect the following rules:
+\begin{itemize}
+\item If the information is modified after the call to {\tt lcmgpd\_c}, a call to {\tt lcmppd\_c}
+must be performed to acknowledge the modification.
+\item The block {\tt *iofset} should never be released using a deallocation function such as
+{\tt rlsara\_c}, {\tt free}, etc.
+\item The address {\tt iofset} must never be copied into another variable.
+\end{itemize}
+Non respect of these rules may cause execution failure (core dump,
+segmentation fault, etc) without possibility to throw an exception.
+
+\vskip 0.2cm
+
+A call to {\tt lcmgpd\_c} doesn't cause any modification to the LCM object.
+The data array information is accessed directly from memory locations {\tt *iofset[0]} to {\tt *iofset[ilong-1]}
+where {\tt iofset} is the address returned by function {\tt lcmgpd\_c}.
+
+\begin{verbatim}
+
+lcmgpd_c(iplist,namp,iofset);
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt iplist} & {\it lcm**} & address of the associative table. \\
+\hline
+{\tt namp} & {\it char*} & name of the block to recover.
+ A call to {\tt xabort\_c} is performed if the block does't exist. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameters:} \\
+\hline
+{\tt iofset} & {\it int\_32**} & address of the data array. \\
+\hline
+\multicolumn{3}{|c|}{\bf value of the function:} \\
+\hline
+\multicolumn{2}{|l|}{\it void} & \\
+\hline
+\end{tabular}
+
+\subsubsection{lcmppd\_c\index{lcmppd\_c}}
+
+Function used to store a block of data (array of elementary type) into an associative table
+{\sl without} making a copy of the information. If the block already exists, it is replaced;
+otherwise, it is created. This operation cannot be performed into a LCM object open in {\tt read-only} mode.
+
+\vskip 0.2cm
+
+{\sl If a block named {\tt namp} already exists in the associative table, the address associated
+with {\tt namp} is replaced by the new address and the information pointed by the old address
+is deallocated.}
+
+\vskip 0.2cm
+
+The array containing information stored by {\tt lcmppd\_c} {\sl must be} originally
+allocated by a call of the form
+{\tt iofset = setara\_c(jlong)} or {\tt iofset = (int\_32*)malloc(jlong*sizeof(int\_32))}.
+where {\tt jlong} is generally equal to {\tt ilong} except if
+{\tt itylcm}=4 or {\tt itylcm}=6 where {\tt jlong}={\tt 2*ilong}.
+
+\begin{verbatim}
+
+lcmppd_c(iplist,namp,ilong,itylcm,iofset);
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt iplist} & {\it lcm**} & address of the associative table. \\
+\hline
+{\tt namp} & {\it char*} & name of the block. \\
+\hline
+{\tt ilong} & {\it int\_32} & length of the block. \\
+\hline
+{\tt itylcm} & {\it int\_32} & type of information. =1 32-bit integer;
+ =2 32-bit real; =3 4-character data;
+ =4 64-bit real; =5 32-bit logical; =6 64-bit complex; =99 undefined. \\
+\hline
+{\tt iofset} & {\it int\_32*} & address of the data array of length {\tt jlong}, as returned by {\tt setara\_c}. {\tt jlong}={\tt 2*ilong}
+ if {\tt itylcm}=4 or {\tt itylcm}=6; {\tt jlong}={\tt ilong} otherwise.
+ Data elements {\tt iofset[0]} to {\tt iofset[jlong-1]}
+ must be initialized before the call to {\tt lcmppd\_c}. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{4.0cm}|p{11cm}|}
+\hline
+\multicolumn{2}{|c|}{\bf value of the function:} \\
+\hline
+{\it void} & \\
+\hline
+\end{tabular}
+
+\vskip 0.4cm
+
+The information block of address {\tt iofset} will automatically be deallocated using function {\tt rlsara\_c}
+at closing time of the LCM object. Situations exist where this block is shared with data structures other
+than LCM, and where the block must {\sl not} be deallocated by the {\sc lcm} API. In this case, it is imperative
+to follow the call to {\tt lcmppd\_c} by a call to function {\tt refpush} of the form:
+
+\begin{verbatim}
+refpush(iplist,iofset);
+\end{verbatim}
+
+\subsubsection{lcmdel\_c\index{lcmdel\_c}}
+
+Function used to erase an information block or a daughter heterogeneous list stored in a memory-resident associative table.
+Function {\tt lcmdel\_c} {\sl cannot} be used with persistent LCM objects.
+
+\begin{verbatim}
+
+lcmdel_c(iplist,namp);
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt iplist} & {\it lcm**} & address of the associative table. \\
+\hline
+{\tt namp} & {\it char*} & name of the block to erase. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{4.0cm}|p{11cm}|}
+\hline
+\multicolumn{2}{|c|}{\bf value of the function:} \\
+\hline
+{\it void} & \\
+\hline
+\end{tabular}
+
+\subsubsection{lcmgdl\_c\index{lcmgdl\_c}}
+
+Function used to recover an information block (array of elementary type) from an heterogeneous list and to copy
+this data into memory.
+
+\begin{verbatim}
+
+lcmgdl_c(iplist,iset,data);
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt iplist} & {\it lcm**} & address of the heterogeneous list. \\
+\hline
+{\tt iset} & {\it int\_32} & index of the block in the heterogeneous list. A call to {\tt xabort\_c}
+ is performed if the block does't exist.
+The first element of the list is located at index $0$. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameters:} \\
+\hline
+{\tt data} & {\it int\_32*} & array of dimension $\ge$ {\tt ilong} in which the block is copied. \\
+\hline
+\multicolumn{3}{|c|}{\bf value of the function:} \\
+\hline
+\multicolumn{2}{|l|}{\it void} & \\
+\hline
+\end{tabular}
+
+\vskip 0.4cm
+
+Function {\tt lcmgdl\_c} can be used to recover character-string information available in a block
+of the LCM object. It is also possible to use subroutine {\tt lcmgcl\_c} presented in \Sect{lcmgclc}. In the following example, a block is stored in an the heterogeneous list located at
+address {\tt iplist}. The block is located at the {\tt iset}--th position of the heterogeneous list and has a length equivalent to 5 32-bit words.
+The information is recovered into the integer array {\tt idata} and transformed into a null-terminated
+character string {\tt hname} using the {\tt strcut\_c} utility:
+
+\begin{verbatim}
+#include "lcm.h"
+ ...
+ char *namp="...", hname[21];
+ int_32 iset,idata[5];
+ lcm *iplist;
+ iplist=... ;
+ iset=...;
+ lcmgdl_c(&iplist,iset,idata);
+ strcut_c(hname,(char *)idata,20);
+\end{verbatim}
+
+\subsubsection{lcmpdl\_c\index{lcmpdl\_c}}
+
+Function used to store a block of data (array of elementary type) into an heterogeneous list.
+The information is copied from memory towards the LCM object. If the block already exists, it is replaced;
+otherwise, it is created. This operation cannot be performed into a LCM object open in {\tt read-only} mode.
+
+\begin{verbatim}
+
+lcmpdl_c(iplist,iset,ilong,itylcm,data);
+\end{verbatim}
+
+\vskip 0.2cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt iplist} & {\it lcm**} & address of the heterogeneous list. \\
+\hline
+{\tt iset} & {\it int\_32} & index of the block in the list.
+The first element of the list is located at index $0$. \\
+\hline
+{\tt ilong} & {\it int\_32} & length of the block. \\
+\hline
+{\tt itylcm} & {\it int\_32} & type of information. =1 32-bit integer;
+ =2 32-bit real; =3 4-character data;
+ =4 64-bit real; =5 32-bit logical; =6 64-bit complex; =99 undefined. \\
+\hline
+{\tt data} & {\it int\_32*} & array of dimension $\ge$ {\tt ilong} to be copied into the LCM object. {\tt jlong}={\tt 2*ilong}
+ if {\tt itylcm}=4 or {\tt itylcm}=6; {\tt jlong}={\tt ilong} otherwise.
+ Array elements {\tt data[0]} to {\tt data[jlong-1]}
+ must be initialized before the call to {\tt lcmpdl\_c}. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{4.0cm}|p{11cm}|}
+\hline
+\multicolumn{2}{|c|}{\bf value of the function:} \\
+\hline
+{\it void} & \\
+\hline
+\end{tabular}
+
+\vskip 0.4cm
+
+Function {\tt lcmpdl\_c} can be used to store character-string information into an heterogeneous list of a LCM object. In the
+following example, a character string {\tt hname} is first transformed into an integer array {\tt idata}
+using the {\tt strfil\_c} utility. This array (block of data) is stored into the LCM object located at
+address {\tt iplist}, using {\tt lcmpdl\_c} . The block is located at the {\tt iset}--th position of the heterogeneous list, has a length equivalent to 5 32-bit words, and a type
+equal to 3.
+
+\begin{verbatim}
+#include "lcm.h"
+ ...
+ char *namp="...", hname[20];
+ int_32 iset,idata[5],it=3,il=5;
+ lcm *iplist;
+ iplist=... ;
+ iset=...;
+ strfil_c((char *)idata,hname,20);
+ lcmpdl_c(&iplist,iset,il,it,idata);
+\end{verbatim}
+
+\subsubsection{lcmgpl\_c\index{lcmgpl\_c}}
+
+Function used to recover the memory address of an information block (array of elementary type) from an heterogeneous list,
+{\sl without} making a copy of the information. Use of this function must respect the following rules:
+\begin{itemize}
+\item If the information is modified after the call to {\tt lcmgpl\_c}, a call to {\tt lcmppl\_c}
+must be performed to acknowledge the modification.
+\item The block {\tt *iofset} should never be released using a deallocation function such as
+{\tt rlsara\_c}, {\tt free}, etc.
+\item The address {\tt iofset} must never be copied into another variable.
+\end{itemize}
+Non respect of these rules may cause execution failure (core dump,
+segmentation fault, etc) without possibility to throw an exception.
+
+\vskip 0.2cm
+
+A call to {\tt lcmgpl\_c} doesn't cause any modification to the LCM object.
+The data array information is accessed directly from memory locations {\tt *iofset[0]} to {\tt *iofset[ilong-1]}
+where {\tt iofset} is the address returned by function {\tt lcmgpl\_c}.
+
+\begin{verbatim}
+
+lcmgpl_c(iplist,iset,iofset);
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt iplist} & {\it lcm**} & address of the heterogeneous list. \\
+\hline
+{\tt iset} & {\it int\_32} & index of the block in the list.
+A call to {\tt xabort\_c} is performed if the block does't exist.
+The first element of the list is located at index $0$. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameters:} \\
+\hline
+{\tt iofset} & {\it int\_32**} & address of the data array, as returned by {\tt setara\_c}. \\
+\hline
+\multicolumn{3}{|c|}{\bf value of the function:} \\
+\hline
+\multicolumn{2}{|l|}{\it void} & \\
+\hline
+\end{tabular}
+
+\subsubsection{lcmppl\_c\index{lcmppl\_c}}
+
+Function used to store a block of data (array of elementary type) into an heterogeneous list
+{\sl without} making a copy of the information. If the block already exists, it is replaced;
+otherwise, it is created. This operation cannot be performed into a LCM object open in {\tt read-only} mode.
+
+\vskip 0.2cm
+
+{\sl If the {\tt iset}-th component of the heterogeneous list already exists, the address associated
+with this component is replaced by the new address and the information pointed by the old address
+is deallocated.}
+
+\vskip 0.2cm
+
+The array containing information stored by {\tt lcmppl\_c} {\sl must be} originally
+allocated by a call of the form
+{\tt iofset = setara\_c(jlong)} or {\tt iofset = (int\_32*)malloc(jlong*sizeof(int\_32))}
+where {\tt jlong} is generally equal to {\tt ilong} except if
+{\tt itylcm}=4 or {\tt itylcm}=6 where {\tt jlong}={\tt 2*ilong}.
+
+\begin{verbatim}
+
+lcmppl_c(iplist,iset,ilong,itylcm,iofset);
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt iplist} & {\it lcm**} & address of the heterogeneous list. \\
+\hline
+{\tt iset} & {\it int\_32} & index of the block in the list.
+The first element of the list is located at index $0$. \\
+\hline
+{\tt ilong} & {\it int\_32} & length of the block. \\
+\hline
+{\tt itylcm} & {\it int\_32} & type of information. =1 32-bit integer;
+ =2 32-bit real; =3 4-character data;
+ =4 64-bit real; =5 32-bit logical; =6 64-bit complex;
+ =99 undefined. \\
+\hline
+{\tt iofset} & {\it int\_32*} & address of the data array, as returned by {\tt setara\_c}. {\tt jlong}={\tt 2*ilong}
+ if {\tt itylcm}=4 or {\tt itylcm}=6; {\tt jlong}={\tt ilong} otherwise.
+ Data elements {\tt iofset[0]} to {\tt iofset[jlong-1]}
+ must be initialized before the call to {\tt lcmppl\_c}. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{4.0cm}|p{11cm}|}
+\hline
+\multicolumn{2}{|c|}{\bf value of the function:} \\
+\hline
+{\it void} & \\
+\hline
+\end{tabular}
+
+\vskip 0.4cm
+
+The information block of address {\tt iofset} will automatically be deallocated using function {\tt rlsara\_c}
+at closing time of the LCM object. Situations exist where this block is shared with data structures other
+than LCM, and where the block must {\sl not} be deallocated by the {\sc lcm} API. In this case, it is imperative
+to follow the call to {\tt lcmppl\_c} by a call to function {\tt refpush} of the form:
+
+\begin{verbatim}
+refpush(iplist,iofset);
+\end{verbatim}
+
+\vskip 0.8cm
+
+\subsection{Management of the associative tables and of the heterogeneous lists}
+
+These functions permit to create ({\tt lcmsix\_c}, {\tt lcmdid\_c}, {\tt lcmdil\_c},
+{\tt lcmlid\_c}, {\tt lcmlil\_c}) or to access ({\tt lcmsix\_c}, {\tt lcmgid\_c}, {\tt lcmgil\_c})
+daughter associative tables or daughter heterogeneous lists. Use of these functions is summarized in the following table:
+
+\vskip 0.4cm
+
+\begin{center}
+\begin{tabular}{|c|l|l|l|}
+\cline{3-4}
+\multicolumn{2}{c|}{} & \multicolumn{2}{c|}{daughter} \\
+\cline{3-4}
+\multicolumn{2}{c|}{} & associative table & heterogeneous list \\
+\hline
+father & associative table & {\tt lcmdid\_c} & {\tt lcmlid\_c} \\
+ & & {\tt lcmgid\_c} & {\tt lcmgid\_c} \\
+\cline{2-4}
+ &heterogeneous list & {\tt lcmdil\_c} & {\tt lcmlil\_c} \\
+ & & {\tt lcmgil\_c} & {\tt lcmgil\_c} \\
+\hline
+\end{tabular}
+\end{center}
+
+\subsubsection{lcmdid\_c\index{lcmdid\_c}}
+
+Function used to create or access a daughter associative table included into a father associative table. This operation cannot be
+performed in a LCM object open in {\tt read-only} mode.
+
+\vskip 0.2cm
+
+The daughter associative table is created if it doesn't already exist. Otherwise, the
+existing daughter associative table is accessed. In the latter case, it is recommended
+to use function {\tt lcmgid\_c} which is faster for a simple access and which can be used
+with LCM object open in {\tt read-only} mode.
+
+\begin{verbatim}
+
+lcmdid_c(iplist,namp);
+\end{verbatim}
+
+\vskip 0.5cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameterss:} \\
+\hline
+{\tt iplist} & {\it lcm**} & address of the father associative table. \\
+\hline
+{\tt namp} & {\it char*} & name of the daughter associative table. \\
+\hline
+\end{tabular}
+
+\vskip 0.4cm
+
+\noindent
+\begin{tabular}{|p{4.0cm}|p{11cm}|}
+\hline
+\multicolumn{2}{|c|}{\bf value of the function:} \\
+\hline
+{\it lcm*} & address of the daughter associative table. \\
+\hline
+\end{tabular}
+
+\subsubsection{lcmlid\_c\index{lcmlid\_c}}
+
+Function used to create or access a daughter heterogeneous list included into a father associative table. This operation cannot be
+performed in a LCM object open in {\tt read-only} mode.
+
+\vskip 0.2cm
+
+In the following example, a daughter heterogeneous list is created as a block {\tt LIST}
+into a father associative table. The heterogeneous list contains 5~components. A block of data
+is stored in each component of the heterogeneous list using {\tt lcmppl\_c}:
+
+\begin{verbatim}
+#include "lcm.h"
+ ...
+ lcm *iplist,*jplist;
+ int_32 n=5, i ;
+ ...
+ jplist=lcmlid_c(&iplist,"LIST",n);
+ for(i=0;i<5;i++) {
+ lcmppl_c(&jplist,i,...
+ }
+\end{verbatim}
+
+\vskip 0.2cm
+
+The heterogeneous list capability is implemented through calls to function {\tt lcmlid\_c}. Such a
+call permit the following possibilities:
+\begin{itemize}
+\item the heterogeneous list is created if it doesn't already exist.
+\item the heterogeneous list is accessed if it already exists {\sl and} if its length is unchanged. In this case,
+it is recommended to use function {\tt lcmgid\_c} which is faster for a simple access and which can be used
+with LCM object open in {\tt read-only} mode.
+\item the heterogeneous list is enlarged (components are added) if it already exists {\sl and} if the new length is larger than the preceding one.
+\end{itemize}
+
+\begin{verbatim}
+
+lcmlid_c(iplist,namp,ilong);
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameterss:} \\
+\hline
+{\tt iplist} & {\it lcm**} & address of the father associative table. \\
+\hline
+{\tt namp} & {\it char*} & name of the daughter heterogeneous list. \\
+\hline
+{\tt ilong} & {\it int\_32} & number of components in the daughter heterogeneous list.\\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{4.0cm}|p{11cm}|}
+\hline
+\multicolumn{2}{|c|}{\bf value of the function:} \\
+\hline
+{\it lcm*} & address of the daughter heterogeneous list named {\tt namp}. \\
+\hline
+\end{tabular}
+
+\subsubsection{lcmlil\_c\index{lcmlil\_c}}
+
+Function used to create or access a daughter heterogeneous list included into a father heterogeneous list. This operation cannot be
+performed in a LCM object open in {\tt read-only} mode.
+
+\vskip 0.2cm
+
+In the following example, a daughter heterogeneous list is created as {\tt 77}-th component
+of a father heterogeneous list. The heterogeneous list contains 5~components. A block of data
+is stored in each component of the heterogeneous list using {\tt lcmppl\_c}:
+
+\begin{verbatim}
+#include "lcm.h"
+ ...
+ lcm *iplist,*jplist;
+ int_32 n=5, i, iset=77 ;
+ ...
+ jplist=lcmlil_c(&iplist,iset,n);
+ for(i=0;i<5;i++) {
+ lcmppl_c(&jplist,i,...
+ }
+\end{verbatim}
+
+\vskip 0.2cm
+
+The heterogeneous list capability is implemented through calls to function {\tt lcmlil\_c}. Such a
+call permit the following possibilities:
+\begin{itemize}
+\item the heterogeneous list is created if it doesn't already exist.
+\item the heterogeneous list is accessed if it already exists {\sl and} if its length is unchanged. In this case,
+it is recommended to use function {\tt lcmgil\_c} which is faster for a simple access and which can be used
+with LCM object open in {\tt read-only} mode.
+\item the heterogeneous list is enlarged (components are added) if it already exists {\sl and} if the new length is larger than the preceding one.
+\end{itemize}
+
+\begin{verbatim}
+
+lcmlil_c(iplist,iset,ilong);
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameterss:} \\
+\hline
+{\tt iplist} & {\it lcm**} & address of the father heterogeneous list. \\
+\hline
+{\tt iset} & {\it int\_32} & index of the daughter heterogeneous list in the father heterogeneous list.
+The first element of the list is located at index $0$. \\
+\hline
+{\tt ilong} & {\it int\_32} & number of components in the daughter heterogeneous list. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{4.0cm}|p{11cm}|}
+\hline
+\multicolumn{2}{|c|}{\bf value of the function:} \\
+\hline
+{\it lcm*} & address of the daughter heterogeneous list. \\
+\hline
+\end{tabular}
+
+\subsubsection{lcmdil\_c\index{lcmdil\_c}}
+
+Function used to create or access a daughter associative table included into a father heterogeneous list. This operation cannot be
+performed in a LCM object open in {\tt read-only} mode.
+
+\vskip 0.2cm
+
+The daughter associative table is created if it doesn't already exist. Otherwise, the
+existing daughter associative table is accessed. In the latter case, it is recommended
+to use function {\tt lcmgil\_c} which is faster for a simple access and which can be used
+with LCM object open in {\tt read-only} mode.
+
+\vskip 0.2cm
+
+It is a good programming practice to replace a set of $N$ distinct associative tables by a
+list made of $N$ associative tables, as depicted in \Fig{f1}.
+
+\vskip 0.2cm
+
+In the example of \Fig{f1}, a set of 5~associative tables, created by {\tt lcmdid\_c}:
+\begin{verbatim}
+#include "lcm.h"
+ ...
+ char HDIR[13]
+ lcm*iplist,*kplist ;
+ int_32 i;
+ HDIR[12] = '\0';
+ for(i=0;i<5;i++) {
+ (void)sprintf(HDIR,"GROUP%3d/ 5",i+1);
+ kplist=lcmsix_c(&iplist,HDIR);
+ lcmppd_c(&kplist,...);
+ ...
+ }
+\end{verbatim}
+
+\noindent are replaced by a list of 5~associative tables, created by {\tt lcmlid\_c} and {\tt lcmdil\_c}:
+
+\begin{verbatim}
+#include "lcm.h"
+ ...
+ lcm *iplist,*jplist,*kplist;
+ int_32 n=5 ;
+ jplist=lcmlid_c(&iplist,'GROUP',n);
+ for(i=0;i<5;i++) {
+ kplist=lcmdil_c(&jplist,i);
+ lcmppd_c(&kplist,...);
+ }
+\end{verbatim}
+
+\vskip 0.2cm
+
+\begin{figure}[htbp]
+\begin{center}
+\epsfxsize=9cm
+\centerline{ \epsffile{vect.eps}}
+\parbox{12cm}{\caption{A list of associative tables.}\label{fig:f1}}
+\end{center}
+\end{figure}
+
+\vskip 0.2cm
+
+The capability to include associative tables into an heterogeneous list is implemented using
+the {\tt lcmdil\_c} function:
+
+\begin{verbatim}
+
+lcmdil_c(iplist,iset);
+\end{verbatim}
+
+\vskip 0.5cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameterss:} \\
+\hline
+{\tt iplist} & {\it lcm**} & address of the father heterogeneous list. \\
+\hline
+{\tt iset} & {\it int\_32} & index of the daughter associative table in the father heterogeneous list.
+The first element of the list is located at index $0$. \\
+\hline
+\end{tabular}
+
+\vskip 0.4cm
+
+\noindent
+\begin{tabular}{|p{4.0cm}|p{11cm}|}
+\hline
+\multicolumn{2}{|c|}{\bf value of the function:} \\
+\hline
+{\it lcm*} & address of the daughter associative table. \\
+\hline
+\end{tabular}
+
+\subsubsection{lcmgid\_c\index{lcmgid\_c}}
+
+Function used to access a daughter associative table {\sl or} heterogeneous list included into a father associative table.
+
+\begin{verbatim}
+
+lcmgid_c(iplist,namp);
+\end{verbatim}
+
+\vskip 0.5cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameterss:} \\
+\hline
+{\tt iplist} & {\it lcm**} & address of the father associative table. \\
+\hline
+{\tt namp} & {\it char*} & name of the daughter associative table or heterogeneous list. \\
+\hline
+\end{tabular}
+
+\vskip 0.4cm
+
+\noindent
+\begin{tabular}{|p{4.0cm}|p{11cm}|}
+\hline
+\multicolumn{2}{|c|}{\bf value of the function:} \\
+\hline
+{\it lcm*} & address of the daughter associative table or heterogeneous list. A call to {\tt xabort\_c} is performed if this daughter doesn't extst. \\
+\hline
+\end{tabular}
+
+\subsubsection{lcmgil\_c\index{lcmgil\_c}}
+
+Function used to access a daughter associative table {\sl or} heterogeneous list included into a father heterogeneous list.
+
+\begin{verbatim}
+
+lcmgil_c(iplist,iset);
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameterss:} \\
+\hline
+{\tt iplist} & {\it lcm**} & address of the father heterogeneous list. \\
+\hline
+{\tt iset} & {\it int\_32} & index of the daughter associative table or heterogeneous list in the father heterogeneous list.
+The first element of the list is located at index $0$. \\
+\hline
+\end{tabular}
+
+\vskip 0.4cm
+
+\noindent
+\begin{tabular}{|p{4.0cm}|p{11cm}|}
+\hline
+\multicolumn{2}{|c|}{\bf value of the function:} \\
+\hline
+{\it lcm*} & address of the daughter associative table or heterogeneous list. A call to {\tt xabort\_c} is performed if this daughter doesn't extst. \\
+\hline
+\end{tabular}
+
+\subsubsection{lcmsix\_c\index{lcmsix\_c}}
+
+Function used to move across the hierarchical structure of a LCM object made of
+associative tables. Using this function, there is no need to remember the names of
+the father (grand-father, etc.) associative tables. If a daughter associative table doesn't
+exist and if the LCM object is open on creation or modification mode, the daughter
+associative table is created. A daughter associative table cannot be created if the
+LCM object is open in {\tt read-only} mode.
+
+\vskip 0.4cm
+
+Function {\tt lcmsix\_c} is deprecated, as {\tt lcmdid\_c} offers a more elegant way to perform the same operation.
+However, {\tt lcmsix\_c} is kept available in the {\sc lcm} API for historical reasons.
+
+\begin{verbatim}
+
+lcmsix_c(iplist,namp,iact);
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt iplist} & {\it lcm**} & address of the associative table before the call to {\tt lcmsix\_c}. \\
+\hline
+{\tt namp} & {\it char**} & name of the daughter associative table if {\tt iact=1}.
+ This parameter is not used if {\tt iact=0} or {\tt iact=2}. \\
+\hline
+{\tt iact} & {\it int\_32} & type of move: =0 return towards the root directory of the LCM object;
+ =1 move towards the daughter associative table (create it if it doesn't exist);
+ =2 return towards the father associative table. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameters:} \\
+\hline
+{\tt iplist} & lcm** & address of the associative table after the call to {\tt lcmsix\_c}. \\
+\hline
+\multicolumn{3}{|c|}{\bf value of the function:} \\
+\hline
+\multicolumn{2}{|l|}{\it void} & \\
+\hline
+\end{tabular}
+
+\vspace{0.8cm}
+
+\subsection{LCM utility functions}
+
+\subsubsection{lcmlib\_c\index{lcmlib\_c}}
+
+Function used to print (towards {\tt stdout}) the content of the active directory of an associative table or heterogeneous list.
+
+\begin{verbatim}
+
+lcmlib_c(iplist);
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameter:} \\
+\hline
+{\tt iplist} & {\it lcm**} & address of the associative table or of the heterogeneous list. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{4.0cm}|p{11cm}|}
+\hline
+\multicolumn{2}{|c|}{\bf value of the function:} \\
+\hline
+{\it void} & \\
+\hline
+\end{tabular}
+
+\subsubsection{lcmequ\_c\index{lcmequ\_c}}
+
+Function used to perform a deep-copy of the information contained in an associative table (address {\tt iplis1})
+towards another associative table (address {\tt iplis2}). Note that the second associative table (address {\tt iplis2}) is modified
+but not created by {\tt lcmequ\_c}.
+
+\begin{verbatim}
+
+lcmequ_c(iplis1,iplis2);
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameter:} \\
+\hline
+{\tt iplis1} & {\it lcm**} & address of the existing associative table or of the heterogeneous list
+ (accessed in {\tt read-only} mode). \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameters:} \\
+\hline
+{\tt iplis2} & {\it lcm**} & address of the associative table or of the heterogeneous list, modified by {\tt lcmequ\_c}. \\
+\hline
+\multicolumn{3}{|c|}{\bf value of the function:} \\
+\hline
+\multicolumn{2}{|l|}{\it void} & \\
+\hline
+\end{tabular}
+
+\subsubsection{lcmexp\_c\index{lcmexp\_c}}
+
+Function used to export (or import) the content of an associative table towards (or from) a sequential file. The sequential file
+can be in binary or {\tt ascii} format.
+
+\vskip 0.4cm
+
+The export of information starts from the active directoty. Note that {lcmexp\_c} is basically a serialization algorithm
+based on the contour algorithm.
+
+\begin{verbatim}
+
+lcmexp_c(iplist,impx,file,imode,idir);
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameterss:} \\
+\hline
+{\tt iplist} & {\it lcm**} & address of the associative table or of the heterogeneous list to be exported (or imported). \\
+\hline
+{\tt impx} & {\it int\_32} & print parameter (equal to 0 for no print). \\
+\hline
+{\tt file} & {\it FILE*} & sequential file. \\
+\hline
+{\tt imode} & {\it int\_32} & =1 binary sequential file;
+ =2 {\sc ascii} sequential file. \\
+\hline
+{\tt idir} & {\it int\_32} & =1 to export; =2 to import. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{4.0cm}|p{11cm}|}
+\hline
+\multicolumn{2}{|c|}{\bf value of the function:} \\
+\hline
+{\it void} & \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\subsection{Using variable-length string arrays}
+
+The following functions are implemented using the C~functions of the preceding sections. They
+permit the use of variable-length string arrays, a capability not yet available with the Fortran
+{\sc lcm} API.
+
+\vskip 0.4cm
+
+\begin{center}
+\begin{tabular}{|c|l|l|l|}
+\cline{3-4}
+\multicolumn{2}{c|}{} & \multicolumn{2}{c|}{type of operation} \\
+\cline{3-4}
+\multicolumn{2}{c|}{} & put~~~~~~~~~~~~~ & get~~~~~~~~~~~~~ \\
+\hline
+father & associative table & {\tt lcmpcd\_c} & {\tt lcmgcd\_c} \\
+\cline{2-4}
+ & heterogeneous list & {\tt lcmpcl\_c} & {\tt lcmgcl\_c} \\
+\hline
+\end{tabular}
+\end{center}
+
+\subsubsection{lcmgcd\_c\index{lcmgcd\_c}}\label{sect:lcmgcdc}
+
+Function used to recover a variable-length string array from a block of data stored in an associative table.
+
+\begin{verbatim}
+
+lcmgcd_c(iplist,namp,hdata);
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt iplist} & {\it lcm**} & address of the associative table. \\
+\hline
+{\tt namp} & {\it char*} & name of the variable-length string array
+to recover. A call to {\tt xabort\_c} is performed if the block does't exist. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameters:} \\
+\hline
+{\tt hdata} & {\it char**} & variable-length string array of dimension $\ge$ {\tt ilong}. The memory space required to represent the string array is allocated by {\tt lcmgcd\_c}.\\
+\hline
+\multicolumn{3}{|c|}{\bf value of the function:} \\
+\hline
+\multicolumn{2}{|l|}{\it void} & \\
+\hline
+\end{tabular}
+
+\subsubsection{lcmpcd\_c\index{lcmpcd\_c}}\label{sect:lcmpcdc}
+
+Function used to store a variable-length string array into a block of data stored in an associative table.
+If the block of data already exists, it is updated; otherwise, it is created. This operation cannot be performed
+in a LCM object open in {\tt read-only} mode.
+
+\begin{verbatim}
+
+lcmpcd_c(iplist,namp,ilong,hdata);
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt iplist} & {\it lcm**} & address of the associative table. \\
+\hline
+{\tt namp} & {\it char*} &name of the variable-length string array
+to store. \\
+\hline
+{\tt ilong} & {\it int\_32} & number of components in the variable-length string array.\\
+\hline
+{\tt hdata} & {\it char**} & array of dimension $\ge$ {\tt ilong} to be copied in the LCM object. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{4.0cm}|p{11cm}|}
+\hline
+\multicolumn{2}{|c|}{\bf value of the function:} \\
+\hline
+{\it void} & \\
+\hline
+\end{tabular}
+
+\vskip 0.4cm
+
+\noindent Example:
+\begin{verbatim}
+#include "lcm.h"
+ ...
+ lcm *iplist;
+ int_32 i, ilong = 5;
+ char *hdata1[ilong],*hdata2[ilong];
+
+ hdata1[0] = "string1";
+ hdata1[1] = " string2";
+ hdata1[2] = " string3";
+ hdata1[3] = " string4";
+ hdata1[4] = " string5";
+ for (i=0;i<ilong;i++) {
+ printf("i=%d string='%s' size=%d\n",i,hdata1[i],strlen(hdata1[i]));
+ }
+
+ lcmop_c(&iplist,"mon_dict",0,1,2);
+
+ /* Store the information */
+ lcmpcd_c(&iplist,"node1",ilong,hdata1);
+
+ /* Recover the information */
+ lcmgcd_c(&iplist,"node1",hdata2);
+
+ for (i=0;i<ilong;i++) {
+ printf("in table i=%d string='%s' size=%d\n",i,hdata2[i],strlen(hdata2[i]));
+ }
+ for (i=0;i<ilong;i++) free(hdata2[i]);
+ lcmcl_c(&iplist,2);
+\end{verbatim}
+
+\subsubsection{lcmgcl\_c\index{lcmgcl\_c}}\label{sect:lcmgclc}
+
+Function used to recover a variable-length string array from a block of data stored in an heterogeneous list.
+
+\begin{verbatim}
+
+lcmgcl_c(iplist,namp,hdata);
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt iplist} & {\it lcm**} & address of the heterogeneous list. \\
+\hline
+{\tt iset} & {\it int\_32} & index of the variable-length string array in the heterogeneous list. A call to {\tt xabort\_c} is performed if the component doesn't exist.
+The first element of the list is located at index $0$. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameters:} \\
+\hline
+{\tt hdata} & {\it char**} & variable-length string array of dimension $\ge$ {\tt ilong}. The memory space required to represent the string array is allocated by {\tt lcmgcl\_c}.\\
+\hline
+\multicolumn{3}{|c|}{\bf value of the function:} \\
+\hline
+\multicolumn{2}{|l|}{\it void} & \\
+\hline
+\end{tabular}
+
+\subsubsection{lcmpcl\_c\index{lcmpcl\_c}}\label{sect:lcmpclc}
+
+Function used to store a variable-length string array into a block of data stored in an heterogeneous list.
+If the block of data already exists, it is updated; otherwise, it is created. This operation cannot be performed
+in a LCM object open in {\tt read-only} mode.
+
+\begin{verbatim}
+
+lcmpcl_c(iplist,iset,ilong,hdata);
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt iplist} & {\it lcm**} & address of the heterogeneous list. \\
+\hline
+{\tt iset} & {\it int\_32} &index of the variable-length string array in the heterogeneous list.
+The first element of the list is located at index $0$. \\
+\hline
+{\tt ilong} & {\it int\_32} & number of components in the variable-length string array .\\
+\hline
+{\tt hdata} & {\it char**} & array of dimension $\ge$ {\tt ilong} to be copied in the LCM object. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{4.0cm}|p{11cm}|}
+\hline
+\multicolumn{2}{|c|}{\bf value of the function:} \\
+\hline
+{\it void} & \\
+\hline
+\end{tabular}
+
+\vskip 0.4cm
+
+\noindent Example:
+\begin{verbatim}
+#include "lcm.h"
+ ...
+ lcm *iplist, *jplist;
+ int_32 i, ilong = 5;
+ char *hdata1[ilong],*hdata2[ilong];
+
+ hdata1[0] = "string1";
+ hdata1[1] = " string2";
+ hdata1[2] = " string3";
+ hdata1[3] = " string4";
+ hdata1[4] = " string5";
+ for (i=0;i<ilong;i++) {
+ printf("i=%d string='%s' size=%d\n",i,hdata1[i],strlen(hdata1[i]));
+ }
+
+ lcmop_c(&iplist,"mon_dict",0,1,2);
+
+ /* Creation of the heterogeneous list */
+ jplist = lcmlid_c(&iplist,"node2",77);
+
+ /* Store the information */
+ lcmpcl_c(&jplist,4,ilong,hdata1);
+
+ /* Recover the information */
+ lcmgcl_c(&jplist,4,hdata2);
+
+ for (i=0;i<ilong;i++) {
+ printf("in list i=%d string='%s' size=%d\n",i,hdata2[i],strlen(hdata2[i]));
+ }
+ for (i=0;i<ilong;i++) free(hdata2[i]);
+
+ lcmcl_c(&iplist,2);
+\end{verbatim}
+
+\vskip 0.8cm
+
+\subsection{Dynamic allocation of the elementary blocks of data}
+
+\subsubsection{setara\_c\index{setara\_c}}\label{sect:setara}
+
+Function used to allocate a block of data for storing a memory-resident {\tt int\_32} data array.
+Function {\tt setara\_c} is a simple wrapper for {\tt malloc} standard library function.
+If the operating system fails to allocate the memory, a call to {\tt xabort\_c} is performed.
+
+\begin{verbatim}
+
+setara_c(ilong);
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameter:} \\
+\hline
+{\tt ilong} & {\it int\_32} & length of the block of data to allocate in unit of 32-bit words. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{4.0cm}|p{11cm}|}
+\hline
+\multicolumn{2}{|c|}{\bf value of the function:} \\
+\hline
+{\it int\_32*} & address of the allocated block of data. \\
+\hline
+\end{tabular}
+
+\subsubsection{rlsara\_c\index{rlsara\_c}}\label{sect:rlsara}
+
+Function used to deallocate a memory-resident block of data previously allocated by {\tt setara\_c}.
+The implementation of {\tt rlsara\_c} in ANSI~C is based on the {\tt free} standard library function. If the operating system fails to deallocate
+the memory, a call to {\tt xabort\_c} is performed.
+
+\begin{verbatim}
+
+rlsara_c(iofset);
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameter:} \\
+\hline
+{\tt iofset} & {\it int\_32*} & address of the block of data to deallocate. This value {\sl must} have been allocated by a previous call to {\tt setara\_c}. \\
+\hline
+\end{tabular}
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{4.0cm}|p{11cm}|}
+\hline
+\multicolumn{2}{|c|}{\bf value of the function:} \\
+\hline
+{\it void} & \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\subsection{Abnormal termination of the execution}
+
+\subsubsection{xabort\_c}
+
+Function used to cause the program termination. A message describing the conditions of the
+termination is printed.
+
+\vskip 0.2cm
+
+It is important to use this function to abort a program instead of using the {\tt exit()}
+function of the standard library. The {\tt xabort\_c} function can be used to implement {\sl exception
+treatment} in situations where the application software is driven by a multi-physics system.
+
+\vskip 0.2cm
+
+If an abnormal termination occurs, the {\tt xabort\_c} function is called as
+\begin{verbatim}
+ xabort_c("sub001: execution failure.");
+\end{verbatim}
+
+\begin{verbatim}
+
+xabort_c(hsmg);
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameter:} \\
+\hline
+{\tt hsmg} & {\it char*} & message describing the conditions of the abnormal termination. \\
+\hline
+\end{tabular}
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{4.0cm}|p{11cm}|}
+\hline
+\multicolumn{2}{|c|}{\bf value of the function:} \\
+\hline
+{\it void} & \\
+\hline
+\end{tabular}
+
+\clearpage
+
+\section {The ANSI C {\sc hdf5} API}\label{sect:hdf5apiC}
+
+HDF5 is a hierarchical filesystem data format. HDF5 is self-describing, allowing an application to interpret the structure and contents
+of a file with no outside information. A HDF5 file created on a little endian CPU can be read on a big endian CPU, and vice versa.
+Similarly, real(4) datasets can be recovered in real(8) arrays, and vice versa. HDF5 includes two major types of object:
+\begin{itemize}
+\item Datasets, which are multidimensional arrays of a homogeneous type
+\item Groups, which are container structures which can hold datasets and other groups.
+\end{itemize}
+The Ganlib5 implementation of HDF5 relies on the official ANSI C API provided by the HDF Group, a non-profit corporation whose mission
+is to ensure continued development of HDF5 technologies and the continued accessibility of data stored in HDF.\opcite{hdf5} The Ganlib5 kernel
+reimplements simplified ANSI C and Fortran bindings of the legacy HDF5 API to facilitate its use. The compilation and link edition of the
+new bindings require the definition of a UNIX environment variables {\tt HDF5\_INC} and {\tt HDF5\_API} pointing towards directories containing
+the official HDF5 {\tt include} and C API sub-directories compatible with your operating system.
+
+\begin{itemize}
+\item On a OSX operating system, these variables may be set as
+\begin{verbatim}
+export HDF5_INC="/usr/local/Cellar/hdf5/1.12.1/include" # HDF5 include directory
+export HDF5_API="$HDF5_INC/../lib" # HDF5 C API
+\end{verbatim}
+\item On a Linux RedHat operating system, these variables may be set as
+\begin{verbatim}
+export HDF5_INC="/usr/local/hdf5/include" # HDF5 include directory
+export HDF5_API="$HDF5_INC/../lib" # HDF5 C API
+\end{verbatim}
+\item On a Linux Scibian operating system, these variables may be set as
+\begin{verbatim}
+export HDF5_INC="/usr/include/hdf5/serial" # HDF5 include directory
+export HDF5_API="/usr/lib/x86\_64-linux-gnu/hdf5/serial" # HDF5 C API
+\end{verbatim}
+\item On a Unix AIX operating system, these variables may be set as
+\begin{verbatim}
+export HDF5_INC="/usr/include" # HDF5 include directory
+export HDF5_API="$HDF5_INC/../lib" # HDF5 C API
+\end{verbatim}
+\end{itemize}
+On Linux and AIX systems, the environment variable {\tt LD\_LIBRARY\_PATH} must also be set:
+\begin{verbatim}
+export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:$HDF5_API"
+\end{verbatim}
+
+Any ANSI C program using the Ganlib5 HDF5 API implementation should use the following include:
+\begin{verbatim}
+#include "hdf5_aux.h"
+\end{verbatim}
+
+\vskip 0.8cm
+
+\subsection{Opening and closing of HDF5 files}
+
+\subsubsection{hdf5\_open\_file\_c}
+
+Open a HDF5 file. Obtain the address of the HDF5 file if it is created. Note that CLE-2000 is responsible to perform the calls to
+{\tt hdf5\_open\_file\_c} for the HDF5 files that are used as parameters of a CLE-2000 module. The use
+of {\tt hdf5\_open\_file\_c} is generally restricted to the use of temporary HDF5 files created within a CLE-2000 module.
+
+\begin{verbatim}
+
+hdf5_open_file_c(fname, ifile, irdonly);
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt fname} & {\it char[1024]} & name of the HDF5 file. \\
+\hline
+{\tt irdonly} & {\it int\_32} & =0 to create a new HDF5 file or to to modify an existing HDF5 file. A file is not created if it does not already exist.
+ =1 to access an existing HDF5 file in {\bf read-only} mode. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameters:} \\
+\hline
+{\tt ifile} & {\it hid\_t*} & HDF5 file identifier. \\
+\hline
+\end{tabular}
+
+\subsubsection{hdf5\_close\_file\_c}
+
+Close a HDF5 file. Note that CLE-2000 is responsible to perform the calls to
+{\tt hdf5\_close\_file\_c} for the HDF5 files that are used as parameters of a CLE-2000 module. The use
+of {\tt hdf5\_close\_file\_c} is generally restricted to the use of temporary HDF5 files created within a CLE-2000 module.
+
+\begin{verbatim}
+
+hdf5_close_file_c(ifile);
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt ifile} & {\it hid\_t*} & HDF5 file identifier. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\subsection{Interrogation of HDF5 files}
+
+The data structures in a HDF5 file are self-described. It is therefore possible to interrogate them in order to know their characteristics.
+
+\subsubsection{hdf5\_list\_c}
+
+List the root table of contents of a group on the standard output. The name of a group can include one or many path separators (character~$\slash$)
+to list different hierarchical levels.
+
+\begin{verbatim}
+
+hdf5_list_c(ifile, namp);
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt ifile} & {\it hid\_t*} & HDF5 file identifier. \\
+\hline
+{\tt namp} & {\it char[1024]} & name of a group. \\
+\hline
+\end{tabular}
+
+\subsubsection{hdf5\_get\_dimensions\_c}
+
+Find the rank (number of dimensions) of a dataset.
+
+\begin{verbatim}
+
+hdf5_get_dimensions_c(ifile, namp, rank);
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt ifile} & {\it hid\_t*} & HDF5 file identifier. \\
+\hline
+{\tt namp} & {\it char[1024]} & name of a dataset. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameters:} \\
+\hline
+{\tt rank} & {\it int\_32*} & rank of the dataset. \\
+\hline
+\end{tabular}
+
+\subsubsection{hdf5\_get\_num\_group\_c}
+
+Find the number of objects (daughter datasets {\sl and} daughter groups) in a group.
+
+\begin{verbatim}
+
+hdf5_get_num_group_c(ifile, namp, nbobj);
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt ifile} & {\it hid\_t*} & HDF5 file identifier. \\
+\hline
+{\tt namp} & {\it char[1024]} & name of a group. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameters:} \\
+\hline
+{\tt nbobj} & {\it int\_32*} & number of objects in group {\tt namp}. \\
+\hline
+\end{tabular}
+
+\subsubsection{hdf5\_list\_datasets\_c}
+
+Recover character daughter dataset names in a group.
+
+\begin{verbatim}
+
+hdf5_list_datasets_c(file, namp, ndsets, idata);
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt ifile} & {\it hid\_t*} & HDF5 file identifier. \\
+\hline
+{\tt namp} & {\it char[1024]} & name of a group. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameters:} \\
+\hline
+{\tt nbobj} & {\it int\_32*} & number of daughter datasets in group {\tt namp}. \\
+\hline
+{\tt idata} & {\it char*} & list of character names of each daughter dataset. Each name is null terminated. \\
+\hline
+\end{tabular}
+
+\subsubsection{hdf5\_list\_groups\_c}
+
+Recover character daughter groups names in a group.
+
+\begin{verbatim}
+
+hdf5_list_groups_c(file, namp, ndsets, idata);
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt ifile} & {\it hid\_t*} & HDF5 file identifier. \\
+\hline
+{\tt namp} & {\it char[1024]} & name of a group. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameters:} \\
+\hline
+{\tt nbobj} & {\it int\_32*} & number of daughter groups in group {\tt namp}. \\
+\hline
+{\tt idata} & {\it char*} & list of character names of each daughter group. Each name is null terminated. \\
+\hline
+\end{tabular}
+
+\subsubsection{hdf5\_info\_c}
+
+Find dataset information.
+
+\begin{verbatim}
+
+hdf5_info_c(ifile, namp, rank, type, nbyte, dimsr);
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt ifile} & {\it hid\_t*} & HDF5 file identifier. \\
+\hline
+{\tt namp} & {\it char[1024]} & name of a dataset. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameters:} \\
+\hline
+{\tt rank} & {\it int\_32*} & rank (number of dimensions) of dataset. \\
+\hline
+{\tt type} & {\it int\_32*} & type of dataset: =1 32-bit integer;
+ =2 32-bit real; =3 character data;
+ =4 64-bit real. \\
+\hline
+{\tt nbyte} & {\it int\_32*} & number of bytes in each component of the dataset. \\
+\hline
+{\tt dimsr} & {\it int\_32*} & integer array containing the dimension of dataset. {\tt rank} values are provided. \\
+\hline
+\end{tabular}
+
+\subsubsection{hdf5\_group\_exists\_c}
+
+Test for existence of a group.
+
+\begin{verbatim}
+
+ierr = hdf5_group_exists_c(ifile, namp);
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt ifile} & {\it hid\_t*} & HDF5 file identifier. \\
+\hline
+{\tt namp} & {\it char[1024]} & name of a group. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameter:} \\
+\hline
+{\tt ierr} & {\it int\_32*} & existence flag: =1/0 the group does/does not exist. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\subsection{Management of groups and datatypes}
+
+\subsubsection{hdf5\_create\_group\_c}
+
+Create a group.
+
+\begin{verbatim}
+
+hdf5_create_group_c(ifile, namp);
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt ifile} & {\it hid\_t*} & HDF5 file identifier. \\
+\hline
+{\tt namp} & {\it char[1024]} & name of the group to create. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\subsubsection{hdf5\_delete\_c}
+
+Delete a group or a dataset.
+
+\begin{verbatim}
+
+hdf5_delete_c(ifile, namp);
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt ifile} & {\it hid\_t*} & HDF5 file identifier. \\
+\hline
+{\tt namp} & {\it char[1024]} & name of the group or dataset to delete. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\subsubsection{hdf5\_copy\_c}
+
+Copy a group or a dataset from one location to another. The source and destination need not be in the same file.
+
+\begin{verbatim}
+
+hdf5_copy_c(ifile_s, namp_s, ifile_d, namp_d);
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt ifile\_s} & {\it hid\_t*} & HDF5 source file identifier. \\
+\hline
+{\tt namp\_s} & {\it char[1024]} & name of the source group or dataset to copy. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameters:} \\
+\hline
+{\tt ifile\_d} & {\it hid\_t*} & HDF5 destination file identifier. \\
+\hline
+{\tt namp\_d} & {\it char[1024]} & name of the destination group or dataset. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\subsubsection{hdf5\_read\_data\_int\_c}
+
+Copy an integer dataset from HDF5 file into memory.
+
+\begin{verbatim}
+
+hdf5_read_data_int_c(ifile, namp, idata);
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt ifile} & {\it hid\_t*} & HDF5 file identifier. \\
+\hline
+{\tt namp} & {\it char[1024]} & name of a dataset. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameters:} \\
+\hline
+{\tt idata} & {\it int\_32*} & integer array. \\
+\hline
+\end{tabular}
+
+\subsubsection{hdf5\_read\_data\_real4\_c}
+
+Copy a real(4) dataset from HDF5 file into memory.
+
+\begin{verbatim}
+
+hdf5_read_data_real4_c(ifile, namp, rdata);
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt ifile} & {\it hid\_t*} & HDF5 file identifier. \\
+\hline
+{\tt namp} & {\it char[1024]} & name of a dataset. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameters:} \\
+\hline
+{\tt rdata} & {\it float*} & real(4) array. \\
+\hline
+\end{tabular}
+
+\subsubsection{hdf5\_read\_data\_real8\_c}
+
+Copy a real(8) dataset from HDF5 file into memory.
+
+\begin{verbatim}
+
+hdf5_read_data_real8_c(ifile, namp, rdata);
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt ifile} & {\it hid\_t*} & HDF5 file identifier. \\
+\hline
+{\tt namp} & {\it char[1024]} & name of a dataset. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameters:} \\
+\hline
+{\tt rdata} & {\it double*} & real(8) array. \\
+\hline
+\end{tabular}
+
+\subsubsection{hdf5\_read\_data\_string\_c}
+
+Copy a character dataset from HDF5 file into memory.
+
+\begin{verbatim}
+
+hdf5_read_data_string_c(ifile, namp, idata);
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt ifile} & {\it hid\_t*} & HDF5 file identifier. \\
+\hline
+{\tt namp} & {\it char[1024]} & name of a dataset. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameters:} \\
+\hline
+{\tt idata} & {\it char*} & character array. \\
+\hline
+\end{tabular}
+
+\subsubsection{hdf5\_write\_data\_int\_c}
+
+Copy an integer array from memory into a HDF5 dataset. If dataset {\tt namp} exists, it is replaced.
+
+\begin{verbatim}
+
+hdf5_write_data_int_c(ifile, namp, rank, dimsr, idata);
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt ifile} & {\it hid\_t*} & HDF5 file identifier. \\
+\hline
+{\tt namp} & {\it char[1024]} & name of a dataset. \\
+\hline
+{\tt rank} & {\it int\_32*} & rank (number of dimensions) of dataset. \\
+\hline
+{\tt dimsr} & {\it int\_32*} & integer array containing the dimension of dataset. {\tt rank} values are provided. \\
+\hline
+{\tt idata} & {\it int\_32*} & integer array. \\
+\hline
+\end{tabular}
+
+\subsubsection{hdf5\_write\_data\_real4\_c}
+
+Copy a real(4) array from memory into a HDF5 dataset. If dataset {\tt namp} exists, it is replaced.
+
+\begin{verbatim}
+
+hdf5_write_data_real4_c(ifile, namp, rank, dimsr, rdata);
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt ifile} & {\it hid\_t*} & HDF5 file identifier. \\
+\hline
+{\tt namp} & {\it char[1024]} & name of a dataset. \\
+\hline
+{\tt rank} & {\it int\_32*} & rank (number of dimensions) of dataset. \\
+\hline
+{\tt dimsr} & {\it int\_32*} & integer array containing the dimension of dataset. {\tt rank} values are provided. \\
+\hline
+{\tt rdata} & {\it float*} & real(4) array. \\
+\hline
+\end{tabular}
+
+\subsubsection{hdf5\_write\_data\_real8\_c}
+
+Copy a real(8) array from memory into a HDF5 dataset. If dataset {\tt namp} exists, it is replaced.
+
+\begin{verbatim}
+
+hdf5_write_data_real8_c(ifile, namp, rank, dimsr, rdata);
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt ifile} & {\it hid\_t*} & HDF5 file identifier. \\
+\hline
+{\tt namp} & {\it char[1024]} & name of a dataset. \\
+\hline
+{\tt rank} & {\it int\_32*} & rank (number of dimensions) of dataset. \\
+\hline
+{\tt dimsr} & {\it int\_32*} & integer array containing the dimension of dataset. {\tt rank} values are provided. \\
+\hline
+{\tt rdata} & {\it double*} & real(8) array. \\
+\hline
+\end{tabular}
+
+\subsubsection{hdf5\_write\_data\_string\_c}
+
+Copy an character array from memory into a HDF5 dataset. If dataset {\tt namp} exists, it is replaced.
+
+\begin{verbatim}
+
+hdf5_write_data_string_c(ifile, namp, rank, dimsr, idata);
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt ifile} & {\it hid\_t*} & HDF5 file identifier. \\
+\hline
+{\tt namp} & {\it char[1024]} & name of a dataset. \\
+\hline
+{\tt rank} & {\it int\_32*} & rank (number of dimensions) of dataset. \\
+\hline
+{\tt len} & {\it int\_32*} & length of a string element in the array (in bytes). \\
+\hline
+{\tt dimsr} & {\it int\_32*} & integer array containing the dimension of dataset. {\tt rank} values are provided. \\
+\hline
+{\tt idata} & {\it char*} & character array. \\
+\hline
+\end{tabular}
+
+\clearpage
+
+\section {The ANSI C CLE-2000 API}\label{sect:cle2000apiC}
+
+\subsection {The main entry point for CLE-2000}
+
+The CLE-2000 supervisor have been entirely reprogrammed in ANSI~C in its GANLIB Version 5 implementation. Its main entry
+point is function {\tt cle2000\_c()} that can be used to execute a {\sl CLE-2000 source file} which can be a {\sl main procedure}
+(a sequential {\sc ascii} file with {\tt .x2m} suffix) or a {\sl parametrized procedure} (a sequential {\sc ascii} file with {\tt .c2m} suffix).
+Parametrized procedures can be called by function {\tt cle2000\_c()} or by other CLE-2000 procedures. Function {\tt cle2000\_c()} is therefore
+recursive. A computational scheme is a set of parametrized procedures.
+
+\subsubsection{cle2000\_c\index{cle2000\_c}}
+
+The general specification of function {\tt cle2000\_c()} is
+
+\begin{verbatim}
+
+cle2000_c(ilevel, dummod, filenm, iprint, my_param);
+\end{verbatim}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt ilevel} & {\it int\_32} & recursivity level of {\tt cle2000\_c()} call. We recommend to call
+{\tt cle2000\_c()} from the main entry point with {\tt ilevel = 1}. \\
+\hline
+{\tt dummod} & {\it int\_32 (*)()} & external ANSI~C function (or C-interoperable Fortran-2003 function) responsible for dispatching the execution among calculation modules. Note that the calculation modules can be implemented in any language that is interoperable with ANSI~C. \\
+\hline
+{\tt filenm} & {\it char*} & name of sequential {\sc ascii} file containing the CLE-2000 source file, without the {\tt .c2m} suffix. Can be set to {\tt " "} (corresponding to {\tt stdin} in ANSI~C, or unit~5 in Fortran). The name is null terminated. \\
+\hline
+{\tt iprint} & {\it int\_32} & print parameter (set to zero for no print). \\
+\hline
+{\tt my\_param} & {\it lifo*} & last-in-first-out (lifo) stack containing LCM (or XSM) objects, files and/or CLE-2000 variables that are exchanged with the CLE-2000 procedure. Set {\tt my\_param = NULL} if no information is exchanged. The specification of {\tt my\_param} is detailed in Sect.~\ref{sect:lifo}. \\
+\hline
+\end{tabular}
+
+\vskip 0.4cm
+
+\noindent
+\begin{tabular}{|p{4.0cm}|p{11cm}|}
+\hline
+\multicolumn{2}{|c|}{\bf value of the function:} \\
+\hline
+{\it int\_32} & error code equal to zero if the execution of the CLE-2000 source file is successful. Equal to the error code otherwise. \\
+\hline
+\end{tabular}
+
+\subsubsection{dummod\index{dummod}}
+
+Function {\tt dummod()} is an external ANSI~C function (or C-interoperable Fortran-2003 function) responsible for dispatching the execution among calculation modules.
+A specific version, named {\tt ganmod()}, is used to dispatch the execution among the modules of the GANLIB. Its specifications are:
+\begin{verbatim}
+
+dummod(cmodul, nentry, hentry, ientry, jentry, kentry, hparam);
+\end{verbatim}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt cmodul} & {\it char*} & name of the calculation module to execute \\
+\hline
+{\tt nentry} & {\it int\_32} & number of parameters (LCM objects or files) for this call \\
+\hline
+{\tt hentry} & {\it char (*)[13]} & names of the parameters as known in the CLE-2000 procedure\\
+\hline
+{\tt ientry} & {\it int\_32*} & types of the parameters. $=1$: memory-resident LCM object; $=2$: persistent LCM object (stored in a XSM file);
+$=3$: sequential binary file;
+$=4$: sequential ascii file;
+$=5$: direct access file;
+$=6$: HDF5 file. \\
+\hline
+{\tt jentry} & {\it int\_32*} & access mode of the parameters. $=0$: the object is created; $=1$: the object is opened for modifications ; $=2$: the object is opened in read-only mode. \\
+\hline
+{\tt kentry} & {\it lcm**} & equal to the address of the LCM object corresponding to a parameter or set to {\tt NULL} if the parameter is a file \\
+\hline
+{\tt hparam} & {\it char (*)[73]} &names of the parameters as known by the operating system \\
+\hline
+\end{tabular}
+
+\vskip 0.4cm
+
+\noindent
+\begin{tabular}{|p{4.0cm}|p{11cm}|}
+\hline
+\multicolumn{2}{|c|}{\bf value of the function:} \\
+\hline
+{\it int\_32} & error code equal to zero if the execution of {\tt dummod()} is successful. Equal to the error code otherwise. \\
+\hline
+\end{tabular}
+
+\subsubsection {Calling a main CLE-2000 procedure}
+
+The simplest situation occurs when a main CLE-2000 procedure is called. This situation corresponds to the case where an application
+software is run in stand-alone mode. In this case, it is sufficient to write a main program calling a main CLE-2000 procedure. The main
+program can be written in ANSI~C (as in the following example) or as a C-interoperable Fortran-2003 program. A main CLE-2000 procedure
+has no in-out CLE-2000 variables and no in-out parameters.
+
+\vskip 0.08cm
+
+In the following example, an application software contains three modules, named {\tt MOD1:}, {\tt MOD2} and {\tt MOD3}, respectively.
+A main program is simply written as
+
+\begin{verbatim}
+#include <string.h>
+#include "cle2000.h"
+main()
+{
+ int_32 iprint = 0;
+ int_32 ier, ilevel = 1;
+ int_32 ganmod();
+
+ ier = cle2000_c(ilevel, &ganmod, " ", iprint, NULL);
+ printf("end of execution; ier=%d\n", ier);
+}
+\end{verbatim}
+
+The {\tt ganmod()} function is another developer-supplied function that is responsible for dispatching the execution among modules
+{\tt MOD1:}, {\tt MOD2} or {\tt MOD3}. The {\tt ganmod()} function is responsible for opening any file that can be requested
+by these modules. This open/close operation may be different, depending if the modules are programmed in ANSI~C (as in this example) or in another language.
+\begin{verbatim}
+#include <string.h>
+#include <stdio.h>
+#include "cle2000.h"
+int_32 ganmod(char *cmodul, int_32 nentry, char (*hentry)[13], int_32 *ientry,
+ int_32 *jentry, lcm **kentry, char (*hparam)[73])
+{
+ int_32 iloop1, ier;
+ FILE *kentry_file[maxent];
+ char hsmg[132];
+
+/* open files */
+ for (iloop1 = 0; iloop1 < nentry; ++iloop1) {
+ if (ientry[iloop1] >= 3) {
+ char *mode;
+ if ((ientry[iloop1] == 3) && (jentry[iloop1] == 0)) {
+ strcpy(mode, "w");
+ } else if ((ientry[iloop1] == 3) && (jentry[iloop1] == 1)) {
+ strcpy(mode, "a");
+ } else if ((ientry[iloop1] == 3) && (jentry[iloop1] == 2)) {
+ strcpy(mode, "r");
+ } else if ((ientry[iloop1] == 4) && (jentry[iloop1] == 0)) {
+ strcpy(mode, "wb");
+ } else if ((ientry[iloop1] == 4) && (jentry[iloop1] == 1)) {
+ strcpy(mode, "ab");
+ } else if ((ientry[iloop1] == 4) && (jentry[iloop1] == 2)) {
+ strcpy(mode, "rb");
+ } else {
+ sprintf(hsmg, "ganmod: type not supported for file %s", hentry[iloop1]);
+ xabort_c(hsmg);
+ }
+ kentry_file[iloop1] = fopen(hparam[iloop1], mode);
+ if (kentry_file[iloop1] == NULL) {
+ sprintf(hsmg, "ganmod: unable to open file %s", hentry[iloop1]);
+ xabort_c(hsmg);
+ }
+ } else {
+ kentry_file[iloop1] = NULL;
+ }
+ }
+
+/* call modules */
+ if(strcmp(cmodul, "MOD1:") == 0) {
+ mod1(nentry, hentry, ientry, jentry, kentry, kentry_file);
+ } else if(strcmp(cmodul, "MOD2:") == 0) {
+ mod2(nentry, hentry, ientry, jentry, kentry, kentry_file);
+ } else if(strcmp(cmodul, "MOD3:") == 0) {
+ mod3(nentry, hentry, ientry, jentry, kentry, kentry_file);
+ } else {
+ return 1;
+ }
+
+/* close files */
+ for (iloop1 = 0; iloop1 < nentry; ++iloop1) {
+ if (ientry[iloop1] >= 3) {
+ ier = fclose(kentry_file[iloop1]);
+ if (ier != 0) {
+ sprintf(hsmg, "ganmod: unable to close file %s", hentry[iloop1]);
+ xabort_c(hsmg);
+ }
+ }
+ }
+ return 0;
+}
+\end{verbatim}
+
+\subsubsection {Calling a parametrized CLE-2000 procedure}
+
+In cases where an application software is called from a multi-physics application, it is likely that the multi-physics application
+will need to call parametrized CLE-2000 procedures (with ``{\tt .c2m}" suffix). This approach provides an efficient way of communication between
+the application software and the multi-physics application. It also permit to develop computational schemes outside the scope (i.e., independently)
+of the multi-physics application. Parameters are either LCM objects (memory-resident) or
+files that are managed by the operating system. Multi-physics applications are generally programmed
+in C++ or in Java. In the latter case, {\sl Java Native Interfaces} (JNIs) are required to allow this communication.
+
+\vskip 0.08cm
+
+In the following example, a parametrized procedure, {\tt TESTproc.c2m}, take two object parameters and three CLE-2000 input variables.
+Note that the CLE-2000 variables are always defined after LCM and file objects. The first parameter, {\tt MACRO\_ASCII}, is
+an {\sc ascii} file written by the procedure and containing an export of the information pointed by the second parameter {\tt MACRO}. This second parameter is a
+memory resident LCM object containing a Macrolib. It is accessed in {\tt read-only} mode. The procedure also prints a table-of-content
+of the root directory of {\tt MACRO}, using the {\tt UTL:} module of the GANLIB. The procedure {\tt TESTproc.c2m} is implemented as
+\begin{verbatim}
+REAL KEFF1 KEFF2 ;
+INTEGER I123 ;
+PARAMETER MACRO_ASCII MACRO ::
+ EDIT 1
+ ::: SEQ_ASCII MACRO_ASCII ;
+ ::: LINKED_LIST MACRO ;
+;
+:: >>KEFF1<< >>KEFF2<< >>I123<< ;
+MODULE UTL: END: ;
+*
+UTL: MACRO :: DIR ;
+MACRO_ASCII := MACRO ;
+ECHO "KEFF1=" KEFF1 ""KEFF2=" KEFF2 "I123=" I123 ;
+ECHO "procedure TESTproc completed" ;
+END: ;
+QUIT "XREF" .
+\end{verbatim}
+
+\noindent More information about the development of CLE-2000 procedures can be found in Ref.~\citen{cle2000}.
+
+\vskip 0.08cm
+
+The next ANSI~C function is an example of how a multi-physics application can call such a procedure. A LCM object
+containing a Macrolib is first created by importing its information from an existing {\sc ascii} file named {\tt Macrolib}. Next, a call to function
+{\tt cle2000\_c()} is performed to execute {\tt TESTproc.c2m}. The corresponding {\tt main} program is written
+\goodbreak
+
+\begin{verbatim}
+#include <string.h>
+#include <stdlib.h>
+#include "cle2000.h"
+main()
+{
+ int_32 iprint = 0;
+ int_32 ier, ilevel = 1;
+ FILE *filein;
+ char cproce[13];
+ int_32 ganmod();
+ lcm *my_lcm;
+ lifo *my_lifo;
+ lifo_node *my_node;
+
+/* create the LCM object containing a Macrolib */
+ filein = fopen("Macrolib", "r");
+ lcmop_c(&my_lcm, "MACRO1", 0, 1, iprint);
+ lcmexp_c(&my_lcm, iprint, filein, 2, 2);
+ fclose(filein);
+ lcmlib_c(&my_lcm);
+ lcmcl_c(&my_lcm, 1);
+
+/* construct the lifo stack */
+ cleopn(&my_lifo);
+ /* node 1 */
+ my_node = (lifo_node *) malloc(sizeof(lifo_node));
+ strcpy(my_node->name, "MACRO_ASCII1"); strcpy(my_node->OSname, "my_ascii_file");
+ my_node->type = -6;
+ clepush(&my_lifo, my_node);
+ /* node 2 */
+ my_node = (lifo_node *) malloc(sizeof(lifo_node));
+ strcpy(my_node->name, "MACRO1"); strcpy(my_node->OSname, "MACRO1"); my_node->type = 3;
+ my_node->value.mylcm = my_lcm;
+ clepush(&my_lifo, my_node);
+ /* node 3 */
+ my_node = (lifo_node *) malloc(sizeof(lifo_node));
+ strcpy(my_node->name, "value1"); my_node->type = 12; my_node->value.fval = 1.703945;
+ clepush(&my_lifo, my_node);
+ /* node 4 */
+ my_node = (lifo_node *) malloc(sizeof(lifo_node));
+ strcpy(my_node->name, "value2"); my_node->type = 12; my_node->value.fval = 1.562276;
+ clepush(&my_lifo, my_node);
+ /* node 5 */
+ my_node = (lifo_node *) malloc(sizeof(lifo_node));
+ strcpy(my_node->name, "value3"); my_node->type = 11; my_node->value.ival = 12345;
+ clepush(&my_lifo, my_node);
+
+/* call the parametrized procedure */
+ strcpy(cproce, "TESTproc");
+ ier = cle2000_c(ilevel, &ganmod, cproce, iprint, my_lifo);
+ if (ier != 0) xabort_c("example2.1.5: cle2000 failure");
+
+/* erase the lifo stack */
+ while (my_lifo->nup > 0) {
+ my_node = clepop(&my_lifo);
+ free(my_node);
+ }
+ clecls(&my_lifo);
+ printf("successful end of execution\n");
+}
+\end{verbatim}
+
+\subsubsection {Calling a CLE-2000 procedure with in-out CLE-2000 variables}
+
+The CLE-2000 API also offers the possibility to exchange CLE-2000 variables with a procedure. The following CLE-2000 procedure
+permits to compute the factorial of a number, as proposed in Ref.~\citen{cle2000}. Here, {\tt n} and {\tt n\_fact} are input and
+output CLE-2000 variable, respectively. The {\tt fact.c2m} procedure is written
+\begin{verbatim}
+!
+! Example of a recursive procedure.
+!
+! input to "fact": *n*
+! output from "fact": *n_fact*
+!
+ INTEGER n n_fact prev_fact ;
+ :: >>n<< ;
+ IF n 1 = THEN
+ EVALUATE n_fact := 1 ;
+ ELSE
+ EVALUATE n := n 1 - ;
+ ! Here, "fact" calls itself
+ PROCEDURE fact ;
+ fact :: <<n>> >>prev_fact<< ;
+ EVALUATE n_fact := n 1 + prev_fact * ;
+ ENDIF ;
+ :: <<n_fact>> ;
+ QUIT " Recursive procedure *fact* XREF " .
+\end{verbatim}
+
+This procedure can be called from a program implemented in ANSI~C, using
+\begin{verbatim}
+#include <string.h>
+#include <stdlib.h>
+#include "cle2000.h"
+main()
+{
+ int_32 iprint = 0;
+ int_32 ier, ilevel = 1;
+ char cproce[13];
+ int_32 ganmod();
+ lifo *my_lifo;
+ lifo_node *my_node;
+
+/* construct the lifo stack */
+ cleopn(&my_lifo);
+ /* node 1 */
+ my_node = (lifo_node *) malloc(sizeof(lifo_node));
+ strcpy(my_node->name, "input_val"); my_node->type = 11; my_node->value.ival = 5;
+ clepush(&my_lifo, my_node);
+ /* node 2 */
+ my_node = (lifo_node *) malloc(sizeof(lifo_node));
+ strcpy(my_node->name, "output_val"); my_node->type = -11;
+ clepush(&my_lifo, my_node);
+
+/* call the procedure with in-out CLE-2000 variables*/
+ strcpy(cproce, "fact");
+ ier = cle2000_c(ilevel, &ganmod, cproce, iprint, my_lifo);
+ if (ier != 0) xabort_c("fact: cle2000 failure");
+
+/* recover and erase the lifo stack */
+ printf("\noutput stack:\n");
+ while (my_lifo->nup > 0) {
+ my_node = clepop(&my_lifo);
+ printf("node %d (name=%12s) ---> %d\n", my_lifo->nup, my_node->name,
+ my_node->value.ival);
+ free(my_node);
+ }
+ clecls(&my_lifo);
+ printf("successful end of execution\n");
+}
+\end{verbatim}
+
+\vskip 0.8cm
+
+\subsection {Calling a calculation module without a CLE-2000 procedure}
+
+The GANLIB API also provides the possibility to call directly a calculation module without a CLE-2000 procedure. This
+capability is required in the first-generation Jargon framework, as presented in Ref.~\citen{jargon}. The actual implementation
+does not support CLE-2000 variables. A calculation module with ``{\tt >>~<<}" variables must therefore be encapsulated in a
+CLE-2000 procedure.
+
+\subsubsection{clemod\_c\index{clemod\_c}}
+
+The general specification of function {\tt clemod\_c()} is
+
+\begin{verbatim}
+
+clemod_c(cmodul, filein, nentry, hentry, ientry, jentry, kentry, hparam, dummod);
+\end{verbatim}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt cmodul} & {\it char*} & name of the calculation module to execute \\
+\hline
+{\tt filein} & {\it FILE*} & sequential {\sc ascii} file containing the data for module {\tt cmodul} (i.e., the data between the ``{\tt ::}" and the ``{\tt ;}"). Can be set to {\tt stdin} (standard input, or unit~5 in Fortran) \\
+\hline
+{\tt nentry} & {\it int\_32} & number of parameters (LCM objects or files) that are exchanged with the CLE-2000 procedure. {\tt nentry = 0} if no parameters are exchanged. \\
+\hline
+{\tt hentry} & {\it char (*)[13]} & names of these parameters, as known by the calculation module. Each name is a character string with a maximum of 12 characters. \\
+\hline
+{\tt ientry} & {\it int\_32*} & types of each parameter. $=1$: memory-resident LCM object; $=2$: persistent LCM object (stored in a XSM file);
+$=3$: sequential binary file;
+$=4$: sequential ascii file;
+$=5$: direct access file;
+$=6$: HDF5 file.
+\\
+\hline
+{\tt jentry} & {\it int\_32*} & mode of each parameter. $=0$: the object is created; $=1$: the object is opened for modifications ; $=2$: the object is opened in read-only mode. \\
+\hline
+{\tt kentry} & {\it lcm**} & addresses of the {\tt lcm} objects (for parameters that are LCM objects). Set to {\tt NULL} for parameters that are files. \\
+\hline
+{\tt hparam} & {\it char (*)[73]} & names of these parameters, as known by the operating system. Each name is a character string with a maximum of 72 characters. \\
+\hline
+{\tt dummod} & {\it int\_32 (*)()} & external ANSI~C function (or C-interoperable Fortran-2003 function) responsible for dispatching the execution among calculation modules. Note that the calculation modules can be implemented in any language that is interoperable with ANSI~C. \\
+\hline
+\end{tabular}
+
+\vskip 0.4cm
+
+\noindent
+\begin{tabular}{|p{4.0cm}|p{11cm}|}
+\hline
+\multicolumn{2}{|c|}{\bf value of the function:} \\
+\hline
+{\it int\_32} & error code equal to zero if the execution of the calculation module is successful. Equal to the error code otherwise. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+In the following example, function {\tt clemod\_c()} is used to call a calculation module of the GANLIB. A LCM object
+containing a Macrolib is first created by importing its information from an existing {\sc ascii} file named {\tt Macrolib}.
+Module {\tt UTL:} is called with this {\tt read-only} Macrolib as unique parameter:
+\begin{verbatim}
+#include <string.h>
+#include "cle2000.h"
+#define maxent 64 /* maximum number of module arguments */
+main()
+{
+ int_32 ganmod();
+ char hentry[maxent][13], hparam[maxent][73];
+ int_32 ier, nentry, ientry[maxent], jentry[maxent];
+ lcm * my_lcm, *kentry[maxent];
+ FILE *filein;
+
+/* create the LCM object containing a Macrolib */
+ filein = fopen("Macrolib", "r");
+ lcmop_c(&my_lcm, "MACRO", 0, 1, 99);
+ lcmexp_c(&my_lcm, 99, filein, 2, 2);
+ fclose(filein);
+
+/* create a file containing the UTL: data */
+ filein = fopen("UTLdata", "r");
+
+/* construct the parameter */
+ nentry = 1 ;
+ strcpy(hentry[0], "MACRO"); strcpy(hparam[0], "MACRO"); ientry[0]=1; jentry[0]=2;
+ kentry[0]=my_lcm;
+
+/* execute the module */
+ ier = clemod_c("UTL:", filein, nentry, hentry, ientry, jentry, kentry, hparam,
+ &ganmod);
+ lcmcl_c(&my_lcm, 1);
+ fclose(filein);
+ printf("end of execution; ier=%d\n", ier);
+}
+\end{verbatim}
+
+\vskip 0.08cm
+
+The ASCII file {\tt UTLdata} contains the data for module {\tt UTL:}. Here, it is defined as
+\begin{verbatim}
+DIR STEP UP GROUP
+STEP AT 1 DIR STEP DOWN
+STEP DOWN ;
+\end{verbatim}
+
+\vskip 0.8cm
+
+\subsection{Management of the last-in-first-out (lifo) stack\index{lifo}}\label{sect:lifo}
+
+A last-in-first-out (lifo) stack manage the stored data so that the last data stored in the stack is the first data removed from the stack. This means that a POP function retrieves the values most recently stored with a PUSH function. CLE-2000 uses one lifo stack to manage information used within each specific CLE-2000 procedure instance and one lifo stack as dummy parameter list each time a CLE-2000 procedure is called.
+
+\vskip 0.08cm
+
+In case where a CLE-2000 procedure is called from a multi-physics environment, the parameter information is first integrated in a lifo stack {\sl before} calling
+function {\tt cle2000\_c()}. After execution of the procedure, output parameter information is recovered from the lifo stack. The lifo stack can contain LCM (or XSM) objects, files and/or CLE-2000 variables. The lifo stack is constructed as a linked list of nodes, each node containing a single parameter. Three important rules must be satisfied:
+\begin{itemize}
+\item LCM (or XSM) objects and files must be defined prior to CLE-2000 variables in the lifo stack used as parameter information.
+\item LCM (or XSM) objects and files must be closed when included in the lifo stack.
+\item Output nodes are also included in the lifo stack before calling function {\tt cle2000\_c()}, but {\sl with negative} {\tt type} component and {\sl without} {\tt value} component.
+\end{itemize}
+
+\vskip 0.08cm
+
+The specification of a lifo node is:
+
+\small
+\begin{verbatim}
+typedef struct LIFO_NODE { /* node in last-in-first-out (lifo) stack */
+ int_32 type; /* type of node: 3= lcm object; 4= xsm file; 5= seq binary;
+ 6= seq ascii; 7= da binary; 8= hdf5 file; 11= integer value;
+ 12= real value; 13= character string; 14= double precision value;
+ 15= logical value */
+ int_32 access; /* 0=creation mode/1=modification mode/2=read-only mode */
+ int_32 lparam; /* record length for DA file objects */
+ union {
+ int_32 ival; /* integer or logical value */
+ float_32 fval; /* real value */
+ double dval; /* double precision value */
+ lcm *mylcm; /* handle towards a LCM object */
+ char hval[73]; /* character value */
+ hid_t myhdf5; /* handle towards a HDF5 file */
+ } value;
+ struct LIFO_NODE *daughter; /* address of the daughter node in stack */
+ char name[13]; /* name of node in the calling script */
+ char name_daughter[13]; /* name of node in the daughter script */
+ char OSname[73]; /* physical filename */
+} lifo_node ;
+\end{verbatim}
+\normalsize
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{2.4cm}|p{1.6cm}|p{10.5cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf life\_node components:} \\
+\hline
+{\tt type} & {\it int\_32} & type of data in node.
+$=\pm 3$: LCM object;
+$=\pm 4$: XSM file;
+$=\pm 5$: sequential binary file;
+$=\pm 6$: sequential ascii file;
+$=\pm 7$: direct access binary file;
+$=\pm 8$: HDF5 file;
+$=\pm 11$: integer CLE-2000 value;
+$=\pm 12$: real CLE-2000 value;
+$=\pm 13$: character string (null-terminated);
+$=\pm 14$: double precision CLE-2000 value;
+$=\pm 15$: logical CLE-2000 value.
+A positive value indicates that an input value is provided; a negative value indicates that {\sl no} input value is provided
+so that the node is {\sl empty}. Empty nodes are defined to receive calculational results.
+\\
+\hline
+{\tt access} & {\it int\_32} & access state of data in node.
+$= 0$: creation mode;
+$= 1$: modification mode;
+$= 2$: read-only mode.
+This information is used internally in {\tt cle2000\_c()} function.
+\\
+\hline
+{\tt lparam} & {\it int\_32} & record length (in bytes) for DA file objects. This data is given if and only if $|${\tt type}$| = 7$.\\
+\hline
+{\tt value.ival} & {\it int\_32} & integer or logical CLE-2000 value. This data is given or is available at output if and only if {\tt type} $= 11$ or $=15$.\\
+\hline
+{\tt value.fval} & {\it float\_32} & real CLE-2000 value. This data is given or is available at output if and only if {\tt type} $= 12$.\\
+\hline
+{\tt value.hval} & {\it char[73]} & character string CLE-2000 value. This data is given or is available at output if and only if {\tt type} $= 13$.\\
+\hline
+{\tt value.dval} & {\it double} & double precision CLE-2000 value. This data is given or is available at output if and only if {\tt type} $= 14$.\\
+\hline
+{\tt value.mylcm} & {\it lcm*} & LCM object (memory-resident). This data is given or is available at output if and only if {\tt type} $= 3$. The LCM object is closed.\\
+\hline
+{\tt daughter} & {\it lifo\_node*} & address of the daughter node in stack. This information is used by the lifo utility to construct the linked list of nodes.\\
+\hline
+{\tt name} & {\it char[13]} & name of node in the calling script.\\
+\hline
+{\tt name\_daughter} & {\it char[13]} & name of node in the daughter script. This name is used internally in {\tt cle2000\_c()} function.\\
+\hline
+{\tt OSname} & {\it char[73]} & name of node as known by the operating system. In the case of a LCM object, it is the name given to {\tt lcmop\_c()} function. In the case of a file, it is the operating system name of the file. The LCM object or file is closed. {\bf This data is given if and only if} $|${\tt type}$| \le 10$.\\
+\hline
+\end{tabular}
+
+\vskip 1.0cm
+
+The following functions are used to manage the lifo stack.
+
+\vskip 0.8cm
+\goodbreak
+
+\subsubsection {cleopn\index{cleopn}}
+
+Create an empty lifo stack.
+
+\begin{verbatim}
+
+cleopn(my_lifo);
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameter:} \\
+\hline
+{\tt my\_lifo} & {\it lifo**} & address of the empty lifo stack. \\
+\hline
+\multicolumn{3}{|c|}{\bf value of the function:} \\
+\hline
+\multicolumn{2}{|l|}{\it void} & \\
+\hline
+\end{tabular}
+
+\subsubsection{clepop\index{clepop}}
+
+Remove the ``last-in" node from the lifo stack.
+
+\begin{verbatim}
+
+clepop(my_lifo);
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameter:} \\
+\hline
+{\tt my\_lifo} & {\it lifo**} & address of the lifo stack. \\
+\hline
+\multicolumn{3}{|c|}{\bf value of the function:} \\
+\hline
+\multicolumn{2}{|l|}{\it lifo\_node*} & node removed from the lifo stack \\
+\hline
+\end{tabular}
+
+\subsubsection{clepush\index{clepush}}
+
+Add a new node in the lifo stack.
+
+\begin{verbatim}
+
+clepush(my_lifo, my_node);
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt my\_lifo} & {\it lifo**} & address of the lifo stack. \\
+\hline
+{\tt my\_node} & {\it lifo\_node*} & node to add to the lifo stack. \\
+\hline
+\multicolumn{3}{|c|}{\bf value of the function:} \\
+\hline
+\multicolumn{2}{|l|}{\it void} & \\
+\hline
+\end{tabular}
+
+\subsubsection{clecls\index{clecls}}
+
+Delete an empty lifo stack.
+
+\begin{verbatim}
+
+clecls(my_lifo);
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameter:} \\
+\hline
+{\tt my\_lifo} & {\it lifo**} & address of the empty lifo stack. \\
+\hline
+\multicolumn{3}{|c|}{\bf value of the function:} \\
+\hline
+\multicolumn{2}{|l|}{\it int\_32} & error code. $=0$: successful; $=-1$: the lifo stack is not empty. \\
+\hline
+\end{tabular}
+
+\subsubsection{clenode\index{clenode}}
+
+Return the node with name {\tt my\_name}. The lifo stack is not modified.
+\begin{verbatim}
+
+clenode(my_lifo, my_name);
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt my\_lifo} & {\it lifo**} & address of the lifo stack. \\
+\hline
+{\tt my\_name} & {\it char*} & name of the node. The name is null-terminated. \\
+\hline
+\multicolumn{3}{|c|}{\bf value of the function:} \\
+\hline
+\multicolumn{2}{|l|}{\it lifo\_node*} & node of name {\tt my\_name} or NULL if the node doesn't exist. \\
+\hline
+\end{tabular}
+
+\subsubsection{clepos\index{clepos}}
+Return the {\tt ipos}--th node in the stack. The lifo stack is not modified.
+\begin{verbatim}
+
+clepos(my_lifo, ipos);
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt my\_lifo} & {\it lifo**} & address of the lifo stack. \\
+\hline
+{\tt ipos} & {\it int\_32} & position of the node in the stack. \\
+\hline
+\multicolumn{3}{|c|}{\bf value of the function:} \\
+\hline
+\multicolumn{2}{|l|}{\it lifo\_node*} & {\tt ipos}--th node or NULL if the node doesn't exist. \\
+\hline
+\end{tabular}
+
+\subsubsection{clelib\index{clelib}}
+Print a table-of-content for the lifo stack.
+\begin{verbatim}
+
+clelib(my_lifo);
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameter:} \\
+\hline
+{\tt my\_lifo} & {\it lifo**} & address of the lifo stack. \\
+\hline
+\multicolumn{3}{|c|}{\bf value of the function:} \\
+\hline
+\multicolumn{2}{|l|}{\it void} & \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\subsection {The free-format input reader}
+
+The free-format inpsut reader of CLE-2000 is implemented using four functions: {\tt redopn\_c()}, {\tt redget\_c()}, {\tt redput\_c()} and {\tt redcls\_c()}.
+Only {\tt redget\_c()} and {\tt redput\_c()} are expected to be used in an application software.
+
+\subsubsection{redopn\_c\index{redopn\_c}}
+
+Function {\tt redopn\_c()} is called to open the input reader.
+The general specification of function {\tt redopn\_c()} is
+
+\begin{verbatim}
+
+redopn_c(iinp1, iout1, hout1, nrec);
+\end{verbatim}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt iinp1} & {\it kdi\_file*} & KDI object containing the CLE-2000 input data, as computed by {\tt clepil()} and {\tt objpil()} functions of CLE-2000.\\
+\hline
+{\tt iout1} & {\it FILE*} & sequential {\sc ascii} file used to write execution messages. Can be set to {\tt stdout}. \\
+\hline
+{\tt hout1} & {\it char*} & name of the sequential {\sc ascii} file used to write execution messages. \\
+\hline
+{\tt nrec} & {\it int\_32} & record index where reading occurs. Can be set to zero at first call. Set to the value returned by {\tt redcls\_c()} at subsequent calls.\\
+\hline
+\end{tabular}
+
+\vskip 0.4cm
+
+\noindent
+\begin{tabular}{|p{4.0cm}|p{11cm}|}
+\hline
+\multicolumn{2}{|c|}{\bf value of the function:} \\
+\hline
+{\it void} & \\
+\hline
+\end{tabular}
+
+\subsubsection{redget\_c\index{redget\_c}}
+
+Function {\tt redget\_c()} is called within modules of the application software to recover the module-specific input data.
+The general specification of function {\tt redget\_c()} is
+
+\begin{verbatim}
+
+redget_c(ityp, nitma, flott, text, dflot);
+\end{verbatim}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameters:} \\
+\hline
+{\tt ityp} & {\it int\_32*} & type of the CLE-2000 variable. A negative value indicates that the variable is to be computed by the application software and returned towards CLE-2000 using a call to {\tt redput\_c}. $=\pm 1$: integer type;
+$=\pm 2$: real (single precision) type;
+$=\pm 3$: string type;
+$=\pm 4$: double precision type;
+$=\pm 5$: logical type.\\
+\hline
+{\tt nitma} & {\it int\_32*} & integer input value when {\tt ityp} $= 1$ or $= 5$; number of characters when {\tt ityp} $= 3$. \\
+\hline
+{\tt flott} & {\it float\_32*} & real input value when {\tt ityp} $= 2$. \\
+\hline
+{\tt text} & {\it char[73]} & character string input value when {\tt ityp} $= 3$. \\
+\hline
+{\tt dflot} & {\it double\_64*} & double precision input value when {\tt ityp} $= 4$. \\
+\hline
+\multicolumn{3}{|c|}{\bf value of the function:} \\
+\hline
+\multicolumn{2}{|l|}{\it void} & \\
+\hline
+\end{tabular}
+
+\subsubsection{redput\_c\index{redput\_c}}
+
+Function {\tt redput\_c()} is called within modules of the application software to make information computed by the module available as CLE-2000 variables to the CLE-2000 procedure.
+The application software must first call {\tt redget\_c()} and obtain a negative value of {\tt ityp}. A call to {\tt redput\_c()} is next performed with its first parameter set to
+$-${\tt ityp} (now, a positive value) and with the corresponding value of the parameter.
+The general specification of function {\tt redput\_c()} is
+
+\begin{verbatim}
+
+redput_c(ityp, nitma, flott, text, dflot);
+\end{verbatim}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt ityp} & {\it int\_32*} & type of the CLE-2000 variable. $=1$: integer type;
+$=2$: real (single precision) type;
+$=3$: string type;
+$=4$: double precision type;
+$=5$: logical type.\\
+\hline
+{\tt nitma} & {\it int\_32*} & integer output value when {\tt ityp} $= 1$ or $= 5$; number of characters when {\tt ityp} $= 3$. \\
+\hline
+{\tt flott} & {\it float\_32*} & real output value when {\tt ityp} $= 2$. \\
+\hline
+{\tt text} & {\it char*} & character string output value when {\tt ityp} $= 3$. \\
+\hline
+{\tt dflot} & {\it double\_64*} & double precision output value when {\tt ityp} $= 4$. \\
+\hline
+\end{tabular}
+
+\vskip 0.4cm
+
+\noindent
+\begin{tabular}{|p{4.0cm}|p{11cm}|}
+\hline
+\multicolumn{2}{|c|}{\bf value of the function:} \\
+\hline
+{\it void} & \\
+\hline
+\end{tabular}
+
+\subsubsection{redcls\_c\index{redcls\_c}}
+
+Function {\tt redcls\_c()} is called to close the input reader.
+The general specification of function {\tt redcls\_c()} is
+
+\begin{verbatim}
+
+redcls_c(iinp1, iout1, hout1, nrec)
+\end{verbatim}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameters:} \\
+\hline
+{\tt iinp1} & {\it kdi\_file**} & KDI object containing the CLE-2000 input data.\\
+\hline
+{\tt iout1} & {\it FILE**} & sequential {\sc ascii} file used to write execution messages. \\
+\hline
+{\tt hout1} & {\it char[73]} & name of the sequential {\sc ascii} file used to write execution messages. \\
+\hline
+{\tt nrec} & {\it int\_32*} & record index where reading occurs. \\
+\hline
+\multicolumn{3}{|c|}{\bf value of the function:} \\
+\hline
+\multicolumn{2}{|l|}{\it void} & \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\subsection{Defining built-in constants in CLE-2000}
+
+CLE-2000 has pre-defined built-in constants, either with mathematical meaning (e.g., $\pi$) or with physical meaning. Currently, available physical constants are
+related to reactor physics. In future, one may want to include more physical constants. Here is the specification of the function available inside CLE-2000 to define these constants.
+
+\subsubsection{clecst\index{clecst}}
+
+Function {\tt dumcst()} is an external ANSI~C function implementing pre-defined parametric constants. A standard version is available in the GANLIB with name {\tt clecst()}. It is specified as
+\begin{verbatim}
+
+clecst(cparm, ityp, nitma, flott, text, dflot);
+\end{verbatim}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameter:} \\
+\hline
+cparm & {\it char*} & name of the parametric constant (name starting with \$) \\
+\hline
+\end{tabular}
+
+\vskip 0.4cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2cm}|p{11cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameters:} \\
+\hline
+{\tt ityp} & {\it int\_32*} & type of the parametric constant ($1 \le$ {\tt ityp} $ \le 5$) \\
+\hline
+{\tt nitma} & {\it int\_32*} & integer value of the parametric constant if {\tt ityp} $= 1$; logical value (=1: true/=-1: false) of the parametric constant if {\tt ityp} $= 5$;
+number of characters in the string if {\tt ityp} $= 3$. \\
+\hline
+{\tt flott} & {\it float\_32*} & real value of the parametric constant if {\tt ityp} $= 2$ \\
+\hline
+{\tt text} & {\it char*} & character string value of the parametric constant if {\tt ityp} $= 3$ \\
+\hline
+{\tt dflot} & {\it double\_64*} & double precision value of the parametric constant if {\tt ityp} $= 4$ \\
+\hline
+\multicolumn{3}{|c|}{\bf value of the function:} \\
+\hline
+\multicolumn{2}{|l|}{{\it int\_32}} & error code equal to zero if the execution of {\tt clecst()} is successful. Equal to the error code otherwise. \\
+\hline
+\end{tabular}
+
+\section {The ISO Fortran {\sc lcm} API}
+
+The ISO Fortran {\sc lcm} API is a set of Fortran-2003 wrapper subroutines or functions programmed around the ANSI-C functions of the {\sc lcm} API. This implementation is using
+the C interoperability capabilities normalized by ISO and available in the Fortran-2003 compilers. All the subroutines and functions presented in this section are ISO-standard and 64-bit clean.
+
+\vskip 0.08cm
+
+Each LCM object has a {\sl root associative table} from which the complete object is constructed.
+
+\vskip 0.08cm
+
+Any subroutines or functions using the Fortran {\sc lcm} API must include a {\tt USE} statement of the form
+\begin{verbatim}
+USE GANLIB
+\end{verbatim}
+
+The address of a LCM object is a {\tt TYPE(C\_PTR)} variable declared as
+\begin{verbatim}
+ TYPE(C_PTR) :: IPLIST
+\end{verbatim}
+\noindent This intrinsic type is defined by the {\tt USE GANLIB} statement. Very few operations are permitted on
+{\tt C\_PTR} variables. A {\tt C\_PTR} variable can be nullified by writing
+\begin{verbatim}
+ IPLIST=C_NULL_PTR
+\end{verbatim}
+\noindent and a {\tt C\_PTR} variable can be checked for association with actual data using
+\begin{verbatim}
+ IF(C_ASSOCIATED(IPLIST)) THEN
+\end{verbatim}
+
+\vskip 0.8cm
+
+\subsection{Opening, closing and validation of LCM objects}
+
+\subsubsection{LCMOP\index{LCMOP}}
+
+Open an LCM object (either memory resident or persistent). Obtain the address of the LCM
+object if it is created. Note that CLE-2000 is responsible to perform the calls to {\tt LCMOP} for the LCM
+objects that are used as parameters of a CLE-2000 module. The use
+of {\tt LCMOP} is generally restricted to the use of temporary LCM objects created within a CLE-2000 module.
+\begin{verbatim}
+
+CALL LCMOP(IPLIST,NAMP,IMP,MEDIUM,IMPX)
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt IPLIST} & {\it TYPE(C\_PTR)} & address of the LCM object if {\tt IMP=1} or {\tt imp=2}. {\tt IPLIST} corresponds to the address of the root associative table. \\
+\hline
+{\tt NAMP} & {\it CHARACTER*72} & name of the LCM object if {\tt IMP=0}. \\
+\hline
+{\tt IMP} & {\it INTEGER} & =0 to create a new LCM object ;
+ =1 to modify an existing LCM object;
+ =2 to access an existing LCM object in {\bf read-only} mode. \\
+\hline
+{\tt MEDIUM} & {\it INTEGER} & =1 to use a memory-resident LCM object;
+ =2 to use an {\sc xsm} file to store the LCM object. \\
+\hline
+{\tt IMPX} & {\it INTEGER} & print parameter. Equal to zero to suppress all printings. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameters:} \\
+\hline
+{\tt IPLIST} & {\it TYPE(C\_PTR)} & address of an LCM object if {\tt IMP=0}. \\
+\hline
+{\tt NAMP} & {\it CHARACTER*12} & name of the LCM object if {\tt IMP=1} or {\tt IMP=2}. \\
+\hline
+\end{tabular}
+
+\subsubsection{LCMCL\index{LCMCL}}
+
+Close an LCM object (either memory resident or persistent). Note that CLE-2000 is responsible to perform the calls to
+{\tt LCMCL} for the LCM objects that are used as parameters of a CLE-2000 module. The use
+of {\tt LCMCL} is generally restricted to the use of temporary LCM objects created within a CLE-2000 module.
+
+\vskip 0.2cm
+
+A LCM object can only be closed if {\tt IPLIST} points towards its root directory.
+
+\begin{verbatim}
+
+CALL LCMCL(IPLIST,IACT)
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt IPLIST} & {\it TYPE(C\_PTR)} & address of the LCM object (address of the root directory of the LCM object). \\
+\hline
+{\tt IACT} & {\it INTEGER} & =1 close the LCM object without destroying it; =2 and destroying it; =3 erase and close the LCM object without destroying it. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameter:} \\
+\hline
+{\tt IPLIST} & {\it TYPE(C\_PTR)} & {\tt IPLIST=0} indicates that the LCM object is closed and destroyed. A memory-resident LCM object keeps the
+same address during its complete existence. A persistent LCM object is associated to an XSM file and is represented by a different
+value of {\tt IPLIST} each time it is reopened. \\
+\hline
+\end{tabular}
+
+\subsubsection{LCMVAL\index{LCMVAL}}
+
+Subroutine to validate a single block of data in a LCM object or the totality of the LCM object,
+starting from the address of an associative table. This function has no effect if the object is
+persistent. The validation consists to verify the connections between the elements of the LCM
+object, to verify that each element of the object is defined and to check for possible memory corruptions.
+If an error is detected, the following message is issued:
+
+\begin{verbatim}
+LCMVAL: BLOCK xxx OF THE TABLE yyy HAS BEEN OVERWRITTEN.
+\end{verbatim}
+
+This function is called as
+
+\begin{verbatim}
+
+CALL LCMVAL(IPLIST,NAMP)
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt IPLIST} & {\it TYPE(C\_PTR)} & address of the associative table or of the heterogeneous list. \\
+\hline
+{\tt NAMP} & {\it CHARACTER*12} & name of the block to validate in the associative table.
+If {\tt NAMP='~'}, all the blocks in the associative table are verified in a recursive way. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\subsection{Interrogation of LCM objects}
+
+The data structures in an LCM object are self-described. It is therefore possible to
+interrogate them in order to know their characteristics.
+
+\vskip 0.4cm
+
+\begin{center}
+\begin{tabular}{|c|l|l|l|}
+\cline{3-4}
+\multicolumn{2}{c|}{} & \multicolumn{2}{c|}{type of interrogation} \\
+\cline{3-4}
+\multicolumn{2}{c|}{} & father structure~~~~ & information block \\
+\hline
+father & associative table & {\tt LCMINF} & {\tt LCMLEN} \\
+ & & {\tt LCMNXT} & \\
+\cline{2-4}
+ & heterogeneous list & {\tt LCMINF} & {\tt LCMLEL} \\
+\hline
+\end{tabular}
+\end{center}
+
+\subsubsection{LCMLEN\index{LCMLEN}}
+
+Subroutine used to recover the length and type of an information block stored in an
+associative table (either memory-resident or persistent). The length is the number of
+elements in a daughter heterogeneous list or the number of elements in an array of elementary type.
+If {\tt itylcm=3}, the length is the number of {\tt character*4} words. As an example, the length required
+to store an array of {\tt character*8} words is twice its dimension.
+
+\begin{verbatim}
+
+CALL LCMLEN(IPLIST,NAMP,ILONG,ITYLCM)
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt IPLIST} & {\it TYPE(C\_PTR)} & address of the associative table. \\
+\hline
+{\tt NAMP} & {\it CHARACTER*12} & name of the block. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameters:} \\
+\hline
+{\tt ILONG} & {\it INTEGER} & length of the block. =$-1$ for a daughter associative table;
+ =$N$ for a daughter heterogeneous list containing $N$ components;
+ =0 if the block does't exist.\\
+\hline
+{\tt ITYLCM} & {\it INTEGER} & type of information. =0 associative table; =1 32-bit integer;
+ =2 32-bit real; =3 {\tt character*4} data;
+ =4 64-bit real; =5 32-bit logical; =6 64-bit complex; =10 heterogeneous list;
+ =99 undefined (99 is returned if the block does't exist). \\
+\hline
+\end{tabular}
+
+\subsubsection{LCMINF\index{LCMINF}}
+
+Subroutine used to recover general information about a LCM object.
+
+\begin{verbatim}
+
+CALL LCMINF(IPLIST,NAMLCM,NAMMY,EMPTY,ILONG,LCM)
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameter:} \\
+\hline
+{\tt IPLIST} & {\it TYPE(C\_PTR)} & address of the associative table or of the heterogeneous list. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameters:} \\
+\hline
+{\tt NAMLCM} & {\it CHARACTER*72} & name of the LCM object. \\
+\hline
+{\tt NAMMY} & {\it CHARACTER*12} & name of the associative table at address {\tt IPLIST}. $=${\tt '/'} if the associative table
+is the root of the LCM object; $=${\tt ' '} if the associative table
+is an heterogeneous list component.
+\\
+\hline
+{\tt EMPTY} & {\it LOGICAL} & logical variable set to {\tt .true.}
+ if the associative table is empty
+ or set to {\tt .false.} otherwise. \\
+\hline
+{\tt ILONG} & {\it INTEGER} & $=-1$: {\tt IPLIST} is an associative table; $>0$: number of components in the heterogeneous list {\tt IPLIST}\\
+\hline
+{\tt LCM} & {\it LOGICAL} & logical variable set to {\tt .true.}
+ if information is memory-resident or set to {\tt .false.} if information is persistent (stored in an XSM file). \\
+\hline
+\end{tabular}
+
+\subsubsection{LCMNXT\index{LCMNXT}}
+
+Subroutine used to find the name of the next block of data in an associative table. Use
+of {\tt LCMNXT} is forbidden if the associative table is empty. The order of names is
+arbitrary. The search cycle indefinitely.
+
+\begin{verbatim}
+
+CALL LCMNXT(IPLIST,NAMP)
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt IPLIST} & {\it TYPE(C\_PTR)} & address of the associative table. \\
+\hline
+{\tt NAMP} & {\it CHARACTER*12} & name of an existing block.
+ {\tt NAMP=' '} can be used to obtain a first name to initiate the search. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameter:} \\
+\hline
+{\tt NAMP} & {\it CHARACTER*12} & name of the next block.
+A call to {\tt XABORT} is performed if the associative table is empty. \\
+\hline
+\end{tabular}
+
+\subsubsection{LCMLEL\index{LCMLEL}}
+
+Subroutine used to recover the length and type of an information block stored in an
+heterogeneous list (either memory-resident or persistent). The length is the number of
+elements in a daughter heterogeneous list or the number of elements in an array of elementary type.
+If {\tt itylcm=3}, the length is the number of {\tt character*4} words. As an example, the length required
+to store an array of {\tt character*8} words is twice its dimension.
+
+\begin{verbatim}
+
+CALL LCMLEL(IPLIST,ISET,ILONG,ITYLCM)
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt IPLIST} & {\it TYPE(C\_PTR)} & address of the heterogeneous list. \\
+\hline
+{\tt ISET} & {\it INTEGER} & index of the block in the list.
+The first element of the list is located at index $1$.\\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameters:} \\
+\hline
+{\tt ILONG} & {\it INTEGER} & length of the block. =0 if the block does't exist. \\
+\hline
+{\tt ITYLCM} & {\it INTEGER} & type of information. =0 associative table; =1 32-bit integer;
+ =2 32-bit real; =3 {\tt character*4} data;
+ =4 64-bit real; =5 32-bit logical; =6 64-bit complex; =10 heterogeneous list;
+ =99 undefined (99 is returned if the block does't exist);
+ =999 undefined (999 is returned if index {\tt ISET} is out of bounds). \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\subsection{Management of the array of elementary type}
+
+Management of the array of elementary type can be performed {\sl with} copy of the data ({\tt LCMPUT}, {\tt LCMGET}, {\tt LCMPDL} or
+{\tt LCMGDL}) or {\sl without} copy ({\tt LCMPPD}, {\tt LCMGPD}, {\tt LCMPPL} or {\tt LCMGPL}).
+
+\vskip 0.4cm
+
+\begin{center}
+\begin{tabular}{|c|l|l|l|}
+\cline{3-4}
+\multicolumn{2}{c|}{} & \multicolumn{2}{c|}{type of operation} \\
+\cline{3-4}
+\multicolumn{2}{c|}{} & put~~~~~~~~~~~~~ & get~~~~~~~~~~~~~ \\
+\hline
+father & associative table & {\tt LCMPUT} & {\tt LCMGET} \\
+ & & {\tt LCMPPD} & {\tt LCMGPD} \\
+\cline{2-4}
+ & heterogeneous list & {\tt LCMPDL} & {\tt LCMGDL} \\
+ & & {\tt LCMPPL} & {\tt LCMGPL} \\
+\hline
+\end{tabular}
+\end{center}
+
+\subsubsection{LCMGET\index{LCMGET}}
+
+Subroutine used to recover an information block (array of elementary type) from an associative table and to copy
+this data into memory.
+
+\begin{verbatim}
+
+CALL LCMGET(IPLIST,NAMP,DATA)
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt IPLIST} & {\it TYPE(C\_PTR)} & address of the associative table. \\
+\hline
+{\tt NAMP} & {\it CHARACTER*12} & name of the block to recover.
+ A call to {\tt XABORT} is performed if the block does't exist. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameter:} \\
+\hline
+{\tt DATA} & {\it CLASS(*)} & array of dimension $\ge$ {\tt ILONG} in which the block is copied. \\
+\hline
+\end{tabular}
+
+\vskip 0.4cm
+
+Subroutine {\tt LCMGET} can be used to recover character-string information available in a block
+of the LCM object. It is also possible to use subroutine {\tt LCMGCD} presented in \Sect{LCMGCD}.
+In the following example, a block is stored in an associative table located at
+address {\tt IPLIST}. The block has a name {\tt NAMP} and a length equivalent to 5 32-bit words.
+The information is recovered into the integer array {\tt IDATA} and transformed into a {\tt character*20} variable named {\tt HNAME} using an internal {\tt WRITE} statement:
+
+\begin{verbatim}
+ USE GANLIB
+ ...
+ CHARACTER NAMP*12,HNAME*20
+ INTEGER IDATA(5)
+ TYPE(C_PTR) IPLIST
+ ...
+ IPLIST=...
+ NAMP=...
+ CALL LCMGET(IPLIST,NAMP,IDATA)
+ WRITE(HNAME,'(5A4)') (IDATA(I),I=1,5)
+\end{verbatim}
+
+\subsubsection{LCMPUT\index{LCMPUT}}
+
+Subroutine used to store a block of data (array of elementary type) into an associative table.
+The information is copied from memory towards the LCM object. If the block already exists, it is replaced;
+otherwise, it is created. This operation cannot be performed into a LCM object open in {\tt read-only} mode.
+
+\begin{verbatim}
+
+CALL LCMPUT(IPLIST,NAMP,ILONG,ITYLCM,DATA)
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt IPLIST} & {\it TYPE(C\_PTR)} & address of the associative table. \\
+\hline
+{\tt NAMP} & {\it CHARACTER*12} & name of the block. \\
+\hline
+{\tt ILONG} & {\it INTEGER} & length of the block. If the array contains $N$ {\tt character*8} words,
+ {\tt ilong} must be set to $2 \times N$. \\
+\hline
+{\tt ITYLCM} & {\it INTEGER} & type of information. =1 32-bit integer;
+ =2 32-bit real; =3 {\tt character*4} data;
+ =4 64-bit real; =5 32-bit logical; =6 64-bit complex; =99 undefined. \\
+\hline
+{\tt DATA} & {\it CLASS(*)} & array of dimension $\ge$ {\tt ILONG} to be copied into the LCM object.
+ Array elements {\tt DATA} must be initialized before the call to {\tt LCMPUT}. \\
+\hline
+\end{tabular}
+
+\vskip 0.4cm
+
+Subroutine {\tt LCMPUT} can be used to store character-string information in an associative table of a LCM object.
+It is also possible to use function {\tt LCMPCD} presented in \Sect{LCMPCD}. In the
+following example, a character string {\tt HNAME} is first transformed into an integer array {\tt IDATA}
+using an internal {\tt READ} statement. This array (block of data) is stored into the LCM object located at
+address {\tt IPLIST}, using {\tt LCMPUT}. The block has a name {\tt NAMP}, a length equivalent to 5 32-bit words, and a type
+equal to 3.
+
+\begin{verbatim}
+ USE GANLIB
+ ...
+ CHARACTER NAMP*12,HNAME*20
+ INTEGER IDATA(5)
+ TYPE(C_PTR) IPLIST
+ ...
+ IPLIST=...
+ NAMP=...
+ READ(HNAME,'(5A4)') (IDATA(I),I=1,5)
+ CALL LCMPUT(IPLIST,NAMP,5,3,IDATA)
+\end{verbatim}
+
+\subsubsection{LCMGPD\index{LCMGPD}}
+
+Subroutine used to recover the {\tt TYPE(C\_PTR)} address of an information block (array of elementary type) from an associative table,
+{\sl without} making a copy of the information. Use of this subroutine must respect the following rules:
+\begin{itemize}
+\item If the information is modified after the call to {\tt LCMGPD}, a call to {\tt LCMPPD}
+must be performed to acknowledge the modification.
+\item The block pointed by {\tt IOFSET} should never be released using a deallocation function such as
+{\tt RLSARA}, {\tt deallocate}, etc.
+\item The variable {\tt IOFSET} must never be copied into another variable.
+\end{itemize}
+Non respect of these rules may cause execution failure (core dump,
+segmentation fault, etc) without possibility to throw an exception.
+
+\vskip 0.2cm
+
+Subroutine {\tt LCMGPD} implements direct {\sl pinning} on LCM data structures. It represents an advanced capability of the {\sc lcm} API and should only be used in situations where
+the economy of computer resources is a critical issue. The {\tt C\_PTR} address is the ANSI~C pointer of a block of
+information made available into a Fortran program. If {\tt IOFSET} is a {\tt C\_PTR} address, the useful information is
+accessed in a Fortran variable {\tt IDATA} set using
+\begin{verbatim}
+ USE GANLIB
+ ...
+ TYPE(C_PTR) :: IOFSET
+ INTEGER, POINTER, DIMENSION(:) :: IDATA
+ ...
+ CALL LCMGPD(IPLIST,NAMP,IOFSET)
+ CALL C_F_POINTER(IOFSET,IDATA, (/ ILONG /))
+\end{verbatim}
+
+The useful information is therefore accessed in memory locations {\tt IDATA(1)} to {\tt IDATA(ILONG)}.
+
+\vskip 0.2cm
+
+A call to {\tt LCMGPD} doesn't cause any modification to the LCM object.
+
+\vskip 0.5cm
+
+\begin{verbatim}
+
+CALL LCMGPD(IPLIST,NAMP,IOFSET)
+\end{verbatim}
+
+\vskip 0.5cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt IPLIST} & {\it TYPE(C\_PTR)} & address of the associative table. \\
+\hline
+{\tt NAMP} & {\it CHARACTER*12} & name of the block to recover.
+A call to {\tt XABORT} is performed if the block does't exist. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameter:} \\
+\hline
+{\tt IOFSET} & {\it TYPE(C\_PTR)} & {\tt C\_PTR} address of the information. \\
+\hline
+\end{tabular}
+
+\subsubsection{LCMPPD\index{LCMPPD}}
+
+Subroutine used to store a block of data (array of elementary type) into an associative table
+{\sl without} making a copy of the information. If the block already exists, it is replaced;
+otherwise, it is created. This operation cannot be performed into a LCM object open in {\tt read-only} mode.
+
+\vskip 0.2cm
+
+{\sl If a block named {\tt NAMP} already exists in the associative table, the address associated
+with {\tt NAMP} is replaced by the new address and the information pointed by the old address
+is deallocated.}
+
+\vskip 0.2cm
+
+Subroutine {\tt LCMPPD} implements direct {\sl pinning} on LCM data structures. It represents an advanced capability of the {\sc lcm} API and should only be used in situations where
+the economy of computer resources is a critical issue. The memory block stored by {\tt LCMPPD} must be previously
+allocated by a call to {\tt LCMARA} of the form
+\begin{verbatim}
+IOFSET=LCMARA(JLONG)
+\end{verbatim}
+
+\noindent where {\tt JLONG} is the number of 32-bit words required to store the memory block. {\tt JLONG} is generally equal to {\tt ILONG} except if
+{\tt ITYLCM}=4 or {\tt ITYLCM}=6 where {\tt JLONG}={\tt 2*ILONG}.
+
+\vskip 0.2cm
+
+If {\tt ITYLCM}=1, the useful information is accessed in a Fortran variable {\tt IDATA} set using a {\tt C\_F\_POINTER} function:
+\begin{verbatim}
+ USE GANLIB
+ ...
+ TYPE(C_PTR) :: IOFSET
+ INTEGER, POINTER, DIMENSION(:) :: IDATA
+ ...
+ IOFSET = LCMARA(ILONG)
+ CALL C_F_POINTER(IOFSET,IDATA, (/ ILONG /))
+ ...
+ CALL LCMPPD(IPLIST,NAMP,ILONG,ITYLCM,IOFSET)
+\end{verbatim}
+
+The useful information is therefore accessed in memory locations {\tt IDATA(1)} to {\tt IDATA(ILONG)}. There is no need to
+declare {\tt LCMARA} as an external function; this declaration is included in the module set by the {\tt USE GANLIB} statement.
+
+\begin{verbatim}
+
+CALL LCMPPD(IPLIST,NAMP,ILONG,ITYLCM,IOFSET)
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt IPLIST} & {\it TYPE(C\_PTR)} & address of the associative table. \\
+\hline
+{\tt NAMP} & {\it CHARACTER*12} & name of the block. \\
+\hline
+{\tt ILONG} & {\it INTEGER} & length of the block. \\
+\hline
+{\tt ITYLCM} & {\it INTEGER} & type of information. =1 32-bit integer;
+ =2 32-bit real; =3 {\tt character*4} data;
+ =4 64-bit real; =5 32-bit logical; =6 64-bit complex; =99 undefined.\\
+\hline
+{\tt IOFSET} & {\it TYPE(C\_PTR)} & {\tt C\_PTR} address of the information. Data elements pointed
+by {\tt IOFSET} must be initialized before the call to {\tt LCMPPD}. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameter:} \\
+\hline
+{\tt IOFSET} & {\it TYPE(C\_PTR)} & {\tt IOFSET=C\_NULL\_PTR} to indicate that the information previously pointed by
+ {\tt IOFSET} is now managed by {\tt LCM}. \\
+\hline
+\end{tabular}
+
+\subsubsection{LCMDEL\index{LCMDEL}}
+
+Subroutine used to erase an information block or a daughter heterogeneous list stored in a memory-resident associative table.
+Subroutine {\tt LCMDEL} {\sl cannot} be used with persistent LCM objects.
+
+\begin{verbatim}
+
+CALL LCMDEL(IPLIST,NAMP)
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt IPLIST} & {\it TYPE(C\_PTR)} & address of the associative table. \\
+\hline
+{\tt NAMP} & {\it CHARACTER*12} & name of the block to erase. \\
+\hline
+\end{tabular}
+
+\subsubsection{LCMGDL\index{LCMGDL}}
+
+Subroutine used to recover an information block (array of elementary type) from an heterogeneous list and to copy
+this data into memory.
+
+\begin{verbatim}
+
+CALL LCMGDL(IPLIST,ISET,DATA)
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt IPLIST} & {\it TYPE(C\_PTR)} & address of the heterogeneous list. \\
+\hline
+{\tt ISET} & {\it INTEGER} & index of the block in the heterogeneous list. A call to {\tt XABORT}
+ is performed if the block does't exist.
+The first element of the list is located at index $1$.\\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameter:} \\
+\hline
+{\tt DATA} & {\it CLASS(*)} & array of dimension $\ge$ {\tt ILONG} in which the block is copied. \\
+\hline
+\end{tabular}
+
+\vskip 0.4cm
+
+Subroutine {\tt LCMGDL} can be used to recover character-string information available in a block
+of the LCM object. It is also possible to use subroutine {\tt LCMGCL} presented in \Sect{LCMGCL}.
+In the following example, a block is stored in an heterogeneous list located at
+address {\tt IPLIST}. The block is located at the {\tt ISET}--th position of the heterogeneous list and has a length equivalent to 5 32-bit words.
+The information is recovered into the integer array {\tt IDATA} and transformed into a {\tt character*20} variable named {\tt HNAME} using an internal {\tt WRITE} statement:
+
+\begin{verbatim}
+ USE GANLIB
+ ...
+ CHARACTER HNAME*20
+ INTEGER IDATA(5)
+ TYPE(C_PTR) IPLIST
+ ...
+ IPLIST=...
+ ISET=...
+ CALL LCMGDL(IPLIST,ISET,IDATA)
+ WRITE(HNAME,'(5A4)') (IDATA(I),I=1,5)
+\end{verbatim}
+
+\subsubsection{LCMPDL\index{LCMPDL}}
+
+Subroutine used to store a block of data (array of elementary type) into an heterogeneous list.
+The information is copied from memory towards the LCM object. If the block already exists, it is replaced;
+otherwise, it is created. This operation cannot be performed into a LCM object open in {\tt read-only} mode.
+
+\begin{verbatim}
+
+CALL LCMPDL(IPLIST,ISET,ILONG,ITYLCM,DATA)
+\end{verbatim}
+
+\vskip 0.2cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt IPLIST} & {\it TYPE(C\_PTR)} & address of the heterogeneous list. \\
+\hline
+{\tt ISET} & {\it INTEGER} & index of the block in the list.
+The first element of the list is located at index $1$.\\
+\hline
+{\tt ILONG} & {\it INTEGER} & length of the block. If the array contains $N$ {\tt character*8} words,
+ {\tt ILONG} must be set to $2 \times N$ \\
+\hline
+{\tt ITYLCM} & {\it INTEGER} & type of information. =1 32-bit integer;
+ =2 32-bit real; =3 {\tt character*4} data;
+ =4 64-bit real; =5 32-bit logical; =6 64-bit complex; =99 undefined. \\
+\hline
+{\tt DATA} & {\it CLASS(*)} & array of dimension $\ge$ {\tt ILONG} to be copied into the LCM object.
+ Array elements {\tt DATA} must be initialized before the call to {\tt LCMPDL}. \\
+\hline
+\end{tabular}
+
+\vskip 0.4cm
+
+Subroutine {\tt LCMPDL} can be used to store character-string information into an heterogeneous list of a LCM object. In the
+following example, a character string {\tt HNAME} is first transformed into an integer array {\tt IDATA}
+using an internal {\tt READ} statement. This array (block of data) is stored into the LCM object located at
+address {\tt IPLIST}, using {\tt LCMPDL} . The block is located at the {\tt ISET}--th position of the heterogeneous list, has a length equivalent to 5 32-bit words, and a type
+equal to 3.
+
+\begin{verbatim}
+ USE GANLIB
+ ...
+ CHARACTER HNAME*20
+ INTEGER IDATA(5)
+ TYPE(C_PTR) IPLIST
+ ...
+ IPLIST=...
+ ISET=...
+ READ(HNAME,'(5A4)') (IDATA(I),I=1,5)
+ CALL LCMPDL(IPLIST,ISET,5,3,IDATA)
+\end{verbatim}
+
+\subsubsection{LCMGPL\index{LCMGPL}}
+
+Subroutine used to recover the {\tt TYPE(C\_PTR)} address of an information block (array of elementary type) from an heterogeneous list,
+{\sl without} making a copy of the information. Use of this subroutine must respect the following rules:
+\begin{itemize}
+\item If the information is modified after the call to {\tt LCMGPL}, a call to {\tt LCMPPL}
+must be performed to acknowledge the modification.
+\item The block pointed by {\tt IOFSET} should never be released using a deallocation function such as
+{\tt RLSARA}, {\tt deallocate}, etc.
+\item The variable {\tt IOFSET} must never be copied into another variable.
+\end{itemize}
+Non respect of these rules may cause execution failure (core dump,
+segmentation fault, etc) without possibility to throw an exception.
+
+\vskip 0.2cm
+
+Subroutine {\tt LCMGPL} implements direct {\sl pinning} on LCM data structures. It represents an advanced capability of the {\sc lcm} API and should only be used in situations where
+the economy of computer resources is a critical issue. The {\tt C\_PTR} address is the ANSI~C pointer of a block of
+information made available into a Fortran program. If {\tt IOFSET} is a {\tt C\_PTR} address, the useful information is
+accessed in a Fortran variable {\tt IDATA} set using
+\begin{verbatim}
+ USE GANLIB
+ ...
+ TYPE(C_PTR) :: IOFSET
+ INTEGER, POINTER, DIMENSION(:) :: IDATA
+ ...
+ CALL LCMGPL(IPLIST,ISET,IOFSET)
+ CALL C_F_POINTER(IOFSET,IDATA, (/ ILONG /))
+\end{verbatim}
+
+The useful information is therefore accessed in memory locations {\tt IDATA(1)} to {\tt IDATA(ILONG)}.
+
+\vskip 0.2cm
+
+A call to {\tt LCMGPL} doesn't cause any modification to the LCM object.
+
+\begin{verbatim}
+
+CALL LCMGPL(IPLIST,ISET,IOFSET)
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt IPLIST} & {\it TYPE(C\_PTR)} & address of the heterogeneous list. \\
+\hline
+{\tt ISET} & {\it INTEGER} & index of the block in the list.
+A call to {\tt XABORT} is performed if the block does't exist.
+The first element of the list is located at index $1$. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameter:} \\
+\hline
+{\tt IOFSET} & {\it TYPE(C\_PTR)} & {\tt C\_PTR} address of the information. \\
+\hline
+\end{tabular}
+
+\subsubsection{LCMPPL\index{LCMPPL}}
+
+Subroutine used to store a block of data (array of elementary type) into an heterogeneous list
+{\sl without} making a copy of the information. If the block already exists, it is replaced;
+otherwise, it is created. This operation cannot be performed into a LCM object open in {\tt read-only} mode.
+
+\vskip 0.2cm
+
+{\sl If the {\tt ISET}-th component of the heterogeneous list already exists, the address associated
+with this component is replaced by the new address and the information pointed by the old address
+is deallocated.}
+
+\vskip 0.2cm
+
+Subroutine {\tt LCMPPL} implements direct {\sl pinning} on LCM data structures. It represents an advanced capability of the {\sc lcm} API and
+should only be used in situations where the economy of computer resources is a critical issue. The memory block stored by {\tt LCMPPL} must be previously
+allocated by a call to {\tt LCMARA} of the form
+\begin{verbatim}
+IOFSET=LCMARA(JLONG)
+\end{verbatim}
+
+\noindent where {\tt JLONG} is the number of 32-bit words required to store the memory block. {\tt JLONG} is generally equal to {\tt ILONG} except if
+{\tt ITYLCM}=4 or {\tt ITYLCM}=6 where {\tt JLONG}={\tt 2*ILONG}.
+
+\vskip 0.2cm
+
+If {\tt ITYLCM}=1, the useful information is accessed in a Fortran variable {\tt IDATA} set using a {\tt C\_F\_POINTER} function:
+\begin{verbatim}
+ USE GANLIB
+ ...
+ TYPE(C_PTR) :: IOFSET
+ INTEGER, POINTER, DIMENSION(:) :: IDATA
+ ...
+ IOFSET = LCMARA(ILONG)
+ CALL C_F_POINTER(IOFSET,IDATA, (/ ILONG /))
+ ...
+ CALL LCMPPL(IPLIST,ISET,ILONG,ITYLCM,IOFSET)
+\end{verbatim}
+
+The useful information is therefore accessed in memory locations {\tt IDATA(1)} to {\tt IDATA(ILONG)}. There is no need to
+declare {\tt LCMARA} as an external function; this declaration is included in the module set by the {\tt USE GANLIB} statement.
+
+\begin{verbatim}
+
+CALL LCMPPL(IPLIST,ISET,ILONG,ITYLCM,IOFSET)
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt IPLIST} & {\it TYPE(C\_PTR)} & address of the heterogeneous list. \\
+\hline
+{\tt ISET} & {\it INTEGER} & index of the block in the list.
+The first element of the list is located at index $1$. \\
+\hline
+{\tt ILONG} & {\it INTEGER} & length of the block. \\
+\hline
+{\tt ITYLCM} & {\it INTEGER} & type of information. =1 32-bit integer;
+ =2 32-bit real; =3 {\tt character*4} data;
+ =4 64-bit real; =5 32-bit logical; =6 64-bit complex;
+ =99 undefined. \\
+\hline
+{\tt IOFSET} & {\it TYPE(C\_PTR)} & {\tt C\_PTR} address of the information. Data elements pointed
+by {\tt IOFSET} must be initialized before the call to {\tt LCMPPL}. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameter:} \\
+\hline
+{\tt IOFSET} & {\it INTEGER} & {\tt IOFSET=C\_NULL\_PTR} to indicate that the information previously pointed by
+ {\tt IOFSET} is now managed by {\tt LCM}. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\subsection{Management of the associative tables and of the heterogeneous lists}
+
+These functions permit to create ({\tt LCMSIX}, {\tt LCMDID}, {\tt LCMDIL},
+{\tt LCMLID}, {\tt LCMLIL}) or to access ({\tt LCMSIX}, {\tt LCMGID}, {\tt LCMGIL})
+daughter associative tables or daughter heterogeneous lists. There is no need to
+declare these functions as external functions; this declaration is included in the module set by the {\tt USE GANLIB} statement. Use of these functions is summarized in the following table:
+
+\begin{center}
+\begin{tabular}{|c|l|l|l|}
+\cline{3-4}
+\multicolumn{2}{c|}{} & \multicolumn{2}{c|}{daughter} \\
+\cline{3-4}
+\multicolumn{2}{c|}{} & associative table & heterogeneous list \\
+\hline
+father & associative table & {\tt LCMDID} & {\tt LCMLID} \\
+ & & {\tt LCMGID} & {\tt LCMGID} \\
+\cline{2-4}
+ & heterogeneous list & {\tt LCMDIL} & {\tt LCMLIL} \\
+ & & {\tt LCMGIL} & {\tt LCMGIL} \\
+\hline
+\end{tabular}
+\end{center}
+
+\subsubsection{LCMDID\index{LCMDID}}
+
+Function used to create or access a daughter associative table included into a father associative table. This operation cannot be
+performed in a LCM object open in {\tt read-only} mode.
+
+\vskip 0.2cm
+
+The daughter associative table is created if it doesn't already exist. Otherwise, the
+existing daughter associative table is accessed. In the latter case, it is recommended
+to use function {\tt LCMGID} which is faster for a simple access and which can be used
+with LCM object open in {\tt read-only} mode.
+
+\begin{verbatim}
+
+JPLIST=LCMDID(IPLIST,NAMP)
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt IPLIST} & {\it TYPE(C\_PTR)} & address of the father associative table. \\
+\hline
+{\tt NAMP} & {\it CHARACTER*12} & name of the daughter associative table. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameter:} \\
+\hline
+{\tt JPLIST} & {\it TYPE(C\_PTR)} & address of the daughter associative table. \\
+\hline
+\end{tabular}
+
+\subsubsection{LCMLID\index{LCMLID}}
+
+Function used to create or access a daughter heterogeneous list included into a father associative table. This operation cannot be
+performed in a LCM object open in {\tt read-only} mode.
+
+\vskip 0.2cm
+
+In the following example, a daughter heterogeneous list is created as a block {\tt LIST}
+into a father associative table. The heterogeneous list contains 5~components. A block of data
+is stored in each component of the heterogeneous list using {\tt LCMPDL}:
+
+\begin{verbatim}
+ USE GANLIB
+ ...
+ TYPE(C_PTR) :: IPLIST, JPLIST
+ ...
+ JPLIST=LCMLID(IPLIST,'LIST',5)
+ DO I=1,5
+ CALL LCMPDL(JPLIST,I,...
+ ...
+ ENDDO
+\end{verbatim}
+
+\vskip 0.2cm
+
+The heterogeneous list capability is implemented through calls to function {\tt LCMLID}. Such a
+call permit the following possibilities:
+\begin{itemize}
+\item the heterogeneous list is created if it doesn't already exist.
+\item the heterogeneous list is accessed if it already exists {\sl and} if its length is unchanged. In this case,
+it is recommended to use function {\tt LCMGID} which is faster for a simple access and which can be used
+with LCM object open in {\tt read-only} mode.
+\item the heterogeneous list is enlarged (components are added) if it already exists {\sl and} if the new length is larger than the preceding one.
+\end{itemize}
+
+\begin{verbatim}
+
+JPLIST=LCMLID(IPLIST,NAMP,ILONG)
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt IPLIST} & {\it TYPE(C\_PTR)} & address of the father associative table. \\
+\hline
+{\tt NAMP} & {\it CHARACTER*12} & name of the daughter heterogeneous list. \\
+\hline
+{\tt ILONG} & {\it INTEGER} & number of components in the daughter heterogeneous list. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameter:} \\
+\hline
+{\tt JPLIST} & {\it INTEGER} & address of the daughter heterogeneous list named {\tt NAMP}. \\
+\hline
+\end{tabular}
+
+\subsubsection{LCMLIL\index{LCMLIL}}
+
+Function used to create or access a daughter heterogeneous list included into a father heterogeneous list. This operation cannot be
+performed in a LCM object open in {\tt read-only} mode.
+
+\vskip 0.2cm
+
+In the following example, a daughter heterogeneous list is created as {\tt 77}-th component
+of a father heterogeneous list. The heterogeneous list contains 5~components. A block of data
+is stored in each component of the heterogeneous list using {\tt LCMPDL}:
+
+\begin{verbatim}
+ USE GANLIB
+ ...
+ TYPE(C_PTR) :: IPLIST, JPLIST
+ ...
+ JPLIST=LCMLIL(IPLIST,77,5)
+ DO I=1,5
+ CALL LCMPDL(JPLIST,I,...
+ ...
+ ENDDO
+\end{verbatim}
+
+\vskip 0.2cm
+
+The heterogeneous list capability is implemented through calls to function {\tt LCMLIL}. Such a
+call permit the following possibilities:
+\begin{itemize}
+\item the heterogeneous list is created if it doesn't already exist.
+\item the heterogeneous list is accessed if it already exists {\sl and} if its length is unchanged. In this case,
+it is recommended to use function {\tt LCMGIL} which is faster for a simple access and which can be used
+with LCM object open in {\tt read-only} mode.
+\item the heterogeneous list is enlarged (components are added) if it already exists {\sl and} if the new length is larger than the preceding one.
+\end{itemize}
+
+\begin{verbatim}
+
+JPLIST=LCMLIL(IPLIST,ISET,ILONG)
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt IPLIST} & {\it TYPE(C\_PTR)} & address of the father heterogeneous list. \\
+\hline
+{\tt ISET} & {\it INTEGER} & index of the daughter heterogeneous list in the father heterogeneous list.
+The first element of the list is located at index $1$. \\
+\hline
+{\tt ILONG} & {\it INTEGER} & number of components in the daughter heterogeneous list. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameter:} \\
+\hline
+{\tt JPLIST} & {\it TYPE(C\_PTR)} & address of the daughter heterogeneous list. \\
+\hline
+\end{tabular}
+
+\subsubsection{LCMDIL\index{LCMDIL}}
+
+Function used to create or access a daughter associative table included into a father heterogeneous list. This operation cannot be
+performed in a LCM object open in {\tt read-only} mode.
+
+\vskip 0.2cm
+
+The daughter associative table is created if it doesn't already exist. Otherwise, the
+existing daughter associative table is accessed. In the latter case, it is recommended
+to use function {\tt LCMGIL} which is faster for a simple access and which can be used
+with LCM object open in {\tt read-only} mode.
+
+\vskip 0.2cm
+
+It is a good programming practice to replace a set of $N$ distinct associative tables by a
+list made of $N$ associative tables, as depicted in \Fig{f1}.
+
+\vskip 0.2cm
+
+\begin{figure}[htbp]
+\begin{center}
+\epsfxsize=9cm
+\centerline{ \epsffile{vect.eps}}
+\parbox{12cm}{\caption{A list of associative tables.}\label{fig:f2}}
+\end{center}
+\end{figure}
+\goodbreak
+
+In the example of \Fig{f2}, a set of 5~associative tables, created by {\tt LCMDID}:
+
+\begin{verbatim}
+ USE GANLIB
+ ...
+ TYPE(C_PTR) :: IPLIST, JPLIST
+ CHARACTER HDIR*12
+ ...
+ DO I=1,5
+ WRITE(HDIR,'(5HGROUP,I3,4H/ 5)') I
+ JPLIST=LCMDID(IPLIST,HDIR)
+ CALL LCMPUT(JPLIST,...
+ ...
+ ENDDO
+\end{verbatim}
+
+\noindent are replaced by a list of 5~associative tables, created by {\tt LCMLID} and {\tt LCMDIL}:
+
+\begin{verbatim}
+ USE GANLIB
+ ...
+ TYPE(C_PTR) :: IPLIST, JPLIST, KPLIST
+ ...
+ JPLIST=LCMLID(IPLIST,'GROUP',5)
+ DO I=1,5
+ KPLIST=LCMDIL(JPLIST,I)
+ CALL LCMPUT(KPLIST,...
+ ...
+ ENDDO
+\end{verbatim}
+
+\vskip 0.2cm
+
+The capability to include associative tables into an heterogeneous list is implemented using
+the {\tt LCMDIL} function:
+
+\begin{verbatim}
+
+JPLIST=LCMDIL(IPLIST,ISET)
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt IPLIST} & {\it TYPE(C\_PTR)} & address of the father heterogeneous list. \\
+\hline
+{\tt ISET} & {\it INTEGER} & index of the daughter associative table in the father heterogeneous list.
+The first element of the list is located at index $1$. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameter:} \\
+\hline
+{\tt JPLIST} & {\it TYPE(C\_PTR)} & address of the daughter associative table. \\
+\hline
+\end{tabular}
+
+\subsubsection{LCMGID\index{LCMGID}}
+
+Function used to access a daughter associative table {\sl or} heterogeneous list included into a father associative table.
+
+\begin{verbatim}
+
+JPLIST=LCMGID(IPLIST,NAMP)
+\end{verbatim}
+
+\vskip 0.5cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt IPLIST} & {\it TYPE(C\_PTR)} & address of the father associative table. \\
+\hline
+{\tt NAMP} & {\it CHARACTER*12} & name of the daughter associative table or heterogeneous list. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameter:} \\
+\hline
+{\tt JPLIST} & {\it TYPE(C\_PTR)} & address of the daughter associative table or heterogeneous list. A call to {\tt XABORT} is performed if this daughter doesn't extst. \\
+\hline
+\end{tabular}
+
+\subsubsection{LCMGIL\index{LCMGIL}}
+
+Function used to access a daughter associative table {\sl or} heterogeneous list included into a father heterogeneous list.
+
+\begin{verbatim}
+
+JPLIST=LCMGIL(IPLIST,ISET)
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt IPLIST} & {\it TYPE(C\_PTR)} & address of the father heterogeneous list. \\
+\hline
+{\tt ISET} & {\it INTEGER} & index of the daughter associative table or heterogeneous list in the father heterogeneous list.
+The first element of the list is located at index $1$. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameter:} \\
+\hline
+{\tt JPLIST} & {\it TYPE(C\_PTR)} & address of the daughter associative table or heterogeneous list. A call to {\tt XABORT} is performed if this daughter doesn't extst. \\
+\hline
+\end{tabular}
+
+\subsubsection{LCMSIX\index{LCMSIX}}
+
+Function used to move across the hierarchical structure of a LCM object made of
+associative tables. Using this function, there is no need to remember the names of
+the father (grand-father, etc.) associative tables. If a daughter associative table doesn't
+exist and if the LCM object is open on creation or modification mode, the daughter
+associative table is created. A daughter associative table cannot be created if the
+LCM object is open in {\tt read-only} mode.
+
+\vskip 0.4cm
+
+Function {\tt LCMSIX} is deprecated, as {\tt LCMDID} offers a more elegant way to perform the same operation.
+However, {\tt LCMSIX} is kept available in the {\sc lcm} API for historical reasons.
+
+\begin{verbatim}
+
+CALL LCMSIX(IPLIST,NAMP,IACT)
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt IPLIST} & {\it TYPE(C\_PTR)} & address of the associative table before the call to {\tt LCMSIX}. \\
+\hline
+{\tt NAMP} & {\it CHARACTER*12} & name of the daughter associative table if {\tt iact=1}.
+ This parameter is not used if {\tt iact=0} or {\tt iact=2}. \\
+\hline
+{\tt IACT} & {\it INTEGER} & type of move: =0 return towards the root directory of the LCM object;
+ =1 move towards the daughter associative table (create it if it doesn't exist);
+ =2 return towards the father associative table. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameter:} \\
+\hline
+{\tt IPLIST} & {\it TYPE(C\_PTR)} & address of the associative table after the call to {\tt LCMSIX}. \\
+\hline
+\\
+\end{tabular}
+
+\vspace{0.8cm}
+
+\subsection{LCM utility functions}
+
+\subsubsection{LCMLIB\index{LCMLIB}}
+
+Function used to print (towards {\tt stdout}) the content of the active directory of an associative table or heterogeneous list.
+
+\begin{verbatim}
+
+CALL LCMLIB(IPLIST)
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameter:} \\
+\hline
+{\tt IPLIST} & {\it TYPE(C\_PTR)} & address of the associative table or of the heterogeneous list. \\
+\hline
+\end{tabular}
+
+\subsubsection{LCMEQU\index{LCMEQU}}
+
+Function used to perform a deep-copy of the information contained in an associative table (address {\tt IPLIS1})
+towards another associative table (address {\tt IPLIS2}). Note that the second associative table (address {\tt IPLIS2}) is modified
+but not created by {\tt LCMEQU}.
+
+\begin{verbatim}
+
+CALL LCMEQU(IPLIS1,IPLIS2)
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameter:} \\
+\hline
+{\tt IPLIS1} & {\it TYPE(C\_PTR)} & address of the existing associative table or of the heterogeneous list
+ (accessed in {\tt read-only} mode). \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameter:} \\
+\hline
+{\tt IPLIS2} & {\it TYPE(C\_PTR)} & address of the associative table or of the heterogeneous list, modified by {\tt LCMEQU}. \\
+\hline
+\end{tabular}
+
+\subsubsection{LCMEXP\index{LCMEXP}}
+
+Function used to export (or import) the content of an associative table towards (or from) a sequential file. The sequential file
+can be in binary or {\tt ascii} format.
+
+\vskip 0.4cm
+
+The export of information starts from the active directoty. Note that {LCMEQU} is basically a serialization algorithm
+based on the contour algorithm.
+
+\begin{verbatim}
+
+CALL LCMEXP(IPLIST,IMPX,NUNIT,IMODE,IDIR)
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt IPLIST} & {\it TYPE(C\_PTR)} & address of the associative table or of the heterogeneous list to be exported (or imported). \\
+\hline
+{\tt IMPX} & {\it INTEGER} & print parameter (equal to 0 for no print). \\
+\hline
+{\tt NUNIT} & {\it INTEGER} & unit number of the sequential file. \\
+\hline
+{\tt IMODE} & {\it INTEGER} & =1 binary sequential file;
+ =2 {\sc ascii} sequential file. \\
+\hline
+{\tt IDIR} & {\it INTEGER} & =1 to export; =2 to import. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\subsection{Using fixed-length character arrays}
+
+The following subroutines are implemented using the LCM Fortran API of the preceding sections. They
+permit the use of fixed-length character arrays. They reproduce an existing capability of the GANLIB4 API.
+
+\vskip 0.4cm
+
+\begin{center}
+\begin{tabular}{|c|l|l|l|}
+\cline{3-4}
+\multicolumn{2}{c|}{} & \multicolumn{2}{c|}{type of operation} \\
+\cline{3-4}
+\multicolumn{2}{c|}{} & put~~~~~~~~~~~~~ & get~~~~~~~~~~~~~ \\
+\hline
+father & associative table & {\tt LCMPTC} & {\tt LCMGTC} \\
+\cline{2-4}
+ & heterogeneous list & {\tt LCMPLC} & {\tt LCMGLC} \\
+\hline
+\end{tabular}
+\end{center}
+
+\subsubsection{LCMGTC\index{LCMGTC}}\label{sect:LCMGTC}
+
+Subroutine used to recover a character array from a block of data stored in an associative table.
+
+\begin{verbatim}
+
+CALL LCMGTC(IPLIST,NAMP,LENG,[NLIN,]HDATA)
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt IPLIST} & {\it TYPE(C\_PTR)} & address of the associative table. \\
+\hline
+{\tt NAMP} & {\it CHARACTER*12} & name of the character array
+to recover. A call to {\tt XABORT} is performed if the block does't exist. \\
+\hline
+{\tt LENG} & {\it INTEGER} & length of each character string in the array {\tt HDATA}. \\
+\hline
+{\tt NLIN} & {\it INTEGER} & dimension of array {\tt HDATA}. This parameter is omitted if {\tt HDATA} \\
+& & is a single character string. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3.5cm}|p{9.5cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameter:} \\
+\hline
+{\tt HDATA} & {\it CHARACTER*(*)(*)} & character array of dimension $\ge$ {\tt NLIN} in which the character information is to be copied \\
+\hline
+\end{tabular}
+
+\subsubsection{LCMPTC\index{LCMPTC}}\label{sect:LCMPTC}
+
+Subroutine used to store a character array into a block of data stored in an associative table.
+If the block of data already exists, it is updated; otherwise, it is created. This operation cannot be performed
+in a LCM object open in {\tt read-only} mode.
+
+\begin{verbatim}
+
+CALL LCMPTC(IPLIST,NAMP,LENG,[NLIN,]HDATA)
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3.5cm}|p{9.5cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt IPLIST} & {\it TYPE(C\_PTR)} & address of the associative table. \\
+\hline
+{\tt NAMP} & {\it CHARACTER*12} & name of the character array
+to store. \\
+\hline
+{\tt LENG} & {\it INTEGER} & length of each character string in the array {\tt HDATA}. \\
+\hline
+{\tt NLIN} & {\it INTEGER} & dimension of array {\tt HDATA}. This parameter is omitted if {\tt HDATA} \\
+& & is a single character string. \\
+\hline
+{\tt HDATA} & {\it CHARACTER*(*)(*)} & character array of dimension $\ge$ {\tt NLIN} from which the character information is recovered. \\
+\hline
+\end{tabular}
+
+\vskip 0.4cm
+\goodbreak
+
+\noindent Example:
+\begin{verbatim}
+ USE GANLIB
+ ...
+ TYPE(C_PTR) :: IPLIST
+ PARAMETER (ILONG=5)
+ CHARACTER*8 HDATA1(ILONG),HDATA2(ILONG)
+*
+ CALL LCMOP(IPLIST,'mon_dict',0,1,2)
+*
+* STORE THE INFORMATION.
+ HDATA1(1)='string1'
+ HDATA1(2)='string2'
+ HDATA1(3)='string3'
+ HDATA1(4)='string4'
+ HDATA1(5)='string5'
+ CALL LCMPTC(IPLIST,'node1',8,ILONG,HDATA1)
+*
+* RECOVER THE INFORMATION.
+ CALL LCMGTC(IPLIST,'node1',8,ILONG,HDATA2)
+ DO I=1,ILONG
+ PRINT *,'I=',I,' RECOVER HDATA2 -->',HDATA2(I),'<--'
+ ENDDO
+*
+ CALL LCMCL(IPLIST,2)
+\end{verbatim}
+
+\subsubsection{LCMGLC\index{LCMGLC}}\label{sect:LCMGLC}
+
+Subroutine used to recover a character array from a block of data stored in an heterogeneous list.
+
+\begin{verbatim}
+
+CALL LCMGLC(IPLIST,ISET,LENG,[NLIN,]HDATA)
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt IPLIST} & {\it TYPE(C\_PTR)} & address of the associative table. \\
+\hline
+{\tt ISET} & {\it INTEGER} & index of the block in the list.
+The first element of the list is located at index $1$. \\
+\hline
+{\tt LENG} & {\it INTEGER} & length of each character string in the array {\tt HDATA}. \\
+\hline
+{\tt NLIN} & {\it INTEGER} & dimension of array {\tt HDATA}. This parameter is omitted if {\tt HDATA} \\
+& & is a single character string. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3.5cm}|p{9.5cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameter:} \\
+\hline
+{\tt HDATA} & {\it CHARACTER*(*)(*)} & character array of dimension $\ge$ {\tt NLIN} in which the character information is to be copied \\
+\hline
+\end{tabular}
+
+\subsubsection{LCMPLC\index{LCMPLC}}\label{sect:LCMPLC}
+
+Subroutine used to store a character array into a block of data stored in an heterogeneous list.
+If the block of data already exists, it is updated; otherwise, it is created. This operation cannot be performed
+in a LCM object open in {\tt read-only} mode.
+
+\begin{verbatim}
+
+CALL LCMPLC(IPLIST,USET,LENG,[NLIN,]HDATA)
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3.5cm}|p{9.5cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt IPLIST} & {\it TYPE(C\_PTR)} & address of the associative table. \\
+\hline
+{\tt ISET} & {\it INTEGER} & index of the block in the list.
+The first element of the list is located at index $1$. \\
+\hline
+{\tt LENG} & {\it INTEGER} & length of each character string in the array {\tt HDATA}. \\
+\hline
+{\tt NLIN} & {\it INTEGER} & dimension of array {\tt HDATA}. This parameter is omitted if {\tt HDATA} \\
+& & is a single character string. \\
+\hline
+{\tt HDATA} & {\it CHARACTER*(*)(*)} & character array of dimension $\ge$ {\tt NLIN} from which the character information is recovered. \\
+\hline
+\end{tabular}
+
+\vskip 0.4cm
+\goodbreak
+
+\noindent Example:
+\begin{verbatim}
+ USE GANLIB
+ ...
+ TYPE(C_PTR) :: IPLIST
+ PARAMETER (ILONG=5)
+ CHARACTER*8 HDATA1(ILONG),HDATA2(ILONG)
+*
+ CALL LCMOP(IPLIST,'mon_dict',0,1,2)
+*
+* STORE THE INFORMATION.
+ HDATA1(1)='string1'
+ HDATA1(2)='string2'
+ HDATA1(3)='string3'
+ HDATA1(4)='string4'
+ HDATA1(5)='string5'
+ CALL LCMPLC(IPLIST,1,8,ILONG,HDATA1)
+*
+* RECOVER THE INFORMATION.
+ CALL LCMGLC(IPLIST,1,8,ILONG,HDATA2)
+ DO I=1,ILONG
+ PRINT *,'I=',I,' RECOVER HDATA2 -->',HDATA2(I),'<--'
+ ENDDO
+*
+ CALL LCMCL(IPLIST,2)
+\end{verbatim}
+
+\vskip 0.8cm
+
+\subsection{Using variable-length character arrays}
+
+The following subroutines are implemented using the LCM Fortran API of the preceding sections. They
+permit the use of variable-length character arrays. They represent a {\sl new capability} of the GANLIB5 API.
+
+\vskip 0.4cm
+
+\begin{center}
+\begin{tabular}{|c|l|l|l|}
+\cline{3-4}
+\multicolumn{2}{c|}{} & \multicolumn{2}{c|}{type of operation} \\
+\cline{3-4}
+\multicolumn{2}{c|}{} & put~~~~~~~~~~~~~ & get~~~~~~~~~~~~~ \\
+\hline
+father & associative table & {\tt LCMPCD} & {\tt LCMGCD} \\
+\cline{2-4}
+ & heterogeneous list & {\tt LCMPCL} & {\tt LCMGCL} \\
+\hline
+\end{tabular}
+\end{center}
+
+\subsubsection{LCMGCD\index{LCMGCD}}\label{sect:LCMGCD}
+
+Function used to recover a character array from a block of data stored in an associative table.
+
+\begin{verbatim}
+
+CALL LCMGCD(IPLIST,NAMP,ILONG,HDATA)
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt IPLIST} & {\it TYPE(C\_PTR)} & address of the associative table. \\
+\hline
+{\tt NAMP} & {\it CHARACTER*12} & name of the character array
+to recover. A call to {\tt XABORT} is performed if the block does't exist. \\
+\hline
+{\tt ILONG} & {\it INTEGER} & number of components in the character array.\\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3.5cm}|p{9.5cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameter:} \\
+\hline
+{\tt HDATA} & {\it CHARACTER*(*)(*)} & character array of dimension $\ge$ {\tt ILONG} in which the character information is to be copied \\
+\hline
+\end{tabular}
+
+\subsubsection{LCMPCD\index{LCMPCD}}\label{sect:LCMPCD}
+
+Subroutine used to store a character array into a block of data stored in an associative table.
+If the block of data already exists, it is updated; otherwise, it is created. This operation cannot be performed
+in a LCM object open in {\tt read-only} mode.
+
+\begin{verbatim}
+
+CALL LCMPCD(IPLIST,NAMP,ILONG,HDATA)
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3.5cm}|p{9.5cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt IPLIST} & {\it TYPE(C\_PTR)} & address of the associative table. \\
+\hline
+{\tt NAMP} & {\it CHARACTER*12} & name of the character array
+to store. \\
+\hline
+{\tt ILONG} & {\it INTEGER} & number of components in the character array.\\
+\hline
+{\tt HDATA} & {\it CHARACTER*(*)(*)} & character array of dimension $\ge$ {\tt ILONG} from which the character information is recovered. \\
+\hline
+\end{tabular}
+
+\vskip 0.4cm
+
+\noindent Example:
+\begin{verbatim}
+ USE GANLIB
+ ...
+ TYPE(C_PTR) :: IPLIST
+ PARAMETER (ILONG=5)
+ CHARACTER*16 HDATA1(ILONG),HDATA2(ILONG)
+*
+ CALL LCMOP(IPLIST,'mon_dict',0,1,2)
+*
+* STORE THE INFORMATION.
+ HDATA1(1)='string1'
+ HDATA1(2)=' string2'
+ HDATA1(3)=' string3'
+ HDATA1(4)=' string4'
+ HDATA1(5)=' string5'
+ CALL LCMPCD(IPLIST,'node1',ILONG,HDATA1)
+*
+* RECOVER THE INFORMATION.
+ CALL LCMGCD(IPLIST,'node1',ILONG,HDATA2)
+ DO I=1,ILONG
+ PRINT *,'I=',I,' RECOVER HDATA2 -->',HDATA2(I),'<--'
+ ENDDO
+*
+ CALL LCMCL(IPLIST,2)
+\end{verbatim}
+
+\subsubsection{LCMGCL\index{LCMGCL}}\label{sect:LCMGCL}
+
+Subroutine used to recover a character array from a block of data stored in an heterogeneous list.
+
+\begin{verbatim}
+
+CALL LCMGCL(IPLIST,ISET,ILONG,HDATA)
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt IPLIST} & {\it TYPE(C\_PTR)} & address of the heterogeneous list. \\
+\hline
+{\tt ISET} & {\it INTEGER} & index of the character array in the heterogeneous list. A call to {\tt XABORT} is performed if the component doesn't exist.
+The first element of the list is located at index $1$.\\
+\hline
+{\tt ILONG} & {\it INTEGER} & number of components in the character array.\\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3.5cm}|p{9.5cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameter:} \\
+\hline
+{\tt HDATA} & {\it CHARACTER*(*)(*)} & character array of dimension $\ge$ {\tt ILONG} in which the character information is to be copied \\
+\hline
+\end{tabular}
+
+\subsubsection{LCMPCL\index{LCMPCL}}\label{sect:LCMPCL}
+
+Subroutine used to store a character array into a block of data stored in an heterogeneous list.
+If the block of data already exists, it is updated; otherwise, it is created. This operation cannot be performed
+in a LCM object open in {\tt read-only} mode.
+
+\begin{verbatim}
+
+CALL LCMPCL(IPLIST,ISET,ILONG,HDATA)
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3.5cm}|p{9.5cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt IPLIST} & {\it TYPE(C\_PTR)} & address of the heterogeneous list. \\
+\hline
+{\tt ISET} & {\it INTEGER} & index of the character array in the heterogeneous list.
+The first element of the list is located at index $1$. \\
+\hline
+{\tt ILONG} & {\it INTEGER} & number of components in the character array .\\
+\hline
+{\tt HDATA} & {\it CHARACTER*(*)(*)} & character array of dimension $\ge$ {\tt ILONG} from which the character information is recovered. \\
+\hline
+\end{tabular}
+
+\vskip 0.4cm
+
+\noindent Example:
+\begin{verbatim}
+ USE GANLIB
+ ...
+ TYPE(C_PTR) :: IPLIST, JPLIST
+ PARAMETER (ILONG=5)
+ CHARACTER*16 HDATA1(ILONG),HDATA2(ILONG)
+*
+ CALL LCMOP(IPLIST,'mon_dict',0,1,2)
+*
+* CREATE THE LIST.
+ JPLIST=LCMLID(IPLIST,'node2',77)
+*
+* STORE THE INFORMATION.
+ HDATA1(1)='string1'
+ HDATA1(2)=' string2'
+ HDATA1(3)=' string3'
+ HDATA1(4)=' string4'
+ HDATA1(5)=' string5'
+ CALL LCMPCL(JPLIST,1,ILONG,HDATA1)
+*
+* RECOVER THE INFORMATION.
+ CALL LCMGCL(JPLIST,1,ILONG,HDATA2)
+ DO I=1,ILONG
+ PRINT *,'I=',I,' RECOVER HDATA2 -->',HDATA2(I),'<--'
+ ENDDO
+*
+ CALL LCMCL(IPLIST,2)
+\end{verbatim}
+
+\vskip 0.8cm
+
+\subsection{Dynamic allocation of an elementary blocks of data in ANSI C}
+
+A function {\tt LCMARA()} and a subroutine {\tt LCMDRD()} are available as wrappers to memory allocator
+{\tt setara\_c} and memory deallocator {\tt rlsara\_c} introduced in Sects.~\ref{sect:setara} and~\ref{sect:rlsara}.
+{\tt LCLARA()} and {\tt LCMDRD()} offer an alternative to the Fortran-90 {\tt ALLOCATE} and {\tt DEALLOCATE}
+capabilities for exceptional situations involving {\sl pinning} towards LCM internal data. Use of {\tt LCLARA()}
+and {\tt LCMDRD()} is 64-bit clean and Fortran-2003 compliant, but its use must be avoided as much as possible. A
+setara address is a {\tt malloc} pointer, as defined in ANSI-C.
+
+\subsubsection{LCMARA\index{LCMARA}}\label{sect:LCMARA}
+
+{\tt LCMARA()} is a Fortran-2003 wrapper for the ANSI-C function {\tt setara\_c} introduced in Sect.~\ref{sect:setara}. This function
+perform a memory allocation and returns a {\tt TYPE(C\_PTR)} pointer variable.
+
+\begin{verbatim}
+
+IDATA_PTR=LCMARA(ILONG)
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameter:} \\
+\hline
+{\tt ILONG} & {\it INTEGER} & length of the data array (in single-precision words). \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameter:} \\
+\hline
+{\tt IDATA\_PTR} & {\it TYPE(C\_PTR)} & setara address of the data array. \\
+\hline
+\end{tabular}
+
+\subsubsection{LCMDRD\index{LCMDRD}}\label{sect:LCMDRD}
+
+{\tt LCMDRD()} is a Fortran-2003 wrapper for the ANSI-C function {\tt rlsara\_c} introduced in Sect.~\ref{sect:rlsara}. This subroutine
+deallocate the memory corresponding to a {\tt TYPE(C\_PTR)} pointer variable.
+
+\begin{verbatim}
+
+CALL LCMDRD(IDATA_PTR)
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameter:} \\
+\hline
+{\tt IDATA\_PTR} & {\it TYPE(C\_PTR)} & setara address of the data array. \\
+\hline
+\end{tabular}
+
+\vskip 0.4cm
+
+\noindent Example:
+\begin{verbatim}
+ USE GANLIB
+ ...
+ TYPE(C_PTR) :: IDATA_PTR
+ INTEGER, POINTER, DIMENSION(:) :: IDATA
+ ...
+ IDATA_PTR=LCMARA(50)
+ CALL C_F_POINTER(IDATA_PTR,IDATA,(/ 50 /))
+ DO I=1,50
+ IDATA(I)=...
+ ENDDO
+ ...
+ CALL LCMDRD(IDATA_PTR)
+\end{verbatim}
+
+\vskip 0.8cm
+
+\subsection{Abnormal termination of the execution}
+
+\subsubsection{XABORT}
+
+Subroutine used to cause the program termination. A message describing the conditions of the
+termination is printed.
+
+\vskip 0.2cm
+
+It is important to use this subroutine to abort a program instead of using the {\tt STOP}
+statement of Fortran. The {\tt XABORT} subroutine can be used to implement {\sl exception
+treatment} in situations where the application software is driven by a multi-physics system.
+
+\vskip 0.2cm
+
+If an abnormal termination occurs, the {\tt XABORT} subroutine is called as
+\begin{verbatim}
+ CALL XABORT('SUB001: EXECUTION FAILURE.')
+\end{verbatim}
+
+\begin{verbatim}
+
+CALL XABORT(HSMG)
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameter:} \\
+\hline
+{\tt HSMG} & {\it CHARACTER*(*)} & message describing the conditions of the abnormal termination. \\
+\hline
+\multicolumn{3}{|c|}{\bf value of the function:} \\
+\hline
+\multicolumn{2}{|l|}{\it void} & \\
+\hline
+\end{tabular}
+
+\clearpage
+
+\section {The ISO Fortran {\sc hdf5} API}
+
+The ISO Fortran {\sc hdf5} API is a set of Fortran-2003 wrapper subroutines or functions programmed around the ANSI-C functions of the {\sc hdf5} API presented in Sect.~\ref{sect:hdf5apiC}. This implementation is using
+the C interoperability capabilities normalized by ISO and available in the Fortran-2003 compilers. All the subroutines and functions presented in this section are ISO-standard and 64-bit clean.
+
+\vskip 0.08cm
+
+Any subroutines or functions using the Fortran {\sc hdf5} API must include a {\tt USE} statement of the form
+\begin{verbatim}
+use hdf5_wrap
+\end{verbatim}
+
+The address of a HDF5 file is a {\tt TYPE(C\_PTR)} variable declared as
+\begin{verbatim}
+ type(c_ptr) :: ifile
+\end{verbatim}
+
+\vskip 0.8cm
+
+\subsection{Opening and closing of HDF5 files}
+
+\subsubsection{hdf5\_open\_file\index{hdf5OpenFile}}
+
+Open a HDF5 file.
+\begin{verbatim}
+
+call hdf5_open_file(fname, ifile, rdonly)
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt fname} & {\it character*1023} & name of the HDF5 file. \\
+\hline
+{\tt rdonly} & {\it logical} & =.true. to access an existing HDF5 file in {\bf read-only} mode. Optional argument.
+By default, the HDF5 file is accessed in read-write mode. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameters:} \\
+\hline
+{\tt ifile} & {\it type(c\_ptr)} & address of the HDF5 file. \\
+\hline
+\end{tabular}
+
+\subsubsection{hdf5\_close\_file\index{hdf5CloseFile}}
+
+Close a HDF5 file.
+
+\begin{verbatim}
+
+call hdf5_close_file(ifile)
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt ifile} & {\it type(c\_ptr)} & address of the HDF5 file. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\subsection{Interrogation of HDF5 files}
+
+The data structures in a HDF5 file are self-described. It is therefore possible to
+interrogate them in order to know their characteristics.
+
+\subsubsection{hdf5\_list\index{hdf5List}}
+
+List the root table of contents of a group on the standard output. The name of a group can include one or many path separators (character~$\slash$)
+to list different hierarchical levels.
+
+\begin{verbatim}
+
+call hdf5_list(ifile, name)
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt ifile} & {\it type(c\_ptr)} & address of the HDF5 file. \\
+\hline
+{\tt name} & {\it character*1023} & name of a group. \\
+\hline
+\end{tabular}
+
+\subsubsection{hdf5\_info\index{hdf5Info}}
+
+Find dataset information.
+
+\begin{verbatim}
+
+call hdf5_info(ifile, name, rank, type, nbyte, dimsr)
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt ifile} & {\it type(c\_ptr)} & address of the HDF5 file. \\
+\hline
+{\tt name} & {\it character*1023} & name of a dataset. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameters:} \\
+\hline
+{\tt rank} & {\it integer} & rank (number of dimensions) of dataset. \\
+\hline
+{\tt type} & {\it integer} & type of dataset: =1 32-bit integer;
+ =2 32-bit real; =3 character data;
+ =4 64-bit real. \\
+\hline
+{\tt nbyte} & {\it integer} & number of bytes in each component of the dataset. \\
+\hline
+{\tt dimsr} & {\it integer(*)} & integer array containing the dimension of dataset. {\tt rank} values are provided. \\
+\hline
+\end{tabular}
+
+\subsubsection{hdf5\_get\_dimensions\index{hdf5GetDimensions}}
+
+Find the rank (number of dimensions) of a dataset.
+
+\begin{verbatim}
+
+rank=hdf5_get_dimensions(ifile, name)
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt ifile} & {\it type(c\_ptr)} & address of the HDF5 file. \\
+\hline
+{\tt name} & {\it character*1023} & name of a dataset. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameters:} \\
+\hline
+{\tt rank} & {\it integer} & rank of the dataset. \\
+\hline
+\end{tabular}
+
+\subsubsection{hdf5\_get\_shape\index{hdf5GetShape}}
+
+Find the shape (dimension array) of a dataset.
+
+\begin{verbatim}
+
+call hdf5_get_shape(ifile, name, dimsr)
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt ifile} & {\it type(c\_ptr)} & address of the HDF5 file. \\
+\hline
+{\tt name} & {\it character*1023} & name of a dataset. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameters:} \\
+\hline
+{\tt dimsr} & {\it integer(*)} & integer array containing the dimension of dataset. {\tt rank} values are provided. \\
+\hline
+\end{tabular}
+
+\subsubsection{hdf5\_list\_datasets\index{hdf5ListDatasets}}
+
+Allocate a character array of the correct size and recover character daughter dataset names in a group.
+
+\begin{verbatim}
+
+call hdf5_list_datasets(ifile, name, dsets)
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt ifile} & {\it type(c\_ptr)} & address of the HDF5 file. \\
+\hline
+{\tt name} & {\it character*1023} & name of a dataset. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{4.5cm}|p{8.5cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameters:} \\
+\hline
+{\tt idata} & {\it character*1023(:),allocatable} & list of character names of each daughter dataset.\\
+\hline
+\end{tabular}
+
+\vskip 0.5cm
+
+\noindent Example:
+\begin{verbatim}
+ use hdf5_wrap
+ type(c_ptr) :: ifile
+ character(len=100), allocatable :: list(:)
+ ...
+ call hdf5_list_datasets(ifile, '/', list)
+ write(*,*) 'dataset table of contents:'
+ do i = 1, size(list)
+ write(*,*) trim(list(i))
+ enddo
+ deallocate(list)
+\end{verbatim}
+
+\subsubsection{hdf5\_list\_groups\index{hdf5ListGroups}}
+
+Allocate a character array of the correct size and recover character daughter group names in a group.
+
+\begin{verbatim}
+
+call hdf5_list_groups(ifile, name, dsets)
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt ifile} & {\it type(c\_ptr)} & address of the HDF5 file. \\
+\hline
+{\tt name} & {\it character*1023} & name of a dataset. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{4.5cm}|p{8.5cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameters:} \\
+\hline
+{\tt idata} & {\it character*1023(:),allocatable} & list of character names of each daughter group.\\
+\hline
+\end{tabular}
+
+\vskip 0.5cm
+
+\noindent Example:
+\begin{verbatim}
+ use hdf5_wrap
+ type(c_ptr) :: ifile
+ character(len=100), allocatable :: list(:)
+ ...
+ call hdf5_list_groups(ifile, '/', list)
+ write(*,*) 'group table of contents:'
+ do i = 1, size(list)
+ write(*,*) trim(list(i))
+ enddo
+ deallocate(list)
+\end{verbatim}
+
+\subsubsection{hdf5\_group\_exists\index{hdf5GroupExists}}
+
+Test for existence of a group.
+
+\begin{verbatim}
+
+ierr=hdf5_group_exists(ifile, name)
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt ifile} & {\it type(c\_ptr)} & address of the HDF5 file. \\
+\hline
+{\tt name} & {\it character*1023} & name of a group. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameter:} \\
+\hline
+{\tt ierr} & {\it logical} & existence flag: =.true. if the group exists. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\subsection{Management of groups and datatypes}
+
+\subsubsection{hdf5\_create\_group\index{hdf5CreateGroup}}
+
+Create a group.
+
+\begin{verbatim}
+
+call hdf5_create_group(ifile, name)
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt ifile} & {\it type(c\_ptr)} & address of the HDF5 file. \\
+\hline
+{\tt name} & {\it character*1023} & name of the group to create. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\subsubsection{hdf5\_delete\index{hdf5Delete}}
+
+Delete a group or a dataset.
+
+\begin{verbatim}
+
+call hdf5_delete(ifile, name)
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt ifile} & {\it type(c\_ptr)} & address of the HDF5 file. \\
+\hline
+{\tt name} & {\it character*1023} & name of the group or dataset to delete. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\subsubsection{hdf5\_copy\index{hdf5Copy}}
+
+Copy a group or a dataset from one location to another. The source and destination need not be in the same file.
+
+\begin{verbatim}
+
+call hdf5_copy(ifile_s, name_s, ifile_d, name_d)
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt ifile\_s} & {\it type(c\_ptr)} & address of the HDF5 source file. \\
+\hline
+{\tt name\_s} & {\it character*1023} & name of the source group or dataset to copy. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameters:} \\
+\hline
+{\tt ifile\_d} & {\it type(c\_ptr)} & address of the HDF5 destination file. \\
+\hline
+{\tt name\_d} & {\it character*1023} & name of the destination group or dataset to delete. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\subsubsection{hdf5\_read\_data\index{hdf5ReadData}}
+
+Allocate an array of the correct type and size and copy a dataset from HDF5 file into memory.
+
+\begin{verbatim}
+
+call hdf5_read_data(ifile, name, data)
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt ifile} & {\it type(c\_ptr)} & address of the HDF5 file. \\
+\hline
+{\tt name} & {\it character*1023} & name of a dataset. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3.5cm}|p{9.5cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameters:} \\
+\hline
+{\tt data} & {\it class(:),allocatable} & array. Note: if the array is replaced by a single integer, real or characcter variable,
+this variable has not the allocatable status.\\
+\hline
+\end{tabular}
+
+\vskip 0.5cm
+
+\noindent The generic {\it class(:),allocatable} data type is selected among the following options:
+
+\vskip 0.2cm
+\begin{tabular}{|p{10.5cm}|}
+\hline
+{\tt integer :: data} \\
+{\tt integer, allocatable, dimension(:) :: data} \\
+{\tt integer, allocatable, dimension(:,:) :: data} \\
+{\tt real(4) :: data} \\
+{\tt real(4), allocatable, dimension(:) :: data} \\
+{\tt real(4), allocatable, dimension(:,:) :: data} \\
+{\tt real(4), allocatable, dimension(:,:,:) :: data} \\
+{\tt real(4), allocatable, dimension(:,:,:,:) :: data} \\
+{\tt real(8) :: data} \\
+{\tt real(8), allocatable, dimension(:) :: data} \\
+{\tt real(8), allocatable, dimension(:,:) :: data} \\
+{\tt real(8), allocatable, dimension(:,:,:) :: data} \\
+{\tt real(8), allocatable, dimension(:,:,:,:) :: data} \\
+{\tt character(len=*) :: data} \\
+{\tt character(len=*), allocatable, dimension(:) :: data} \\
+\hline
+\end{tabular}
+
+\vskip 0.4cm
+\goodbreak
+
+\noindent Example 1:
+\begin{verbatim}
+ use hdf5_wrap
+ type(c_ptr) :: ifile
+ integer :: ncalc
+ ...
+ call hdf5_read_data(ifile,"NCALS",ncalc)
+ write(*,*) 'ncalc=',ncalc
+\end{verbatim}
+
+\vskip 0.3cm
+
+\noindent Example 2:
+\begin{verbatim}
+ use hdf5_wrap
+ type(c_ptr) :: ifile
+ character(len=8), allocatable, dimension(:) :: isoname
+ ...
+ call hdf5_read_data(ifile,"/explicit/ISONAME",isoname)
+ write(*,*) 'isotope names:'
+ do i = 1, size(isoname)
+ write(*,*) trim(isoname(i))
+ enddo
+ deallocate(isoname)
+\end{verbatim}
+
+\vskip 0.3cm
+
+\noindent Example 3:
+\begin{verbatim}
+ use hdf5_wrap
+ type(c_ptr) :: ifile
+ real(8), allocatable, dimension(:,:) :: yields_matrix
+ ...
+ call hdf5_read_data(ifile,"/physconst/FYIELDS",yields_matrix)
+ no_fiss=size(yields_matrix,1)
+ no_fp=size(yields_matrix,2)
+ write(*,*) 'no_fiss=',no_fiss,' no_fp=',no_fp
+ deallocate(yields_matrix)
+\end{verbatim}
+
+\subsubsection{hdf5\_write\_data\index{hdf5WriteData}}
+
+Copy an array from memory into a HDF5 dataset. If dataset {\tt name} exists, it is replaced.
+
+\begin{verbatim}
+
+call hdf5_write_data(ifile, name, idata)
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt ifile} & {\it type(c\_ptr)} & address of the HDF5 file. \\
+\hline
+{\tt name} & {\it character*1023} & name of a dataset. \\
+\hline
+{\tt data} & {\it class(*)} & array.\\
+\hline
+\end{tabular}
+
+\vskip 0.5cm
+\goodbreak
+
+\noindent The generic {\it class(*)} data type is selected among the following options:
+
+\vskip 0.2cm
+\begin{tabular}{|p{8.5cm}|}
+\hline
+{\tt integer,intent(in) :: data} \\
+{\tt integer,dimension(:) :: data} \\
+{\tt integer,dimension(:,:) :: data} \\
+{\tt real(4) :: data} \\
+{\tt real(4),dimension(:) :: data} \\
+{\tt real(4),dimension(:,:) :: data} \\
+{\tt real(4),dimension(:,:,:) :: data} \\
+{\tt real(4),dimension(:,:,:,:) :: data} \\
+{\tt real(8) :: data} \\
+{\tt real(8),dimension(:) :: data} \\
+{\tt real(8),dimension(:,:) :: data} \\
+{\tt real(8),dimension(:,:,:) :: data} \\
+{\tt real(8),dimension(:,:,:,:) :: data} \\
+{\tt character(len=*) :: data} \\
+{\tt character(len=*), dimension(:) :: data} \\
+\hline
+\end{tabular}
+
+\vskip 0.4cm
+
+\noindent Example:
+\begin{verbatim}
+ use hdf5_wrap
+ type(c_ptr) :: ifile
+ integer, allocatable, dimension(:) :: nitmaV1
+ ...
+ allocate(nitmaV1(10))
+ nitmaV1(:10)=100
+ call hdf5_write_data(ifile, 'my_dummy_record', nitmaV1)
+ deallocate(nitmaV1)
+\end{verbatim}
+
+\clearpage
+
+\section {The ISO Fortran CLE-2000 API}
+
+\subsection {Management of Fortran files outside CLE-2000}
+
+The {\tt KDROPN} utility is a general system for managing Fortran files in a software application.
+
+\subsubsection{KDROPN\index{KDROPN}}
+
+Function used to open a file and allocate its unit number. Allocate a unit number to file
+name. If unit is already opened, returns its address. Sequential (formatted
+or not) and direct access (DA) files are permitted.
+
+\begin{verbatim}
+
+IFILE=KDROPN(CUNAME,IACTIO,IUTYPE,LRDA)
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt CUNAME} & {\it CHARACTER*(*)} & file name. If {\tt cuname}$=${\tt ' '}, use a default name. \\
+\hline
+{\tt IACTIO} & {\it INTEGER} & action on file.
+$=0$: to allocate a new file;
+$=1$: to access and modify an existing file;
+$=2$: to access an existing file in {\tt read-only} mode. \\
+\hline
+{\tt IUTYPE} & {\it INTEGER} & file type.
+$=1$: (not used);
+$=2$: sequential unformatted;
+$=3$: sequential formatted;
+$=4$: direct access (DA) unformatted file. \\
+\hline
+{\tt LRDA} & {\it INTEGER} & number of words in a DA record (used if {\tt IUTYPE} $= 4$). \\
+\hline
+\end{tabular}
+
+\vskip 0.4cm
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameter:} \\
+\hline
+{\tt IFILE} & {\it INTEGER} & unit number of the allocated file. Equal to the error code if the allocation failed. \\
+\hline
+\end{tabular}
+
+\subsubsection{KDRCLS\index{KDRCLS}}
+
+Function used to close a file and release its unit number.
+
+\begin{verbatim}
+
+IER=KDRCLS(IFILE,IACTIO)
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt IFILE} & {\it INTEGER} & unit number of the allocated file (as returned by {\tt KDROPN}). \\
+\hline
+{\tt IACTIO} & {\it INTEGER} & action on file.
+$=1$: to keep the file;
+$=2$: to delete the file. \\
+\hline
+\end{tabular}
+
+\vskip 0.4cm
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameter:} \\
+\hline
+{\tt IER} & {\it INTEGER} & error code. Equal to zero if the close is successful. \\
+\hline
+\end{tabular}
+
+\clearpage
+
+\subsection {Management of word-addressable (KDI) files outside CLE-2000}
+
+The {\tt KDIOP} utility is a general system for managing word-addressable (KDI) files in a software application.
+
+\subsubsection{KDIOP\index{KDIOP}}
+
+Function used to open a KDI file and allocate its header.
+
+\begin{verbatim}
+
+MY_FILE=KDIOP(CUNAME,IACTIO)
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt CUNAME} & {\it CHARACTER*(*)} & file name. \\
+\hline
+{\tt IACTIO} & {\it INTEGER} & action on file.
+$=0$: to allocate a new file;
+$=1$: to access and modify an existing file;
+$=2$: to access an existing file in {\tt read-only} mode. \\
+\hline
+\end{tabular}
+
+\vskip 0.4cm
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameter:} \\
+\hline
+{\tt MY\_FILE} & {\it TYPE(C\_PTR)} & address of the allocated file. Equal to {\tt C\_NULL\_PTR} if the allocation failed. \\
+\hline
+\end{tabular}
+
+\subsubsection{KDIGET\index{KDIGET}}
+
+Subroutine used to read a data array from a KDI file at offset {\tt IOFSET}.
+
+\begin{verbatim}
+
+CALL KDIGET(MY_FILE, IDATA, IOFSET, LENGTH)
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt MY\_FILE} & {\it TYPE(C\_PTR)} & address of the allocated file (as returned by {\tt KDIOP}). \\
+\hline
+{\tt IOFSET} & {\it INTEGER} & offset of the information in the KDI file. \\
+\hline
+{\tt LENGTH} & {\it INTEGER} & length of the array of information, in unit of 32-bit words. \\
+\hline
+\end{tabular}
+
+\vskip 0.4cm
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameter:} \\
+\hline
+{\tt IDATA} & {\it INTEGER} & array of information. \\
+\hline
+\end{tabular}
+
+\subsubsection{KDIPUT\index{KDIPUT}}
+
+Subroutine used to store a data array in a KDI file at offset {\tt IOFSET}.
+
+\begin{verbatim}
+
+CALL KDIPUT(MY_FILE, IDATA, IOFSET, LENGTH)
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt MY\_FILE} & {\it TYPE(C\_PTR)} & address of the allocated file (as returned by {\tt KDIOP}). \\
+\hline
+{\tt IDATA} & {\it INTEGER} & array of information. \\
+\hline
+{\tt IOFSET} & {\it INTEGER} & offset of the information in the KDI file. \\
+\hline
+{\tt LENGTH} & {\it INTEGER} & length of the array of information, in unit of 32-bit words. \\
+\hline
+\end{tabular}
+
+\subsubsection{KDICL\index{KDICL}}
+
+Function used to close a KDI file.
+
+\begin{verbatim}
+
+IER=KDICL(MY_FILE,IACTIO)
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt MY\_FILE} & {\it TYPE(C\_PTR)} & address of the allocated file (as returned by {\tt KDIOP}). \\
+\hline
+{\tt IACTIO} & {\it INTEGER} & action on file.
+$=1$: to keep the file;
+$=2$: to delete the file. \\
+\hline
+\end{tabular}
+
+\vskip 0.4cm
+\goodbreak
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameter:} \\
+\hline
+{\tt IER} & {\it INTEGER} & error code. Equal to zero if the close is successful. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\subsection {Management of Fortran and KDI files used as CLE-2000 parameters}
+
+CLE-2000 allows a module of the application software to exchange information using LCM objects and files. If the
+application software is programmed in Fortran, the CLE-2000 driver expects all these parameters to be {\tt TYPE(C\_PTR)}
+variables. The ISO Fortran CLE-2000 API defines a collection of four functions to wrap the {\tt KDROPN} utility
+in such a way that Fortran files are referred by {\tt TYPE(C\_PTR)} variables.
+
+\subsubsection{FILOPN\index{FILOPN}}
+
+Function used to open a file and allocate its unit number. Allocate a unit number to file
+name. If unit is already opened, returns its address. Word addressable (KDI), sequential (formatted
+or not) and direct access (DA) files are permitted.
+This function is a GANLIB wrapper for the {\tt KDROPN} and {\tt KDIOP} utilities.
+
+\begin{verbatim}
+
+IFILE=FILOPN(CUNAME,IACTIO,IUTYPE,LRDA)
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt CUNAME} & {\it CHARACTER*(*)} & file name. If {\tt cuname}$=${\tt ' '}, use a default name. \\
+\hline
+{\tt IACTIO} & {\it INTEGER} & action on file.
+$=0$: to allocate a new file;
+$=1$: to access and modify an existing file;
+$=2$: to access an existing file in {\tt read-only} mode. \\
+\hline
+{\tt IUTYPE} & {\it INTEGER} & file type.
+$=1$: KDI word addressable file;
+$=2$: sequential unformatted;
+$=3$: sequential formatted;
+$=4$: direct access (DA) unformatted file. \\
+\hline
+{\tt LRDA} & {\it INTEGER} & number of words in a DA record (used if {\tt IUTYPE} $= 4$). \\
+\hline
+\end{tabular}
+
+\vskip 0.4cm
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameter:} \\
+\hline
+{\tt IFILE} & {\it TYPE(FIL\_file)} & handle to the allocated file. Equal to {\tt C\_NULL\_PTR} if the allocation failed. \\
+\hline
+\end{tabular}
+
+\subsubsection{FILCLS\index{FILCLS}}
+
+Function used to close a file and release its unit number.
+This function is a GANLIB wrapper for the {\tt KDRCLS} and {\tt KDICL} utilities.
+
+\begin{verbatim}
+
+IER=FILCLS(MY_FILE,IACTIO)
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt MY\_FILE} & {\it TYPE(FIL\_file)} & handle to the allocated file (as returned by {\tt FILOPN}). \\
+\hline
+{\tt IACTIO} & {\it INTEGER} & action on file.
+$=1$: to keep the file;
+$=2$: to delete the file. \\
+\hline
+\end{tabular}
+
+\vskip 0.4cm
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameter:} \\
+\hline
+{\tt IER} & {\it INTEGER} & error code. Equal to zero if the close is successful. \\
+\hline
+\end{tabular}
+
+\subsubsection{FILUNIT\index{FILUNIT}}
+
+Function used to recover the Fortran file unit number
+
+\begin{verbatim}
+
+IUNIT=FILUNIT(FILE_PT)
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameter:} \\
+\hline
+{\tt FILE\_PT} & {\it TYPE(C\_PTR)} & address of the allocated file ({\tt c\_loc(MY\_FILE)}, as returned by {\tt FILOPN}). \\
+\hline
+\end{tabular}
+
+\vskip 0.4cm
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameter:} \\
+\hline
+{\tt IUNIT} & {\it INTEGER} & file unit number. Equal to $-1$ in case of error. \\
+\hline
+\end{tabular}
+
+\subsubsection{FILKDI\index{FILKDI}}
+
+Function used to recover the address of the KDI file.
+
+\begin{verbatim}
+
+KDI_PT=FILKDI(FILE_PT)
+\end{verbatim}
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameter:} \\
+\hline
+{\tt FILE\_PT} & {\it TYPE(C\_PTR)} & address of the allocated file ({\tt c\_loc(MY\_FILE)}, as returned by {\tt FILOPN}). \\
+\hline
+\end{tabular}
+
+\vskip 0.4cm
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameter:} \\
+\hline
+{\tt KDI\_PT} & {\it TYPE(C\_PTR)} & address of the KDI file. Equal to {\tt C\_NULL\_PTR} if case of error. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\subsection {The main entry point for CLE-2000}
+
+Function {\tt KERNEL} is a Fortran wrapper around function {\tt cle2000\_c()} to serve as the main entry point for CLE-2000.
+Function {\tt KERNEL} is specialized to the case where the application software is executed in stand-alone mode. It is
+therefore limited to the simple case where a CLE-2000 procedure has no parameters and no in-out CLE-2000 variables.
+Moreover, the main CLE-2000 procedure is recovered from the standard unit (i.e., from unit 5) and is assumed to have a {\tt .x2m}
+suffix. This limitation is making sense as no multi-physics system is currently programmed in Fortran.
+
+\subsubsection{KERNEL\index{KERNEL}}
+
+The general specification of function {\tt KERNEL} is
+
+\begin{verbatim}
+
+IER=KERNEL(DUMMOD,IPRINT)
+\end{verbatim}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt DUMMOD} & {\it EXTERNAL} & external C-interoperable Fortran-2003 function responsible for dispatching the execution among calculation modules. \\
+\hline
+{\tt IPRINT} & {\it INTEGER} & print parameter (set to zero for no print). \\
+\hline
+\end{tabular}
+
+\vskip 0.4cm
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameter:} \\
+\hline
+{\tt IER} & {\it INTEGER} & error code. Equal to zero if the execution of {\tt KERNEL} is successful. \\
+\hline
+\end{tabular}
+
+\subsubsection{DUMMOD\index{DUMMOD}}
+
+Function {\tt KERNEL} has one of its arguments that is a developer-defined external function. Function {\tt DUMMOD} is a C-interoperable Fortran-2003 function responsible for dispatching the execution among calculation modules. An instance of function {\tt DUMMOD} is implemented for
+each Fortran application software using the GANLIB.
+
+\vskip 0.08cm
+
+A stand-alone GANLIB application can be set by using the following implementation of {\tt GANMOD}
+\begin{verbatim}
+!
+!-----------------------------------------------------------------------
+!
+!Purpose:
+! Dispatch to a calculation module in GANLIB. ANSI-C interoperable.
+!
+!Copyright:
+! Copyright (C) 2009 Ecole Polytechnique de Montreal
+! This library is free software; you can redistribute it and/or
+! modify it under the terms of the GNU Lesser General Public
+! License as published by the Free Software Foundation; either
+! version 2.1 of the License, or (at your option) any later version.
+!
+!Author(s): A. Hebert
+!
+!-----------------------------------------------------------------------
+!
+integer(c_int) function GANMOD(cmodul, nentry, hentry, ientry, jentry, &
+ kentry, hparam_c) bind(c)
+!
+ use GANLIB
+ implicit none
+!----
+! subroutine arguments
+!----
+ character(kind=c_char), dimension(*) :: cmodul
+ integer(c_int), value :: nentry
+ character(kind=c_char), dimension(13,*) :: hentry
+ integer(c_int), dimension(nentry) :: ientry, jentry
+ type(c_ptr), dimension(nentry) :: kentry
+ character(kind=c_char), dimension(73,*) :: hparam_c
+!----
+! local variables
+!----
+ integer :: i, ier
+ character :: hmodul*12, hsmg*131, hparam*72
+ character(len=12), allocatable :: hentry_f(:)
+ type(c_ptr) :: my_file
+ integer, external :: GANDRV
+!
+ allocate(hentry_f(nentry))
+ call STRFIL(hmodul, cmodul)
+ do i=1,nentry
+ call STRFIL(hentry_f(i), hentry(1,i))
+ if(ientry(i) >= 3) then
+! open a Fortran file.
+ call STRFIL(hparam, hparam_c(1,i))
+ my_file=FILOPN(hparam,jentry(i),ientry(i)-1,0)
+ if(.not.c_associated(my_file)) then
+ write(hsmg,'(29hGANMOD: unable to open file '',a12,2h''.)') hentry_f(i)
+ call XABORT(hsmg)
+ endif
+ kentry(i)=my_file
+ endif
+ enddo
+! ----------------------------------------------------------
+ GANMOD=GANDRV(hmodul,nentry,hentry_f,ientry,jentry,kentry)
+! ----------------------------------------------------------
+ do i=1,nentry
+ if(ientry(i) >= 3) then
+! close a Fortran file.
+ ier=FILCLS(kentry(i),1)
+ if(ier < 0) then
+ write(hsmg,'(30hGANMOD: unable to close file '',a12,2h''.)') hentry_f(i)
+ call XABORT(hsmg)
+ endif
+ endif
+ enddo
+ deallocate(hentry_f)
+ flush(6)
+ return
+end function GANMOD
+\end{verbatim}
+
+\noindent with function {\tt GANDRV} implemented as
+\begin{verbatim}
+integer function GANDRV(hmodul,nentry,hentry,ientry,jentry,kentry)
+!
+!-----------------------------------------------------------------------
+!
+!Purpose:
+! standard utility operator driver for Ganlib.
+!
+!Copyright:
+! Copyright (C) 2002 Ecole Polytechnique de Montreal
+! This library is free software; you can redistribute it and/or
+! modify it under the terms of the GNU Lesser General Public
+! License as published by the Free Software Foundation; either
+! version 2.1 of the License, or (at your option) any later version
+!
+!Author(s): A. Hebert
+!
+!Parameters: input/output
+! hmodul name of the operator.
+! nentry number of LCM objects or files used by the operator.
+! hentry name of each LCM object or file.
+! ientry type of each LCM object or file:
+! =1 LCM memory object; =2 XSM file; =3 sequential binary file;
+! =4 sequential ascii file.
+! jentry access of each LCM object or file:
+! =0 the LCM object or file is created;
+! =1 the LCM object or file is open for modifications;
+! =2 the LCM object or file is open in read-only mode.
+! kentry LCM object address or file unit number.
+!
+!Parameters: output
+! kdrstd completion flag (=0: operator hmodul exists; =1: does not exists).
+!
+!-----------------------------------------------------------------------
+!
+!----
+! subroutine arguments
+!----
+ use GANLIB
+ integer nentry
+ character hmodul*(*),hentry(nentry)*12
+ integer ientry(nentry),jentry(nentry)
+ type(c_ptr) kentry(nentry)
+!
+ GANDRV=0
+ if(hmodul == 'EQU:' )then
+! standard equality module.
+ call DRVEQU(nentry,hentry,ientry,jentry,kentry)
+ else if(hmodul == 'GREP:') then
+! standard grep module.
+ call DRVGRP(nentry,hentry,ientry,jentry,kentry)
+ else if(hmodul == 'UTL:') then
+! standard LCM/XSM utility module.
+ call DRVUTL(nentry,hentry,ientry,jentry,kentry)
+ else if(hmodul == 'ADD:') then
+! standard addition module.
+ call DRVADD(nentry,hentry,ientry,jentry,kentry)
+ else if(hmodul == 'MPX:') then
+! standard multiplication module.
+ call DRVMPX(nentry,hentry,ientry,jentry,kentry)
+ else if(hmodul == 'STAT:') then
+! standard compare module.
+ call DRVSTA(nentry,hentry,ientry,jentry,kentry)
+ else if(hmodul == 'BACKUP:') then
+! standard backup module.
+ call DRVBAC(nentry,hentry,ientry,jentry,kentry)
+ else if(hmodul == 'RECOVER:') then
+! standard recovery module.
+ call DRVREC(nentry,hentry,ientry,jentry,kentry)
+ else if(hmodul == 'FIND0:') then
+! standard module to find zero of a continuous function.
+ call DRV000(nentry,hentry,ientry,jentry,kentry)
+ else if(hmodul == 'MSTR:') then
+! manage user-defined structures.
+ call MSTR(nentry,hentry,ientry,jentry,kentry)
+ else if(hmodul == 'MODUL1:') then
+! user-defined module.
+ call DRVMO1(nentry,hentry,ientry,jentry,kentry)
+ else if(hmodul == 'ABORT:') then
+! requested abort.
+ call XABORT('GANDRV: requested abort.')
+ else
+ GANDRV=1
+ endif
+ return
+end function GANDRV
+\end{verbatim}
+
+\vskip 0.8cm
+
+\subsection {The free-format input reader}
+
+Subroutines {\tt REDOPN}, {\tt REDGET}, {\tt REDPUT} and {\tt REDCLS} are Fortran wrappers around ANSI~C functions {\tt redopn\_c()}, {\tt redget\_c()}, {\tt redput\_c()} and {\tt redcls\_c()}.
+Only {\tt REDGET} and {\tt REDPUT} are expected to be used in an application software.
+
+\subsubsection{REDOPN\index{REDOPN}}
+
+Subroutine {\tt REDOPN} is called to open the input reader. The general specification of function {\tt REDOPN} is
+
+\begin{verbatim}
+
+CALL REDOPN(IINP1,IOUT1,NREC)
+\end{verbatim}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2.5cm}|p{10.5cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt IINP1} & {\it TYPE(C\_PTR)} & KDI object containing the CLE-2000 input data.\\
+\hline
+{\tt IOUT1} & {\it INTEGER} & unit number of the sequential {\sc ascii} file used to write execution messages. Can be set to 6 for standard output. \\
+\hline
+{\tt NREC} & {\it INTEGER} & record index where reading occurs. Can be set to zero at first call. Set to the value returned by {\tt REDCLS} at subsequent calls.\\
+\hline
+\end{tabular}
+
+\subsubsection{REDGET\index{REDGET}}
+
+Subroutine {\tt REDGET} is called within modules of the application software to recover the module-specific input data.
+The general specification of function {\tt REDGET} is
+
+\begin{verbatim}
+
+CALL REDGET(ITYP,NITMA,FLOTT,TEXT,DFLOT)
+\end{verbatim}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameters:} \\
+\hline
+{\tt ITYP} & {\it INTEGER} & type of the CLE-2000 variable. A negative value indicates that the variable is to be computed by the application software and returned towards CLE-2000 using a call to {\tt redput\_c}. $=\pm 1$: integer type;
+$=\pm 2$: real (single precision) type;
+$=\pm 3$: string type;
+$=\pm 4$: double precision type;
+$=\pm 5$: logical type.\\
+\hline
+{\tt NITMA} & {\it INTEGER} & integer input value when {\tt ITYP} $= 1$ or $= 5$; number of characters when {\tt ITYP} $= 3$. \\
+\hline
+{\tt FLOTT} & {\it REAL} & real input value when {\tt ITYP} $= 2$. \\
+\hline
+{\tt TEXT} & {\it CHARACTER*(*)} & character string input value when {\tt ITYP} $= 3$. \\
+\hline
+{\tt DFLOT} & {\it DOUBLE PRECISION} & double precision input value when {\tt ITYP} $= 4$. \\
+\hline
+\end{tabular}
+
+\subsubsection{REDPUT\index{REDPUT}}
+
+Subroutine {\tt REDPUT} is called within modules of the application software to make information computed by the module available as CLE-2000 variables to the CLE-2000 procedure.
+The application software must first call {\tt REDGET} and obtain a negative value of {\tt ITYP}. A call to {\tt REDPUT} is next performed with its first parameter set to
+$-${\tt ITYP} (now, a positive value) and with the corresponding value of the parameter.
+The general specification of function {\tt REDPUT} is
+
+\begin{verbatim}
+
+CALL REDPUT(ITYP,NITMA,FLOTT,TEXT,DFLOT)
+\end{verbatim}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{3cm}|p{10cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf input parameters:} \\
+\hline
+{\tt ITYP} & {\it INTEGER} & type of the CLE-2000 variable. $=1$: integer type;
+$=2$: real (single precision) type;
+$=3$: string type;
+$=4$: double precision type;
+$=5$: logical type.\\
+\hline
+{\tt NITMA} & {\it INTEGER} & integer output value when {\tt ITYP} $= 1$ or $= 5$; number of characters when {\tt ITYP} $= 3$. \\
+\hline
+{\tt FLOTT} & {\it REAL} & real output value when {\tt ITYP} $= 2$. \\
+\hline
+{\tt TEXT} & {\it CHARACTER*(*)} & character string output value when {\tt ITYP} $= 3$. \\
+\hline
+{\tt DFLOT} & {\it DOUBLE PRECISION} & double precision output value when {\tt ITYP} $= 4$. \\
+\hline
+\end{tabular}
+
+\subsubsection{REDCLS\index{REDCLS}}
+
+Subroutine {\tt REDCLS} is called to close the input reader.
+The general specification of function {\tt REDCLS} is
+
+\begin{verbatim}
+
+CALL REDCLS(IINP1,IOUT1,NREC)
+\end{verbatim}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular}{|p{1.5cm}|p{2.5cm}|p{10.5cm}|}
+\hline
+\multicolumn{3}{|c|}{\bf output parameters:} \\
+\hline
+{\tt IINP1} & {\it TYPE(C\_PTR)} & KDI object containing the CLE-2000 input data.\\
+\hline
+{\tt IOUT1} & {\it INTEGER} & unit number of the sequential {\sc ascii} file used to write execution messages. \\
+\hline
+{\tt NREC} & {\it INTEGER} & record index where reading occurs. \\
+\hline
+\end{tabular}
+
+\section{The Python3 {\sc lcm} API}
+
+The Python3 {\sc lcm} API, or Py{\sc lcm} API, is a component of the PyGan library, available in the Version5 distribution.
+PyGan is a Python3 library made of three classes, as depicted in Fig.~\ref{fig:PyGan}, so as to encapsulate Ganlib5 capabilities.
+The extension module {\tt lcm} contains a class providing {\sl in-out} support of {\sl hererogeneous lists} and
+{\sl associative tables}, as implemented in the {\sc lcm} API of Sect.~\ref{sect:lcmapiC}, to Python3 users.
+
+\begin{figure}[htbp]
+\begin{center}
+\epsfxsize=2.4cm
+\centerline{ \epsffile{cle2000_hierarchy_uml.eps}}
+\parbox{12cm}{\caption{The PyGan class model.}\label{fig:PyGan}}
+\end{center}
+\end{figure}
+
+\vskip 0.2cm
+
+{\sl Associative tables} in Ganlib5 are similar to Python dictionaries and can be handled
+as such in the Python3 dataset. Each element of an associative table
+ is associated with a string.
+{\sl Hererogeneous lists} in Ganlib5 are similar to Python lists and therefore are an ordered set
+of elements. Each list element is identified by an index and contains
+an information block. As for the information blocks, they are either
+strings, or NumPy arrays.\opcite {npython}
+A PyLCM object can physically be, either in memory or located on a {\sc xsm} file.
+
+\vskip 0.2cm
+
+{\sl LCM Python bindings} allow Python to use the API
+{\sc lcm} transparently. Associative tables and heterogeneous lists are
+represented as Python dictionaries and Python lists, respectively. The
+information blocks in integer and floating point {\sc lcm} or {\sc xsm} arrays
+are automatically transformed into {\sl numpy} arrays.
+Methods of the {\sc lcm} API have been adapted to manage the use of files.
+
+\vskip 0.2cm
+
+The compilation and link edition of the API require the definition of a UNIX environment variable {\tt FORTRANPATH} pointing towards the {\tt libgfortran.a} library
+compatible with your operating system. On a OSX operating system, this variable may be set as
+\begin{verbatim}
+export FORTRANPATH=/usr/local/lib/gcc/11/ # contains libgfortran.a
+\end{verbatim}
+\noindent On a Linux {\tt x86\_64} operating system, the environment variable is set as
+\begin{verbatim}
+export FORTRANPATH=/usr/lib/gcc/x86\_64-redhat-linux/4.8.5/ # contains libgfortran.so
+\end{verbatim}
+\noindent On a Linux {\tt aarm} operating system, the environment variable is set as
+\begin{verbatim}
+export FORTRANPATH="/usr/lib/gcc/aarch64-linux-gnu/9/" # contains libgfortran.so
+\end{verbatim}
+
+\vskip 0.8cm
+
+\subsection{Structures}
+
+\begin{description}
+\item[Associative tables] An associative table is equivalent to a Python dictionary.
+Each element of a table is an association between a string of 12
+characters and an information block (scalar value or vector
+of a given type). Associative tables can contain lists or other tables
+associative and thus form a tree structure.
+
+\item[Heterogeneous lists] A list is an ordered set of elements of heterogeneous types. Each element is
+accessed by an integer index and contains an information block.
+Lists can contain scalar values or elementary information blocks,
+as written in the next section. Lists can also contain
+child lists or other associative tables.
+
+\item[Elementary information blocks] An elementary information block constitutes a set of values whose Dragon5/Donjon5 module
+needs to perform the calculation. Unlike tables or lists
+which only allow you to order information, the elementary information block is the useful data
+to be used in a calculation. A block of information is either strings of characters,
+either numerical arrays (array) with one dimension (similar to {\sl numpy} arrays).
+The elementary blocks of information belong to one of the following types:
+
+\begin{tabular} {| p {3.0cm} | p {11.5cm} |}
+\hline
+Int array & An item of the associative table can correspond to an array of
+32-bit integers (type~{\tt l} from NumPy).\\
+Float32 array & An item of the associative table can correspond to an array of
+32-bit reals (type~{\tt f} from NumPy).\\
+Character array & An item of the associative table can correspond to an array of
+of characters (array of type {\tt Char} from Python).\\
+Float64 array & An item of the associative table can correspond to an array of
+64-bit reals (type~{\tt d} from NumPy) \\
+Logical32 array & An item of the associative table can correspond to an array of
+32-bit integers (type~{\tt i} from NumPy containing 1/0 to denote true/false).\\
+Complex32 array & An associative table item can correspond to an array of of 64-bit complex variables (type~{\tt F} from NumPy).\\
+\hline
+\end{tabular}
+
+\end{description}
+
+\vskip 0.8cm
+
+\subsection{LCM object Python API} \label {sect: APIP}
+
+The {\tt lcm} module, accessible from Python3, is imported by the command
+\begin{verbatim}
+import lcm
+\end{verbatim}
+It has one constructor: {\tt lcm.new()}, used to create an {\sl object instance} {\tt o}.
+
+\subsubsection{Attribute Variables \index {attribute variables}}
+
+A PyLCM object {\tt o} contains six attribute variables. The first five are read-only; {\tt o.\_impx} has read-write access.
+
+\begin {description}
+\item [{\tt o.\_name}] Python (len=72) name of the PyLCM object containing the root
+\item [{\tt o.\_directory}] Name (len=12) of the current directory. $=$ {\tt '/'} for the
+root directory. This attribute variable is undefined for
+lists and for files created by {\tt lcm.file()}.
+\item [{\tt o.\_long}] $ = - 1 $: associative table; $ \ge 1 $: heterogeneous list of length {\tt o.\_long}.
+\item [{\tt o.\_type}] Type of the object. $ = 1 $: LCM object in memory
+(similar to a Python dictionary); $ = 2 $: persistent LCM object (of type {\sc xsm} file);
+$ = 3 $: binary sequential file; $ = 4 $: sequential {\sc ascii} file; $=$ 5:
+direct access file; $=$ 6: HDF5 file.
+\item [{\tt o.\_access}] Access mode of the object. $ = 0 $: closed object (i.e., not
+accessible); $ = 1 $: object in modification mode; $ = 2 $: object in read mode
+(read-only).
+\item [{\tt o.\_impx}] Edition index for the object ($=0$ for minimum printouts).
+\end {description}
+
+\subsubsection{lcm.new()}
+
+This method is used to create a PyLCM object made up of an associative table or of a file. A {\sc lcm} object is a {\sl memory-resident} structure
+implemented with the {\sc lcm} API of Sect.~\ref{sect:lcmapiC}. A {\sc xsm} object store similar information in a direct access file and is implemented with the same API. This object occupies very little memory space and can be
+used to store very large objects whose maximum dimension is not
+limited only by the available disk space. In general, we can always replace
+a ``memory'' PyLCM object by a persistent PyLCM object (at the cost of a certain
+increase in CPU time). A persistent PyLCM object can
+also be used as archiving medium for a ``memory'' PyLCM object.
+
+\vskip 0.2cm
+
+This {\tt new} constructor is used to perform the following actions:
+\begin{itemize}
+\item for creating a new empty PyLCM object;
+\item for retrieving a file made by a Dragon5/Donjon5 module or to transfer a file to a Dragon5/Donjon5 module. At the end of this call, the variable
+attribute {\tt o.\_access} is equal to $1$ or $2$. The PyLCM object thus created does not have
+the {\tt \_directory} and {\tt \_long} attributes. It does not own the {\tt keys()},
+{\tt lib()}, {\tt rep()}, {\tt lis()} and {\tt copy()} methods;
+\item to create a PyLCM object containing a memory or persistent LCM object from the serialized information contained in a sequential file (import action);
+\item to serialize the content of an existing PyLCM object containing a memory or persistent LCM object into a sequential file (export action);
+\item to perform a deep copy of an existing PyLCM object containing a memory or persistent LCM object into another.
+\end{itemize}
+
+\begin{verbatim}
+o = lcm.new(type, [name], [iact], [pyobj], [lrda], [impx])
+\end{verbatim}
+
+\noindent
+\begin{tabular} {| p {1.5cm} | p {1.5cm} | p {11.5cm} |}
+\hline
+\multicolumn {3} {| c |} {\bf input parameter:} \\
+\hline
+{\tt type} & {\it string} & type of the PyLCM object that will be created. $=$ {\tt LCM}
+object {\sc lcm} in memory; $=$ {\tt XSM} persistent object of type {\sc xsm}; $=$ {\tt BINARY}
+sequential binary file; $=$ {\tt ASCII}; sequential {\sc ascii} file ;
+$=$ {\tt DA}; direct access file; $=$ {\tt HDF5}; HDF5 file; $=$ {\tt LCM\_IMP}
+object {\sc lcm} in memory built from the file "{\tt \_}"$ + $ {\tt name} containing
+a serialized PyLCM object or from a deep copy of object {\tt pyobj}; $=$ {\tt XSM\_INP} persistent object of type {\sc xsm} built
+from the file "{\tt \_}"$ + $ {\tt name} containing a serialized PyLCM object or from a deep copy of object {\tt pyobj}. The serialized
+PyLCM object is assumed to be a sequential binary file if its extension is {\tt .bin}; otherwise, it is assumed to be a sequential {\sc ascii} file.\\
+{\tt name} & {\it string} & name (len=72) of the PyLCM object that will be created. By default, a name is generated automatically
+from the address of the PyLCM object or from the name of object {\tt pyobj}. \\
+{\tt iact} & {\it int} &access mode. $=0$: a new object is created (default); $=1$: existing object content open in read/write mode
+ $=$2: existing object content open in read-only mode. \\
+{\tt pyobj} & {\it LCM} & existing PyLCM object containing a memory or persistent LCM object. \\
+{\tt lrda} & {\it int} & number of words in a direct-access record
+(only used if {\tt type} $ = $ {\tt DA}). By default, {\tt lrda} $= 128$. \\
+{\tt impx} & {\it int} & edition index for the object ($=0$ for minimum printouts). \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular} {| p {1.5cm} | p {1.5cm} | p {11.5cm} |}
+\hline
+\multicolumn {3} {| c |} {\bf output parameter:} \\
+\hline
+{\tt o} & {\it LCM} & PyLCM object created. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\subsubsection{o.keys()}
+
+This method allows you to create a Python list containing the key names of the associative table
+(memory or {\sc xsm} file). This method is not available for FILE objects.
+
+\begin{verbatim}
+o2 = o.keys()
+\end{verbatim}
+
+\noindent
+\begin{tabular} {| p {1.5cm} | p {1.5cm} | p {11.5cm} |}
+\hline
+\multicolumn {3} {| c |} {\bf output parameter:} \\
+\hline
+{\tt o2} & {\it list} & Python list containing the keys of the associative table. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\subsubsection{o.lib()}
+
+This method allows you to print the table-of-contents of a PyLCM object (memory or {\sc xsm} file). This method is not available for
+FILE objects.
+
+\vskip 0.8cm
+
+\subsubsection{o.val()}
+
+This method allows you to validate the content of a PyLCM object (memory or {\sc xsm} file). This method is not available for
+FILE objects.
+
+\vskip 0.8cm
+
+\subsubsection{o.close()}
+
+This method allows you to close a PyLCM object (memory or {\sc xsm} file) without erasing its contents. This method is not available for
+FILE objects.
+
+\vskip 0.8cm
+
+\subsubsection{o.erase()}
+
+This method allows you to erase the contents of a PyLCM object (memory or {\sc xsm} file).
+
+\vskip 0.8cm
+
+\subsubsection{o.len()}
+
+This method returns the lenght of the active directory in a PyLCM object (memory or {\sc xsm} file). This method is not available for FILE objects.
+
+\begin{verbatim}
+length = o.len()
+\end{verbatim}
+
+\noindent
+\begin{tabular} {| p {1.5cm} | p {1.5cm} | p {11.5cm} |}
+\hline
+\multicolumn {3} {| c |} {\bf output parameter:} \\
+\hline
+{\tt lenght} & {\it int} & length of the heterogeneous list; equal to $-1$ if the active directory is an associative table. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\subsubsection{o.rep()}
+
+This method allows you to create an daughter associative table in the associative table (dictionary) or the list {\tt o}. This method is not available for
+FILE objects.
+
+\begin{verbatim}
+[o2 =] o.rep({key | iset})
+\end{verbatim}
+
+\noindent
+\begin{tabular} {| p {1.5cm} | p {1.5cm} | p {11.5cm} |}
+\hline
+\multicolumn {3} {| c |} {\bf input parameters:} \\
+\hline
+{\tt key} & {\it string} & if {\tt o} is a table; compulsory string (len $=12$) corresponding to the key of the daughter associative table \\
+\hline
+{\tt iset} & {\it int} & if {\tt o} is a list; index in the list {\tt o} where we find
+the daughter associative table. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular} {| p {1.5cm} | p {1.5cm} | p {11.5cm} |}
+\hline
+\multicolumn {3} {| c |} {\bf output parameter:} \\
+\hline
+{\tt o2} & {\it LCM} & daughter associative table. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\subsubsection{o.lis()}
+
+This method allows you to create a nested child list in the associative table (dictionary) or
+the {\tt o} list. The first element of the child list is located at index [0].
+This method is not available for FILE objects.
+
+\begin{verbatim}
+[o2 =] o.lis({key | iset}, ilong)
+\end{verbatim}
+
+\noindent
+\begin{tabular} {| p {1.5cm} | p {1.5cm} | p {11.5cm} |}
+\hline
+\multicolumn {3} {| c |} {\bf input parameters:} \\
+\hline
+{\tt key} & {\it string} & if {\tt o} is a table; compulsory string (len $=12$) corresponding to the key
+from the daughter list. \\
+\hline
+{\tt iset} & {\it int} & if {\tt o} is a list; index in the list {\tt o} where we find the list daughter list. \\
+\hline
+{\tt ilong} & {\it int} & positive integer (required) which gives the length of the list daughter list. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular} {| p {1.5cm} | p {1.5cm} | p {11.5cm} |}
+\hline
+\multicolumn {3} {| c |} {\bf output parameter:} \\
+\hline
+{\tt o2} & {\it LCM} & daughter list. \\
+\hline
+\end{tabular}
+
+\section{The Python3 CLE-2000 API}
+
+The Python3 CLE-2000 API is a component of the PyGAN library, available in the Version5 distribution. It contains two extension modules, each of them containing a class: {\sc lifo} and {\sc cle2000}, both implemented using the CLE-2000 API of Sect.~\ref{sect:cle2000apiC}.
+
+\vskip 0.8cm
+
+\subsection{The lifo class}
+
+The {\sc lifo} extension module allows {\sl in-out} access to the {\sc lifo} objects ("last in first out" stack) used by CLE-2000.
+
+The {\tt lifo} module, accessible from Python3, is imported by the command
+\begin{verbatim}
+import lifo
+\end{verbatim}
+It has one constructor: {\tt lifo.new()}, used to create an {\sl object instance} {\tt o}.
+
+\subsubsection{Attribute Variables \index {attribute variables}}
+
+A {\sc lifo} object {\tt o} contains one read-write attribute variable:
+
+\begin {description}
+\item [{\tt o.\_impx}] Edition index for the object ($=0$ for minimum printouts).
+\end {description}
+
+\subsubsection{lifo.new()}
+
+This method is used to create a {\sc lifo} object made up of an empty stack. A {\sc lifo} stack is a memory-resident structure
+implemented with the CLE-2000 API of Sect.~\ref{sect:cle2000apiC}.
+
+\begin{verbatim}
+o = lifo.new([impx])
+\end{verbatim}
+
+\noindent
+\begin{tabular} {| p {1.5cm} | p {1.5cm} | p {11.5cm} |}
+\hline
+\multicolumn {3} {| c |} {\bf input parameter:} \\
+\hline
+{\tt impx} & {\it int} & edition index for the object ($=0$ for minimum printouts). \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular} {| p {1.5cm} | p {1.5cm} | p {11.5cm} |}
+\hline
+\multicolumn {3} {| c |} {\bf output parameter:} \\
+\hline
+{\tt o} & {\it LIFO} & {\sc lifo} object created. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\subsubsection{o.lib()}
+
+This method allows you to print the table-of-contents of a {\sc lifo} object.
+
+\begin{verbatim}
+o.lib()
+\end{verbatim}
+
+\vskip 0.8cm
+
+\subsubsection{o.push()}
+
+This method is used to push a new node into the {\sc lifo} object. The new node is a Python3 object of specific type. Empty nodes have defined names and types but no assigned value. The number of nodes stored in the {\sc lifo} object is increased by one.
+
+\begin{verbatim}
+o.push(data)
+\end{verbatim}
+
+\noindent
+\begin{tabular} {| p {1.5cm} | p {1.5cm} | p {11.5cm} |}
+\hline
+\multicolumn {3} {| c |} {\bf input parameter:} \\
+\hline
+{\tt data} & {\it object} & Python3 object to push in the stack. The following Python3 types are allowed: integer variable (int), character string (str), double-precision variable (float),
+logical variable (bool), PyLCM object, empty variable of type int, str, float or bool.\\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\subsubsection{o.pushEmpty()}
+
+This method is used to push an empty node into the {\sc lifo} object. Empty nodes have defined names and types but no assigned value. The number of nodes stored in the {\sc lifo} object is increased by one.
+
+\begin{verbatim}
+o.pushEmpty(name, [type])
+\end{verbatim}
+
+\noindent
+\begin{tabular} {| p {1.5cm} | p {1.5cm} | p {11.5cm} |}
+\hline
+\multicolumn {3} {| c |} {\bf input parameter:} \\
+\hline
+{\tt name} & {\it string} & character (len=72) name of the empty node. Used to name the PyLCM object. \\
+{\tt type} & {\it string} & character type of the empty object to push in the stack. The following character types are allowed: ``{\tt I}'': integer variable, ``{\tt S}'': character string, ``{\tt D}'': double precision variable, ``{\tt B}'':
+logical variable, ``{\tt LCM}'': PyLCM object of type {\sc lcm}, ``{\tt XSM}'': PyLCM object of type {\sc xsm}, ``{\tt BINARY}'': PyLCM object containing a sequential binary file, ``{\tt ASCII}'': PyLCM object containing a sqquential {\sc ascii} file,
+``{\tt DA}'': PyLCM object containing a direct access file, ``{\tt HDF5}'': PyLCM object containing a HDF5 file. By default, {\tt type} $=$ ``{\tt LCM}''.\\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\subsubsection{o.pop()}
+
+This method is used to pop a node from the {\sc lifo} object. The number of nodes stored in the {\sc lifo} object is decreased by one.
+
+\begin{verbatim}
+[obj =] o.pop()
+\end{verbatim}
+
+\noindent
+\begin{tabular} {| p {1.5cm} | p {1.5cm} | p {11.5cm} |}
+\hline
+\multicolumn {3} {| c |} {\bf output parameter:} \\
+\hline
+{\tt obj} & {\it object} & Python3 object contained in the node. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\subsubsection{o.node()}
+
+This method is used to recover a node from the {\sc lifo} object without changing its content. The number of nodes stored in the {\sc lifo} object is left unchanged.
+
+\begin{verbatim}
+obj = o.node({ ipos | name })
+\end{verbatim}
+
+\noindent
+\begin{tabular} {| p {1.5cm} | p {1.5cm} | p {11.5cm} |}
+\hline
+\multicolumn {3} {| c |} {\bf input parameter:} \\
+\hline
+{\tt ipos} & {\it int} & position of the node in the stack (the first node is at position 0). \\
+{\tt name} & {\it string} & name (len=72) of the node in the stack. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular} {| p {1.5cm} | p {1.5cm} | p {11.5cm} |}
+\hline
+\multicolumn {3} {| c |} {\bf output parameter:} \\
+\hline
+{\tt obj} & {\it object} & Python3 object contained in the node. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\subsubsection{o.getMax()}
+
+This method returns the number of nodes in a {\sc lifo} object.
+
+\begin{verbatim}
+length = o.getMax()
+\end{verbatim}
+
+\noindent
+\begin{tabular} {| p {1.5cm} | p {1.5cm} | p {11.5cm} |}
+\hline
+\multicolumn {3} {| c |} {\bf output parameter:} \\
+\hline
+{\tt lenght} & {\it int} & number of nodes in the {\sc lifo} object.\\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\subsubsection{o.OSname()}
+
+This method returns the name of a node.
+
+\begin{verbatim}
+name = o.OSname(ipos)
+\end{verbatim}
+
+\noindent
+\begin{tabular} {| p {1.5cm} | p {1.5cm} | p {11.5cm} |}
+\hline
+\multicolumn {3} {| c |} {\bf input parameter:} \\
+\hline
+{\tt ipos} & {\it int} & position of the node in the stack (the first node is at position 0). \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular} {| p {1.5cm} | p {1.5cm} | p {11.5cm} |}
+\hline
+\multicolumn {3} {| c |} {\bf output parameter:} \\
+\hline
+{\tt name} & {\it string} & name (len=72) of the node.\\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\subsection{The cle2000 class}
+
+The {\sc cle2000} extension module allows to encapsulate Ganlib5, Trivac5, Dragon5 or Donjon5 {\sl and} to execute a CLE-2000 procedure, itself calling modules of these codes or sub-CLE-2000 procedures. This extension module is based on the CLE-2000 API of Sect.~\ref{sect:cle2000apiC}.
+
+The {\tt cle2000} module, accessible from Python3, is imported by the command
+\begin{verbatim}
+import cle2000
+\end{verbatim}
+It has one constructor: {\tt cle2000.new()}, used to create an {\sl object instance} {\tt o}.
+
+\subsubsection{Attribute Variables}
+
+A {\sc cle2000} object {\tt o} contains one read-write attribute variable:
+
+\begin {description}
+\item [{\tt o.\_impx}] Edition index for the object ($=0$ for minimum printouts).
+\end {description}
+
+\subsubsection{cle2000.new()}
+
+This method is used to create a {\sc cle2000} object including an {\tt exec()} method for executing a CLE-2000 specific procedure.
+
+\begin{verbatim}
+o = cle2000.new(procname, olifo, [impx])
+\end{verbatim}
+
+\noindent
+\begin{tabular} {| p {1.5cm} | p {1.5cm} | p {11.5cm} |}
+\hline
+\multicolumn {3} {| c |} {\bf input parameter:} \\
+\hline
+{\tt procname} & {\it string} & name (len=12) of the CLE-2000 procedure. The OS filename of the procedure is {\tt procname} $+$ ``{\tt .c2m}'' \\
+{\tt olifo} & {\it LIFO} &{\sc lifo} object containing the procedure parameters. The {\sc lifo} object can be empty at construction time and can be filled before the call to the {\tt exec()} method.\\
+{\tt impx} & {\it int} & edition index for the object ($=0$ for minimum printouts). \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\noindent
+\begin{tabular} {| p {1.5cm} | p {1.5cm} | p {11.5cm} |}
+\hline
+\multicolumn {3} {| c |} {\bf output parameter:} \\
+\hline
+{\tt o} & {\it CLE2000} & {\sc cle2000} object created. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\subsubsection{o.exec()}
+
+This method execute the procedure.
+
+\begin{verbatim}
+o.exec()
+\end{verbatim}
+
+\vskip 0.8cm
+
+\subsubsection{o.getLifo()}
+
+This method returns the {\sl lifo} stack containing the procedure parameters.
+
+\begin{verbatim}
+olifo = o.getLifo()
+\end{verbatim}
+
+\noindent
+\begin{tabular} {| p {1.5cm} | p {1.5cm} | p {11.5cm} |}
+\hline
+\multicolumn {3} {| c |} {\bf output parameter:} \\
+\hline
+{\tt olifo} & {\it LIFO} & {\sc lifo} object. \\
+\hline
+\end{tabular}
+
+\vskip 0.8cm
+
+\subsubsection{o.putLifo()}
+
+This method put a new {\sc lifo} stack in the procedure.
+
+\begin{verbatim}
+o.putLifo(olifo)
+\end{verbatim}
+
+\noindent
+\begin{tabular} {| p {1.5cm} | p {1.5cm} | p {11.5cm} |}
+\hline
+\multicolumn {3} {| c |} {\bf input parameter:} \\
+\hline
+{\tt olifo} & {\it LIFO} & {\sc lifo} object. \\
+\hline
+\end{tabular}