Salome HOME
[doc] Updating tutorial to only use "import medcoupling as mc"
[tools/medcoupling.git] / doc / tutorial / medcoupling_3Dcube.rst
1
2 Meshing a 3D cube
3 -----------------
4
5 Objective
6 ~~~~~~~~~
7
8 The meshing class of the SALOME MED module allows user to create a mesh from scratch. 
9 In this example we propose to build a mesh on a 3D cube by three methods (classical method, method by extrusion and grid method). Each cell of the mesh must be a hexaedron.
10 We see also how creating a group.
11 Then we create a field on all the 3D cube.
12 Each result will be saved in a med file, and then visualized with the SMESH module of Salome.
13
14 In spite of a mesh in MEDCoupling has only one dimension, it's possible to save some meshes with different dimension in one med file. We will see this method.
15
16 .. image:: images/Mesh_cube3D.jpg
17
18
19 Beginning of implementation
20 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
21
22 To implement this exercice we use the python language script and import the medcoupling module. We need also mathematical functions, so we import the python math module::
23
24     import medcoupling as mc
25         from math import *
26
27 You must define 3 variables for space dimension, number of nodes on each dimension and total number of nodes::
28
29         MeshDim3D = 3
30         MeshDim2D = 2
31         N = ...
32         NbCell2D = (N-1)*(N-1)
33         NbCell3D = NbCell2D*(N-1)
34         NbNode2D = N*N
35         NbNode3D = NbNode2D*N
36
37
38 Classical method
39 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
40
41 First instantiate a meshing object. Therefore, we need to define :
42
43  * its name
44  * its dimension
45  * its number of cells
46
47 .. note:: All this initialisation is necessary. If one is missing, you'll have a segmentation fault!.
48
49 ::
50
51         mesh = mc.MEDCouplingUMesh.New()
52         mesh.setMeshDimension(3)
53         mesh.allocateCells(...)
54         mesh.setName("3Dcube")
55
56 Definition of nodes coordinates
57 ```````````````````````````````
58
59 Define the coordinates of the nodes of the 3D cube mesh, and then use the setCoords function to set it::
60
61         # Initialisation of coordinates
62         coordinates = []
63         for k in range(N):
64                 for j in range(N):
65                         for i in range(N):
66                                 coordinates.append(...)
67                                 
68         myCoords = mc.DataArrayDouble.New()
69         myCoords.setValues(coordinates,nbOfNodes,3)
70         mesh.setCoords(myCoords)
71         
72
73 Definition of hexahedrons connectivity
74 ``````````````````````````````````````
75 For each hexahedron of the mesh, you have to give its connectivity: the list of the nodes which belong to the hexahedron. The order of the nodes in the connectivity array must respect the MEDCoupling format (see the following figure).
76
77 .. image:: images/cube.jpg
78
79 .. warning:: Connectivity elements begin to 0 from (n-1) elements
80
81 ::
82
83         connectivity = []
84         for k in range(N-1):
85                 for j in range(N-1):
86                         for i in range(N-1):
87                                 inode = ...
88                                 connectivity.append(inode)
89                                 connectivity.append(...)
90
91         # Adding cells in meshing
92         for i in range(nbOfCells):
93                 mesh.insertNextCell(mc.NORM_HEXA8,8,connectivity[8*i:8*(i+1)])
94                 pass
95                 
96         # Check mesh consistency:
97         mesh.checkConsistencyLight()
98         
99 Method by extrusion
100 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
101
102 In order to create a extruded mesh, we need one 2D mesh and one 1D mesh which define the vector of extrusion and the number of steps.
103
104 Definition of 2D mesh
105 ``````````````````````````````````````
106 ::
107
108         coordinates = []
109         for j in range(N):
110                 for i in range(N):
111                         coordinates.append(...)
112                         ...
113         Connectivities = [...]
114         myCoords = mc.DataArrayDouble.New()
115         myCoords.setValues(coordinates,NbNode2D,MeshDim2D)
116
117         m1 = mc.MEDCouplingUMesh.New()
118         m1.setMeshDimension(MeshDim2D)
119         m1.allocateCells(NbCell2D)
120         m1.setCoords(myCoords)
121         m1.setName("2D_Support")
122
123         for i in range(NbCell2D):
124                 m1.insertNextCell(mc.NORM_QUAD4,4,Connectivities[4*i:4*(i+1)])
125         m1.changeSpaceDimension(3)
126
127 Definition of 1D mesh
128 ``````````````````````````````````````
129 ::
130
131         coords = [ ... ]
132         conn   = [ ... ]
133         m2 = mc.MEDCouplingUMesh.New()
134         m2.setMeshDimension(1)
135         m2.allocateCells(3)
136         m2.insertNextCell(mc.NORM_SEG2,2,conn[0:2])
137         m2.insertNextCell(mc.NORM_SEG2,2,conn[2:4])
138         m2.insertNextCell(mc.NORM_SEG2,2,conn[4:6])
139         myCoords1D=mc.DataArrayDouble.New()
140         myCoords1D.setValues(coords,4,1)
141         m2.setCoords(myCoords1D)
142         m2.changeSpaceDimension(3)
143
144 Definition of extruded mesh
145 ``````````````````````````````````````
146
147 Since 1D meshing isn't well oriented (along 0x vector), we need to imply a transformation on it.
148 Then, we can extrude 2D meshing.
149
150 ::
151
152         center = [...]
153         vector = [...]
154         m2.rotate(...)
155         m3 = m1.buildExtrudedMesh(m2,0)
156         m3.setName("Extrusion")
157
158 Grid method
159 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
160
161 it's the easiest way to create a grid since you have no connectivity to set. They will be automatically setting. Incrementation of ids will be made first along Ox axis, then along Oy axis and finally along Oz axis.
162
163 ::
164
165         mesh=mc.MEDCouplingCMesh.New()
166         coordsX=mc.DataArrayDouble.New()
167         arrX=[ ... ]
168         coordsX.setValues(arrX,4,1)
169         coordsY=mc.DataArrayDouble.New()
170         arrY=[ ... ]
171         coordsY.setValues(arrY,4,1)
172         coordsZ=mc.DataArrayDouble.New()
173         arrZ=[ ... ]
174         coordsZ.setValues(arrZ,4,1)
175         mesh.setCoords(coordsX,coordsY,coordsZ)
176
177 Really in order to save this mesh, you need to transform this structured mesh to an unstructerd mesh.
178 ::
179
180         meshU=mesh.buildUnstructured()
181         meshU.setName("Grid")
182
183 Creation of groups
184 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
185
186 A group is a set of cells defining by their id. This set must the input for creating a group.
187 Generally ids cells using in group are known. So you just need put these ids in a DataArray.
188 ::
189
190         tabIdCells = mc.DataArrayInt.New()
191         IdCells = [ ... ]
192         tabIdCells.setValues(IdCells,...)
193
194
195 .. note:: It's also possible to retrieve ids cells from a submesh of the principal mesh.
196
197 ::
198
199         ret,tabIdCells = mesh.areCellsIncludedIn(subMesh,0)
200
201
202 Once the DataArray is created, some initializations have to be done.
203 ::
204
205         # Definition of the name group
206         tabIdCells.setName("meshGroup")
207
208
209 In order to add a group on a mesh, you need to transform your unstructured mesh in a file unstructured mesh.
210 Moreover, we need to define:
211
212  * its name
213  * its description
214  * its coordinates
215  * its dimension
216  * its number of cells
217
218
219 ::
220
221         # Passing MEDCoupling to MEDFile
222         fmeshU = mc.MEDFileUMesh.New()
223         fmeshU.setName("Grid")
224         fmeshU.setDescription("IHopeToConvinceLastMEDMEMUsers")
225         myCoords = meshU.getCoords()
226         fmeshU.setCoords(myCoords)
227         fmeshU.setMeshAtLevel(0,meshU)
228
229 Then, you can 
230 Therefore, you need to define the level (ie. the dimension) of the group.
231 This information is given by a number : 0,-1 or -2.
232
233  * 0 means the same level at mesh
234
235 ::
236
237         fmeshU.setGroupsAtLevel(0,[tabIdCells],False)
238
239 Create field on 3D cube
240 ~~~~~~~~~~~~~~~~~~~~~~~
241
242 First you need to create a CouplingField and initialize some data:
243
244  * its name
245  * its support (ie mesh)
246  * its nature
247  * its values
248
249  
250 The field will be a sin function dependent of distance of the barycenter of each cell from origin. So we need to create a barycenter field on the 3D mesh::
251
252         # Creation of field : with following definition
253         # => Definition of the mesh support
254         # => Definition of field name
255         # => Definition of field nature
256         field = mc.MEDCouplingFieldDouble.New(ON_CELLS)
257         field.setMesh(mesh)
258         field.setName("field")
259         field.setNature(ExtensiveMaximum)
260
261         # Computing and setting field values
262         myCoords=mc.DataArrayDouble.New()
263         sampleTab=[]
264         bar = mesh.computeCellCenterOfMass()
265         print(bar.getNbOfElems())
266         for i in range(nbOfCells):
267                 x = bar.getIJ(...)
268                 y = bar.getIJ(...)
269                 z = bar.getIJ(...)
270                 d = sqrt(x*x+y*y+z*z)
271                 sinus = sin(d)
272         .       sampleTab.append(sinus)
273
274         myCoords.setValues(sampleTab,nbOfCells,1)
275         field.setArray(myCoords)
276
277
278 Saving the mesh in a med file
279 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
280 General Case
281 ````````````
282 ::
283
284         medFileName = "MEDCoupling_Extrudedcube3D.med"
285         mc.WriteUMesh(medFileName,meshU,True)
286
287 .. note:: True / False in Write* functions : True for overwriting existing file and False for adding in existing file 
288
289 Multi mesh Case
290 ````````````````
291
292 In spite of a MEDCoupling mesh has only one dimension, it's possible to generate a file with multi dimension.
293 Therefore, you need to create as meshes as necessary dimensions.
294
295 You have to give the connectivity of the faces on the bottom face of the 3D cube: the list of the nodes which belong to the face.
296 The connectivity must respect following figure:
297
298 .. image:: images/face.jpg
299
300 ::
301
302         # Extraction of surfacic meshing
303         pt=[0.,0.,0.]
304         vec=[0.,0.,1.]
305         nodes = mesh.findNodesOnPlane(pt,vec,1e-12)
306         mesh2D = mesh.buildFacePartOfMySelfNode(nodes,True)
307         #print(mesh2D)
308         mesh2D.setName("3Dcube")
309         mesh2D.checkConsistencyLight()
310         
311         medFileName = "MEDCoupling_cube3D.med"
312         meshes=[mesh2D,mesh]
313         mc.WriteUMeshes(medFileName,meshes,True)
314         
315 Group Case
316 ````````````
317 ::
318
319         medFileName = "MEDCoupling_Gridcube3D.med"
320         fmeshU.write(medFileName,2)
321
322 Saving the fields in the med file
323 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
324
325 ::
326
327         mc.WriteField(medFileName,field,False)
328
329 Visualize the mesh with the SMESH module of Salome
330 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
331
332 Launch Salome platform, then select SMESH module and import your MED file. First You can see the number of elements of your mesh. For that, select your mesh in the object browser, set select Mesh menu and "Advanced Mesh Info" option. Verify the number of faces and the number of hexahedrons. To visualize your mesh: click right bottom on your mesh and select "Show" option. You can also visualize your groups. Select one group, click right bottom on your group and select "Show only" option.
333
334 Visualize the fields with the VISU module of Salome
335 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
336
337 Launch Salome platform, then select VISU module and import your MED file. You can see in the object browser the 2 fields you have created. Then you have to create a scalar map on each field to visualize them.
338
339 .. image:: images/Field_Cube3D.jpg
340
341 Solution
342 ~~~~~~~~
343
344 :ref:`python_testMEDCouplingcube_solution`