1 // C++ : Table d'hexaedres (Evol Versions 3)
3 // Copyright (C) 2009-2013 CEA/DEN, EDF R&D
5 // This library is free software; you can redistribute it and/or
6 // modify it under the terms of the GNU Lesser General Public
7 // License as published by the Free Software Foundation; either
8 // version 2.1 of the License.
10 // This library is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 // Lesser General Public License for more details.
15 // You should have received a copy of the GNU Lesser General Public
16 // License along with this library; if not, write to the Free Software
17 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 #include "HexElements.hxx"
24 #include "HexDocument.hxx"
25 #include "HexVector.hxx"
26 #include "HexVertex.hxx"
27 #include "HexEdge.hxx"
28 #include "HexHexa.hxx"
29 #include "HexMatrix.hxx"
30 #include "HexGlobale.hxx"
32 #include "HexNewShape.hxx"
33 #include "HexEdgeShape.hxx"
34 #include "HexAssoEdge.hxx"
40 // static bool db=false;
42 // ====================================================== getCylPoint
43 int Elements::getCylPoint (int nr, int na, int nh, double& px, double& py,
46 if (grid_type == GR_CYLINDRIC)
48 px = cyl_radext * cos (na*cyl_dtheta);
49 py = cyl_radext * sin (na*cyl_dtheta);
54 bool rind = (grid_type == GR_RIND || grid_type == GR_PART_RIND);
55 double sinphi = sin (cyl_phi0 + nh*cyl_dphi);
56 double cosphi = cos (cyl_phi0 + nh*cyl_dphi);
61 rayon = cyl_radint + nr*(cyl_radext-cyl_radint)/size_hx;
67 pz = cyl_radext*sinphi;
68 rayon = cyl_radhole + nr*(cyl_radext*cosphi - cyl_radhole)/size_hx;
69 rayon = std::max (cyl_radhole, rayon);
72 px = rayon * cos (na*cyl_dtheta);
73 py = rayon * sin (na*cyl_dtheta);
77 // ====================================================== controlRind
78 int Elements::controlRind (EnumGrid type, Vertex* cx, Vector* vx, Vector* vz,
79 double rext, double rint, double rhole,
80 Vertex* px, double angle,
81 int nrad, int nang, int nhaut,
82 double &phi0, double &phi1)
84 const double Epsil1 = 1e-6;
87 if (cx == NULL || vx == NULL || vz == NULL)
90 if (nrad<=0 || nang<=0 || nhaut<=0)
102 double nvx = vx->getNorm();
103 double nvz = vz->getNorm();
105 if (nvx < Epsil1 || nvz < Epsil1)
108 double alpha = asin (rhole/rext);
109 double beta = -M_PI*DEMI;
110 if (type==GR_HEMISPHERIC || type==GR_PART_SPHERIC)
116 double oh = ((px->getX() - cx->getX()) * vz->getDx()
117 + (px->getY() - cx->getY()) * vz->getDy()
118 + (px->getZ() - cx->getZ()) * vz->getDz()) / nvz;
122 beta = asin (oh/rext);
125 phi0 = std::max (alpha - M_PI*DEMI, beta);
126 phi1 = M_PI*DEMI - alpha;
129 // ====================================================== getHexas
130 int Elements::getHexas (Hexas& liste)
133 for (int nro = 0 ; nro<nbr_hexas ; nro++)
135 Hexa* cell = tab_hexa [nro];
136 if (cell!=NULL && cell->isValid())
137 liste.push_back (cell);
141 // ====================================================== assoCylinder
142 void Elements::assoCylinder (Vertex* ori, Vector* normal, double angle)
144 if (normal==NULL || ori==NULL)
149 normal->getCoord (vz);
150 ori ->getPoint (center);
151 assoCylinders (center, vz, angle, tangles);
153 // ====================================================== assoCylinders
154 void Elements::assoCylinders (Vertex* ori, Vector* normal, double angle,
155 RealVector& t_angles)
157 if (normal==NULL || ori==NULL)
161 normal->getCoord (vz);
162 ori ->getPoint (center);
163 assoCylinders (center, vz, angle, t_angles);
165 // ====================================================== assoCylinders
166 void Elements::assoCylinders (double* ori, double* vk, double angle,
167 RealVector& t_angles)
170 sprintf (name, "grid_%02d", el_id);
171 NewShape* geom = el_root->addShape (name, SH_CYLINDER);
175 // Real3 vk = { normal->getDx(), normal->getDy(), normal->getDz() };
176 // normer_vecteur (vk);
178 for (int nz=0 ; nz<size_vz ; nz++)
180 for (int nx=0 ; nx<size_vx ; nx++)
182 Vertex* pm = getVertexIJK (nx, 0, nz);
183 Real3 om = { pm->getX() - ori[dir_x],
184 pm->getY() - ori[dir_y],
185 pm->getZ() - ori[dir_z] };
187 double oh = prod_scalaire (om, vk);
190 for (int dd=dir_x; dd<=dir_z ; dd++)
192 ph [dd] = ori[dd] + oh*vk[dd];
193 hm [dd] = pm ->getCoord(dd) - ph[dd];
194 rayon += hm[dd] * hm[dd];
197 rayon = sqrt (rayon);
198 int subid = geom->addCircle (ph, rayon, vk, hm);
200 for (int ny=0 ; ny<size_hy ; ny++)
202 double pmin = t_angles [ny]/360;
203 double pmax = t_angles [ny+1]/360;
204 Edge* edge = getEdgeJ (nx, ny, nz);
205 geom->addAssociation (edge, subid, pmin, pmax);
206 cout << " assoCylinders : ny= " << ny << ", nz= " << nz
207 << " param = (" << pmin << ", " << pmax << ")\n";
211 // Association automatique des vertex non associes -> bph
212 // Traitement des faces spheriques
214 Real3 vi = { -vk[dir_x], -vk[dir_y], -vk[dir_z] };
218 case GR_HEMISPHERIC : // Pour l'exterieur
219 case GR_PART_SPHERIC :
220 assoRind (ori, vi, size_vx-1, geom);
222 case GR_PART_RIND : // Exterieur + interieur
224 assoRind (ori, vi, 0, geom);
225 assoRind (ori, vi, size_vx-1, geom);
232 // ====================================================== calcul_param
233 double calcul_param (double* ori, double* vi, Vertex* vert)
236 vert->getPoint (pnt);
237 calc_vecteur (ori, pnt, vj);
239 double kos = prod_scalaire (vi, vj);
240 double alpha = acos (kos) / (2*M_PI);
243 // ====================================================== assoRind
244 // Association des meridiennes
245 // Creation sphere geometrique + association faces
246 void Elements::assoRind (double* ori, double* vi, int nx, NewShape* geom)
249 double radius = nx==0 ? cyl_radint : cyl_radext;
250 int sphid = geom->addSphere (ori, radius);
253 int nb_secteurs = cyl_closed ? size_vy-1 : size_vy;
255 for (int ny=0 ; ny<nb_secteurs ; ny++)
257 Vertex* pm = getVertexIJK (nx, ny, nz1);
258 Real3 vj = { pm->getX(), pm->getY(), pm->getZ() };
259 prod_vectoriel (vi, vj, vk);
260 double rayon = cyl_radint + nx*(cyl_radext-cyl_radint)/size_hx;
261 int subid = geom->addCircle (ori, rayon, vk, vi);
263 for (int nz=0 ; nz<size_hz ; nz++)
265 Quad* quad = getQuadJK (nx, ny, nz);
266 Edge* edge = getEdgeK (nx, ny, nz);
267 Vertex* nd1 = edge->getVertex (V_AMONT);
268 Vertex* nd2 = edge->getVertex (V_AVAL);
269 double pmin = calcul_param (ori, vi, nd1);
270 double pmax = calcul_param (ori, vi, nd2);
271 cout << " assoRind : ny= " << ny << ", nz= " << nz
272 << " param = (" << pmin << ", " << pmax << ")\n";
274 geom->addAssociation (edge, subid, pmin, pmax);
275 geom->addAssociation (quad, sphid);
279 // ====================================================== assoCircle
280 // ==== utilise pour les spheres carrees
281 void Elements::assoCircle (double* center, Edge* ed1, Edge* ed2, NewShape* geom)
283 Real3 oa, ob, normal;
284 Real3 pta, ptb, ptc, ptd;
287 // Les 2 edges dont les petits cotes d'un rectangle de rapport L/l=sqrt(2)
288 // Soit le cercle circonscrit a ce rectangle.
289 // * la largeur est balayee par l'angle alpha
290 // * la longueur par l'angle beta = pi -alpha
292 ed1->getVertex(V_AMONT)->getPoint (pta);
293 ed1->getVertex(V_AVAL )->getPoint (ptb);
294 ed2->getVertex(V_AMONT)->getPoint (ptc);
295 ed2->getVertex(V_AVAL )->getPoint (ptd);
297 double d1 = calc_distance (pta, ptc);
298 double d2 = calc_distance (pta, ptd);
302 ed2->getVertex(V_AMONT)->getPoint (ptd);
303 ed2->getVertex(V_AVAL )->getPoint (ptc);
306 calc_vecteur (center, pta, oa);
307 calc_vecteur (center, ptb, ob);
308 prod_vectoriel (oa, ob, normal);
310 double rayon = calc_norme (oa);
311 int subid = geom->addCircle (center, rayon, normal, oa);
313 const double alpha = atan (sqrt(2.)/2)/M_PI; // angle proche de 70.528 degres
314 // asso1->setBounds (0, alpha);
315 // asso2->setBounds (0.5, alpha + 0.5);
317 geom->addAssociation (ed1, subid, 0.0, alpha);
318 geom->addAssociation (ed2, subid, 0.5, alpha+0.5);
320 // ====================================================== assoSphere
321 void Elements::assoSphere (double* center, Edge* t_edge[], Quad* t_quad[])
324 sprintf (name, "grid_%02d", el_id);
325 NewShape* geom = el_root->addShape (name, SH_SPHERE);
326 geom -> openShape ();
330 assoCircle (center, t_edge [E_AC], t_edge [E_BD], geom);
331 assoCircle (center, t_edge [E_AD], t_edge [E_BC], geom);
332 assoCircle (center, t_edge [E_AE], t_edge [E_BF], geom);
333 assoCircle (center, t_edge [E_AF], t_edge [E_BE], geom);
334 assoCircle (center, t_edge [E_CE], t_edge [E_DF], geom);
335 assoCircle (center, t_edge [E_CF], t_edge [E_DE], geom);
337 t_edge[E_AC]->getVertex(V_AMONT)->getPoint (sommet);
338 double radius = calc_distance (center, sommet);
340 int sphid = geom -> addSphere (center, radius);
343 for (int nf=0 ; nf < HQ_MAXI ; nf++)
344 t_quad[nf]->addAssociation (geom, sphid);
346 // ==================================================== propagateAssociation
347 int Elements::propagateAssociation (Edge* orig, Edge* dest, Edge* dir)
351 if (revo_lution || orig==NULL || dest==NULL || dir==NULL)
354 const Shapes& tab_shapes = orig->getAssociations ();
355 const Shapes& tab_dest = dest->getAssociations ();
356 int nbdest = tab_dest.size();
357 int nbshapes = tab_shapes.size();
358 bool on_edge = nbshapes!=0 && nbdest==0;
360 Vertex* vo1 = orig->commonVertex (dir);
361 Vertex* vd1 = dest->commonVertex (dir);
362 Vertex* vo2 = orig->opposedVertex (vo1);
363 Vertex* vd2 = dest->opposedVertex (vd1);
365 if (vo1==NULL || vd1==NULL)
369 Real3 pa, pb, vdir1, vdir2;
370 calc_vecteur (vo1->getPoint (pa), vd1->getPoint (pb), vdir1);
371 calc_vecteur (vo2->getPoint (pa), vd2->getPoint (pb), vdir2);
373 double dd = calc_distance (vdir1, vdir2);
374 bool para = dd < 1.0e-3;
378 for (int nro=0 ; nro<nbshapes ; nro++)
380 Shape* shape = tab_shapes[nro];
383 string brep = shape->getBrep();
384 translate_brep (brep, vdir1, trep);
385 // Shape* tshape = new Shape (trep);
386 // tshape->setBounds (shape->getStart(), shape->getEnd());
387 // dest->addAssociation (tshape);
392 double* vdir = vdir1;
393 for (int nro=V_AMONT ; nro<=V_AVAL ; nro++)
395 Shape* shape = vo1->getAssociation ();
396 if (shape!=NULL && vd1->getAssociation ()==NULL)
398 string brep = shape->getBrep();
399 translate_brep (brep, vdir, trep);
400 // Shape* tshape = new Shape (trep);
401 // vd1->setAssociation (tshape);
410 // ==================================================== prismAssociation
411 int Elements::prismAssociation (Edge* lorig, Edge* ldest, int nh)
413 if (lorig==NULL || ldest==NULL)
417 int nbshapes = lorig->countAssociation ();
421 NewShape* new_shape = getShape ();
422 for (int nro=0 ; nro<nbshapes ; nro++)
424 AssoEdge* asso = lorig->getAssociation (nro);
425 EdgeShape* shape = asso ->getEdgeShape();
426 double p1 = asso ->getStart();
427 double p2 = asso ->getEnd ();
431 sprintf (name, "0x%lx#%d", (unsigned long) shape, nh);
432 map<string,int>::iterator iter = map_shape.find (name);
433 if (iter != map_shape.end())
434 subid = iter->second;
436 subid = map_shape[name] = new_shape->transfoShape (cum_matrix, shape);
438 new_shape->addAssociation (ldest, subid, p1, p2);
439 printf (" prismAsso : %s -> %s(%d) = %s [ %g , %g]\n",
440 lorig->getName(), ldest->getName(), nh, name, p1, p2);
444 // ====================================================== assoResiduelle
445 void Elements::assoResiduelle ()
447 // int nbre = tab_vertex.size();
448 // for (int nv=0 ; nv<nbre ; nv++)
450 // geom_asso_point (tab_vertex [nv]);
453 // ====================================================== moveDisco
454 void Elements::moveDisco (Hexa* hexa)
458 hexa->getCenter (center);
459 matrix.defScale (center, 0.55);
461 int nbre = tab_vertex.size();
462 for (int nv=0 ; nv<nbre ; nv++)
464 matrix.perform (tab_vertex [nv]);
467 // =================================================== getStrate
468 Hexa* Elements::getStrate (int couche, EnumHQuad nroface)
471 int nro = couche <= 0 ? 0 : (couche-1)*HQ_MAXI + nroface + 1;
473 if (nbr_hexas==0 || nro >= nbr_hexas)
476 cell = tab_hexa [nro];
480 // ============================================================ setHexa
481 void Elements::setHexa (Hexa* elt, int nro)
483 if (nro >=0 && nro < nbr_hexas)
484 tab_hexa [nro] = elt;
486 // ============================================================ setQuad
487 void Elements::setQuad (Quad* elt, int nro)
489 if (nro >=0 && nro < nbr_quads)
490 tab_quad [nro] = elt;
492 // ============================================================ setEdge
493 void Elements::setEdge (Edge* elt, int nro)
495 if (nro >=0 && nro < nbr_edges)
496 tab_edge [nro] = elt;
498 // ============================================================ setVertex
499 void Elements::setVertex (Vertex* elt, int nro)
501 if (nro >=0 && nro < nbr_vertex)
502 tab_vertex [nro] = elt;
504 // -----------------------------------------------------------------------
505 // -----------------------------------------------------------------------
506 // ============================================================ getHexa
507 Hexa* Elements::getHexa (int nro)
509 DumpStart ("getHexa", nro);
512 int nombre=tab_hexa.size();
513 // if (nro >=0 && nro < nbr_hexas && el_status == HOK Abu 2010/05/06
514 if (nro >=0 && nro < nombre && el_status == HOK
515 && tab_hexa [nro] != NULL && tab_hexa [nro]->isValid())
516 elt = tab_hexa [nro];
521 // ============================================================ getQuad
522 Quad* Elements::getQuad (int nro)
524 DumpStart ("getQuad", nro);
527 if (nro >=0 && nro < nbr_quads && el_status == HOK
528 && tab_quad [nro] != NULL && tab_quad [nro]->isValid())
529 elt = tab_quad [nro];
534 // ============================================================ getEdge
535 Edge* Elements::getEdge (int nro)
537 DumpStart ("getEdge", nro);
540 if (nro >=0 && nro < nbr_edges && el_status == HOK
541 && tab_edge [nro] != NULL && tab_edge [nro]->isValid())
542 elt = tab_edge [nro];
547 // ============================================================ getVertex
548 Vertex* Elements::getVertex (int nro)
550 DumpStart ("getVertex", nro);
553 if (nro >=0 && nro < nbr_vertex && el_status == HOK
554 && tab_vertex [nro] != NULL && tab_vertex [nro]->isValid())
555 elt = tab_vertex [nro];
560 // ============================================================ indVertex
561 int Elements::indVertex (int nquad, int nsommet, int nh)
563 int nro = nsommet + QUAD4*nquad + nbr_orig*QUAD4*(nh+1);
566 // ============================================================ nroVertex
567 int Elements::nroVertex (int nquad, int nsommet, int nh)
569 int nro = nsommet + QUAD4*nquad + nbr_orig*QUAD4*nh;
572 // ============================================================ indVertex
573 int Elements::indVertex (int ref_edge, int nh)
575 int nro = ref_edge + nbr_orig*QUAD4*nh;
578 // ============================================================ nroEdgeH
579 int Elements::nroEdgeH (int nvertex)
581 return QUAD4*nbr_orig*gr_hauteur + nvertex;
583 // ============================================================ nroEdgeH
584 int Elements::nroEdgeH (int nquad, int nsommet, int nh)
586 return QUAD4*nbr_orig*gr_hauteur + indVertex (nquad, nsommet, nh);
588 // ============================================================ nroHexa
589 int Elements::nroHexa (int nquad, int nh)
591 int nro = gr_hauteur*nquad + nh;
595 // ============================================================ addHexa
596 void Elements::addHexa (Hexa* element)
598 tab_hexa.push_back (element);
601 // ============================================================ addQuad
602 void Elements::addQuad (Quad* element)
604 tab_quad.push_back (element);
607 // ============================================================ addEdge
608 void Elements::addEdge (Edge* element)
610 tab_edge.push_back (element);
613 // ============================================================ addVertex
614 void Elements::addVertex (Vertex* element)
616 tab_vertex.push_back (element);
619 // ============================================================ findHexa
620 int Elements::findHexa (Hexa* element)
622 int nbre = tab_hexa.size();
623 for (int nro=0 ; nro<nbre ; nro++)
624 if (tab_hexa [nro] == element)
628 // ============================================================ findQuad
629 int Elements::findQuad (Quad* element)
631 int nbre = tab_quad.size();
632 for (int nro=0 ; nro<nbre ; nro++)
633 if (tab_quad [nro] == element)
637 // ============================================================ findEdge
638 int Elements::findEdge (Edge* element)
640 int nbre = tab_edge.size();
641 for (int nro=0 ; nro<nbre ; nro++)
642 if (tab_edge [nro] == element)
646 // ============================================================ findVertex
647 int Elements::findVertex (Vertex* element)
649 int nbre = tab_vertex.size();
650 for (int nro=0 ; nro<nbre ; nro++)
651 if (tab_vertex [nro] == element)
655 // ========================================================= saveVtk (avec nro)
656 int Elements::saveVtk (cpchar radical, int &nro)
659 sprintf (num, "%d", nro);
662 string filename = radical;
665 int ier = saveVtk (filename.c_str());