From 7dfcc480ba1e19bd3232349fc733caef94034292 Mon Sep 17 00:00:00 2001 From: stainer_t Date: Mon, 8 Sep 2025 13:48:49 +0200 Subject: Initial commit from Polytechnique Montreal --- doc/IGE332/chapter1.tex | 7412 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 7412 insertions(+) create mode 100644 doc/IGE332/chapter1.tex (limited to 'doc/IGE332/chapter1.tex') 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 +#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 +#include +#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 +#include +#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 :: <> >>prev_fact<< ; + EVALUATE n_fact := n 1 + prev_fact * ; + ENDIF ; + :: <> ; + QUIT " Recursive procedure *fact* XREF " . +\end{verbatim} + +This procedure can be called from a program implemented in ANSI~C, using +\begin{verbatim} +#include +#include +#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 +#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} -- cgit v1.2.3