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 resize (GR_CARTESIAN, px+mx, py+my, pz+mz);
199 makeCartesianNodes (orig, v1, v2, v3, px, py, pz, mx, my, mz);
204 // ====================================================== makeCylindricalGrid
205 int Elements::makeCylindricalGrid (Vertex* c, Vector* b, Vector* h,
206 double dr, double da, double dl, int nr, int na, int nl, bool fill)
208 resize (GR_CYLINDRIC, nr, na, nl);
209 cyl_closed = da >= 360.0;
210 makeCylindricalNodes (c, b, h, dr, da, dl, nr, na, nl, fill);
212 assoCylinder (c, h, da);
215 // ====================================================== makeSphericalGrid
216 int Elements::makeSphericalGrid (Vertex* c, Vector* dv, int nb, double k)
218 resize (GR_SPHERIC, nb);
222 else if (dv->getDx()<=ZEROR || dv->getDy()<=ZEROR || dv->getDz()<=ZEROR)
225 Vertex* i_node [HV_MAXI]; // Les noeuds de l'hexa englobant
226 Edge* i_edge [HE_MAXI]; // Les noeuds de l'hexa englobant
227 Quad* i_quad [HQ_MAXI]; // Les noeuds de l'hexa englobant
229 for (int nro=0 ; nro<HV_MAXI; nro++)
231 double dx = glob->CoordVertex (nro, dir_x) * dv->getDx();
232 double dy = glob->CoordVertex (nro, dir_y) * dv->getDy();
233 double dz = glob->CoordVertex (nro, dir_z) * dv->getDz();
235 i_node [nro] = el_root->addVertex (c->getX ()+dx, c->getY ()+dy,
239 for (int nro=0 ; nro<HE_MAXI; nro++)
241 int v1 = glob->EdgeVertex (nro, V_AMONT);
242 int v2 = glob->EdgeVertex (nro, V_AVAL);
243 i_edge[nro] = newEdge (i_node[v1], i_node[v2]);
247 char nm0[8], nm1 [8], nm2 [8];
248 printf (" %2d : %s = %s = [%s, %s] = [%d,%d] = [%s,%s]\n", nro,
249 glob->namofHexaEdge(nro), i_edge[nro]->getName(nm0),
250 glob->namofHexaVertex(v1), glob->namofHexaVertex(v2), v1, v2,
251 i_node[v1]->getName(nm1), i_node[v2]->getName(nm2));
255 for (int nro=0 ; nro<HQ_MAXI; nro++)
256 i_quad[nro] = newQuad (i_edge[glob->QuadEdge (nro, E_A)],
257 i_edge[glob->QuadEdge (nro, E_B)],
258 i_edge[glob->QuadEdge (nro, E_C)],
259 i_edge[glob->QuadEdge (nro, E_D)]);
261 tab_hexa.push_back (newHexa (i_quad[Q_A], i_quad[Q_B], i_quad[Q_C],
262 i_quad[Q_D], i_quad[Q_E], i_quad[Q_F]));
265 for (int niv=0; niv<gr_rayon ; niv++)
267 double lambda0 = lambda;
270 addStrate (i_quad, i_edge, i_node, c, lambda/lambda0);
275 // ====================================================== addStrate
276 int Elements::addStrate (Quad* i_quad[], Edge* i_edge[], Vertex* i_node[],
277 Vertex* center, double lambda)
279 Vertex* e_node [HV_MAXI]; // Les noeuds de l'hexa englobant
280 Edge* e_edge [HE_MAXI]; // Les noeuds de l'hexa englobant
281 Quad* e_quad [HQ_MAXI]; // Les noeuds de l'hexa englobant
283 Edge* d_edge [HV_MAXI]; // Les aretes diagonales (1 par sommet)
284 Quad* d_quad [HE_MAXI]; // Les faces diagonales (1 par arete)
287 // + les aretes diagonales
288 for (int nv=0 ; nv<HV_MAXI ; nv++)
290 double px0 = center->getX ();
291 double py0 = center->getY ();
292 double pz0 = center->getZ ();
293 e_node[nv] = el_root->addVertex (px0+lambda*(i_node[nv]->getX()-px0),
294 py0+lambda*(i_node[nv]->getY()-py0),
295 pz0+lambda*(i_node[nv]->getZ()-pz0));
297 d_edge[nv] = newEdge (i_node[nv], e_node[nv]);
299 // Les aretes exterieures
300 // + les faces diagonales
301 for (int nro=0 ; nro<HE_MAXI ; nro++)
303 int nv0 = glob->EdgeVertex (nro, V_AMONT);
304 int nv1 = glob->EdgeVertex (nro, V_AVAL );
305 e_edge[nro] = newEdge (e_node [nv0], e_node [nv1]);
306 d_quad[nro] = newQuad (i_edge [nro], d_edge [nv0],
307 e_edge [nro], d_edge [nv1]);
309 // Les faces exterieures
312 for (int nro=0 ; nro<HQ_MAXI ; nro++)
314 int ne0 = glob->QuadEdge (nro, E_A);
315 int ne1 = glob->QuadEdge (nro, E_B);
316 int ne2 = glob->QuadEdge (nro, E_C);
317 int ne3 = glob->QuadEdge (nro, E_D);
319 e_quad[nro] = newQuad (e_edge[ne0], e_edge[ne1],
320 e_edge[ne2], e_edge[ne3]);
321 strate = newHexa (i_quad[nro], e_quad[nro], d_quad[ne0],
322 d_quad[ne2], d_quad[ne1], d_quad[ne3]);
323 tab_hexa.push_back (strate);
326 for (int nv=0 ; nv<HV_MAXI ; nv++) i_node [nv] = e_node [nv];
327 for (int ns=0 ; ns<HE_MAXI ; ns++) i_edge [ns] = e_edge [ns];
328 for (int nq=0 ; nq<HQ_MAXI ; nq++) i_quad [nq] = e_quad [nq];
332 // ====================================================== saveVtk
333 int Elements::saveVtk (cpchar nomfic)
335 // -- 1) Raz numerotation precedente
336 for (int nro=0 ; nro<nbr_hexas ; nro++)
338 Hexa* cell = tab_hexa[nro];
339 if (cell!=NULL && cell->isHere())
346 for (int nro=0 ; nro<nbr_hexas ; nro++)
348 Hexa* cell = tab_hexa[nro];
349 if (cell!=NULL && cell->isHere())
352 nbnodes += cell->countNodes ();
356 pfile vtk = fopen (nomfic, "w");
357 fprintf (vtk, "# vtk DataFile Version 3.1\n");
358 fprintf (vtk, "%s \n", nomfic);
359 fprintf (vtk, "ASCII\n");
360 fprintf (vtk, "DATASET UNSTRUCTURED_GRID\n");
361 fprintf (vtk, "POINTS %d float\n", nbnodes);
365 for (int nro=0 ; nro<nbr_hexas ; nro++)
367 Hexa* cell = tab_hexa[nro];
368 if (cell!=NULL && cell->isHere())
369 cell->printNodes (vtk, nronode);
373 fprintf (vtk, "CELLS %d %d\n", nbcells, nbcells*(HV_MAXI+1));
375 for (int nro=0 ; nro<nbr_hexas ; nro++)
377 Hexa* cell = tab_hexa[nro];
378 if (cell!=NULL && cell->isHere())
379 cell->printHexa (vtk);
382 fprintf (vtk, "CELL_TYPES %d\n", nbcells);
383 for (int nro=0 ; nro<nbcells ; nro++)
384 fprintf (vtk, "%d\n", HE_MAXI);
389 // ============ = = = = = = = = = Vertices ..........
390 // ====================================================== newEdge
391 Edge* Elements::newEdge (Vertex* v1, Vertex* v2)
393 if (v1==NULL || v2==NULL)
396 Edge* elt = new Edge (v1, v2);
399 // ====================================================== newQuad
400 Quad* Elements::newQuad (Edge* e1, Edge* e2, Edge* e3, Edge* e4)
402 if (e1==NULL || e2==NULL || e3==NULL|| e4==NULL)
405 Quad* elt = new Quad (e1, e2, e3, e4);
408 // ====================================================== newHexa
409 Hexa* Elements::newHexa (Quad* qa, Quad* qb, Quad* qc, Quad* qd,
412 if (qa==NULL || qb==NULL || qc==NULL|| qd==NULL || qe==NULL|| qf==NULL)
415 Hexa* elt = new Hexa (qa, qb, qc, qd, qe, qf);
418 // ====================================================== joinQuads
419 int Elements::joinQuads (Quads& orig, int nb, Vertex* v1, Vertex* v2,
420 Vertex* v3, Vertex* v4, Quad* cible)
422 resize (GR_JOINT, orig.size(), nb);
424 el_root->markAll (IS_NONE);
426 // db = el_root->debug ();
429 nbr_orig = orig.size();
431 for (int nro=0 ; nro<nbr_orig ; nro++)
433 Quad* face = orig[nro];
437 printf (" *** joinQuads : donnees incorrectes\n");
438 printf (" *** le %deme quadrangle de depart est NULL\n", nro);
441 else if (face->getNbrParents()>1)
444 printf (" *** joinQuads : donnees incorrectes\n");
445 printf (" *** le %deme quadrangle de depart n'est pas une "
446 "face externe\n", nro);
450 orig [nro]->setMark (nro);
451 tab_orig.push_back (orig[nro]);
454 Edge* e_orig = tab_orig[0] -> findEdge (v1, v3);
455 Edge* e_dest = cible -> findEdge (v2, v4);
460 printf (" *** joinQuads : donnees incorrectes\n");
461 printf (" *** Les vertex v1 et v3 passes en argument ne definissent\n");
462 printf (" *** pas une arete du 1er quadrangle de depart\n");
472 printf (" *** joinQuads : donnees incorrectes\n");
473 printf (" *** Les vertex v2 et v4 passes en argument ne definissent\n");
474 printf (" *** pas une arete du quadrangle cible\n");
481 if (e_orig==NULL || e_dest==NULL)
484 StrOrient orient (v1, v3, v2, v4);
485 int ier = this ->coupler (0, cible, &orient);
488 ier = orig[0]->coupler (cible, &orient, this);
491 // ======================================================== coupler
492 int Elements::coupler (int nquad, Quad* dest, StrOrient* orient)
494 Quad* orig = tab_orig [nquad];
496 setQuad (orig, dir_z, 0, 0, 0);
497 setQuad (dest, dir_z, nquad, 0, 0);
499 int n11 = orig->indexVertex (orient->v11);
500 int n12 = orig->indexVertex (orient->v12);
501 int n21 = dest->indexVertex (orient->v21);
502 int n22 = dest->indexVertex (orient->v22);
504 // ---------------- Les 4 sommets initiaux
505 Vertex* vorig[QUAD4] = { orient->v11, orient->v12,
506 orig->getVertex((n11+2) MODULO QUAD4),
507 orig->getVertex((n12+2) MODULO QUAD4) };
509 Vertex* vdest[QUAD4] = { orient->v21, orient->v22,
510 dest->getVertex((n21+2) MODULO QUAD4),
511 dest->getVertex((n22+2) MODULO QUAD4) };
514 printf ("Quad nro %d : ", nquad);
515 orig->printName (" est couple avec ");
516 dest->printName ("\n");
517 printf ("Orientation : (");
518 for (int ii=0 ; ii<QUAD4 ; ii++) printf("%s ", vorig[ii]->getName());
521 for (int ii=0 ; ii<QUAD4 ; ii++) printf("%s ", vdest[ii]->getName());
525 // ---------------- Les sommets + les aretes verticales
526 for (int ns=0 ; ns< QUAD4 ; ns++)
528 Vertex* nd1 = vorig[ns];
529 Vertex* nd2 = vdest[ns];
530 int nref0 = nd1->getMark();
531 tab_vertex [nroVertex (nquad,ns,0)] = nd1;
535 double px0 = nd1->getX();
536 double py0 = nd1->getY();
537 double pz0 = nd1->getZ();
539 double dx = (nd2->getX() - nd1->getX()) / gr_hauteur;
540 double dy = (nd2->getY() - nd1->getY()) / gr_hauteur;
541 double dz = (nd2->getZ() - nd1->getZ()) / gr_hauteur;
543 nd1->setMark (indVertex (nquad, ns, 0));
546 for (int nh=0 ; nh<gr_hauteur ; nh++)
550 if (nh == gr_hauteur-1)
553 nd = el_root->addVertex (px0 + nh1*dx, py0 + nh1*dy,
555 int nv = indVertex (nquad, ns, nh);
556 tab_vertex [nv] = nd;
557 tab_edge [nv] = el_root->addEdge (ndp, nd);
559 printf (" Edge vertical nro %d = %s = (%s, %s)\n", nv,
560 tab_edge[nv]->getName(),
561 ndp->getName(), nd->getName());
566 for (int nh=0 ; nh<gr_hauteur ; nh++)
568 int nv = indVertex (nquad, ns, nh);
569 int nv0 = indVertex (nref0, nh);
570 tab_vertex [nv] = tab_vertex [nv0];
571 tab_edge [nv] = tab_edge [nv0];
575 // ---------------- Les quads verticaux + aretes horiz
576 for (int ns=0 ; ns< QUAD4 ; ns++)
578 int next = (ns+1) MODULO QUAD4;
579 Edge* arete = orig->findEdge (vorig[ns], vorig[next]);
580 int nref0 = arete->getMark();
581 int nref = indVertex (nquad, ns, 0);
582 // Construction des faces & aretes H
585 arete->setMark (nref);
590 for (int nh=0 ; nh< gr_hauteur ; nh++)
592 nva = indVertex (nquad, ns, nh);
593 nvb = indVertex (nquad, next, nh);
594 nha = nroEdgeH (nva);
599 if (nh==gr_hauteur-1)
600 ea = dest->findEdge (vdest[ns], vdest[next]);
602 ea = el_root->addEdge (tab_vertex [nva], tab_vertex [nvb]);
604 propagateAssociation (ec, ea, eb);
605 tab_quad [nva] = newQuad (ea, eb, ec, ed);
606 if (BadElement (tab_quad [nva]))
611 // L'arete a deja ete traitee
614 for (int nh=0 ; nh<gr_hauteur ; nh++)
616 int nva = indVertex (nquad, ns, nh);
617 int nha = nroEdgeH (nva);
619 int nvb = indVertex (nref0, nh);
620 int nhb = nroEdgeH (nvb);
622 tab_quad [nva] = tab_quad [nvb];
623 tab_edge [nha] = tab_edge [nhb];
627 // -------------------------------- Les Hexas
629 Quad *fa, *fc, *fd, *fe, *ff;
630 for (int nh=0 ; nh< gr_hauteur ; nh++)
633 if (nh == gr_hauteur-1)
636 fb = newQuad (tab_edge [nroEdgeH (nquad, E_A, nh)],
637 tab_edge [nroEdgeH (nquad, E_B, nh)],
638 tab_edge [nroEdgeH (nquad, E_C, nh)],
639 tab_edge [nroEdgeH (nquad, E_D, nh)]);
641 fc = tab_quad [indVertex (nquad, E_A, nh)];
642 fd = tab_quad [indVertex (nquad, E_C, nh)];
643 fe = tab_quad [indVertex (nquad, E_B, nh)];
644 ff = tab_quad [indVertex (nquad, E_D, nh)];
646 tab_hexa [nroHexa(nquad,nh)] = newHexa (fa,fb,fc,fd,fe,ff);
647 if (BadElement (tab_hexa [nroHexa(nquad,nh)]))
652 // ====================================================== makeCartesianNodes
653 int Elements::makeCartesianNodes (Vertex* orig, Vector* v1, Vector* v2,
654 Vector* v3, int px, int py, int pz, int mx, int my, int mz)
656 double dx = v1->getDx() + v2->getDx() + v3->getDx();
657 double dy = v1->getDy() + v2->getDy() + v3->getDy();
658 double dz = v1->getDz() + v2->getDz() + v3->getDz();
660 double px0 = orig->getX () - mx * dx;
661 double py0 = orig->getY () - my * dy;
662 double pz0 = orig->getZ () - mz * dz;
666 for (int nz=0 ; nz<size_vz ; nz++)
667 for (int ny=0 ; ny<size_vy ; ny++)
668 for (int nx=0 ; nx<size_vx ; nx++)
671 if (nx!=mx || ny!=my || nz!=mz)
672 node = el_root->addVertex (px0 + nx*dx, py0 + ny*dy,
674 setVertex (node, nx, ny, nz);
679 // ====================================================== makeCylindricalNodes
680 int Elements::makeCylindricalNodes (Vertex* orig, Vector* base, Vector* haut,
681 double dr, double da, double dl, int nr, int na, int nl, bool fill)
683 int ier = makeBasicCylinder (dr, da, dl, nr, na, nl, fill);
687 transfoVertices (orig, base, haut);
690 // ====================================================== transfoVertices
691 void Elements::transfoVertices (Vertex* orig, Vector* base, Vector* haut)
693 Vector* iprim = new Vector (base);
694 Vector* jprim = new Vector (base);
695 Vector* kprim = new Vector (haut);
697 int ier = kprim->renormer ();
701 jprim->vectoriel (kprim, base);
702 ier = jprim->renormer ();
706 iprim->vectoriel (jprim, kprim);
707 transfoVertices (orig, iprim, jprim, kprim);
709 // ====================================================== transfoVertices
710 void Elements::transfoVertices (Vertex* orig, Vector* iprim, Vector* jprim,
713 double matrice[DIM3][DIM3]={{iprim->getDx(),jprim->getDx(),kprim->getDx()},
714 {iprim->getDy(),jprim->getDy(),kprim->getDy()},
715 {iprim->getDz(),jprim->getDz(),kprim->getDz()}};
717 double matkx = orig->getX();
718 double matky = orig->getY();
719 double matkz = orig->getZ();
721 int nbre = tab_vertex.size ();
722 for (int nro=0 ; nro<nbre ; nro++)
724 if (tab_vertex[nro] != NULL)
725 tab_vertex[nro]->setMark (NO_USED);
728 for (int nro=0 ; nro<nbre ; nro++)
730 Vertex* node = tab_vertex[nro];
731 if (node != NULL && node->getMark() == NO_USED)
733 double point [DIM3] = {node->getX(), node->getY(), node->getZ()};
734 double result[DIM3] = {matkx, matky, matkz};
736 for (int ni=0 ; ni<DIM3; ni++)
737 for (int nj=0 ; nj<DIM3; nj++)
738 result [ni] += matrice[ni][nj] * point[nj];
740 node->setCoord (result[dir_x], result[dir_y], result[dir_z]);
741 node->setMark (IS_USED);
745 // ====================================================== transform
746 int Elements::transform (Matrix* matrice)
749 for (int nro=0 ; nro<nbr_hexas ; nro++)
751 Hexa* cell = tab_hexa[nro];
752 if (cell!=NULL && cell->isHere())
756 for (int nro=0 ; nro<nbr_hexas ; nro++)
758 Hexa* cell = tab_hexa[nro];
759 if (cell!=NULL && cell->isHere())
760 cell->moveNodes (matrice);
765 // -- Cas pathologique : il n'y avait pas d'hexas
766 // -- On se rabat sur les sommets
768 for (int nro=0 ; nro<nbr_vertex ; nro++)
770 Vertex* node = tab_vertex[nro];
771 if (node!=NULL && node->isHere())
772 matrice->perform (node);
777 // ====================================================== cutHexas
778 int Elements::cutHexas (const Edges& t_edges, int nbcuts)
780 // 1) marquage des hexas
781 el_root->markAll (NO_USED);
783 vector <Quad*> q_amont;
784 vector <Quad*> q_aval;
785 map <Vertex*, Vertex*> vis_a_vis;
787 int nbnodes = t_edges.size();
788 vector <Vertex*> v_amont (nbnodes);
789 vector <Vertex*> v_aval (nbnodes);
792 for (int nro=0; nro<nbnodes ; nro++)
794 Edge* arete = t_edges [nro];
795 v_amont [nro] = arete->getAmont ();
796 v_aval [nro] = arete->getAval ();
799 printf (" %3d : Edge = (", nro);
800 v_amont[nro]->printName (", ");
801 v_aval [nro]->printName (")\n");
804 vis_a_vis [v_amont[nro]] = v_aval[nro];
805 vis_a_vis [v_aval[nro]] = v_amont[nro];
806 int nbcells = arete->getNbrParents ();
808 for (int nq=0 ; nq<nbcells ; nq++)
810 Quad* quad = arete->getParent (nq);
811 if (quad->getMark () != IS_USED)
813 quad->setMark (IS_USED);
814 int nbcubes = quad->getNbrParents ();
815 for (int nh=0 ; nh<nbcubes ; nh++)
817 Hexa* hexa = quad->getParent (nh);
818 if (hexa->getMark () != IS_USED)
820 hexa->setMark (IS_USED);
821 int namont = hexa->getBase (v_amont[nro], arete);
822 int naval = glob->getOpposedQuad (namont);
823 q_amont.push_back (hexa->getQuad (namont));
824 q_aval .push_back (hexa->getQuad (naval ));
828 printf (" %3d : Quad = ", nbfaces);
829 hexa->printName (", ");
830 printf (" Faces = (");
831 hexa->getQuad (namont)->printName (", ");
832 hexa->getQuad (naval )->printName (")\n");
840 // ------------------- Dimensionnement
841 int nbcells = q_amont.size ();
842 nbr_vertex = nbnodes*(nbcuts+2);
843 int nbpiliers = nbnodes*(nbcuts+1); // aretes verticales
844 int nbpoutres = nbcells*(nbcuts+2)*QUAD4; // aretes horizontales
845 nbr_edges = nbpoutres;
846 nbr_quads = nbcells*(nbcuts+1)*QUAD4; // faces Verticales
847 nbr_hexas = nbcells*(nbcuts+1);
849 // ------------------- Les noeuds et les aretes verticales
850 tab_quad.resize (nbr_quads);
851 tab_edge.resize (nbr_edges);
852 tab_hexa.resize (nbr_hexas);
853 tab_vertex.resize (nbr_vertex);
854 vector <Edge*> tab_pilier (nbpiliers);
856 int nbinter = nbcuts + 1;
857 for (int ned=0; ned<nbnodes ; ned++)
859 Shapes ass_shapes = t_edges[ned] -> getAssociations ();
861 t_edges [ned]->remove ();
862 Vertex* ndamont = v_amont [ned];
863 Vertex* ndaval = v_aval [ned];
865 double dx = (ndaval->getX() - ndamont->getX()) / nbinter;
866 double dy = (ndaval->getY() - ndamont->getY()) / nbinter;
867 double dz = (ndaval->getZ() - ndamont->getZ()) / nbinter;
869 Vertex* nd0 = tab_vertex [ned] = ndamont;
870 for (int nc=0; nc<nbcuts ; nc++)
873 Vertex* nd1 = el_root->addVertex (ndamont->getX() + nc1*dx,
874 ndamont->getY() + nc1*dy,
875 ndamont->getZ() + nc1*dz);
876 tab_vertex [nc1*nbnodes + ned] = nd1;
877 tab_pilier [nc *nbnodes + ned] = newEdge (nd0, nd1);
878 ass_edges.push_back (tab_pilier [nc *nbnodes + ned]);
881 tab_vertex [nbinter*nbnodes + ned] = ndaval;
882 tab_pilier [nbcuts *nbnodes + ned] = newEdge (nd0, ndaval);
883 ass_edges.push_back (tab_pilier[nbcuts *nbnodes + ned]);
884 ndamont->setMark (ned);
885 cutAssociation (ass_shapes, ass_edges);
887 // ------------------- Les aretes horizontales
888 // ------------------- Les faces verticales
889 HexDisplay (nbcells);
890 int sizelig = nbcells*QUAD4;
891 for (int nro=0; nro<nbcells ; nro++)
893 Quad* sol = q_amont [nro];
894 Quad* toit = q_aval [nro];
895 for (int ns=0; ns<QUAD4 ; ns++)
897 Edge* plinthe = sol->getEdge (ns);
898 int nmur = nro*QUAD4 + ns;
899 int nmur0 = plinthe->getMark();
902 for (int nc=0 ; nc<nbinter ; nc++)
904 tab_edge [nc*sizelig + nmur] = tab_edge [nc*sizelig + nmur0];
905 tab_quad [nc*sizelig + nmur] = tab_quad [nc *sizelig + nmur0];
908 printf (" %2d : %d quad_vertical [%02d] =", nro, ns,
910 printf (" quad_vertical [%02d]\n", nc*sizelig + nmur0);
913 tab_edge [nbinter*sizelig+nmur] = tab_edge[nbinter*sizelig+nmur0];
917 plinthe->setMark (nmur);
918 Vertex* vs1 = sol->getVertex (ns);
919 Vertex* vs2 = sol->getVertex ((ns+1) MODULO QUAD4);
920 int nd1 = vs1->getMark ();
921 int nd2 = vs2->getMark ();
922 Edge* ed0 = tab_edge [nmur] = plinthe;
926 for (int nc=0 ; nc<nbinter ; nc++)
931 v1 = tab_vertex [nc1*nbnodes + nd1];
932 v2 = tab_vertex [nc1*nbnodes + nd2];
933 ed2 = newEdge (v1, v2);
937 v1 = vis_a_vis [vs1];
938 v2 = vis_a_vis [vs2];
939 ed2 = toit->findEdge (v1, v2);
942 tab_edge [nc1*sizelig + nmur] = ed2;
943 tab_quad [nc *sizelig + nmur] = newQuad (ed0,
944 tab_pilier [nc*nbnodes + nd1], ed2,
945 tab_pilier [nc*nbnodes + nd2]);
949 printf (" %2d : %d quad_vertical [%02d] = ", nro, ns,
951 PrintName (tab_quad [nc *sizelig + nmur]);
958 // ------------------- Les faces horizontales
959 // ------------------- Les hexas
960 // Rappel : sizelig = nbcells*QUAD4
961 for (int nro=0; nro<nbcells ; nro++)
963 Quad* qa = q_amont [nro];
964 for (int nc=0 ; nc<nbinter ; nc++)
966 int quadv = nc*nbcells*QUAD4 + nro*QUAD4;
967 Quad* qb = q_aval[nro];
970 int edh = (nc+1)*nbcells*QUAD4 + nro*QUAD4;
971 qb = newQuad (tab_edge[edh], tab_edge[edh+1],
972 tab_edge[edh+2], tab_edge[edh+3]);
976 Quad* qc = tab_quad [quadv];
977 Quad* qd = tab_quad [quadv + 2];
978 Quad* qe = tab_quad [quadv + 1];
979 Quad* qf = tab_quad [quadv + 3];
980 Hexa* hexa = newHexa (qa, qb, qc, qd, qe, qf);
981 if (BadElement(hexa))
983 tab_hexa [nc*nbcells + nro] = hexa;
989 // ====================================================== clear_associations
990 void clear_associations (std::vector<Quad*>& table)
992 int nbelts = table.size();
993 for (int nro=0 ; nro<nbelts ; nro++)
994 clear_association (table[nro]);
996 // ====================================================== clear_associations
997 void clear_associations (std::vector<Edge*>& table)
999 int nbelts = table.size();
1000 for (int nro=0 ; nro<nbelts ; nro++)
1001 clear_association (table[nro]);
1003 // ====================================================== clear_associations
1004 void clear_associations (std::vector<Vertex*>& table)
1006 int nbelts = table.size();
1007 for (int nro=0 ; nro<nbelts ; nro++)
1008 clear_association (table[nro]);
1010 // ====================================================== clearAssociation
1011 void Elements::clearAssociation ()
1013 // clear_associations (tab_hexa);
1014 clear_associations (tab_quad);
1015 clear_associations (tab_edge);
1016 clear_associations (tab_vertex);
1018 // clear_associations (tab_orig);
1020 clear_associations (ker_hquad);
1021 clear_associations (ker_vquad);
1022 clear_associations (ker_hedge);
1023 clear_associations (ker_vedge);
1025 /* ***********************************************
1026 nbelts = tab_hexa.size();
1027 for (int nro=0 ; nro<nbelts ; nro++)
1029 Hexa* elt = tab_hexa[nro];
1030 if (elt != NULL && elt->isValid())
1031 elt->clearAssociation ();
1033 *********************************************** */
1035 // ============================================================ findVertex
1036 int Elements::findVertex (double vx, double vy, double vz)
1038 double tol = el_root->getTolerance ();
1039 double xmin = vx - tol;
1040 double xmax = vx + tol;
1041 double ymin = vy - tol;
1042 double ymax = vy + tol;
1043 double zmin = vz - tol;
1044 double zmax = vz + tol;
1046 int nbre = tab_vertex.size();
1047 for (int nro=0 ; nro<nbre ; nro++)
1049 Vertex* node = tab_vertex [nro];
1050 if (node != NULL && node->isHere ()
1051 && node->isin (xmin, xmax, ymin, ymax, zmin, zmax))