Example: Python script for a connecting rod
===========================================
-.. image:: _static/cad_bielle.PNG
+.. image:: _static/cad_bielle.png
:align: center
.. centered::
::
- import os
- import geompy
- import hexablock
- import math
+ import math
- STEP_PATH = os.path.expandvars("$HEXABLOCK_ROOT_DIR/bin/salome/crank.stp")
+ import geompy
+ import hexablock
- #=============================
- # CREATION DOCUMENT
- #=============================
- doc = hexablock.addDocument()
+ doc = hexablock.addDocument("bielle")
- #=============================
- # MODEL CREATION
- #=============================
+ # ------------------------------------- Build 2 cylindrical grids
- # For the connecting rod, two cylindrical grids have to be build and
- # the quadrangles have to be prismed between these wo grids
+ centre_pb = doc.addVertex(0, 0, 0)
+ centre_gb = doc.addVertex(7, 0, 0)
- #=============================
- # PARAMETRES
- #=============================
+ angle_px = math.pi / 3
+ vecteur_px = doc.addVector(math.cos(angle_px), math.sin(angle_px), 0)
+ vecteur_gx = doc.addVector(1, 0, 0)
- R = 0.095168291790720005
+ vecteur_z = doc.addVector(0, 0, 1)
- r_pte = R
- r_pte_t = R/2.0
+ grille_p = doc.makeCylindrical(centre_pb, vecteur_px, vecteur_z, 1, 360, 1, 1, 3, 1, False)
+ grille_g = doc.makeCylindrical(centre_gb, vecteur_gx, vecteur_z, 1, 360, 1, 1, 3, 1, False)
- xpetit = 0.0
- xgrand = 1.35739 + 0.1595
- longueur = (xgrand - xpetit)/2.0
- hauteur = 0.019999999553*2
+ # ------------------------------------- Join the grids
- dr_pte = R
- da_pte = 360
- dl_pte = hauteur
+ quad_p = grille_p.getQuadJK(1, 2, 0)
+ quad_g = grille_g.getQuadJK(1, 1, 0)
+
+ point_p1 = grille_p.getVertexIJK(1, 0, 0)
+ point_p2 = grille_p.getVertexIJK(1, 2, 0)
- nr_pte = 1
- na_pte = 6
- nl_pte = 1
+ point_g1 = grille_g.getVertexIJK(1, 1, 0)
+ point_g2 = grille_g.getVertexIJK(1, 2, 0)
- #=============================
- # Vectors Creation
- #=============================
+ prisme = doc.joinQuad(quad_p, quad_g, point_p1, point_g1,
+ point_p2, point_g2, 3)
- dx = doc.addVector(longueur, 0, 0)
- dy = doc.addVector(0, longueur, 0)
- dz = doc.addVector(0, 0, longueur)
- #=================================================
- # Creation of cylindrical grid centers
- #=================================================
+Go back to :ref:`menu`
+
+.. _recover:
- c_pte = doc.addVertex(xpetit, 0, 0)
- c_grd = doc.addVertex(2*longueur, 0, 0)
- dx_prime = doc.addVectorVertices(c_pte, c_grd)
+Recovering edges and faces from geometry before the association
+===============================================================
+
+::
- #=================================================
- # small cylindrical grid creation
- #=================================================
+ bielle = geompy.ImportSTEP("bielle.stp")
- grille_cyl_pte = doc.makeCylindrical(c_pte, dx, dz, dr_pte, da_pte, dl_pte, nr_pte, na_pte, nl_pte, False)
- #=================================
- # Small cylindrical grid creation
- #=================================
+ sommets = geompy.SubShapeAllSortedCentres(bielle, geompy.ShapeType["VERTEX"])
- grille_cyl_grd = doc.makeTranslation(grille_cyl_pte, dx_prime)
+ sommets_petit = [ 6, 8, 7, 9 ]
+ sommets_grand = [ 10, 12, 11, 13 ]
- #==================================
- # Joining the two cylindrical grids
- #==================================
+ aretes = geompy.SubShapeAllSortedCentres(bielle, geompy.ShapeType["EDGE"])
- mod_x1 = grille_cyl_pte.getVertexIJK(1, 0, 1)
- mod_x2 = grille_cyl_pte.getVertexIJK(1, 1, 0)
- mod_x3 = grille_cyl_pte.getVertexIJK(1, 5, 0)
- mod_x4 = grille_cyl_pte.getVertexIJK(1, 0, 0)
- quad_11 = doc.findQuad(mod_x1, mod_x2)
- quad_12 = doc.findQuad(mod_x1, mod_x3)
+ aretes_petit = [ 7, 9, 8, 10 ]
+ aretes_grand = [ 19, 21, 20, 22 ]
- mod_y1 = grille_cyl_grd.getVertexIJK(1, 3, 1)
- mod_y2 = grille_cyl_grd.getVertexIJK(1, 2, 0)
- mod_y3 = grille_cyl_grd.getVertexIJK(1, 4, 0)
- mod_y4 = grille_cyl_grd.getVertexIJK(1, 3, 0)
+ ga_pbcd = aretes[ 0]
+ ga_pbe = aretes[ 2]
- quad_21 = doc.findQuad(mod_y1, mod_y2)
- quad_22 = doc.findQuad(mod_y1, mod_y3)
+ ga_phcd = aretes[ 1]
+ ga_phe = aretes[ 3]
+
+ ga_gbcd = aretes[27]
+ ga_gbe = aretes[25]
- model_biell_fin = doc.joinQuads([quad_11, quad_12], quad_21, mod_x1, mod_y1, mod_x4, mod_y4, 1)
+ ga_ghcd = aretes[28]
+ ga_ghe = aretes[26]
Go back to :ref:`menu`
-.. _recover:
+.. _assoc:
-Recovering edges and faces before the association
-=================================================
+Association of the model to the geometry
+========================================
::
- bielle_geom = geompy.ImportFile(STEP_PATH, "STEP")
- doc.setShape(bielle_geom)
- geompy.addToStudy(bielle_geom, "bielle_geom")
- all_edges_bielle = geompy.SubShapeAllSorted(bielle_geom, geompy.ShapeType["EDGE"])
+ doc.setShape(bielle)
+ # ---------------------------- Clean implicit associations of the model
+ doc.clearAssociation()
- # dictionnaire des edges de la géométrie :
- # key = nom, value = indice dans all_edges_bielle
- dic_edge_names = {"edge_ray_pte_b": 0, "edge_ray_pte_h": 1,
- "edge_trou_pte_b": 2, "edge_trou_pte_h" :3,
- "edge_arr_pte_g_b": 7, "edge_arr_pte_g_h": 8,
- "edge_arr_pte_d_b": 9, "edge_arr_pte_d_h": 10,
- "edge_arr_grd_g_b": 19, "edge_arr_grd_g_h": 20,
- "edge_arr_grd_d_b": 21, "edge_arr_grd_d_h": 22,
- "edge_trou_grd_b": 25, "edge_trou_grd_h": 26,
- "edge_ray_grd_b": 27, "edge_ray_grd_h": 28,
- "edge_long_g_b": 13, "edge_long_g_h": 14,
- "edge_long_d_b": 15, "edge_long_d_h": 16
- }
+ # -------------------------- Procedure who associates external circles
+ def cercle(grille, k, ge, p):
+ ms = grille.getVertexIJK(0, 0, k)
+ ma1 = grille.getEdgeJ(0, 2, k)
+ ma2 = grille.getEdgeJ(0, 1, k)
+ ma3 = grille.getEdgeJ(0, 0, k)
- all_faces_bielle = geompy.SubShapeAllSorted(bielle_geom, geompy.ShapeType["FACE"])
- # dictionnaire des faces de la geometrie :
- # key = nom, value = indice dans all_faces_bielle
- dic_face_names = {"face_ray_pte": 0, "face_trou_pte": 1, "face_pte_g": 2,
- "face_pte_d": 3, "face_long_g": 4, "face_long_d": 5,
- "face_bas": 6, "face_haut": 7, "face_grd_g": 8,
- "face_grd_d": 9, "face_trou_grd": 10,
- "face_ray_grd": 11
- }
+ doc.associateClosedLine(ms, ma1, [ ma2, ma3 ], ge, p, False, [])
+ cercle(grille_p, 0, ga_pbe, 5.0/6)
+ cercle(grille_p, 1, ga_phe, 5.0/6)
+
+ cercle(grille_g, 0, ga_gbe, 0)
+ cercle(grille_g, 1, ga_ghe, 0)
+ # ------------------- Procedure who associates external decentered lines
+ def arc(grille, i1, i2, k, ge):
+ ma1 = grille.getEdgeJ(1, i1, k)
+ ma2 = grille.getEdgeJ(1, i2, k)
+
+ doc.associateOpenedLine(ma1, [ ma2 ], ge, 0, [], 1)
+ arc(grille_p, 1, 0, 0, ga_pbcd)
+ arc(grille_p, 1, 0, 1, ga_phcd)
-Go back to :ref:`menu`
-
-.. _assoc:
+ arc(grille_g, 0, 2, 0, ga_gbcd)
+ arc(grille_g, 0, 2, 1, ga_ghcd)
-Association of the model to the geometry
-========================================
-::
+ # ---------------------- Associate archs vertices with connection circles
- dico_haut_bas = {"h": 1, "b": 0}
+ hm = prisme.getHexa(1)
+ for i in xrange(0, 4):
+ vm = hm.getVertex(i)
+ ga = sommets[ sommets_petit[i] ]
+ vm.setAssociation(ga)
- # 1. lignes internes (trou) haut/bas du petit cylindre
- # ====================================================
- for z in dico_haut_bas.iteritems():
+ hm = prisme.getHexa(2)
+ for i in xrange(0, 4):
+ vm = hm.getVertex(i)
+ ga = sommets[ sommets_grand[i] ]
+ vm.setAssociation(ga)
- mod_line = [grille_cyl_pte.getEdgeJ(0, j, z[1]) for j in range(5)]
- mod_start = grille_cyl_pte.getEdgeJ(0, 5, z[1])
- mod_first = mod_start.getVertex(1)
+ # ---------------------- Associate connection circles
- # geometrie : 1 seule ligne
- edge_hole_in = all_edges_bielle[dic_edge_names["edge_trou_pte_"+z[0]]]
- geo_start = edge_hole_in
- par_start = 0.0
- geo_line = []
+ hm = prisme.getHexa(0)
+ for i in xrange(0, 4):
+ em = hm.getEdge(i+8)
+ ga = aretes[ aretes_petit[i] ]
+ em.addAssociation(ga, 0, 1)
- # association :
- ier = doc.associateClosedLine(mod_first, mod_start, mod_line,
- geo_start, par_start, geo_line)
-
+ hm = prisme.getHexa(2)
+ for i in xrange(0, 4):
+ em = hm.getEdge(i+8)
+ ga = aretes[ aretes_grand[i] ]
+ em.addAssociation(ga, 0, 1)
- # 2. lignes internes (trou) haut/bas du grand cylindre
- # =====================================================
- for z in dico_haut_bas.iteritems():
-
- mod_start = grille_cyl_grd.getEdgeJ(0, 5, z[1])
- mod_first = mod_start.getVertex(1)
- mod_line = [grille_cyl_grd.getEdgeJ(0, j, z[1]) for j in range (5)]
-
- # geometrie : 1 seule ligne
- edge_hole_in = all_edges_bielle[dic_edge_names["edge_trou_grd_"+z[0]]]
- geo_start = edge_hole_in
- par_start = 0.0
- geo_line = []
-
- # association :
- ier = doc.associateClosedLine(mod_first, mod_start, mod_line,
- geo_start, par_start, geo_line)
-
-
- # 3. lignes externes haut/bas du petit cylindre
- # =============================================
- for z in dico_haut_bas.iteritems():
-
- # modele de blocs :
- mod_start = grille_cyl_pte.getEdgeJ(1, 1, z[1])
- # table des edges :
- mod_line = [grille_cyl_pte.getEdgeJ(1, j, z[1]) for j in [2, 3, 4]]
-
- # geometrie :
- # les edges de la geometrie correspondant sont, dans l'ordre (par
- # exemple pour le haut) :
- # edge_arr_pte_d_h, edge_ray_pte_h, edge_arr_pte_g_h
- geo_start = all_edges_bielle[dic_edge_names["edge_arr_pte_d_"+z[0]]]
-
- geo_line = []
- geo_line.append(all_edges_bielle[dic_edge_names["edge_ray_pte_"+z[0]]])
- geo_line.append(all_edges_bielle[dic_edge_names["edge_arr_pte_g_"+z[0]]])
-
- # association :
- # la première est la dernière ligne sont orientées "dans le
- # mauvais sens" => on fournit cette info :
- par_start = 0.0
- par_end = 1.0
- ier = doc.associateOpenedLine(mod_start, mod_line,
- geo_start, par_start, geo_line, par_end)
-
-
- ## # 4. lignes externes haut/bas du grand cylindre
- ## # =============================================
- for z in dico_haut_bas.iteritems():
-
- # modele de blocs :
- mod_start = grille_cyl_grd.getEdgeJ(1, 4, z[1])
- # table des edges :
- mod_line = [grille_cyl_grd.getEdgeJ(1, j, z[1]) for j in [5, 0, 1]]
-
- # geometrie :
- # les edges de la geometrie correspondant sont, dans l'ordre (par
- # exemple pour le haut) :
- # edge_arr_grd_g_h, edge_ray_grd_h, edge_arr_grd_d_h
- geo_start = all_edges_bielle[dic_edge_names["edge_arr_grd_g_"+z[0]]]
-
- geo_line = []
- geo_line.append(all_edges_bielle[dic_edge_names["edge_ray_grd_"+z[0]]])
- geo_line.append(all_edges_bielle[dic_edge_names["edge_arr_grd_d_"+z[0]]])
-
- # association :
- # la première est la dernière ligne sont orientées "dans le
- # mauvais sens" => on fournit cette info :
- par_start = 0.0
- par_end = 1.0
- ier = doc.associateOpenedLine(mod_start, mod_line,
- geo_start, par_start, geo_line, par_end)
-
- # 6. association des 4 points restants (x1, x4, y1, y4) :
- # =======================================================
-
- # NB:
- # h = top (haut)
- # b = bottom (bas)
- # g = big (grand)
- # p = small (petit)
- # t = hole (trou)
-
- face_haut = all_faces_bielle[dic_face_names["face_haut"]]
-
- edge_haut_droite = geompy.GetEdgesByLength(face_haut, 0.136, 0.137)
- edge_haut_gauche = geompy.GetEdgesByLength(face_haut, 0.131, 0.132)
-
- # 1. grand cylindre :
- y_h_g = geompy.MakeVertexOnSurface(face_haut, 1, 0.5)
- u_h_g = geompy.MakeVertexOnCurve(edge_haut_droite, 1)
- w_h_g = geompy.MakeVertexOnCurve(edge_haut_gauche, 0)
- edge_v_grd = geompy.MakeLineTwoPnt(u_h_g, w_h_g)
-
- geo_y1 = geompy.MakeVertexOnCurve(edge_v_grd, 0.5)
- geo_y4 = geompy.MakeVertexWithRef(geo_y1, 0.0, 0.0, -hauteur)
-
- # vertex cote grande grille cylindrique :
- mod_y1.setAssociation(geo_y1)
- mod_y4.setAssociation(geo_y4)
-
- # 2. petit cylindre :
- # REM : le modele grand cylindre a ete cree par translation / au petit
- # cylindre.
- v_h_p = geompy.MakeVertexOnSurface(face_haut, 0, 0.5)
- x_h_p = geompy.MakeVertexOnCurve(edge_haut_droite, 0)
- z_h_p = geompy.MakeVertexOnCurve(edge_haut_gauche, 1)
- edge_v_pte = geompy.MakeLineTwoPnt(x_h_p, z_h_p)
-
- geo_x1 = geompy.MakeVertexOnCurve(edge_v_pte, 0.5)
- geo_x4 = geompy.MakeVertexWithRef(geo_x1, 0.0, 0.0, -hauteur)
-
- # vertex cote petite grille cylindrique :
- mod_x1.setAssociation(geo_x1)
- mod_x4.setAssociation(geo_x4)
-
- # 7. association des faces :
- quad1 = grille_cyl_pte.getQuadJK(1, 1, 0)
- quad1.addAssociation(all_faces_bielle[dic_face_names["face_pte_d"]])
- quad2 = grille_cyl_pte.getQuadJK(1, 4, 0)
- quad2.addAssociation(all_faces_bielle[dic_face_names["face_pte_g"]])
- quad3 = grille_cyl_grd.getQuadJK(1, 1, 0)
- quad3.addAssociation(all_faces_bielle[dic_face_names["face_grd_d"]])
- quad4 = grille_cyl_grd.getQuadJK(1, 4, 0)
- quad4.addAssociation(all_faces_bielle[dic_face_names["face_grd_g"]])
+ # --------------------- Round implicit cylindrical associations
+ for h, i, ech in [ [0, 0, 0.95], [0, 1, 0.95], [2, 2, 0.85], [2, 3, 0.85] ]:
+ hm = prisme.getHexa(h)
+ em = hm.getEdge(i)
+ va = em.getVertex(0).getAssociation()
+ vb = em.getVertex(1).getAssociation()
+ vax, vay, vaz = geompy.PointCoordinates(va)
+ vbx, vby, vbz = geompy.PointCoordinates(vb)
+ vmx = ( vax + vbx ) / 2.0 * ech
+ vmy = ( vay + vby ) / 2.0
+ vmz = ( vaz + vbz ) / 2.0
+ vm = geompy.MakeVertex(vmx, vmy, vmz)
+ eg = geompy.MakeArc(va, vm, vb)
+ em.clearAssociation()
+ em.addAssociation(eg, 0, 1)
Go back to :ref:`menu`
::
- # We define 3 groups
+ # -------------------------- # Define 5 faces groups
+
+ groupe_petit = doc.addQuadGroup("Petit")
+ groupe_grand = doc.addQuadGroup("Grand")
+ groupe_bas = doc.addQuadGroup("Bas")
+ groupe_haut = doc.addQuadGroup("Haut")
+ groupe_contour = doc.addQuadGroup("Contour")
- # groupe d edges (arretes)
- edge_grp = doc.addEdgeGroup("Edge_grp")
- for i in range(doc.countEdge()):
- edge_grp.addElement(doc.getEdge(i))
+ # -------------------------- Define little and big cylinder groups
- # groupe de quads (faces)
- quad_grp = doc.addQuadGroup("Quad_grp")
- for i in range(doc.countQuad()):
- quad_grp.addElement(doc.getQuad(i))
+ for i in xrange(3):
+ groupe_petit.addElement( grille_p.getQuadJK(0, i, 0) )
+ groupe_grand.addElement( grille_g.getQuadJK(0, i, 0) )
- # groupe d hexas (solids)
- hexa_grp = doc.addHexaGroup("Hexa_grp")
- for i in range(doc.countHexa()):
- hexa_grp.addElement(doc.getHexa(i))
+ # -------------------------- Define bottum and up groups
+
+ for i in xrange(3):
+ groupe_bas.addElement( grille_p.getQuadIJ(0, i, 0) )
+ groupe_bas.addElement( grille_g.getQuadIJ(0, i, 0) )
+
+ groupe_haut.addElement( grille_p.getQuadIJ(0, i, 1) )
+ groupe_haut.addElement( grille_g.getQuadIJ(0, i, 1) )
+
+ for i in xrange(3):
+ h = prisme.getHexa(i)
+
+ groupe_bas.addElement( h.getQuad(2) )
+ groupe_haut.addElement( h.getQuad(3) )
+
+ # -------------------------- Define border group
+
+ for i in xrange(2):
+ groupe_contour.addElement( grille_p.getQuadJK(1, i, 0) )
+
+ for i in [0, 2]:
+ groupe_contour.addElement( grille_g.getQuadJK(1, i, 0) )
+
+ for i in xrange(3):
+ h = prisme.getHexa(i)
+
+ groupe_contour.addElement( h.getQuad(4) )
+ groupe_contour.addElement( h.getQuad(5) )
+
+ # -------------------------- Define 3 groups of volumes
+
+ groupe_petit = doc.addHexaGroup("Petit")
+ groupe_grand = doc.addHexaGroup("Grand")
+ groupe_prisme = doc.addHexaGroup("Prisme")
+
+ for i in xrange(3):
+ groupe_petit.addElement( grille_p.getHexa(i) )
+ groupe_grand.addElement( grille_g.getHexa(i) )
+
+ for i in xrange(3):
+ groupe_prisme.addElement( prisme.getHexa(i) )
- # groupe de noeuds de vertex pour tout le modele
- vertex_nod_grp = doc.addVertexNodeGroup("Vertex_Nod_Grp")
- for i in range(doc.countVertex()):
- vertex_nod_grp.addElement(doc.getVertex(i))
Go back to :ref:`menu`
.. _lawdisc:
-Definition of a law discretization
-==================================
+Definition of a law discretization laws :
+========================================
::
- law = doc.addLaw("Uniform", 4)
+ hexablock.addLaws(doc, 0.003, True)
- for j in range(doc.countPropagation()):
- propa = doc.getPropagation(j)
- propa.setLaw(law) # apply discretization law on the model and generate the mesh
Go back to :ref:`menu`
::
- print " --- HEXAHEDRICAL MESH --- "
- mesh_hexas = hexablock.mesh("Bielle:hexas", doc)
-
- print "Number of hexahedra:", mesh_hexas.NbHexas()
- print "Number of quadrangles:", mesh_hexas.NbQuadrangles()
- print "Number of segments:", mesh_hexas.NbEdges()
- print "Number of nodes:", mesh_hexas.NbNodes()
-
+ blocs = hexablock.mesh(doc)
+ ## .. and show statistics
+ muv, mue, muq, muh = hexablock.dump(doc, blocs)