Salome HOME
9278de76a40755ee7a0d3cd71bf9bce6d3f27fc1
[modules/med.git] / src / MEDCalc / cmp / test_medcalc_components.py
1 #!/usr/bin/env python3
2 # Copyright (C) 2007-2023  CEA, EDF
3 #
4 # This library is free software; you can redistribute it and/or
5 # modify it under the terms of the GNU Lesser General Public
6 # License as published by the Free Software Foundation; either
7 # version 2.1 of the License, or (at your option) any later version.
8 #
9 # This library is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 # Lesser General Public License for more details.
13 #
14 # You should have received a copy of the GNU Lesser General Public
15 # License along with this library; if not, write to the Free Software
16 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
17 #
18 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 #
20
21 # This file is a set of basic use case to test (from the python
22 # context) the functions developed in the MEDCALC engine and the
23 # associated MEDCALC CORBA interface (MEDDataManager and
24 # MEDCalaculator).
25 #
26 # (gboulant - 16/6/2011)
27 #
28
29 # WARN: this scripts is a unit tests runner for testing the SALOME
30 # MEDCALC CORBA components and it should stay self-consistent. Then,
31 # it's on purpose that the script does not use the xmed python
32 # package. Conversely, some (small) parts of this code could be
33 # redundant with code from the xmed package.
34
35 #
36 # ===============================================================
37 # Initializing some CORBA stuff
38 # ===============================================================
39 #
40
41 # Remember SALOME definitions:
42 # ---------------------------
43 #
44 # componentName = Name of the component (a library lib<componentName>Engine
45 # should exist with a C function named <componentName>Engine_factory, and the
46 # component should be registered in the catalog MEDCatalog.xml).
47 #
48 # corbaModule = Name of the corba module that contains the IDL
49 # specifications of the component (name as defined in the idl file)
50 #
51 # containerType = Name of the container factory
52 #
53 componentName = "MEDFactory"
54 corbaModule   = "MEDCALC"
55 containerType = "FactoryServer"
56
57 import salome
58 if salome.lcc is None:
59     salome.salome_init()
60 __import__(corbaModule)
61 factory=salome.lcc.FindOrLoadComponent(containerType,componentName)
62 # This is not the main CORBA component of the SALOME module FIELDS
63 # (i.e. the engine associated to the study), but the CORBA
64 # entry point for MED fields operations (i.e. a CORBA component
65 # reachable throughout the LifeCycleCORBA). This entry point is used to
66 # get the other SALOME CORBA components required for MED field
67 # operations, in particular the dataManager and the calculator
68
69 #
70 # ==================================================
71 # Helper functions to localize tests files and get data
72 # ==================================================
73 #
74 import os
75
76 try:
77     FIELDS_ROOT_DIR=os.environ["FIELDS_ROOT_DIR"]
78 except KeyError as e:
79     raise RuntimeError("FIELDS_ROOT_DIR should be defined to load the test data")
80
81 RESDIR=os.path.join(FIELDS_ROOT_DIR,"share","salome","resources","fields","medcalc_testfiles")
82
83 def getFilePath(filename):
84     """
85     Returns the absolute path for a given file base name. The base
86     name must match with a file contained in the test files directory.
87     """
88     filepath = os.path.join(RESDIR,filename)
89     if not os.path.exists(filepath):
90         raise RuntimeError("The file %s does not exists"%filepath)
91     return filepath
92
93 testFileName = "smallmesh_varfield.med"
94 testMeshName = "My2DMesh"
95 testFieldName= "testfield2"
96 testFieldIt  = 1
97 testFieldDt  = 1
98 testTypeOfField = 1 # On nodes
99 testFilePath = getFilePath(testFileName)
100
101 #
102 # ==================================================
103 # Basic use cases of the MEDDataManager
104 # ==================================================
105 #
106 def TEST_getDataManager():
107     dataManager = factory.getDataManager()
108     if "loadDatasource" not in dir(dataManager):
109         return False
110     return True
111
112 def TEST_loadDatasource():
113     dataManager = factory.getDataManager()
114     datasource = dataManager.loadDatasource(testFilePath)
115     if datasource.name != testFileName:
116         print("ERR: datasource.name=%s (should be %s)"%(datasource.name,testFilePath))
117         return False
118
119     # We try to load the file twice. It should not load twice and
120     # return the same datasource as previously registered (same id).
121     sourceid_ref = datasource.id
122     datasource = dataManager.loadDatasource(testFilePath)
123     if datasource.id != sourceid_ref:
124         print("ERR: datasource.id=%s (should be %s)"%(datasource.id,sourceid_ref))
125         return False
126
127     return True
128
129 def TEST_getFieldHandlerList():
130     dataManager = factory.getDataManager()
131     datasource = dataManager.loadDatasource(testFilePath)
132     fieldHandlerList = dataManager.getFieldHandlerList()
133     if fieldHandlerList is None or len(fieldHandlerList) == 0:
134         return False
135     return True
136
137 def TEST_getFieldRepresentation():
138     dataManager = factory.getDataManager()
139     datasource = dataManager.loadDatasource(testFilePath)
140     fieldHandlerList = dataManager.getFieldHandlerList()
141     fieldHandler0 = fieldHandlerList[0]
142
143     print(dataManager.getFieldRepresentation(fieldHandler0.id))
144     return True
145
146 def TEST_updateFieldMetadata():
147     dataManager = factory.getDataManager()
148     datasource = dataManager.loadDatasource(testFilePath)
149     fieldHandlerList = dataManager.getFieldHandlerList()
150     fieldHandler0 = fieldHandlerList[0]
151
152     fieldid = fieldHandler0.id
153     newname = fieldHandler0.fieldname + " modified"
154
155     dataManager.updateFieldMetadata(fieldid, newname,
156                                     fieldHandler0.iteration,
157                                     fieldHandler0.order,
158                                     fieldHandler0.source)
159
160     fieldHandlerModified = dataManager.getFieldHandler(fieldid)
161     print(fieldHandlerModified)
162
163     if fieldHandlerModified.fieldname != newname:
164         print("ERR: the name is %s (should be %s)"%(fieldHandlerModified.fieldname,newname))
165         return False
166     return True
167
168 def TEST_saveFields():
169     dataManager = factory.getDataManager()
170     datasource = dataManager.loadDatasource(testFilePath)
171     fieldHandlerList = dataManager.getFieldHandlerList()
172     fieldHandler0 = fieldHandlerList[0]
173     fieldIdList = [fieldHandler0.id]
174     filepath = "/tmp/test_xmed_saveFields.med"
175
176     print("fieldIdList = %s"%fieldIdList)
177     print("filepath = %s"%filepath)
178
179     dataManager.saveFields(filepath,fieldIdList)
180     # We just control that the file exists. But we should reload the
181     # contents to check the fields
182     import os
183     if not os.path.exists(filepath):
184         print("ERR: the file %s does not exist"%(filepath))
185         return False
186     return True
187
188 #
189 # ==================================================
190 # Use cases of the MEDDataManager for data loading
191 # ==================================================
192 #
193 def TEST_MEDDataManager_getMeshHandlerList():
194     dataManager = factory.getDataManager()
195     datasourceHandler = dataManager.loadDatasource(testFilePath)
196     meshHandlerList = dataManager.getMeshHandlerList(datasourceHandler.id)
197     print(meshHandlerList)
198
199     if len(meshHandlerList) == 0:
200         return False
201     return True
202
203 def TEST_MEDDataManager_getMesh():
204     dataManager = factory.getDataManager()
205     datasourceHandler = dataManager.loadDatasource(testFilePath)
206     meshHandlerList = dataManager.getMeshHandlerList(datasourceHandler.id)
207     for mRef in meshHandlerList:
208         meshId = mRef.id
209         mRes = dataManager.getMeshHandler(meshId)
210         print(mRes)
211         if ( mRes.name != mRef.name ) or ( mRes.sourceid != mRef.sourceid):
212             return False
213     return True
214
215 def TEST_MEDDataManager_getFieldseriesListOnMesh():
216     dataManager = factory.getDataManager()
217     datasourceHandler = dataManager.loadDatasource(testFilePath)
218
219     meshHandlerList = dataManager.getMeshHandlerList(datasourceHandler.id)
220     # We look for the fieldseries defined on the first mesh of the list
221     meshId = meshHandlerList[0].id
222     fieldseriesList = dataManager.getFieldseriesListOnMesh(meshId)
223     print(fieldseriesList)
224
225     if len(fieldseriesList) == 0:
226         return False
227     return True
228
229 def TEST_MEDDataManager_getFieldListInFieldseries():
230     dataManager = factory.getDataManager()
231     testFilePath = os.path.join(RESDIR,testFileName)
232
233     testFilePath  = getFilePath("timeseries.med")
234     datasourceHandler = dataManager.loadDatasource(testFilePath)
235
236     meshHandlerList = dataManager.getMeshHandlerList(datasourceHandler.id)
237     # We look for the fieldseries defined on the first mesh of the list
238     meshId = meshHandlerList[0].id
239     fieldseriesList = dataManager.getFieldseriesListOnMesh(meshId)
240     # We look for the fields defined in the first fieldseries,
241     # i.e. the time steps for this field.
242     fieldseriesId = fieldseriesList[0].id
243     fieldList = dataManager.getFieldListInFieldseries(fieldseriesId)
244     print(fieldList)
245
246     if len(fieldList) == 0:
247         return False
248     return True
249
250 def TEST_MEDDataManager_getFieldIdAtTimestamp():
251     dataManager = factory.getDataManager()
252     testFilePath = os.path.join(RESDIR,testFileName)
253
254     testFilePath  = getFilePath("timeseries.med")
255     datasourceHandler = dataManager.loadDatasource(testFilePath)
256
257     meshHandlerList = dataManager.getMeshHandlerList(datasourceHandler.id)
258     # We look for the fieldseries defined on the first mesh of the list
259     meshId = meshHandlerList[0].id
260     fieldseriesList = dataManager.getFieldseriesListOnMesh(meshId)
261     # We look for the fields defined in the first fieldseries,
262     # i.e. the time steps for this field.
263     fieldseriesId = fieldseriesList[0].id
264     requestedTimestamp8 = 8
265     fieldId8 = dataManager.getFieldIdAtTimestamp(fieldseriesId, requestedTimestamp8)
266     timestamp8 = dataManager.getFieldTimestamp(fieldId8)
267     print("fieldId8: ", fieldId8)
268     print("timestamp8: ", timestamp8)
269     requestedTimestamp9 = 9
270     fieldId9 = dataManager.getFieldIdAtTimestamp(fieldseriesId, 9)
271     timestamp9 = dataManager.getFieldTimestamp(fieldId9)
272     print("fieldId9: ", fieldId9)
273     print("timestamp9: ", timestamp9)
274
275     if (timestamp8!=requestedTimestamp8):
276       return False
277     if (timestamp9!=requestedTimestamp9):
278       return False
279     return True
280
281 #
282 # ==================================================
283 # Use cases of the MEDCalculator
284 # ==================================================
285 #
286 def TEST_Calculator_basics():
287     dataManager = factory.getDataManager()
288     datasource = dataManager.loadDatasource(testFilePath)
289     fieldHandlerList = dataManager.getFieldHandlerList()
290
291     # Try to operate on the two first fields
292     fieldHandler0 = fieldHandlerList[0]
293     fieldHandler1 = fieldHandlerList[1]
294     print(fieldHandler0)
295     print(fieldHandler1)
296
297     calculator = factory.getCalculator()
298     add = calculator.add(fieldHandler0, fieldHandler1)
299     print(add)
300     sub = calculator.sub(fieldHandler0, fieldHandler1)
301     print(sub)
302     mul = calculator.mul(fieldHandler0, fieldHandler1)
303     print(mul)
304     div = calculator.div(fieldHandler0, fieldHandler1)
305     print(div)
306     #power = calculator.pow(fieldHandler0, 2)
307     # print(power)
308     linear = calculator.lin(fieldHandler0, 3,2)
309     print(linear)
310
311     return True
312
313 def TEST_Calculator_applyFunc():
314     dataManager = factory.getDataManager()
315     datasource = dataManager.loadDatasource(testFilePath)
316     fieldHandlerList = dataManager.getFieldHandlerList()
317     fieldHandler = fieldHandlerList[0]
318
319     # In this example, "u" stands for the whole field
320     calculator = factory.getCalculator()
321     import MEDCALC
322     nbResultingComponent = MEDCALC.NBCOMP_DEFAULT
323     res = calculator.fct(fieldHandler,"abs(u)",nbResultingComponent);
324     print(res)
325
326     # In this example, "a" stands for the first component
327     nbResultingComponent = 1
328     res = calculator.fct(fieldHandler,"a+2",nbResultingComponent)
329     print(res)
330
331     return True
332
333 #
334 # ==================================================
335 # Use cases of the MEDDataManager that need MEDCalculator
336 # ==================================================
337 #
338 def TEST_markAsPersistent():
339     dataManager = factory.getDataManager()
340     datasource = dataManager.loadDatasource(testFilePath)
341     fieldHandlerList = dataManager.getFieldHandlerList()
342     fieldHandler0 = fieldHandlerList[0]
343     fieldHandler1 = fieldHandlerList[1]
344
345     calculator = factory.getCalculator()
346     add = calculator.add(fieldHandler0, fieldHandler1)
347
348     filepath = "/tmp/test_xmed_markAsPersistent.med"
349     dataManager.markAsPersistent(add.id, True)
350     dataManager.savePersistentFields(filepath)
351     import os
352     if not os.path.exists(filepath):
353         print("ERR: the file %s does not exist"%(filepath))
354         return False
355     return True
356
357 #
358 # =============================================================
359 # Unit tests runner
360 # =============================================================
361 #
362 import unittest
363 from salome.kernel import pyunittester
364 class MyTestSuite(unittest.TestCase):
365
366     # === MEDDataManager (core functions)
367     def test_getDataManager(self):
368         self.assertTrue(TEST_getDataManager())
369
370     def test_loadDatasource(self):
371         self.assertTrue(TEST_loadDatasource())
372
373     def test_getFieldHandlerList(self):
374         self.assertTrue(TEST_getFieldHandlerList())
375
376     def test_getFieldRepresentation(self):
377         self.assertTrue(TEST_getFieldRepresentation())
378
379     def test_updateFieldMetadata(self):
380         self.assertTrue(TEST_updateFieldMetadata())
381
382     def test_saveFields(self):
383         self.assertTrue(TEST_saveFields())
384
385     # === MEDDataManager (data request functions)
386     def test_MEDDataManager_getMeshHandlerList(self):
387         self.assertTrue(TEST_MEDDataManager_getMeshHandlerList())
388
389     def test_MEDDataManager_getMesh(self):
390         self.assertTrue(TEST_MEDDataManager_getMesh())
391
392     def test_MEDDataManager_getFieldseriesListOnMesh(self):
393         self.assertTrue(TEST_MEDDataManager_getFieldseriesListOnMesh())
394
395     def test_MEDDataManager_getFieldListInFieldseries(self):
396         self.assertTrue(TEST_MEDDataManager_getFieldListInFieldseries())
397
398     def test_MEDDataManager_getFieldIdAtTimestamp(self):
399         self.assertTrue(TEST_MEDDataManager_getFieldIdAtTimestamp())
400
401     # === MEDCalculator (need MEDDataManager)
402     def test_Calculator_basics(self):
403         self.assertTrue(TEST_Calculator_basics())
404
405     def test_Calculator_applyFunc(self):
406         self.assertTrue(TEST_Calculator_applyFunc())
407
408     # === MEDDataManager (need MEDCalculator)
409     def test_markAsPersistent(self):
410         self.assertTrue(TEST_markAsPersistent())
411
412 def myunittests():
413     pyunittester.run(MyTestSuite)
414
415 if __name__ == "__main__":
416     myunittests()