// C++ : Gestion des Hexaedres
-// Copyright (C) 2009-2012 CEA/DEN, EDF R&D
+// Copyright (C) 2009-2016 CEA/DEN, EDF R&D
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
-// version 2.1 of the License.
+// version 2.1 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
h_vertex [V_ADE] = vc; // = vb ; Modif Abu 30/08/2011
h_vertex [V_ADF] = vd;
- h_vertex [V_BCE] = ve;
+ h_vertex [V_BCE] = ve;
h_vertex [V_BCF] = vf; // = vg ; Modif Abu 30/08/2011
h_vertex [V_BDE] = vg; // = vf ; Modif Abu 30/08/2011
h_vertex [V_BDF] = vh;
for (int nro=0 ; nro<HE_MAXI ; nro++)
{
- h_edge[nro] = new Edge (h_vertex[glob->EdgeVertex (nro, V_AMONT)],
+ h_edge[nro] = new Edge (h_vertex[glob->EdgeVertex (nro, V_AMONT)],
h_vertex[glob->EdgeVertex (nro, V_AVAL)]);
}
h_quad[nro] -> addParent (this);
}
majReferences ();
+ if (el_root != NULL && el_status==HOK)
+ el_root->addHexa (this);
}
// ======================================================== Constructeur 2
Hexa::Hexa (Quad* qa, Quad* qb, Quad* qc, Quad* qd, Quad* qe, Quad* qf)
majReferences ();
if (el_status != HOK)
- {
+ {
printf (" +++++++++++++++++++++++++++++++++++++++++++ \n");
printf (" +++ Heaedre impossible \n");
printf (" +++++++++++++++++++++++++++++++++++++++++++ \n");
printf (" +++++++++++++++++++++++++++++++++++++++++++ \n");
// exit (1);
}
+ else
+ el_root->addHexa (this);
}
// ========================================================= Constructeur 3
// === a utiliser uniquement pour le clonage
for (int nro=0 ; nro<HQ_MAXI ; nro++) h_quad [nro] = NULL;
for (int nro=0 ; nro<HE_MAXI ; nro++) h_edge [nro] = NULL;
for (int nro=0 ; nro<HV_MAXI ; nro++) h_vertex [nro] = NULL;
+ h_clone = NULL;
+
+ if (el_root != NULL && el_status==HOK)
+ el_root->addHexa (this);
}
// ======================================================== majReferences
void Hexa::majReferences ()
h_edge [arete] = h_quad[face1]->commonEdge (h_quad[face2]);
if (h_edge [arete]==NULL)
{
- el_root->putError (W_H_BAD_EDGE,
+ el_root->putError (W_H_BAD_EDGE,
el_root->glob->namofHexaEdge (arete));
el_status = 888;
}
h_vertex [node] = hv;
if (hv == NULL)
{
- el_root->putError (W_H_BAD_VERTEX,
+ el_root->putError (W_H_BAD_VERTEX,
el_root->glob->namofHexaVertex(node));
el_status = 888;
}
else if (hv == NULL || h_edge[ne3]->index (hv)<0)
{
char b[10];
- el_root->putError (W_H_BAD_VERTEX,
+ el_root->putError (W_H_BAD_VERTEX,
el_root->glob->namofHexaVertex(node));
el_status = 888;
- printf ("%s = %s\n", el_root->glob->namofHexaVertex(node),
+ printf ("%s = %s\n", el_root->glob->namofHexaVertex(node),
hv->getName(b));
- printf ("%s = %s\n", el_root->glob->namofHexaEdge(ne1),
+ printf ("%s = %s\n", el_root->glob->namofHexaEdge(ne1),
h_edge[ne1]->getName(b));
- printf ("%s = %s\n", el_root->glob->namofHexaEdge(ne2),
+ printf ("%s = %s\n", el_root->glob->namofHexaEdge(ne2),
h_edge[ne2]->getName(b));
- printf ("%s = %s\n", el_root->glob->namofHexaEdge(ne3),
+ printf ("%s = %s\n", el_root->glob->namofHexaEdge(ne3),
h_edge[ne3]->getName(b));
}
}
// ======================================================== controlerFaces
void Hexa::controlerFaces ()
{
- for (int n1=0 ; n1<HQ_MAXI ; n1++)
+ for (int n1=0 ; n1<HQ_MAXI ; n1++)
{
if (BadElement (h_quad [n1]))
{
- el_root->putError (W_H_NULL_QUAD,
+ el_root->putError (W_H_NULL_QUAD,
el_root->glob->namofHexaQuad (n1));
setError (886);
return;
}
- for (int n2=n1+1 ; n2<HQ_MAXI ; n2++)
+ for (int n2=n1+1 ; n2<HQ_MAXI ; n2++)
if (h_quad [n1] == h_quad[n2])
{
- el_root->putError (W_H_EQ_QUAD,
- el_root->glob->namofHexaQuad (n1),
+ el_root->putError (W_H_EQ_QUAD,
+ el_root->glob->namofHexaQuad (n1),
el_root->glob->namofHexaQuad (n2));
setError (888);
}
}
+ for (int dd=0 ; dd<DIM3 ; dd++)
+ {
+ Quad* qa = h_quad [2*dd];
+ Quad* qb = h_quad [2*dd+1];
+ Edge* cut = qa->inter (qb);
+ if (cut != NULL)
+ {
+ bool more = true;
+ for (int nc=2*dd+2 ; more && nc<HQ_MAXI ; nc++)
+ {
+ Edge* cut = qa->inter (h_quad[nc]);
+ if (cut==NULL)
+ {
+ more = false;
+ // cout << " ... le quad oppose au quad " << 2*dd
+ // << " est le " << nc << endl;
+ qb = h_quad[nc];
+ h_quad[nc] = h_quad [2*dd+1];
+ h_quad[2*dd+1] = qb;
+ }
+ }
+ if (more)
+ {
+ char num [10];
+ sprintf (num, "%d", 2*dd+1);
+ el_root->putError ("addHexa : the %sth quad has no opposed quad",
+ num);
+ setError (886);
+ return ;
+ }
+ }
+ }
}
// ======================================================== controlerSommets
void Hexa::controlerSommets ()
{
- for (int n1=0 ; n1<HV_MAXI ; n1++)
+ for (int n1=0 ; n1<HV_MAXI ; n1++)
{
if (BadElement (h_vertex [n1]))
{
- el_root->putError (W_H_NULL_QUAD,
+ el_root->putError (W_H_NULL_QUAD,
el_root->glob->namofHexaVertex (n1));
setError (886);
return;
}
- for (int n2=n1+1 ; n2<HQ_MAXI ; n2++)
+ for (int n2=n1+1 ; n2<HQ_MAXI ; n2++)
if (h_vertex [n1] == h_vertex[n2])
{
- el_root->putError (W_H_EQ_QUAD,
- el_root->glob->namofHexaVertex (n1),
+ el_root->putError (W_H_EQ_QUAD,
+ el_root->glob->namofHexaVertex (n1),
el_root->glob->namofHexaVertex (n2));
setError (888);
}
controlerSommet (V_BCE, E_BC, E_BE, E_CE);
controlerSommet (V_BCF, E_BC, E_BF, E_CF);
controlerSommet (V_BDF, E_BD, E_BF, E_DF);
- controlerSommet (V_BDE, E_BD, E_BE, E_DE);
+ controlerSommet (V_BDE, E_BD, E_BE, E_DE);
}
// ======================================================== Inter
Quad* Hexa::Inter (Hexa* other)
// ======================================================= razNodes
void Hexa::razNodes ()
{
- for (int nb=0 ; nb<HV_MAXI ; nb++)
+ for (int nb=0 ; nb<HV_MAXI ; nb++)
h_vertex[nb]->setMark (NO_COUNTED);
}
// ======================================================= countNodes
int Hexa::countNodes ()
{
int nombre = 0;
- for (int nb=0 ; nb<HV_MAXI ; nb++)
- if (h_vertex[nb]->getMark () == NO_COUNTED)
+ for (int nb=0 ; nb<HV_MAXI ; nb++)
+ if (h_vertex[nb]->getMark () == NO_COUNTED)
{
h_vertex[nb]->setMark (NO_USED);
nombre ++;
const double minvtk = 1e-30;
Real3 koord;
- for (int nb=0 ; nb<HV_MAXI ; nb++)
+ for (int nb=0 ; nb<HV_MAXI ; nb++)
if (h_vertex[nb]->getMark()==NO_USED)
{
h_vertex[nb]->getPoint (koord);
// ======================================================= colorNodes
void Hexa::colorNodes (pfile vtk)
{
- for (int nb=0 ; nb<HV_MAXI ; nb++)
+ for (int nb=0 ; nb<HV_MAXI ; nb++)
if (h_vertex[nb]->getMark()>=0)
{
double color = 100*(h_vertex[nb]->getScalar()+1);
// ======================================================= moveNodes
void Hexa::moveNodes (Matrix* matrice)
{
- for (int nb=0 ; nb<HV_MAXI ; nb++)
+ for (int nb=0 ; nb<HV_MAXI ; nb++)
if (h_vertex[nb]->getMark()!=IS_USED)
{
matrice->perform (h_vertex[nb]);
// ======================================================= transform
void Hexa::transform (Matrix* matrice)
{
- for (int nb=0 ; nb<HV_MAXI ; nb++)
+ for (int nb=0 ; nb<HV_MAXI ; nb++)
matrice->perform (h_vertex[nb]);
}
// ======================================================= printHexa
if (h_edge[nro]->getMark()<0)
h_edge[nro]->propager (prop, nro);
}
-// ========================================================= saveXml
+// ========================================================= saveXml
void Hexa::saveXml (XmlWriter* xml)
{
char ident[12];
xml->openMark ("Hexa");
xml->addAttribute ("id", ident);
xml->addAttribute ("quads", quads);
- if (el_name!=ident)
+ if (el_name!=ident)
xml->addAttribute ("name", el_name);
xml->closeMark ();
}
-// ========================================================= findQuad
+// ========================================================= findQuad
int Hexa::findQuad (Quad* element)
{
for (int nro=0 ; nro<HQ_MAXI ; nro++)
return NOTHING;
}
-// ========================================================= findEdge
+// ========================================================= findEdge
int Hexa::findEdge (Edge* element)
{
for (int nro=0 ; nro<HE_MAXI ; nro++)
return NOTHING;
}
-// ========================================================= findVertex
+// ========================================================= findVertex
int Hexa::findVertex (Vertex* element)
{
for (int nro=0 ; nro<HV_MAXI ; nro++)
return NOTHING;
}
-// ========================================================= disconnectQuad
+// ========================================================= disconnectQuad
Elements* Hexa::disconnectQuad (Quad* quad)
{
if (quad==NULL)
printf (" a dissocier\n");
else
printf ("\n");
-
+
}
}
Quad* pface = h_quad [ind_opp_quad [nro]];
int bid;
int ncut = pface->inter (quad, bid);
- Edge* ecut = pface->getEdge ((ncut+1) MODULO QUAD4);
+ Edge* ecut = pface->getEdge ((ncut+1) MODULO QUAD4);
Vertex* vopp = ecut->getVertex(V_AMONT);
if (vopp==o_v0)
vopp = ecut->getVertex (V_AVAL);
else if (o_v0 != ecut->getVertex (V_AVAL));
{
- ecut = pface->getEdge ((ncut+3) MODULO QUAD4);
+ ecut = pface->getEdge ((ncut+3) MODULO QUAD4);
vopp = ecut->getVertex(V_AMONT);
if (vopp==o_v0)
vopp = ecut->getVertex (V_AVAL);
}
}
- Quad* new_quad = new Quad (new_node[0], new_node[1], new_node[2],
+ Quad* new_quad = new Quad (new_node[0], new_node[1], new_node[2],
new_node[3]);
Quad* new_opp_quad [QUAD4];
new_opp_quad [nro] = NULL;
if (make_quad[nro])
{
- int nro1 = (nro+1) MODULO QUAD4;
+ int nro1 = (nro+1) MODULO QUAD4;
Edge* n_edge0 = new_quad->getEdge (nro);
Edge* n_edge1 = new_opp_edge [nro];
int iv3 = n_edge3->inter (n_edge0);
if (iv1 <0 || iv3 <0)
return NULL;
-
+
Quad* o_face = h_quad [ind_opp_quad [nro]];
- Edge* edge2 = o_face->findEdge (n_edge1->getVertex (1-iv1),
+ Edge* edge2 = o_face->findEdge (n_edge1->getVertex (1-iv1),
n_edge3->getVertex (1-iv3));
if (edge2==NULL)
return NULL;
nouveaux->moveDisco (this);
return nouveaux;
}
-// ========================================================= disconnectEdge
+// ========================================================= disconnectEdge
Elements* Hexa::disconnectEdge (Edge* arete)
{
int nedge = findEdge (arete);
if ( n_edge[nro]==NULL && h_edge[nro] != NULL
&& h_edge[nro]->getNbrParents()>2)
{
- Vertex* va = h_edge[nro]->getVertex (V_AMONT);
- Vertex* vb = h_edge[nro]->getVertex (V_AVAL);
+ Vertex* va = h_edge[nro]->getVertex (V_AMONT);
+ Vertex* vb = h_edge[nro]->getVertex (V_AVAL);
if (va==old_amont)
n_edge [nro] = new Edge (new_amont, vb);
}
}
- // Un quad non remplace, qui contient un edge remplace
+ // Un quad non remplace, qui contient un edge remplace
// commun a plus de 2 Hexas
// doit etre duplique
duplic = true;
}
}
- if (duplic)
- n_quad[nro] = new Quad (qedge[Q_A], qedge[Q_B],
+ if (duplic)
+ n_quad[nro] = new Quad (qedge[Q_A], qedge[Q_B],
qedge[Q_C], qedge[Q_D]);
}
nouveaux->moveDisco (this);
return nouveaux;
}
-// ========================================================= disconnectVertex
+// ========================================================= disconnectVertex
Elements* Hexa::disconnectVertex (Vertex* noeud)
{
if (debug())
{
new_quad [nro] = NULL;
// Cete face contient le sommet et est commune a 2 hexas
- if ( h_quad[nro]->indexVertex(noeud) >= 0
+ if ( h_quad[nro]->indexVertex(noeud) >= 0
&& h_quad[nro]->getNbrParents () >= 2)
{
int nbmod = 0;
int indv = arete->index (noeud);
if (indv>=0)
{
- nbmod++;
+ nbmod++;
int hed = findEdge (arete);
if (hed<0)
return NULL;
if (new_edge [hed]==NULL)
- new_edge [hed] = new Edge (new_node,
+ new_edge [hed] = new Edge (new_node,
arete->getVertex(1-indv));
tedge [qed] = new_edge [hed];
}
}
if (nbmod!=2)
- return NULL;
+ return NULL;
new_quad [nro] = new Quad (tedge[0], tedge[1], tedge[2], tedge[3]);
}
}
Elements* nouveaux = new Elements (el_root);
- for (int nro=0 ; nro<HQ_MAXI ; nro++)
+ for (int nro=0 ; nro<HQ_MAXI ; nro++)
if (new_quad [nro] != NULL)
{
replaceQuad (h_quad [nro], new_quad [nro]);
nouveaux->addQuad (new_quad[nro]);
}
- for (int nro=0 ; nro<HE_MAXI ; nro++)
+ for (int nro=0 ; nro<HE_MAXI ; nro++)
if (new_edge [nro] != NULL)
{
replaceEdge (h_edge [nro], new_edge [nro]);
nouveaux->moveDisco (this);
return nouveaux;
}
-// ========================================================= getBase
+// ========================================================= getBase
int Hexa::getBase (Vertex* orig, Edge* normale)
{
for (int nq=0 ; nq<HQ_MAXI ; nq++)
{
- if ( h_quad[nq]->indexVertex(orig) >= 0
+ if ( h_quad[nq]->indexVertex(orig) >= 0
&& h_quad[nq]->indexEdge (normale) < 0)
return nq;
}
{
for (int nro=0 ; nro<HQ_MAXI ; nro++)
{
- if (h_quad[nro]==old)
+ if (h_quad[nro]==old)
{
h_quad[nro] = par;
if (debug())
}
}
}
-
+
}
// ======================================================== replaceEdge
void Hexa::replaceEdge (Edge* old, Edge* par)
{
for (int nro=0 ; nro<HE_MAXI ; nro++)
{
- if (h_edge[nro]==old)
+ if (h_edge[nro]==old)
{
h_edge[nro] = par;
if (debug())
{
for (int nro=0 ; nro<HV_MAXI ; nro++)
{
- if (h_vertex [nro]==old)
+ if (h_vertex [nro]==old)
{
h_vertex [nro] = par;
if (debug())
// ======================================================== removeConnected
void Hexa::removeConnected ()
{
-
+
if (el_type == EL_REMOVED)
return;
{
Quad* face = h_quad [nro];
int nbhexas = face->getNbrParents ();
-
+
for (int nc=0 ; nc<nbhexas ; nc++)
{
Hexa* cell = face->getParent(nc);
printf (")\n");
printf (" = (");
-
+
for (int nro=0; nro<HE_MAXI ; nro++)
{
PrintName (h_edge[nro]);
- if (nro==3 || nro ==7)
+ if (nro==3 || nro ==7)
printf ("\n ");
}
printf (")\n");
for (int nro=0; nro<HV_MAXI ; nro++)
PrintName (h_vertex[nro]);
printf (")\n");
- Real3 cg;
+ Real3 cg;
getCenter (cg);
printf ("cg = (%g, %g, %g)\n", cg[0], cg[1], cg[2]);
else if (face == h_quad [Q_F]) return h_quad [Q_F];
else return NULL;
}
-// ========================================================= findQuad
+// ========================================================= findQuad
Quad* Hexa::findQuad (Edge* ed1, Edge* ed2)
{
for (int nro=0 ; nro<HQ_MAXI ; nro++)
{
if ( h_quad[nro]->indexEdge (ed1) >= 0
- && h_quad[nro]->indexEdge (ed2) >= 0)
+ && h_quad[nro]->indexEdge (ed2) >= 0)
return h_quad [nro];
}
return NULL;
}
-// ========================================================= findEdge
+// ========================================================= findEdge
Edge* Hexa::findEdge (Vertex* v1, Vertex* v2)
{
for (int nro=0 ; nro<HE_MAXI ; nro++)
{
if ( h_edge[nro]->index (v1) >= 0
- && h_edge[nro]->index (v2) >= 0)
+ && h_edge[nro]->index (v2) >= 0)
return h_edge [nro];
}
return NULL;
}
-// ====================================================== getPerpendicularEdge
-Edge* Hexa::getPerpendicularEdge (Quad* quad, Vertex* vertex)
+// ====================================================== opposedVertex
+Vertex* Hexa::opposedVertex (Quad* quad, Vertex* vertex)
{
if (quad==NULL || vertex==NULL)
return NULL;
for (int nro=0 ; nro<HE_MAXI ; nro++)
{
- if (quad->indexEdge (h_edge[nro])<0 && h_edge[nro]->index(vertex)>=0)
+ Edge* edge = h_edge [nro];
+ int nv = edge->index (vertex);
+ if (nv>=0 && quad->indexEdge(edge) <0)
+ return edge->getVertex (1-nv);
+ }
+
+ return NULL;
+}
+// ====================================================== perpendicularEdge
+Edge* Hexa::perpendicularEdge (Quad* quad, Vertex* vertex)
+{
+ if (quad==NULL || vertex==NULL)
+ return NULL;
+
+ int nv = quad->indexVertex (vertex);
+ int nq = findQuad (quad);
+ if (nv<0 || nq<0)
+ return NULL;
+
+ for (int nro=0 ; nro<HE_MAXI ; nro++)
+ {
+ if (quad->indexEdge (h_edge[nro])<0 && h_edge[nro]->index(vertex)>=0)
return h_edge [nro];
}
return NULL;
}
+// ====================================================== perpendicularQuad
+Quad* Hexa::perpendicularQuad (Quad* quad, Edge* edge)
+{
+ if (BadElement (quad) || BadElement (edge))
+ return NULL;
+
+ int qed = quad->indexEdge (edge);
+ int ned = findEdge (edge);
+ int nq = findQuad (quad);
+ if (qed <0 || ned<0 || nq<0)
+ return NULL;
+
+ for (int nro=0 ; nro<HQ_MAXI ; nro++)
+ {
+ if (nro != nq)
+ {
+ Quad* face = h_quad[nro];
+ if (EltIsValid(face) && face->indexEdge (edge)>=0)
+ return face;
+ }
+ }
+ return NULL;
+}
+// ============================================================ getQuad
+Quad* Hexa::getQuad (int nro)
+{
+ Quad* elt = NULL;
+ if (nro >=0 && nro < HQ_MAXI && el_status == HOK && h_quad [nro]->isValid())
+ elt = h_quad [nro];
+
+ return elt;
+}
+// ============================================================ getEdge
+Edge* Hexa::getEdge (int nro)
+{
+ Edge* elt = NULL;
+ if (nro >=0 && nro < HE_MAXI && el_status == HOK && h_edge [nro]->isValid())
+ elt = h_edge [nro];
+
+ return elt;
+}
+// ============================================================ getVertex
+Vertex* Hexa::getVertex (int nro)
+{
+ Vertex* elt = NULL;
+ if (nro >=0 && nro < HV_MAXI && el_status == HOK && h_vertex [nro]->isValid())
+ elt = h_vertex [nro];
+
+ return elt;
+}
+// ============================================================ getCenter
+double* Hexa::getCenter (double centre[])
+{
+ centre [dir_x] = centre [dir_y] = centre [dir_z] = 0;
+
+ for (int nv=0 ; nv<HV_MAXI ; nv++)
+ {
+ centre [dir_x] += h_vertex[nv]->getX ();
+ centre [dir_y] += h_vertex[nv]->getY ();
+ centre [dir_z] += h_vertex[nv]->getZ ();
+ }
+
+ centre [dir_x] /= HV_MAXI;
+ centre [dir_y] /= HV_MAXI;
+ centre [dir_z] /= HV_MAXI;
+ return centre;
+}
+// =============================================================== definedBy
+bool Hexa::definedBy (Vertex* v1, Vertex* v2)
+{
+ for (int n1=0 ; n1< HV_MAXI ; n1++)
+ {
+// ( Diagonale ) Dessus
+ int n2 = (n1 + 2) MODULO HV_MAXI + HV_MAXI;
+ if ( (v1 == h_vertex[n1] && v2 == h_vertex[n2])
+ || (v1 == h_vertex[n2] && v2 == h_vertex[n1])) return true;
+ }
+ return false;
+}
+// =============================================================== definedBy
+bool Hexa::definedBy (Quad* qa, Quad* qb)
+{
+ if (qa==qb || BadElement (qa) || BadElement (qb))
+ return false;
+
+ bool p1 = false, p2 = false;
+ for (int nq=0 ; nq< HQ_MAXI ; nq++)
+ {
+ if (qa == h_quad[nq])
+ p1 = true;
+ else if (qb == h_quad[nq])
+ p2 = true;
+ }
+ return p1 && p2;
+}
+// =============================================================== setColor
+void Hexa::setColor (double val)
+{
+ for (int nc=0 ; nc< HV_MAXI ; nc++)
+ h_vertex[nc] -> setColor (val);
+}
+// ============================================================== markElements
+void Hexa::markElements (int marque)
+{
+ for (int nc=0 ; nc< HQ_MAXI ; nc++) h_quad [nc] -> setMark (marque);
+ for (int nc=0 ; nc< HE_MAXI ; nc++) h_edge [nc] -> setMark (marque);
+ for (int nc=0 ; nc< HV_MAXI ; nc++) h_vertex[nc] -> setMark (marque);
+}
+// =============================================================== duplicate
+void Hexa::duplicate ()
+{
+ h_clone = new Hexa (GetClone (h_quad [Q_A]),
+ GetClone (h_quad [Q_B]),
+ GetClone (h_quad [Q_C]),
+ GetClone (h_quad [Q_D]),
+ GetClone (h_quad [Q_E]),
+ GetClone (h_quad [Q_F]));
+}
END_NAMESPACE_HEXA