Salome HOME
bos #29864 Irrelevant assert in test.
[modules/yacs.git] / doc / compInterne.rst
1
2 .. _seccompinterne:
3
4 Defining an internal object
5 ===============================
6
7 .. index:: single: internal object
8
9 In the remainder of this document, it is assumed that an **internal object** is a **C++ or python object** that provides a 
10 first interface to the initial code.  The form of this object and communication between the internal object and the 
11 initial code will be different depending on the form of the initial code (executable binary, static or dynamic library, 
12 f77, C, C++ or python source files).
13
14 Object methods and attributes
15 --------------------------------
16 In each case, the services and the internal state of the internal object will have to be defined.  In particular:
17
18 * choose the different services of this object
19 * for each service, define input and output data
20 * for each input and each output, define the data type and possibly associated pre-conditions and post-conditions (for example positive input data)
21 * define the internal state of the object and possibly its value before and after the call to different services.
22
23 **Services** will be implemented in the form of **public methods** and the **internal state** will be implemented in the form of **attributes**.  
24 If the designer of the object allows the user to access the attributes in read and write, he must provide services to access these attributes.
25
26 Fortran77 routines / C functions / C++ classes 
27 --------------------------------------------------
28 Principle
29 ^^^^^^^^^^^
30 In the case of Fortran77 routines, C functions and C++ classes, the integrator will simply add a C++ envelope around 
31 these functions (see figure :ref:`C++ internal object<figobjetinterne>`), to obtain the internal object.  
32 Each method in the object:
33
34 - extracts information from the input parameters if necessary
35 - calls the internal routine(s) concerned,
36 - formats the results of these internal routines in the output parameters.
37
38 .. _figobjetinterne:
39
40
41 .. image:: images/objintcpp.png
42    :align: center
43
44 .. centered:: C++ internal object
45
46
47 .. _exemple1:
48
49 Example 1
50 ^^^^^^^^^
51
52
53 Consider the following f77 fortran routines performing linear algebra calculations on one dimensional floating tables:
54
55 ``addvec.f``
56
57 .. include:: ./exemples/exemple1/addvec.f
58    :literal:
59
60
61 ``prdscl.f``
62
63 .. include:: ./exemples/exemple1/prdscl.f
64    :literal:
65
66 and a C++ class simulating a (very) rudimentary vector type:
67
68 .. _vecteur.hxx:
69
70
71 ``vecteur.hxx (C++ interface)``
72
73 .. include:: ./exemples/exemple1/exec2/vecteur.hxx
74    :literal:
75
76
77 ``vecteur.cxx (C++ implementation)``
78
79 .. include:: ./exemples/exemple1/exec2/vecteur.cxx
80    :literal:
81
82 The internal object (i.e. the C++ class) in the example is:
83
84
85 ``alglin.hxx``
86
87 .. include:: ./exemples/exemple1/exec2/alglin.hxx
88    :literal:
89
90
91 ``alglin.cxx``
92
93 .. include:: ./exemples/exemple1/exec2/alglin.cxx
94    :literal:
95
96 **Notes**:
97
98 #. The integrator chooses methods, parameter transfers and parameter types (in accordance with the requirements of object users).  
99    The correspondence between parameters of the internal object and parameters of routines in the initial code is organised 
100    by the implementation (file ``alglin.cxx``, above).
101 #. In particular, if MED structures [MED]_ are transferred as input arguments, the C++ implementation file will be required to extract 
102    and format information to be transferred to internal calculation routines (in the form of simple and scalar tables for internal 
103    fortran routines).  For output arguments in the MED format, the implementation will introduce the results of internal routines 
104    into the MED objects to be returned.
105
106 Note the following in the above example:
107
108 * the ``“C” extern`` declaration in front of C++ prototypes of fortran functions
109 * the “underscore” character added to the C++ name of fortran functions
110 * the mode of transferring arguments, the rule being that pointers will be transferred apart from exceptions (length of 
111   character strings).  For scalar arguments, the addresses of the scalar arguments will be transferred;  for pointer 
112   arguments (tables), the pointers will be transferred as is.
113
114 The internal object can now be used in a C++ code:
115
116 .. include:: ./exemples/exemple1/exec2/main_extraits.cxx
117    :literal:
118
119
120 References
121 ^^^^^^^^^^
122 The C / fortran77 encapsulation in a C++ code follows the standard procedure (formats of reals / integers, 
123 routine names, transfer of arguments).  For example, further information on this subject is given in [ForCpp]_ or [ForCpp2]_.
124
125 Python function/classes
126 ------------------------
127 Principle
128 ^^^^^^^^^^
129 The principle of encapsulation of python functions / classes in an internal object (python) is the same as in the previous case
130
131   .. _figobjetinterne2:
132
133
134   .. image:: images/objintpy.png
135      :align: center
136
137   .. centered:: Python internal object
138
139
140 Example 2
141 ^^^^^^^^^
142
143 An example similar to the previous example starts from Python functions to be encapsulated:
144
145 ``func.py``
146
147 .. include:: ./exemples/exemple2/func.py
148    :literal:
149
150 It is easy to integrate these functions into a python class:
151
152
153 ``compo.py``
154
155 .. include:: ./exemples/exemple2/compo.py
156    :literal:
157
158 **Note**:  
159   In fact, it is not even necessary to embed python functions of ``func.py``, but it is “cleaner” (particularly if 
160   the object has an internal state).  The following script uses the Python internal object from a python interpreter:
161
162 .. include:: ./exemples/exemple2/exmpl.py
163    :literal:
164
165
166 Initial code in the form of executables
167 --------------------------------------------
168 Principle
169 ^^^^^^^^^^
170 This case occurs when there are no internal code sources (or when it is not required to integrate these sources 
171 into the internal architecture).  It will be assumed that the code is in the form of a binary that can be executed 
172 by the operating system.  Communications can be made with the code.
173
174 1. In  input, either:
175
176   - by one or several files,
177   - by the command line,
178   - using the keyboard to answer questions from the code 
179
180 2. In output, either:
181
182   - by one or several files,
183   - on-screen display.
184
185 Communication with executables is made using commands (available in C++ and in python):
186
187 - ``system``:  start an executable with which input communications are made through files or the command line, and 
188   output communications are made through files,
189 - ``popen``:  same functions as the previous case, also with the possibility of retrieving the standard output (screen) 
190   for the executable.
191
192 The above commands are stored in order of increasing complexity (it is recommended that ``system`` should be used as much as possible).
193
194 Example 3:  Python internal object connected to external executables
195 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
196 It is required to use a “System” object that has 5 services:
197
198 - ``cd``, that starts from a path (character string) and sets a current directory,
199 - ``cp``, that starts from 2 file names, and copies the first file onto the second in the current directory,
200 - ``touch``, that starts from a file name and updates the date of the file if there is one, and otherwise creates it,
201 - ``rm``, that starts from a file name and destroys the file in the current directory,
202 - ``dir``, that lists the files contained in the current directory.
203
204 The internal state of the object will be composed of the name of the current directory in which the services of the 
205 object (that is set by the ``cd`` service) will work.
206
207 In Python, the object class could be written:
208
209 ``systeme.py``
210
211 .. include:: ./exemples/exemple3/systeme.py
212    :literal:
213
214 and its use from the python interpreter:
215
216
217 .. include:: ./exemples/exemple3/use.py
218    :literal:
219
220 **Notes**
221
222 #. This is given as an example, Python has everything necessary in the standard version to perform these services, without 
223    the use of system commands (``system`` and ``popen``).
224 #. The example illustrates transfer of input arguments through the command line (names transferred as arguments) and the “capture” of 
225    screen outputs from external executables (``system`` that cannot simply recover the standard output from the unix command ``ls``, and 
226    in this case ``popen`` is used).
227
228 .. _exemple4:
229
230 Example 4:  Internal object connected to an external executable
231 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
232 This example shows a (very) partial interface of a binary executable *FreeFem* [FreeFem]_ in the form of a C++ object.  
233 The interface provides access to the definition of a 2D geometry through its boundary, and the approximate resolution of a 
234 simple equation (forced convection) on this geometry.  The different methods of the internal object are:
235
236 - a method that records the geometry of the domain,
237 - a method that records the convecting velocity fields,
238 - the calculation method that receives the initial condition (in analytic form – character string), the time step and the number of time steps.
239
240 The internal state of the object is composed of the geometry and the velocity field.  
241 The calculation method creates a file starting from its parameters and the internal state, and then starts a calculation 
242 loop (by a system call).  The object does not recover the calculation results.
243
244 **Comments**
245
246 #. A complete encapsulation of FreeFem would require far too much effort, this is simply an example.
247 #. We do not retrieve a result in the C++ object in this example (the change is only displayed by the FreeFem internal graphic 
248    engine).  If it was required to do so, it would be necessary to read the file produced by the external code after the system 
249    call, and transfer the results in a form that could be understood by the User of the internal object.
250
251 Two versions (C++ and python) are listed below.
252
253 .. _freefem.hxx:
254
255
256 ``FreeFem.hxx``
257
258 .. include:: ./exemples/exemple4/FreeFem.hxx
259    :literal:
260
261
262 ``FreeFem.cxx``
263
264 .. include:: ./exemples/exemple4/FreeFem.cxx
265    :literal:
266
267
268 ``FreeFem.py``
269
270 .. include:: ./exemples/exemple4/FreeFem.py
271    :literal:
272
273 Use from a C++ code or a python interpreter is similar in the 2 versions:
274
275 ``version C++``
276
277 .. include:: ./exemples/exemple4/main.cxx
278    :literal:
279
280
281 ``version python``
282
283 .. include:: ./exemples/exemple4/useFreeFem.py
284    :literal:
285