4 // Copyright (C) 2009-2012 CEA/DEN, EDF R&D
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 #include "HexElements.hxx"
24 #include "HexDocument.hxx"
25 #include "HexVector.hxx"
26 #include "HexVertex.hxx"
27 #include "HexHexa.hxx"
28 #include "HexEdge.hxx"
29 #include "HexGlobale.hxx"
38 // ====================================================== Constructeur
39 Elements::Elements (Document* doc) : EltBase (doc)
41 glob = Globale::getInstance ();
44 size_qx = size_ex = size_vx = size_hx = 0;
45 size_qy = size_ey = size_vy = size_hy = 0;
46 size_qz = size_ez = size_vz = size_hz = 0;
47 size_qvplus = size_qhplus = size_ehplus = size_evplus = size_hplus = 0;
49 nbr_hexas = nbr_quads = nbr_edges = nbr_vertex = 0;
54 cyl_dispo = CYL_NOFILL;
58 // ====================================================== Constructeur
59 Elements::Elements (Document* doc, int nx, int ny, int nz) : EltBase (doc)
61 glob = Globale::getInstance ();
64 size_qx = size_ex = size_vx = size_hx = 0;
65 size_qy = size_ey = size_vy = size_hy = 0;
66 size_qz = size_ez = size_vz = size_hz = 0;
67 size_qvplus = size_qhplus = size_ehplus = size_evplus = size_hplus = 0;
69 nbr_hexas = nbr_quads = nbr_edges = nbr_vertex = 0;
72 cyl_dispo = CYL_NOFILL;
74 resize (GR_CYLINDRIC, nx, ny, nz);
77 // ====================================================== Constructeur (clonage)
78 Elements::Elements (Elements* orig) : EltBase (orig->el_root)
80 glob = Globale::getInstance ();
82 grid_type = orig->grid_type;
83 cyl_closed = orig->cyl_closed;
84 cyl_fill = orig->cyl_fill;
85 cyl_dispo = orig->cyl_dispo;
87 size_qx = size_ex = size_vx = size_hx = 0;
88 size_qy = size_ey = size_vy = size_hy = 0;
89 size_qz = size_ez = size_vz = size_hz = 0;
90 size_qvplus = size_qhplus = size_ehplus = size_evplus = size_hplus = 0;
91 nbr_hexas = nbr_quads = nbr_edges = nbr_vertex = 0;
93 resize (orig->grid_type, orig->size_hx, orig->size_hy, orig->size_hz);
94 cyl_closed = orig->cyl_closed;
96 // ====================================================== resize
97 void Elements::resize (EnumGrid type, int nx, int ny, int nz, int nplus)
108 size_hx = std::max (nx, 1);
109 size_hy = std::max (ny, 1);
110 size_hz = std::max (nz, 1);
112 size_qx = size_ex = size_vx = size_hx + 1;
113 size_qy = size_ey = size_vy = size_hy + 1;
114 size_qz = size_ez = size_vz = size_hz + 1;
116 nbr_hexas = size_hx * size_hy * size_hz;
117 nbr_quads = size_qx * size_qy * size_qz * DIM3;
118 nbr_edges = size_ex * size_ey * size_ez * DIM3;
119 nbr_vertex = size_vx * size_vy * size_vz;
123 size_qx = size_ex = size_vx = size_hx = 0;
124 size_qy = size_ey = size_vy = size_hy = 0;
125 size_qz = size_ez = size_vz = size_hz = 0;
126 nbr_quads = nbr_edges = nbr_vertex = 0;
127 gr_rayon = std::max (nx, 1);
129 nbr_hexas = 1 + gr_rayon*HQ_MAXI;
131 ker_vertex = nbr_vertex;
135 nbr_orig = std::max (nx, 1);
136 gr_hauteur = std::max (ny, 1);
139 size_hz = gr_hauteur;
141 nbr_hexas = nbr_orig * gr_hauteur;
142 nbr_vertex = nbr_hexas * QUAD4;
143 nbr_vertex = nbr_orig * (gr_hauteur+1)*QUAD4;
144 nbr_quads = nbr_vertex;
145 nbr_edges = 2*nbr_vertex;
149 nbr_orig = std::max (nx, 1); // nb quads du pattern
150 gr_hauteur = ny + 1; // Hauteur des hexas
151 pat_nbvertex = std::max (nz, 1); // nb vertex du pattern
152 pat_nbedges = std::max (nplus, 1); // nb edges du pattern
155 size_hz = gr_hauteur;
157 nbr_hexas = nbr_orig * gr_hauteur;
158 nbr_vertex = pat_nbvertex * (gr_hauteur+1);
159 nbr_edges = pat_nbedges * (gr_hauteur+1) + pat_nbvertex*gr_hauteur;
160 nbr_quads = nbr_orig * (gr_hauteur+1) + pat_nbedges *gr_hauteur;
169 size_qx = size_ex = size_vx = size_hx + 1;
170 size_qy = size_ey = size_vy = size_hy + 1;
171 size_qz = size_ez = size_vz = size_hz + 1;
173 nbr_hexas = size_hx * size_hy * size_hz;
174 nbr_quads = size_qx * size_qy * size_qz * DIM3;
175 nbr_edges = size_ex * size_ey * size_ez * DIM3;
176 nbr_vertex = size_vx * size_vy * size_vz;
180 tab_hexa .resize (nbr_hexas);
181 tab_quad .resize (nbr_quads);
182 tab_edge .resize (nbr_edges);
183 tab_vertex.resize (nbr_vertex);
185 ker_vertex = nbr_vertex;
187 for (int nc=0 ; nc< nbr_hexas ; nc++) tab_hexa [nc] = NULL;
188 for (int nc=0 ; nc< nbr_quads ; nc++) tab_quad [nc] = NULL;
189 for (int nc=0 ; nc< nbr_edges ; nc++) tab_edge [nc] = NULL;
190 for (int nc=0 ; nc< nbr_vertex ; nc++) tab_vertex [nc] = NULL;
193 // ====================================================== makeCartesianGrid
194 int Elements::makeCartesianGrid (Vertex* orig, Vector* v1, Vector* v2,
195 Vector* v3, int px, int py, int pz, int mx, int my, int mz)
197 if (BadElement (orig) || BadElement(v1) || BadElement(v2) || BadElement(v3)
198 || px<=0 || py<=0 || pz <= 0
199 || v1->getNorm () <= Epsil || v2->getNorm () <= Epsil
200 || v3->getNorm () <= Epsil)
206 resize (GR_CARTESIAN, px+mx, py+my, pz+mz);
208 makeCartesianNodes (orig, v1, v2, v3, px, py, pz, mx, my, mz);
213 // ====================================================== makeCylindricalGrid
214 int Elements::makeCylindricalGrid (Vertex* c, Vector* b, Vector* h,
215 double dr, double da, double dl, int nr, int na, int nl, bool fill)
217 if (BadElement (c) || BadElement(b) || BadElement(h)
218 || nr<=0 || na<=0 || nl <= 0 || dr < Epsil || da < Epsil || dl < Epsil
219 || b->getNorm () <= Epsil || h->getNorm () <= Epsil)
224 resize (GR_CYLINDRIC, nr, na, nl);
225 cyl_closed = da >= 360.0;
226 makeCylindricalNodes (c, b, h, dr, da, dl, nr, na, nl, fill);
228 assoCylinder (c, h, da);
231 // ====================================================== makeSphericalGrid
232 int Elements::makeSphericalGrid (Vertex* c, Vector* dv, int nb, double k)
234 if (BadElement (c) || BadElement(dv)
235 || nb<=0 || k < Epsil
236 || dv->getDx()<=Epsil || dv->getDy()<=Epsil || dv->getDz()<=Epsil)
242 resize (GR_SPHERIC, nb);
244 Vertex* i_node [HV_MAXI]; // Les noeuds de l'hexa englobant
245 Edge* i_edge [HE_MAXI]; // Les noeuds de l'hexa englobant
246 Quad* i_quad [HQ_MAXI]; // Les noeuds de l'hexa englobant
248 for (int nro=0 ; nro<HV_MAXI; nro++)
250 double dx = glob->CoordVertex (nro, dir_x) * dv->getDx();
251 double dy = glob->CoordVertex (nro, dir_y) * dv->getDy();
252 double dz = glob->CoordVertex (nro, dir_z) * dv->getDz();
254 i_node [nro] = el_root->addVertex (c->getX ()+dx, c->getY ()+dy,
258 for (int nro=0 ; nro<HE_MAXI; nro++)
260 int v1 = glob->EdgeVertex (nro, V_AMONT);
261 int v2 = glob->EdgeVertex (nro, V_AVAL);
262 i_edge[nro] = newEdge (i_node[v1], i_node[v2]);
266 char nm0[8], nm1 [8], nm2 [8];
267 printf (" %2d : %s = %s = [%s, %s] = [%d,%d] = [%s,%s]\n", nro,
268 glob->namofHexaEdge(nro), i_edge[nro]->getName(nm0),
269 glob->namofHexaVertex(v1), glob->namofHexaVertex(v2), v1, v2,
270 i_node[v1]->getName(nm1), i_node[v2]->getName(nm2));
274 for (int nro=0 ; nro<HQ_MAXI; nro++)
275 i_quad[nro] = newQuad (i_edge[glob->QuadEdge (nro, E_A)],
276 i_edge[glob->QuadEdge (nro, E_B)],
277 i_edge[glob->QuadEdge (nro, E_C)],
278 i_edge[glob->QuadEdge (nro, E_D)]);
280 tab_hexa.push_back (newHexa (i_quad[Q_A], i_quad[Q_B], i_quad[Q_C],
281 i_quad[Q_D], i_quad[Q_E], i_quad[Q_F]));
284 for (int niv=0; niv<gr_rayon ; niv++)
286 double lambda0 = lambda;
289 addStrate (i_quad, i_edge, i_node, c, lambda/lambda0);
294 // ====================================================== addStrate
295 int Elements::addStrate (Quad* i_quad[], Edge* i_edge[], Vertex* i_node[],
296 Vertex* center, double lambda)
298 Vertex* e_node [HV_MAXI]; // Les noeuds de l'hexa englobant
299 Edge* e_edge [HE_MAXI]; // Les noeuds de l'hexa englobant
300 Quad* e_quad [HQ_MAXI]; // Les noeuds de l'hexa englobant
302 Edge* d_edge [HV_MAXI]; // Les aretes diagonales (1 par sommet)
303 Quad* d_quad [HE_MAXI]; // Les faces diagonales (1 par arete)
306 // + les aretes diagonales
307 for (int nv=0 ; nv<HV_MAXI ; nv++)
309 double px0 = center->getX ();
310 double py0 = center->getY ();
311 double pz0 = center->getZ ();
312 e_node[nv] = el_root->addVertex (px0+lambda*(i_node[nv]->getX()-px0),
313 py0+lambda*(i_node[nv]->getY()-py0),
314 pz0+lambda*(i_node[nv]->getZ()-pz0));
316 d_edge[nv] = newEdge (i_node[nv], e_node[nv]);
318 // Les aretes exterieures
319 // + les faces diagonales
320 for (int nro=0 ; nro<HE_MAXI ; nro++)
322 int nv0 = glob->EdgeVertex (nro, V_AMONT);
323 int nv1 = glob->EdgeVertex (nro, V_AVAL );
324 e_edge[nro] = newEdge (e_node [nv0], e_node [nv1]);
325 d_quad[nro] = newQuad (i_edge [nro], d_edge [nv0],
326 e_edge [nro], d_edge [nv1]);
328 // Les faces exterieures
331 for (int nro=0 ; nro<HQ_MAXI ; nro++)
333 int ne0 = glob->QuadEdge (nro, E_A);
334 int ne1 = glob->QuadEdge (nro, E_B);
335 int ne2 = glob->QuadEdge (nro, E_C);
336 int ne3 = glob->QuadEdge (nro, E_D);
338 e_quad[nro] = newQuad (e_edge[ne0], e_edge[ne1],
339 e_edge[ne2], e_edge[ne3]);
340 strate = newHexa (i_quad[nro], e_quad[nro], d_quad[ne0],
341 d_quad[ne2], d_quad[ne1], d_quad[ne3]);
342 tab_hexa.push_back (strate);
345 for (int nv=0 ; nv<HV_MAXI ; nv++) i_node [nv] = e_node [nv];
346 for (int ns=0 ; ns<HE_MAXI ; ns++) i_edge [ns] = e_edge [ns];
347 for (int nq=0 ; nq<HQ_MAXI ; nq++) i_quad [nq] = e_quad [nq];
351 // ====================================================== saveVtk
352 int Elements::saveVtk (cpchar nomfic)
354 // -- 1) Raz numerotation precedente
355 for (int nro=0 ; nro<nbr_hexas ; nro++)
357 Hexa* cell = tab_hexa[nro];
358 if (cell!=NULL && cell->isHere())
365 for (int nro=0 ; nro<nbr_hexas ; nro++)
367 Hexa* cell = tab_hexa[nro];
368 if (cell!=NULL && cell->isHere())
371 nbnodes += cell->countNodes ();
375 pfile vtk = fopen (nomfic, "w");
376 fprintf (vtk, "# vtk DataFile Version 3.1\n");
377 fprintf (vtk, "%s \n", nomfic);
378 fprintf (vtk, "ASCII\n");
379 fprintf (vtk, "DATASET UNSTRUCTURED_GRID\n");
380 fprintf (vtk, "POINTS %d float\n", nbnodes);
384 for (int nro=0 ; nro<nbr_hexas ; nro++)
386 Hexa* cell = tab_hexa[nro];
387 if (cell!=NULL && cell->isHere())
388 cell->printNodes (vtk, nronode);
392 fprintf (vtk, "CELLS %d %d\n", nbcells, nbcells*(HV_MAXI+1));
394 for (int nro=0 ; nro<nbr_hexas ; nro++)
396 Hexa* cell = tab_hexa[nro];
397 if (cell!=NULL && cell->isHere())
398 cell->printHexa (vtk);
401 fprintf (vtk, "CELL_TYPES %d\n", nbcells);
402 for (int nro=0 ; nro<nbcells ; nro++)
403 fprintf (vtk, "%d\n", HE_MAXI);
408 // ============ = = = = = = = = = Vertices ..........
409 // ====================================================== newEdge
410 Edge* Elements::newEdge (Vertex* v1, Vertex* v2)
412 if (v1==NULL || v2==NULL)
415 Edge* elt = new Edge (v1, v2);
418 // ====================================================== newQuad
419 Quad* Elements::newQuad (Edge* e1, Edge* e2, Edge* e3, Edge* e4)
421 if (e1==NULL || e2==NULL || e3==NULL|| e4==NULL)
424 Quad* elt = new Quad (e1, e2, e3, e4);
427 // ====================================================== newHexa
428 Hexa* Elements::newHexa (Quad* qa, Quad* qb, Quad* qc, Quad* qd,
431 if (qa==NULL || qb==NULL || qc==NULL|| qd==NULL || qe==NULL|| qf==NULL)
434 Hexa* elt = new Hexa (qa, qb, qc, qd, qe, qf);
437 // ====================================================== joinQuads
438 int Elements::joinQuads (Quads& orig, int nb, Vertex* v1, Vertex* v2,
439 Vertex* v3, Vertex* v4, Quad* cible)
441 resize (GR_JOINT, orig.size(), nb);
443 el_root->markAll (IS_NONE);
445 // db = el_root->debug ();
448 nbr_orig = orig.size();
450 for (int nro=0 ; nro<nbr_orig ; nro++)
452 Quad* face = orig[nro];
456 printf (" *** joinQuads : donnees incorrectes\n");
457 printf (" *** le %deme quadrangle de depart est NULL\n", nro);
461 else if (face->getNbrParents()>1)
464 printf (" *** joinQuads : donnees incorrectes\n");
465 printf (" *** le %deme quadrangle de depart n'est pas une "
466 "face externe\n", nro);
471 orig [nro]->setMark (nro);
472 tab_orig.push_back (orig[nro]);
475 Edge* e_orig = tab_orig[0] -> findEdge (v1, v3);
476 Edge* e_dest = cible -> findEdge (v2, v4);
481 printf (" *** joinQuads : donnees incorrectes\n");
482 printf (" *** Les vertex v1 et v3 passes en argument ne definissent\n");
483 printf (" *** pas une arete du 1er quadrangle de depart\n");
493 printf (" *** joinQuads : donnees incorrectes\n");
494 printf (" *** Les vertex v2 et v4 passes en argument ne definissent\n");
495 printf (" *** pas une arete du quadrangle cible\n");
502 if (e_orig==NULL || e_dest==NULL)
508 StrOrient orient (v1, v3, v2, v4);
509 int ier = this ->coupler (0, cible, &orient);
515 ier = orig[0]->coupler (cible, &orient, this);
518 // ======================================================== coupler
519 int Elements::coupler (int nquad, Quad* dest, StrOrient* orient)
521 Quad* orig = tab_orig [nquad];
523 setQuad (orig, dir_z, 0, 0, 0);
524 setQuad (dest, dir_z, nquad, 0, 0);
526 int n11 = orig->indexVertex (orient->v11);
527 int n12 = orig->indexVertex (orient->v12);
528 int n21 = dest->indexVertex (orient->v21);
529 int n22 = dest->indexVertex (orient->v22);
531 // ---------------- Les 4 sommets initiaux
532 Vertex* vorig[QUAD4] = { orient->v11, orient->v12,
533 orig->getVertex((n11+2) MODULO QUAD4),
534 orig->getVertex((n12+2) MODULO QUAD4) };
536 Vertex* vdest[QUAD4] = { orient->v21, orient->v22,
537 dest->getVertex((n21+2) MODULO QUAD4),
538 dest->getVertex((n22+2) MODULO QUAD4) };
541 printf ("Quad nro %d : ", nquad);
542 orig->printName (" est couple avec ");
543 dest->printName ("\n");
544 printf ("Orientation : (");
545 for (int ii=0 ; ii<QUAD4 ; ii++) printf("%s ", vorig[ii]->getName());
548 for (int ii=0 ; ii<QUAD4 ; ii++) printf("%s ", vdest[ii]->getName());
552 // ---------------- Les sommets + les aretes verticales
553 for (int ns=0 ; ns< QUAD4 ; ns++)
555 Vertex* nd1 = vorig[ns];
556 Vertex* nd2 = vdest[ns];
557 int nref0 = nd1->getMark();
558 tab_vertex [nroVertex (nquad,ns,0)] = nd1;
562 double px0 = nd1->getX();
563 double py0 = nd1->getY();
564 double pz0 = nd1->getZ();
566 double dx = (nd2->getX() - nd1->getX()) / gr_hauteur;
567 double dy = (nd2->getY() - nd1->getY()) / gr_hauteur;
568 double dz = (nd2->getZ() - nd1->getZ()) / gr_hauteur;
570 nd1->setMark (indVertex (nquad, ns, 0));
573 for (int nh=0 ; nh<gr_hauteur ; nh++)
577 if (nh == gr_hauteur-1)
580 nd = el_root->addVertex (px0 + nh1*dx, py0 + nh1*dy,
582 int nv = indVertex (nquad, ns, nh);
583 tab_vertex [nv] = nd;
584 tab_edge [nv] = el_root->addEdge (ndp, nd);
586 printf (" Edge vertical nro %d = %s = (%s, %s)\n", nv,
587 tab_edge[nv]->getName(),
588 ndp->getName(), nd->getName());
593 for (int nh=0 ; nh<gr_hauteur ; nh++)
595 int nv = indVertex (nquad, ns, nh);
596 int nv0 = indVertex (nref0, nh);
597 tab_vertex [nv] = tab_vertex [nv0];
598 tab_edge [nv] = tab_edge [nv0];
602 // ---------------- Les quads verticaux + aretes horiz
603 for (int ns=0 ; ns< QUAD4 ; ns++)
605 int next = (ns+1) MODULO QUAD4;
606 Edge* arete = orig->findEdge (vorig[ns], vorig[next]);
607 int nref0 = arete->getMark();
608 int nref = indVertex (nquad, ns, 0);
609 // Construction des faces & aretes H
612 arete->setMark (nref);
617 for (int nh=0 ; nh< gr_hauteur ; nh++)
619 nva = indVertex (nquad, ns, nh);
620 nvb = indVertex (nquad, next, nh);
621 nha = nroEdgeH (nva);
626 if (nh==gr_hauteur-1)
627 ea = dest->findEdge (vdest[ns], vdest[next]);
629 ea = el_root->addEdge (tab_vertex [nva], tab_vertex [nvb]);
631 propagateAssociation (ec, ea, eb);
632 tab_quad [nva] = newQuad (ea, eb, ec, ed);
633 if (BadElement (tab_quad [nva]))
638 // L'arete a deja ete traitee
641 for (int nh=0 ; nh<gr_hauteur ; nh++)
643 int nva = indVertex (nquad, ns, nh);
644 int nha = nroEdgeH (nva);
646 int nvb = indVertex (nref0, nh);
647 int nhb = nroEdgeH (nvb);
649 tab_quad [nva] = tab_quad [nvb];
650 tab_edge [nha] = tab_edge [nhb];
654 // -------------------------------- Les Hexas
656 Quad *fa, *fc, *fd, *fe, *ff;
657 for (int nh=0 ; nh< gr_hauteur ; nh++)
660 if (nh == gr_hauteur-1)
663 fb = newQuad (tab_edge [nroEdgeH (nquad, E_A, nh)],
664 tab_edge [nroEdgeH (nquad, E_B, nh)],
665 tab_edge [nroEdgeH (nquad, E_C, nh)],
666 tab_edge [nroEdgeH (nquad, E_D, nh)]);
668 fc = tab_quad [indVertex (nquad, E_A, nh)];
669 fd = tab_quad [indVertex (nquad, E_C, nh)];
670 fe = tab_quad [indVertex (nquad, E_B, nh)];
671 ff = tab_quad [indVertex (nquad, E_D, nh)];
673 tab_hexa [nroHexa(nquad,nh)] = newHexa (fa,fb,fc,fd,fe,ff);
674 if (BadElement (tab_hexa [nroHexa(nquad,nh)]))
679 // ====================================================== makeCartesianNodes
680 int Elements::makeCartesianNodes (Vertex* orig, Vector* v1, Vector* v2,
681 Vector* v3, int px, int py, int pz, int mx, int my, int mz)
683 double dx = v1->getDx() + v2->getDx() + v3->getDx();
684 double dy = v1->getDy() + v2->getDy() + v3->getDy();
685 double dz = v1->getDz() + v2->getDz() + v3->getDz();
687 double px0 = orig->getX () - mx * dx;
688 double py0 = orig->getY () - my * dy;
689 double pz0 = orig->getZ () - mz * dz;
693 for (int nz=0 ; nz<size_vz ; nz++)
694 for (int ny=0 ; ny<size_vy ; ny++)
695 for (int nx=0 ; nx<size_vx ; nx++)
698 if (nx!=mx || ny!=my || nz!=mz)
699 node = el_root->addVertex (px0 + nx*dx, py0 + ny*dy,
701 setVertex (node, nx, ny, nz);
706 // ====================================================== makeCylindricalNodes
707 int Elements::makeCylindricalNodes (Vertex* orig, Vector* base, Vector* haut,
708 double dr, double da, double dl, int nr, int na, int nl, bool fill)
710 int ier = makeBasicCylinder (dr, da, dl, nr, na, nl, fill);
714 transfoVertices (orig, base, haut);
717 // ====================================================== transfoVertices
718 void Elements::transfoVertices (Vertex* orig, Vector* base, Vector* haut)
720 Vector* iprim = new Vector (base);
721 Vector* jprim = new Vector (base);
722 Vector* kprim = new Vector (haut);
724 int ier = kprim->renormer ();
728 jprim->vectoriel (kprim, base);
729 ier = jprim->renormer ();
733 iprim->vectoriel (jprim, kprim);
734 transfoVertices (orig, iprim, jprim, kprim);
736 // ====================================================== transfoVertices
737 void Elements::transfoVertices (Vertex* orig, Vector* iprim, Vector* jprim,
740 double matrice[DIM3][DIM3]={{iprim->getDx(),jprim->getDx(),kprim->getDx()},
741 {iprim->getDy(),jprim->getDy(),kprim->getDy()},
742 {iprim->getDz(),jprim->getDz(),kprim->getDz()}};
744 double matkx = orig->getX();
745 double matky = orig->getY();
746 double matkz = orig->getZ();
748 int nbre = tab_vertex.size ();
749 for (int nro=0 ; nro<nbre ; nro++)
751 if (tab_vertex[nro] != NULL)
752 tab_vertex[nro]->setMark (NO_USED);
755 for (int nro=0 ; nro<nbre ; nro++)
757 Vertex* node = tab_vertex[nro];
758 if (node != NULL && node->getMark() == NO_USED)
760 double point [DIM3] = {node->getX(), node->getY(), node->getZ()};
761 double result[DIM3] = {matkx, matky, matkz};
763 for (int ni=0 ; ni<DIM3; ni++)
764 for (int nj=0 ; nj<DIM3; nj++)
765 result [ni] += matrice[ni][nj] * point[nj];
767 node->setCoord (result[dir_x], result[dir_y], result[dir_z]);
768 node->setMark (IS_USED);
772 // ====================================================== transform
773 int Elements::transform (Matrix* matrice)
776 for (int nro=0 ; nro<nbr_hexas ; nro++)
778 Hexa* cell = tab_hexa[nro];
779 if (cell!=NULL && cell->isHere())
783 for (int nro=0 ; nro<nbr_hexas ; nro++)
785 Hexa* cell = tab_hexa[nro];
786 if (cell!=NULL && cell->isHere())
787 cell->moveNodes (matrice);
792 // -- Cas pathologique : il n'y avait pas d'hexas
793 // -- On se rabat sur les sommets
795 for (int nro=0 ; nro<nbr_vertex ; nro++)
797 Vertex* node = tab_vertex[nro];
798 if (node!=NULL && node->isHere())
799 matrice->perform (node);
804 // ====================================================== cutHexas
805 int Elements::cutHexas (const Edges& t_edges, int nbcuts)
807 // 1) marquage des hexas
808 el_root->markAll (NO_USED);
810 vector <Quad*> q_amont;
811 vector <Quad*> q_aval;
812 map <Vertex*, Vertex*> vis_a_vis;
814 int nbnodes = t_edges.size();
815 vector <Vertex*> v_amont (nbnodes);
816 vector <Vertex*> v_aval (nbnodes);
819 for (int nro=0; nro<nbnodes ; nro++)
821 Edge* arete = t_edges [nro];
822 v_amont [nro] = arete->getAmont ();
823 v_aval [nro] = arete->getAval ();
826 printf (" %3d : Edge = (", nro);
827 v_amont[nro]->printName (", ");
828 v_aval [nro]->printName (")\n");
831 vis_a_vis [v_amont[nro]] = v_aval[nro];
832 vis_a_vis [v_aval[nro]] = v_amont[nro];
833 int nbcells = arete->getNbrParents ();
835 for (int nq=0 ; nq<nbcells ; nq++)
837 Quad* quad = arete->getParent (nq);
838 if (quad->getMark () != IS_USED)
840 quad->setMark (IS_USED);
841 int nbcubes = quad->getNbrParents ();
842 for (int nh=0 ; nh<nbcubes ; nh++)
844 Hexa* hexa = quad->getParent (nh);
845 if (hexa->getMark () != IS_USED)
847 hexa->setMark (IS_USED);
848 int namont = hexa->getBase (v_amont[nro], arete);
849 int naval = glob->getOpposedQuad (namont);
850 q_amont.push_back (hexa->getQuad (namont));
851 q_aval .push_back (hexa->getQuad (naval ));
855 printf (" %3d : Quad = ", nbfaces);
856 hexa->printName (", ");
857 printf (" Faces = (");
858 hexa->getQuad (namont)->printName (", ");
859 hexa->getQuad (naval )->printName (")\n");
867 // ------------------- Dimensionnement
868 int nbcells = q_amont.size ();
869 nbr_vertex = nbnodes*(nbcuts+2);
870 int nbpiliers = nbnodes*(nbcuts+1); // aretes verticales
871 int nbpoutres = nbcells*(nbcuts+2)*QUAD4; // aretes horizontales
872 nbr_edges = nbpoutres;
873 nbr_quads = nbcells*(nbcuts+1)*QUAD4; // faces Verticales
874 nbr_hexas = nbcells*(nbcuts+1);
876 // ------------------- Les noeuds et les aretes verticales
877 tab_quad.resize (nbr_quads);
878 tab_edge.resize (nbr_edges);
879 tab_hexa.resize (nbr_hexas);
880 tab_vertex.resize (nbr_vertex);
881 vector <Edge*> tab_pilier (nbpiliers);
883 int nbinter = nbcuts + 1;
884 for (int ned=0; ned<nbnodes ; ned++)
886 Shapes ass_shapes = t_edges[ned] -> getAssociations ();
888 t_edges [ned]->remove ();
889 Vertex* ndamont = v_amont [ned];
890 Vertex* ndaval = v_aval [ned];
892 double dx = (ndaval->getX() - ndamont->getX()) / nbinter;
893 double dy = (ndaval->getY() - ndamont->getY()) / nbinter;
894 double dz = (ndaval->getZ() - ndamont->getZ()) / nbinter;
896 Vertex* nd0 = tab_vertex [ned] = ndamont;
897 for (int nc=0; nc<nbcuts ; nc++)
900 Vertex* nd1 = el_root->addVertex (ndamont->getX() + nc1*dx,
901 ndamont->getY() + nc1*dy,
902 ndamont->getZ() + nc1*dz);
903 tab_vertex [nc1*nbnodes + ned] = nd1;
904 tab_pilier [nc *nbnodes + ned] = newEdge (nd0, nd1);
905 ass_edges.push_back (tab_pilier [nc *nbnodes + ned]);
908 tab_vertex [nbinter*nbnodes + ned] = ndaval;
909 tab_pilier [nbcuts *nbnodes + ned] = newEdge (nd0, ndaval);
910 ass_edges.push_back (tab_pilier[nbcuts *nbnodes + ned]);
911 ndamont->setMark (ned);
912 cutAssociation (ass_shapes, ass_edges);
914 // ------------------- Les aretes horizontales
915 // ------------------- Les faces verticales
916 HexDisplay (nbcells);
917 int sizelig = nbcells*QUAD4;
918 for (int nro=0; nro<nbcells ; nro++)
920 Quad* sol = q_amont [nro];
921 Quad* toit = q_aval [nro];
922 for (int ns=0; ns<QUAD4 ; ns++)
924 Edge* plinthe = sol->getEdge (ns);
925 int nmur = nro*QUAD4 + ns;
926 int nmur0 = plinthe->getMark();
929 for (int nc=0 ; nc<nbinter ; nc++)
931 tab_edge [nc*sizelig + nmur] = tab_edge [nc*sizelig + nmur0];
932 tab_quad [nc*sizelig + nmur] = tab_quad [nc *sizelig + nmur0];
935 printf (" %2d : %d quad_vertical [%02d] =", nro, ns,
937 printf (" quad_vertical [%02d]\n", nc*sizelig + nmur0);
940 tab_edge [nbinter*sizelig+nmur] = tab_edge[nbinter*sizelig+nmur0];
944 plinthe->setMark (nmur);
945 Vertex* vs1 = sol->getVertex (ns);
946 Vertex* vs2 = sol->getVertex ((ns+1) MODULO QUAD4);
947 int nd1 = vs1->getMark ();
948 int nd2 = vs2->getMark ();
949 Edge* ed0 = tab_edge [nmur] = plinthe;
953 for (int nc=0 ; nc<nbinter ; nc++)
958 v1 = tab_vertex [nc1*nbnodes + nd1];
959 v2 = tab_vertex [nc1*nbnodes + nd2];
960 ed2 = newEdge (v1, v2);
964 v1 = vis_a_vis [vs1];
965 v2 = vis_a_vis [vs2];
966 ed2 = toit->findEdge (v1, v2);
969 tab_edge [nc1*sizelig + nmur] = ed2;
970 tab_quad [nc *sizelig + nmur] = newQuad (ed0,
971 tab_pilier [nc*nbnodes + nd1], ed2,
972 tab_pilier [nc*nbnodes + nd2]);
976 printf (" %2d : %d quad_vertical [%02d] = ", nro, ns,
978 PrintName (tab_quad [nc *sizelig + nmur]);
985 // ------------------- Les faces horizontales
986 // ------------------- Les hexas
987 // Rappel : sizelig = nbcells*QUAD4
988 for (int nro=0; nro<nbcells ; nro++)
990 Quad* qa = q_amont [nro];
991 for (int nc=0 ; nc<nbinter ; nc++)
993 int quadv = nc*nbcells*QUAD4 + nro*QUAD4;
994 Quad* qb = q_aval[nro];
997 int edh = (nc+1)*nbcells*QUAD4 + nro*QUAD4;
998 qb = newQuad (tab_edge[edh], tab_edge[edh+1],
999 tab_edge[edh+2], tab_edge[edh+3]);
1003 Quad* qc = tab_quad [quadv];
1004 Quad* qd = tab_quad [quadv + 2];
1005 Quad* qe = tab_quad [quadv + 1];
1006 Quad* qf = tab_quad [quadv + 3];
1007 Hexa* hexa = newHexa (qa, qb, qc, qd, qe, qf);
1008 if (BadElement(hexa))
1010 tab_hexa [nc*nbcells + nro] = hexa;
1016 // ====================================================== clear_associations
1017 void clear_associations (std::vector<Quad*>& table)
1019 int nbelts = table.size();
1020 for (int nro=0 ; nro<nbelts ; nro++)
1021 clear_association (table[nro]);
1023 // ====================================================== clear_associations
1024 void clear_associations (std::vector<Edge*>& table)
1026 int nbelts = table.size();
1027 for (int nro=0 ; nro<nbelts ; nro++)
1028 clear_association (table[nro]);
1030 // ====================================================== clear_associations
1031 void clear_associations (std::vector<Vertex*>& table)
1033 int nbelts = table.size();
1034 for (int nro=0 ; nro<nbelts ; nro++)
1035 clear_association (table[nro]);
1037 // ====================================================== clearAssociation
1038 void Elements::clearAssociation ()
1040 // clear_associations (tab_hexa);
1041 clear_associations (tab_quad);
1042 clear_associations (tab_edge);
1043 clear_associations (tab_vertex);
1045 // clear_associations (tab_orig);
1047 clear_associations (ker_hquad);
1048 clear_associations (ker_vquad);
1049 clear_associations (ker_hedge);
1050 clear_associations (ker_vedge);
1052 /* ***********************************************
1053 nbelts = tab_hexa.size();
1054 for (int nro=0 ; nro<nbelts ; nro++)
1056 Hexa* elt = tab_hexa[nro];
1057 if (elt != NULL && elt->isValid())
1058 elt->clearAssociation ();
1060 *********************************************** */
1062 // ============================================================ findVertex
1063 int Elements::findVertex (double vx, double vy, double vz)
1065 double tol = el_root->getTolerance ();
1066 double xmin = vx - tol;
1067 double xmax = vx + tol;
1068 double ymin = vy - tol;
1069 double ymax = vy + tol;
1070 double zmin = vz - tol;
1071 double zmax = vz + tol;
1073 int nbre = tab_vertex.size();
1074 for (int nro=0 ; nro<nbre ; nro++)
1076 Vertex* node = tab_vertex [nro];
1077 if (node != NULL && node->isHere ()
1078 && node->isin (xmin, xmax, ymin, ymax, zmin, zmax))