Salome HOME
Update copyrights 2014.
[modules/med.git] / src / MEDOP / tut / medcoupling / testmed_gendata.py
1 #!/usr/bin/env python
2 #  -*- coding: iso-8859-1 -*-
3 # Copyright (C) 2011-2014  CEA/DEN, EDF R&D
4 #
5 # This library is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU Lesser General Public
7 # License as published by the Free Software Foundation; either
8 # version 2.1 of the License, or (at your option) any later version.
9 #
10 # This library is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 # Lesser General Public License for more details.
14 #
15 # You should have received a copy of the GNU Lesser General Public
16 # License along with this library; if not, write to the Free Software
17 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
18 #
19 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #
21
22 # This script illustrates the basic usage of MEDCoupling and MEDLoader
23 # to generate test data files for various cases of med operation. It
24 # illustrates also the usage of numpy to specify the values of the
25 # fields when defined on a cartesian mesh (grid).
26 # (gboulant - 11/07/2011)
27
28 import MEDCoupling as MC
29 import MEDLoader as ML
30
31 import numpy
32
33 #
34 # ===============================================================
35 # Helper functions to create meshes
36 # ===============================================================
37 #
38
39 def createGridMesh(meshName, nbCellsX, nbCellsY):
40     """
41     The mesh is created using MEDCoupling. The code below creates a
42     cartesian mesh as a grid with nbCellsX segments in the X direction
43     and nbCellsY in the Y direction (nb. cells = nbCellsX * nbCellsY)
44     """
45     print "Creating grid mesh of size %sx%s"%(nbCellsX, nbCellsY)
46     cmesh=MC.MEDCouplingCMesh.New();
47
48     # Create X coordinates
49     nbNodesX = nbCellsX+1
50     stepX = 0.1
51     arrX = [float(i * stepX) for i in range(nbNodesX)]    
52     coordsX=MC.DataArrayDouble.New()
53     coordsX.setValues(arrX,nbNodesX,1)
54
55     # Create Y coordinates
56     nbNodesY = nbCellsY+1
57     stepY = 0.1
58     arrY=[float(i * stepY) for i in range(nbNodesY)]
59     coordsY=MC.DataArrayDouble.New()
60     coordsY.setValues(arrY,nbNodesY,1)
61
62     # Create the grid
63     cmesh.setCoords(coordsX,coordsY)
64     cmesh.setName(meshName)
65
66     return cmesh
67
68 def unstructuredMesh(cartesianMesh):
69     """
70     Convert the cartesian mesh in unstructured mesh for the need of
71     write function of MEDLoader
72     """
73     print "Creating unstructured mesh from %s"%(cartesianMesh.getName())
74     umesh=cartesianMesh.buildUnstructured();
75     umesh.setName(cartesianMesh.getName())
76     return umesh
77
78 #
79 # ===============================================================
80 # Creating a cartesian mesh
81 # ===============================================================
82 #
83 # The size is the number of discrete values in a direction, and then
84 # corresponds to the number of cells in that direction.
85 size=80
86 #size=512
87
88
89 # >>>
90 # WARNING: remember the problem of tics and spaces. The parameter
91 # "size" is considered to be a number of cells (intervals). The number
92 # of nodes in that direction is size+1.
93 # <<<
94
95 nbCellsX = size
96 nbNodesX = nbCellsX+1
97
98 nbCellsY = size # The size could be different than the X size
99 nbNodesY = nbCellsY+1
100
101 meshName = "Grid_%sx%s"%(nbCellsX, nbCellsY)
102 cmesh = createGridMesh(meshName, nbCellsX, nbCellsY)
103 umesh = unstructuredMesh(cmesh)
104 medFileName="gendata.med"
105 ML.MEDLoader.WriteUMesh(medFileName,umesh,True);
106
107 #
108 # ===============================================================
109 # Creating a scalar field, working with numpy
110 # ===============================================================
111 #
112
113 def createField(fieldName,gridMesh,
114                 numpy2Darray,typeOfField=MC.ON_CELLS,
115                 iteration=0):
116     """
117     The number of values for the fields is deduced from the sizes of
118     the numpy array. If typeOfField is ON_CELLS, the size is considered
119     as the number of cells, otherwise it's considered as the number of
120     nodes. In any case, it must be consistent with the dimensions of
121     the numpy 2D array.
122     """
123     print "Creating field %s with iteration=%s"%(fieldName,iteration)
124
125     # The sizes are deduced from the numpy array. Note that if
126     # typeOfField is ON_CELLS, then the size should correspond to the
127     # number of cells, while if typeOfField is ON_NODES, then the size
128     # should correspond to the number of nodes
129     [sizeX,sizeY] = numpy2Darray.shape
130
131     # We first have to reshape the 2D numpy array in a 1D vector that
132     # concatenate all the rows
133     data=numpy2Darray.reshape(1,sizeX*sizeY)[0]
134     # Then, we can create a simple list as required by the MEDCoupling
135     # DataArrayDouble. Note also the usage of float type because
136     # MEDCoupling works only with real numbers
137     listdata=list(data)
138     
139     # Create the field using the list obtained from the numpy array
140     field = MC.MEDCouplingFieldDouble.New(typeOfField,MC.ONE_TIME);
141     field.setName(fieldName);
142     field.setMesh(gridMesh);
143     field.setIteration(iteration)
144     field.setTimeValue(float(iteration))
145     
146     nbComponents=1 # Only one single component for a scalar field
147     nbCells=sizeX*sizeY
148     dataArray=MC.DataArrayDouble.New();
149     dataArray.setValues(listdata,nbCells,nbComponents)
150     field.setArray(dataArray);
151
152     return field
153
154 def writeField(fieldName, numpy2Darray,
155                typeOfField=MC.ON_CELLS,
156                iteration=0):
157
158     field = createField(fieldName, umesh, numpy2Darray,
159                         typeOfField, iteration)
160     createFromScratch=False
161     ML.MEDLoader.WriteField(medFileName,field,createFromScratch)
162     
163
164 def createTestNumpy2DArray(sizeX, sizeY):
165     """
166     This illustrates how to create a numpy 2D array for input of the
167     createField function.
168     """
169     rows=[]
170     for irow in range(sizeY):
171         row = numpy.arange(start = irow*sizeY,
172                            stop  = irow*sizeY+sizeX,
173                            step  = 1,
174                            dtype='float64')
175         rows.append(row)
176
177     numpy2Darray = numpy.vstack(rows)
178     return numpy2Darray
179     
180 def createTestFieldOnCells():
181     # Test field on cells
182     numpy2Darray = createTestNumpy2DArray(sizeX=nbCellsX, sizeY=nbCellsY)
183     writeField("FieldOnCells", numpy2Darray,
184                typeOfField=MC.ON_CELLS)
185
186 def createTestFieldOnNodes():
187     # Test field on nodes
188     numpy2Darray = createTestNumpy2DArray(sizeX=nbNodesX, sizeY=nbNodesY)
189     writeField("FieldOnNodes", numpy2Darray,
190                typeOfField=MC.ON_NODES)
191     
192
193 #
194 # =================================================
195 # Creating a time series
196 # =================================================
197 #
198
199 # -------------------------------------------------
200 # Simple demo of the principles
201 # -------------------------------------------------
202
203 # In these functions, (x,y) are the indexes of the element in the
204 # numpy array. Note that theses indexes maps the indexes of the
205 # cartesian mesh.
206
207 # A function can be a simple python function ...
208 def f1(x,y):
209     z = 10*x
210     print "x=%s\ny=%s\nz=%s"%(x,y,z)
211     return z
212
213 # ... but also a more sophisticated callable object, for example to
214 # defines some parameters
215 class Function(object):
216     def __init__(self, sizeX, sizeY, param):
217         self.sizeX = sizeX
218         self.sizeY = sizeY
219         self.param = param
220
221     def function(self, x,y):
222         z = self.param*x
223         print "x=%s\ny=%s\nz=%s"%(x,y,z)
224         return z
225
226     def __call__(self, x,y):
227         return self.function(x,y)
228
229 fOnNodes=Function(sizeX=nbNodesX, sizeY=nbNodesY, param=10)
230 fOnCells=Function(sizeX=nbCellsX, sizeY=nbCellsY, param=3)
231
232 def createFunctionField_01():
233     sizeX=nbNodesX
234     sizeY=nbNodesY
235     typeOfField=MC.ON_NODES
236     f=fOnNodes
237     numpy2Darray = numpy.fromfunction(f,(sizeX,sizeY),dtype='float64')
238     writeField("FieldOnNodesUsingFunc", numpy2Darray,typeOfField)
239
240     f=fOnCells
241     sizeX=nbCellsX
242     sizeY=nbCellsY
243     typeOfField=MC.ON_CELLS
244     numpy2Darray = numpy.fromfunction(f,(sizeX,sizeY),dtype='float64')
245     writeField("FieldOnCellsUsingFunc", numpy2Darray,typeOfField)
246
247
248 # -------------------------------------------------
249 # Using the pyfunctions package to generate data
250 # -------------------------------------------------
251
252 def createNumpy2DArrayWithFunc(sizeX, sizeY, function):
253     """
254     @function : a callable than can be used as a function of X.
255     Typically function should be an instance of Function object
256     defined in pyfunctions.functions.
257     """
258
259     # X coordinates should range between 0 and 1 to use the normalized
260     # functions. We have to generate sizeX points:
261     step=1./sizeX
262     arrX=[float(i * step) for i in range(sizeX)]
263
264     values = function(arrX)
265
266     # Then on can create the base row for the numpy 2D array
267     rowX = numpy.array(values)
268     # and replicate this row along the Y axis
269     rows=[]
270     for irow in range(sizeY):
271         rows.append(rowX)
272
273     numpy2Darray = numpy.vstack(rows)
274     return numpy2Darray
275
276 from pyfunctions.functions import FuncStiffPulse
277 def createNumpy2DArrayWithFuncStiff(sizeX, sizeY):
278     f=FuncStiffPulse(xlimit=0.3,stiffness=30,nbPeriods=10)
279     return createNumpy2DArrayWithFunc(sizeX, sizeY, f)
280     
281 def createFunctionField_02():
282     sizeX=nbCellsX
283     sizeY=nbCellsY
284     typeOfField=MC.ON_CELLS
285     numpy2Darray = createNumpy2DArrayWithFuncStiff(sizeX,sizeY)
286     writeField("FieldOnCellsUsingFunc02", numpy2Darray,typeOfField)
287
288     sizeX=nbNodesX
289     sizeY=nbNodesY
290     typeOfField=MC.ON_NODES
291     numpy2Darray = createNumpy2DArrayWithFuncStiff(sizeX,sizeY)
292     writeField("FieldOnNodesUsingFunc02", numpy2Darray,typeOfField)
293
294 #
295 # =================================================
296 # Functions to create custom fields for MEDOP tests
297 # =================================================
298 #
299 def createTimeSeries():
300     """
301     Create a single med file with a single mesh and a field defined on
302     several time steps (time series).
303     """
304     meshName = "Grid_%sx%s"%(nbCellsX, nbCellsY)
305     cmesh = createGridMesh(meshName, nbCellsX, nbCellsY)
306     umesh = unstructuredMesh(cmesh)
307     medFileName="timeseries.med"
308     ML.MEDLoader.WriteUMesh(medFileName,umesh,True);
309
310     sizeX=nbNodesX
311     sizeY=nbNodesY
312     typeOfField=MC.ON_NODES
313
314     nbIterations=10
315     pulseStiffNess = 20
316     pulseNbPeriods = 10
317     for iteration in range(nbIterations):
318         xlimit = float(iteration)/float(nbIterations)
319         f=FuncStiffPulse(xlimit,stiffness=pulseStiffNess,nbPeriods=pulseNbPeriods)
320         numpy2Darray = createNumpy2DArrayWithFunc(sizeX,sizeY,f)
321         field = createField("Pulse",umesh,numpy2Darray,typeOfField,iteration)
322         ML.MEDLoader.WriteField(medFileName,field,False)
323
324 from pyfunctions.functions import FuncStiffExp
325 def createParametrics():
326     """
327     Create 2 med files containing each a mesh (identical) and a field
328     defined on this mesh in each file.
329     """
330     meshName = "Grid_%sx%s_01"%(nbCellsX, nbCellsY)
331     cmesh = createGridMesh(meshName, nbCellsX, nbCellsY)
332     umesh = unstructuredMesh(cmesh)
333     
334     sizeX=nbNodesX
335     sizeY=nbNodesY
336     typeOfField=MC.ON_NODES
337
338     medFileName="parametric_01.med"
339     ML.MEDLoader.WriteUMesh(medFileName,umesh,True);
340     f=FuncStiffExp(xlimit=0.3,stiffness=30)
341     numpy2Darray = createNumpy2DArrayWithFunc(sizeX,sizeY,f)
342     fieldName = "StiffExp_01"
343     field = createField(fieldName,umesh, numpy2Darray,typeOfField)
344     ML.MEDLoader.WriteField(medFileName,field,False)
345
346     medFileName="parametric_02.med"
347     umesh.setName("Grid_%sx%s_02"%(nbCellsX, nbCellsY))
348     ML.MEDLoader.WriteUMesh(medFileName,umesh,True);
349     f=FuncStiffExp(xlimit=0.4,stiffness=30)
350     numpy2Darray = createNumpy2DArrayWithFunc(sizeX,sizeY,f)
351     fieldName = "StiffExp_02"
352     field = createField(fieldName,umesh, numpy2Darray,typeOfField)
353     ML.MEDLoader.WriteField(medFileName,field,False)
354
355 def createParametrics_demo():
356     """
357     Create 2 med files containing each a mesh (identical) and a field
358     defined on this mesh in each file.
359     """
360     meshName = "mesh1"
361     cmesh = createGridMesh(meshName, nbCellsX, nbCellsY)
362     umesh = unstructuredMesh(cmesh)
363     
364     sizeX=nbNodesX
365     sizeY=nbNodesY
366     typeOfField=MC.ON_NODES
367
368     listIteration = [0,1,2,3,4]
369
370     medFileName="parametric_01.med"
371     ML.MEDLoader.WriteUMesh(medFileName,umesh,True);
372     fieldName = "field1"
373     for iteration in listIteration:
374         #f=FuncStiffPulse(xlimit=0.3+0.1*iteration,stiffness=10,nbPeriods=5)
375         f=FuncStiffExp(xlimit=0.3+0.1*iteration,stiffness=10)
376         numpy2Darray = createNumpy2DArrayWithFunc(sizeX,sizeY,f)
377         field = createField(fieldName,umesh, numpy2Darray,typeOfField,iteration)
378         ML.MEDLoader.WriteField(medFileName,field,False)
379     
380     medFileName="parametric_02.med"
381     umesh.setName("mesh2")
382     ML.MEDLoader.WriteUMesh(medFileName,umesh,True);
383     fieldName = "field2"
384     for iteration in listIteration:
385         #f=FuncStiffPulse(xlimit=0.3+0.1*iteration,stiffness=10,nbPeriods=6)
386         f=FuncStiffExp(xlimit=0.3+0.1*iteration,stiffness=15)
387         numpy2Darray = createNumpy2DArrayWithFunc(sizeX,sizeY,f)
388         field = createField(fieldName,umesh, numpy2Darray,typeOfField,iteration)
389         ML.MEDLoader.WriteField(medFileName,field,False)
390
391
392
393 #
394 # =================================================
395 # Main runner
396 # =================================================
397 #
398 if __name__ == "__main__":
399     #createTestFieldOnCells()
400     #createTestFieldOnNodes()
401     #createFunctionField_01()
402     #createFunctionField_02()
403     #createTimeSeries()
404     createParametrics_demo()