1 # -*- coding: latin-1 -*-
2 # Copyright (C) 2009-2012 CEA/DEN, EDF R&D
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.
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.
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
18 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
26 STEP_PATH = os.path.expandvars("$HEXABLOCK_ROOT_DIR/bin/salome/crank.stp")
29 #=============================
31 #=============================
33 doc = hexablock.addDocument("bielle")
35 #=============================
37 #=============================
39 # For the connecting rod, two cylindrical grids have to be build and
40 # the quadrangles have to be prismed between these wo grids
42 #=============================
44 #=============================
47 R = 0.095168291790720005
53 xgrand = 1.35739 + 0.1595
54 longueur = (xgrand - xpetit)/2.0
55 hauteur = 0.019999999553*2
66 f_mod_apres = open(os.path.join(os.environ['TMP'],
67 "bielle_model_apres.txt"), 'w')
72 # @todo JPL le 08/07/2011 :
73 # refaire le mod�le de blocs avec des pentagones pour les grilles
74 # cylindriques, et 1 hexaedre reliant ces 2 grilles.
76 #=============================
78 #=============================
80 dx = doc.addVector(longueur, 0, 0)
81 dy = doc.addVector(0, longueur, 0)
82 dz = doc.addVector(0, 0, longueur)
84 #=================================================
85 # Creation of cylindrical grid centers
86 #=================================================
88 c_pte = doc.addVertex(xpetit, 0, 0)
89 c_grd = doc.addVertex(2*longueur, 0, 0)
90 dx_prime = doc.addVectorVertices(c_pte, c_grd)
92 #=================================================
93 # small cylindrical grid creation
94 #=================================================
96 grille_cyl_pte = doc.makeCylindrical(c_pte, dx, dz, dr_pte, da_pte, dl_pte, nr_pte, na_pte, nl_pte, False)
98 #=================================
99 # Small cylindrical grid creation
100 #=================================
102 grille_cyl_grd = doc.makeTranslation(grille_cyl_pte, dx_prime)
105 file_name = os.path.join(os.environ['TMP'], 'bielle0.vtk')
106 doc.saveVtk(file_name)
109 #==================================
110 # Joining the two cylindrical grids
111 #==================================
113 mod_x1 = grille_cyl_pte.getVertexIJK(1, 0, 1)
114 mod_x2 = grille_cyl_pte.getVertexIJK(1, 1, 0)
115 mod_x3 = grille_cyl_pte.getVertexIJK(1, 5, 0)
116 mod_x4 = grille_cyl_pte.getVertexIJK(1, 0, 0)
117 quad_11 = doc.findQuad(mod_x1, mod_x2)
118 quad_12 = doc.findQuad(mod_x1, mod_x3)
120 mod_y1 = grille_cyl_grd.getVertexIJK(1, 3, 1)
121 mod_y2 = grille_cyl_grd.getVertexIJK(1, 2, 0)
122 mod_y3 = grille_cyl_grd.getVertexIJK(1, 4, 0)
123 mod_y4 = grille_cyl_grd.getVertexIJK(1, 3, 0)
125 quad_21 = doc.findQuad(mod_y1, mod_y2)
126 quad_22 = doc.findQuad(mod_y1, mod_y3)
128 model_biell_fin = doc.joinQuads([quad_11, quad_12], quad_21, mod_x1, mod_y1, mod_x4, mod_y4, 1)
131 file_name = os.path.join(os.environ['TMP'], 'bielle1.vtk')
132 doc.saveVtk(file_name)
135 #=======================
136 # CREATION ASSOCIATION
137 #=======================
139 # JPL le 08/07/2011 :
140 # la premi�re solution :
141 # 1. 4 associations par ligne fermee pour les trous
142 # 2. 2 associations par ligne fermee pour les contours
143 # => pose probl�me car les points associ�s par cette m�thode sont
144 # uniform�ment r�partis sur le contour => �a d�pend de la longueur
145 # entre les 2 grilles cylindriques.
146 # REM : a retester apr�s la correction d'Alain pour voir ce que �a
149 # deuxi�me solution :
150 # 1. 4 associations par ligne fermee pour les trous
151 # => pour chaque association, 6 edges du modele <-> 1 ligne de la geometrie
152 # 2. 4 associations par lignes ouvertes pour les contours externes des
153 # grilles cylindriques
154 # => pour chaque association, 4 edges du modele <-> 3 lignes de la geometrie
155 # 3. 4 associations de points restants (mod_x1, mod_x4, mod_y1, mod_y4)
157 # => cette solution pose probl�me (� cause de l'association par ligne
160 bielle_geom = geompy.ImportFile(STEP_PATH, "STEP")
161 doc.setShape(bielle_geom)
162 geompy.addToStudy(bielle_geom, "bielle_geom")
163 all_edges_bielle = geompy.SubShapeAllSorted(bielle_geom, geompy.ShapeType["EDGE"])
167 # dictionnaire des edges de la g�om�trie :
168 # key = nom, value = indice dans all_edges_bielle
169 dic_edge_names = {"edge_ray_pte_b": 0, "edge_ray_pte_h": 1,
170 "edge_trou_pte_b": 2, "edge_trou_pte_h" :3,
171 "edge_arr_pte_g_b": 7, "edge_arr_pte_g_h": 8,
172 "edge_arr_pte_d_b": 9, "edge_arr_pte_d_h": 10,
173 "edge_arr_grd_g_b": 19, "edge_arr_grd_g_h": 20,
174 "edge_arr_grd_d_b": 21, "edge_arr_grd_d_h": 22,
175 "edge_trou_grd_b": 25, "edge_trou_grd_h": 26,
176 "edge_ray_grd_b": 27, "edge_ray_grd_h": 28,
177 "edge_long_g_b": 13, "edge_long_g_h": 14,
178 "edge_long_d_b": 15, "edge_long_d_h": 16
182 all_faces_bielle = geompy.SubShapeAllSorted(bielle_geom, geompy.ShapeType["FACE"])
183 # dictionnaire des faces de la geometrie :
184 # key = nom, value = indice dans all_faces_bielle
185 dic_face_names = {"face_ray_pte": 0, "face_trou_pte": 1, "face_pte_g": 2,
186 "face_pte_d": 3, "face_long_g": 4, "face_long_d": 5,
187 "face_bas": 6, "face_haut": 7, "face_grd_g": 8,
188 "face_grd_d": 9, "face_trou_grd": 10,
193 # la clef correspond a la geometrie, la valeur a l'indice en z dans le
194 # modele de bloc (grille cylindrique)
195 # NOTE : les dictionnaires ordonn�s ne sont pas encore introduits dans
196 # la version 2.6.6 de python (Salome 6.2). On ne connait donc pas
197 # l'ordre de bouclage (haut/bas ou bas/haut) mais �a n'a pas
199 dico_haut_bas = {"h": 1, "b": 0}
201 # 1. lignes internes (trou) haut/bas du petit cylindre
202 # ====================================================
203 for z in dico_haut_bas.iteritems():
205 # REM : la direction de la ligne geometrique est dans le sens anti-trigonometrique
206 # => on parcourt le modele en sens inverse
208 ## # modele de blocs :
209 ## mod_start = grille_cyl_pte.getEdgeJ(0, 5, z[1])
210 ## mod_first = mod_start.getVertex(1)
211 ## # table des edges :
212 ## mod_line = [grille_cyl_pte.getEdgeJ(0, j, z[1]) for j in range(4, -1, -1)]
215 mod_start = grille_cyl_pte.getEdgeJ(0, 0, z[1])
216 mod_first = mod_start.getVertex(0)
218 mod_line = [grille_cyl_pte.getEdgeJ(0, j, z[1]) for j in range(1, 6)]
221 # geometrie : 1 seule ligne
222 edge_hole_in = all_edges_bielle[dic_edge_names["edge_trou_pte_"+z[0]]]
223 geo_start = edge_hole_in
228 ier = doc.associateClosedLine(mod_first, mod_start, mod_line,
229 geo_start, par_start, geo_line)
232 # 2. lignes internes (trou) haut/bas du grand cylindre
233 # =====================================================
234 for z in dico_haut_bas.iteritems():
236 # REM : la direction de la ligne geometrique est dans le sens anti-trigonometrique
237 # => on parcourt le modele en sens inverse
239 ## # modele de blocs :
240 ## mod_start = grille_cyl_grd.getEdgeJ(0, 5, z[1])
241 ## mod_first = mod_start.getVertex(1)
242 ## # table des edges :
243 ## mod_line = [grille_cyl_grd.getEdgeJ(0, j, z[1]) for j in range(4, -1, -1)]
245 mod_start = grille_cyl_grd.getEdgeJ(0, 0, z[1])
246 mod_first = mod_start.getVertex(1)
248 mod_line = [grille_cyl_grd.getEdgeJ(0, j, z[1]) for j in range(1, 6)]
250 # geometrie : 1 seule ligne
251 edge_hole_in = all_edges_bielle[dic_edge_names["edge_trou_grd_"+z[0]]]
252 geo_start = edge_hole_in
257 ier = doc.associateClosedLine(mod_first, mod_start, mod_line,
258 geo_start, par_start, geo_line)
261 # 3. lignes externes haut/bas du petit cylindre
262 # =============================================
263 for z in dico_haut_bas.iteritems():
265 # JPL le 08/07/2011 : on utilise ici l'association par ligne
266 # ouverte. Avec le nouvelle version, les points sont r�partis de
267 # mani�re �quidistance sur la ligne geometrique form�e par la
268 # concat�nation des lignes fournies en entr�e.
271 mod_start = grille_cyl_pte.getEdgeJ(1, 1, z[1])
273 mod_line = [grille_cyl_pte.getEdgeJ(1, j, z[1]) for j in [2, 3, 4]]
276 # les edges de la geometrie correspondant sont, dans l'ordre (par
277 # exemple pour le haut) :
278 # edge_arr_pte_d_h, edge_ray_pte_h, edge_arr_pte_g_h
279 geo_start = all_edges_bielle[dic_edge_names["edge_arr_pte_d_"+z[0]]]
282 geo_line.append(all_edges_bielle[dic_edge_names["edge_ray_pte_"+z[0]]])
283 geo_line.append(all_edges_bielle[dic_edge_names["edge_arr_pte_g_"+z[0]]])
286 # la premi�re est la derni�re ligne sont orient�es "dans le
287 # mauvais sens" => on fournit cette info :
290 ier = doc.associateOpenedLine(mod_start, mod_line,
291 geo_start, par_start, geo_line, par_end)
294 ## # 4. lignes externes haut/bas du grand cylindre
295 ## # =============================================
296 for z in dico_haut_bas.iteritems():
298 # JPL le 08/07/2011 : on utilise ici l'association par ligne
299 # ouverte. Avec le nouvelle version, les points sont r�partis de
300 # mani�re �quidistance sur la ligne geometrique form�e par la
301 # concat�nation des lignes fournies en entr�e.
304 mod_start = grille_cyl_grd.getEdgeJ(1, 4, z[1])
306 mod_line = [grille_cyl_grd.getEdgeJ(1, j, z[1]) for j in [5, 0, 1]]
309 # les edges de la geometrie correspondant sont, dans l'ordre (par
310 # exemple pour le haut) :
311 # edge_arr_grd_g_h, edge_ray_grd_h, edge_arr_grd_d_h
312 geo_start = all_edges_bielle[dic_edge_names["edge_arr_grd_g_"+z[0]]]
315 geo_line.append(all_edges_bielle[dic_edge_names["edge_ray_grd_"+z[0]]])
316 geo_line.append(all_edges_bielle[dic_edge_names["edge_arr_grd_d_"+z[0]]])
319 # la premi�re est la derni�re ligne sont orient�es "dans le
320 # mauvais sens" => on fournit cette info :
323 ier = doc.associateOpenedLine(mod_start, mod_line,
324 geo_start, par_start, geo_line, par_end)
326 # JPL le 26/07/2011 :
327 # l'association des edges n'est pas necessaire (implicite)
329 # 6. association des 4 points restants (x1, x4, y1, y4) :
330 # =======================================================
339 # JPL le 08/07/2011 :
340 # seuls 4 points de la geometrie sont n�cessaires (pour l'association
341 # vertex/point : pour le reste on utilise l'association par lignes) :
342 # dictionnaire geom_vertices
343 # il s'agit de points des grilles cylindriques, � l'int�rieur
344 # de la bielle, ayant servis au joinQuads (ie: mod_x1, mod_x4, mod_y1, mod_y4)
347 ## pt_a = geompy.MakeVertex(0, 0, hauteur/2.)
348 ## face_haut = geompy.GetFaceNearPoint(bielle_geom, pt_a)
349 ## pt_b = geompy.MakeVertex(0, 0, -hauteur/2.)
350 ## face_bas = geompy.GetFaceNearPoint(bielle_geom, pt_b)
352 face_haut = all_faces_bielle[dic_face_names["face_haut"]]
354 edge_haut_droite = geompy.GetEdgesByLength(face_haut, 0.136, 0.137)
355 edge_haut_gauche = geompy.GetEdgesByLength(face_haut, 0.131, 0.132)
357 # 1. grand cylindre :
358 y_h_g = geompy.MakeVertexOnSurface(face_haut, 1, 0.5)
359 u_h_g = geompy.MakeVertexOnCurve(edge_haut_droite, 1)
360 w_h_g = geompy.MakeVertexOnCurve(edge_haut_gauche, 0)
361 edge_v_grd = geompy.MakeLineTwoPnt(u_h_g, w_h_g)
363 geo_y1 = geompy.MakeVertexOnCurve(edge_v_grd, 0.5)
364 geo_y4 = geompy.MakeVertexWithRef(geo_y1, 0.0, 0.0, -hauteur)
366 # vertex cote grande grille cylindrique :
367 mod_y1.setAssociation(geo_y1)
368 mod_y4.setAssociation(geo_y4)
370 # 2. petit cylindre :
371 # REM : le modele grand cylindre a ete cree par translation / au petit
373 v_h_p = geompy.MakeVertexOnSurface(face_haut, 0, 0.5)
374 x_h_p = geompy.MakeVertexOnCurve(edge_haut_droite, 0)
375 z_h_p = geompy.MakeVertexOnCurve(edge_haut_gauche, 1)
376 edge_v_pte = geompy.MakeLineTwoPnt(x_h_p, z_h_p)
378 geo_x1 = geompy.MakeVertexOnCurve(edge_v_pte, 0.5)
379 geo_x4 = geompy.MakeVertexWithRef(geo_x1, 0.0, 0.0, -hauteur)
381 # vertex cote petite grille cylindrique :
382 mod_x1.setAssociation(geo_x1)
383 mod_x4.setAssociation(geo_x4)
385 # 7. association des faces :
386 # REM : l'association des faces internes ne semble pas necessaire (cylindres)
387 # pas d'association des face_ray_XXX : pas necessaire ? De toute
388 # fa�on, on a pour chaque 2 quads du mod�le...
389 # les associations de face_haut, face_bas, face_long_g et face_long_d
390 # ne sont pas necessaires ?
392 # a decommenter donc si necessaire :
393 ## quad1 = grille_cyl_pte.getQuadJK(1, 1, 0)
394 ## quad1.addAssociation(all_faces_bielle[dic_face_names["face_pte_d"]])
395 ## quad2 = grille_cyl_pte.getQuadJK(1, 4, 0)
396 ## quad2.addAssociation(all_faces_bielle[dic_face_names["face_pte_g"]])
397 ## quad3 = grille_cyl_grd.getQuadJK(1, 1, 0)
398 ## quad3.addAssociation(all_faces_bielle[dic_face_names["face_grd_d"]])
399 ## quad4 = grille_cyl_grd.getQuadJK(1, 4, 0)
400 ## quad4.addAssociation(all_faces_bielle[dic_face_names["face_grd_g"]])
403 #############################################################################################
404 #############################################################################################
407 file_name = os.path.join(os.environ['TMP'], 'bielle2.vtk')
408 doc.saveVtk(file_name)
410 # affichage des points des 2 grilles cylindriques avec les
411 # nouvelles coordonn�es (apres association)
414 # petite grille cylindrique
417 vertex = grille_cyl_pte.getVertexIJK(i, j, k)
418 value = " ".join(["i =", str(i), "j =", str(j),
419 str(vertex.getX()), str(vertex.getY()), str(vertex.getZ()), '\n'])
420 f_mod_apres.write(str(value))
423 f_mod_apres.write("stop\n")
426 # on n'inclut pas les vertex associ�s individuellement (qui ne
427 # changent pas de coordonn�es...) : => j = 1 -> 5
428 for j in range(1, 6):
429 vertex = grille_cyl_pte.getVertexIJK(i, j, k)
430 value = " ".join(["i =", str(i), "j =", str(j),
431 str(vertex.getX()), str(vertex.getY()), str(vertex.getZ()), '\n'])
432 f_mod_apres.write(str(value))
435 f_mod_apres.write("stop\n")
437 # grande grille cylindrique
440 vertex = grille_cyl_grd.getVertexIJK(i, j, k)
441 value = " ".join(["i =", str(i), "j =", str(j),
442 str(vertex.getX()), str(vertex.getY()), str(vertex.getZ()), '\n'])
443 f_mod_apres.write(str(value))
446 f_mod_apres.write("stop\n")
449 # on n'inclut pas les vertex associ�s individuellement (qui ne
450 # changent pas de coordonn�es...) (j = 3)
451 # on ecrit les points dans le meme ordre que l'association :
452 for j in [4, 5, 0, 1, 2]:
453 vertex = grille_cyl_grd.getVertexIJK(i, j, k)
454 value = " ".join(["i =", str(i), "j =", str(j),
455 str(vertex.getX()), str(vertex.getY()), str(vertex.getZ()), '\n'])
456 f_mod_apres.write(str(value))
460 f_mod_apres.write("stop\n")
462 #############################################################################################
463 #############################################################################################
466 ## #=================================================
467 ## # VERTEX, EDGES, FACES DANS L'ARBRE D'ETUDE SALOME
468 ## #=================================================
471 geompy.addToStudy(geo_x1, 'vertex_x1')
472 geompy.addToStudy(geo_x4, 'vertex_x4')
473 geompy.addToStudy(geo_y1, 'vertex_y1')
474 geompy.addToStudy(geo_y4, 'vertex_y4')
477 for key, value in dic_edge_names.iteritems():
478 geompy.addToStudy(all_edges_bielle[value], key)
480 # faces (juste pour les tests) :
481 for i, face in enumerate(all_faces_bielle):
482 geompy.addToStudy(face, "face_"+str(i))
484 #====================================
486 #====================================
489 #=================================================
490 # Definir les groupes d elements pour le maillage
491 #=================================================
493 # On definit 3 groupes de mailles
495 # JPL (le 09/05/2011) :
496 # @todo a revoir : apres correction des bugs "countXXX()" dans le moteur
498 # groupe d edges (arretes)
499 edge_grp = doc.addEdgeGroup("Edge_grp")
500 for i in range(doc.countEdge()):
501 edge_grp.addElement(doc.getEdge(i))
503 # groupe de quads (faces)
504 quad_grp = doc.addQuadGroup("Quad_grp")
505 for i in range(doc.countQuad()):
506 quad_grp.addElement(doc.getQuad(i))
508 # groupe d hexas (solids)
509 hexa_grp = doc.addHexaGroup("Hexa_grp")
510 for i in range(doc.countHexa()):
511 hexa_grp.addElement(doc.getHexa(i))
513 # groupe de noeuds de vertex pour tout le modele
514 vertex_nod_grp = doc.addVertexNodeGroup("Vertex_Nod_Grp")
515 for i in range(doc.countVertex()):
516 vertex_nod_grp.addElement(doc.getVertex(i))
518 #====================================
519 # Definir une loi de discretisation
520 #====================================
521 # definir une loi: le choix de la loi reste aux utilisateurs
522 law = doc.addLaw("Uniform", 4)
524 # TEST : pour avoir le mod�le de blocs :
525 ## law = doc.addLaw("Uniform", 0)
527 # chercher les propagations du modele
528 for j in range(doc.countPropagation()):
529 propa = doc.getPropagation(j)
530 propa.setLaw(law) # appliquer la loi de discretisation sur tout le modele et generer le maillage
532 #====================================
533 # G�n�rer des maillages
534 #====================================
536 print " --- MAILLAGE HEXAHEDRIQUE --- "
537 mesh_hexas = hexablock.mesh(doc)
539 print "Nombre d hexaedres:", mesh_hexas.NbHexas()
540 print "Nombre de quadrangles:", mesh_hexas.NbQuadrangles()
541 print "Nombre de segments:", mesh_hexas.NbEdges()
542 print "Nombre de noeuds:", mesh_hexas.NbNodes()