TRUST 1.9.8
HPC thermohydraulic platform
Loading...
Searching...
No Matches
Quadrangle_VEF.cpp
1/****************************************************************************
2* Copyright (c) 2025, CEA
3* All rights reserved.
4*
5* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
9*
10* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
11* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
12* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13*
14*****************************************************************************/
15
16#include <Quadrangle_VEF.h>
17#include <Domaine.h>
18#include <Triangle.h>
19#include <Polygon_geom_tools.h>
20
21// Definition des sommets :
22// y
23// ^
24// |
25// 2-----3
26// | |
27// | |
28// | |
29// 0-----1--> x
30//
31// Definition des faces d'un quadrangle:
32//
33// *--3--*
34// | |
35// 0 2
36// | |
37// *--1--*
38static int faces_sommets_quadra[4][2] =
39{
40 { 0, 2 },
41 { 0, 1 },
42 { 1, 3 },
43 { 2, 3 }
44};
45
46Implemente_instanciable_32_64(Quadrangle_VEF_32_64,"Quadrangle",Elem_geom_base_32_64<_T_>);
47
48template <typename _SIZE_>
50{
51 return s;
52}
53
54
55template <typename _SIZE_>
57{
58 return s;
59}
60
61
62/*! @brief Renvoie le nom LML d'un Quadrangle_VEF = "GOLGOTH24".
63 *
64 * @return (Nom&) toujours egal a "GOLGOTH24"
65 */
66template <typename _SIZE_>
68{
69 // static Nom nom="GOLGOTH24";
70 static Nom nom="VOXEL8";
71 if (dimension==3) nom="QUADRANGLE_3D";
72 return nom;
73}
74
75
76/*! @brief Renvoie 1 si l'element ielem du domaine associe a l'element geometrique contient le point
77 *
78 * de coordonnees specifiees par le parametre "pos".
79 * Renvoie 0 sinon.
80 *
81 * @param (DoubleVect& pos) coordonnees du point que l'on cherche a localiser
82 * @param (int ielem) le numero de l'element du domaine dans lequel on cherche le point.
83 * @return (int) 1 si le point de coordonnees specifiees appartient a l'element ielem 0 sinon
84 */
85template <typename _SIZE_>
86int Quadrangle_VEF_32_64<_SIZE_>::contient(const ArrOfDouble& pos, int_t element) const
87{
88 assert(pos.size_array()==2);
89 const Domaine_t& domaine=mon_dom.valeur();
90 const Domaine_t& dom=domaine;
91 int_t som0 = domaine.sommet_elem(element,0);
92 int_t som1 = domaine.sommet_elem(element,1);
93 int_t som2 = domaine.sommet_elem(element,2);
94 int_t som3 = domaine.sommet_elem(element,3);
95 // On regarde tout d'abord si le point cherche n'est pas un des
96 // sommets du quadrangle
97 if( (est_egal(dom.coord(som0,0),pos[0]) && est_egal(dom.coord(som0,1),pos[1]))
98 || (est_egal(dom.coord(som1,0),pos[0]) && est_egal(dom.coord(som1,1),pos[1]))
99 || (est_egal(dom.coord(som2,0),pos[0]) && est_egal(dom.coord(som2,1),pos[1]))
100 || (est_egal(dom.coord(som3,0),pos[0]) && est_egal(dom.coord(som3,1),pos[1])) )
101 return 1;
102 double prod,p0,p1,p2,p3;
103 // Calcul de prod = 01 vectoriel 02 selon z
104 prod = (dom.coord(som1,0)-dom.coord(som0,0))*(dom.coord(som2,1)-dom.coord(som0,1))
105 - (dom.coord(som1,1)-dom.coord(som0,1))*(dom.coord(som2,0)-dom.coord(som0,0));
106 double signe;
107 if (prod >= 0)
108 signe = 1;
109 else
110 signe = -1;
111 // Calcul de p0 = 0M vectoriel 1M selon z
112 p0 = (pos[0]-dom.coord(som0,0))*(pos[1]-dom.coord(som1,1))
113 - (pos[1]-dom.coord(som0,1))*(pos[0]-dom.coord(som1,0));
114 p0 *= signe;
115 // Calcul de p1 = 1M vectoriel 3M selon z
116 p1 = (pos[0]-dom.coord(som1,0))*(pos[1]-dom.coord(som3,1))
117 - (pos[1]-dom.coord(som1,1))*(pos[0]-dom.coord(som3,0));
118 p1 *= signe;
119 // Calcul de p2 = 3M vectoriel 2M selon z
120 p2 = (pos[0]-dom.coord(som3,0))*(pos[1]-dom.coord(som2,1))
121 - (pos[1]-dom.coord(som3,1))*(pos[0]-dom.coord(som2,0));
122 p2 *= signe;
123 // Calcul de p3 = 2M vectoriel 0M selon z
124 p3 = (pos[0]-dom.coord(som2,0))*(pos[1]-dom.coord(som0,1))
125 - (pos[1]-dom.coord(som2,1))*(pos[0]-dom.coord(som0,0));
126 p3 *= signe;
127 double epsilon=std::fabs(prod)*Objet_U::precision_geom;
128 if ((p0>-epsilon) && (p1>-epsilon) && (p2>-epsilon) && (p3>-epsilon))
129 return 1;
130 else
131 return 0;
132}
133
134
135/*! @brief Renvoie 1 si les sommets specifies par le parametre "pos" sont les sommets de l'element "element" du domaine associe a
136 *
137 * l'element geometrique.
138 *
139 * @param (IntVect& pos) les numeros des sommets a comparer avec ceux de l'elements "element"
140 * @param (int element) le numero de l'element du domaine dont on veut comparer les sommets
141 * @return (int) 1 si les sommets passes en parametre sont ceux de l'element specifie, 0 sinon
142 */
143template <typename _SIZE_>
145{
146 const Domaine_t& domaine=mon_dom.valeur();
147 if((domaine.sommet_elem(element,0)==som[0])&&
148 (domaine.sommet_elem(element,1)==som[1])&&
149 (domaine.sommet_elem(element,2)==som[2])&&
150 (domaine.sommet_elem(element,3)==som[3]))
151 return 1;
152 else
153 return 0;
154}
155
156/*! @brief Calcule les volumes des elements du domaine associe.
157 *
158 * @param (DoubleVect& volumes) le vecteur contenant les valeurs des des volumes des elements du domaine
159 */
160template <typename _SIZE_>
162{
163 const Domaine_t& domaine = mon_dom.valeur();
164 const DoubleTab_t& coord = domaine.coord_sommets();
165 const int_t size_tot = domaine.nb_elem_tot();
166 assert(volumes.size_totale() == size_tot);
167
168 for (int_t num_poly = 0; num_poly < size_tot; num_poly++)
169 {
170 const int_t S0 = domaine.sommet_elem(num_poly,0);
171 const int_t S1 = domaine.sommet_elem(num_poly,1);
172 const int_t S2 = domaine.sommet_elem(num_poly,2);
173 const int_t S3 = domaine.sommet_elem(num_poly,3);
174 const int_t S[4] = { S0, S1, S2, S3 };
175
176 // TRUST quadrangle local numbering is "papillonnée": 0-1-2-3.
177 // The boundary (CCW) order is 0-1-3-2; use this for the shoelace formula.
178 static const int ord[4] = {0, 1, 3, 2};
179
180 const auto index_of = [&](int i) -> int_t { return S[ ord[i] ]; };
181 const Polygon_geom_data geom = compute_polygon_geom(coord, dimension, 4, index_of, Objet_U::bidim_axi);
182
184 volumes[num_poly] = geom.area_;
185 else
186 volumes[num_poly] = 2.0 * M_PI * std::fabs(geom.moment_r_);
187 }
188}
189
190
191/*! @brief Reordonne
192 */
193template <typename _SIZE_>
195{
196 Domaine_t& domaine=mon_dom.valeur();
197 IntTab_t& elem=domaine.les_elems();
198
199 SmallArrOfTID_t S(4);
200 //ArrOfInt NS(4);
201 //DoubleTab co(4,2);
202 int_t num_poly;
203 const int_t nb_elem=domaine.nb_elem();
204 for (num_poly=0; num_poly<nb_elem; num_poly++)
205 {
206 for(int i=0; i<4; i++)
207 S[i] = elem(num_poly,i);
208
209 // adaptation de Hexaedre_VEF ::reordonne
210
211 const DoubleTab_t& coord=domaine.les_sommets();
212 DoubleTab v(3,3);
213 for (int i=1; i<4; i++)
214 for (int dir=0; dir<2; dir++)
215 v(i-1,dir)=coord(S[i],dir)-coord(S[0],dir);
216 ArrOfDouble prod_(3);
217 int opp=-1;
218 for (int op=0; op<3; op++)
219 {
220 DoubleTab prod_v(3,3);
221 for (int i=0; i<3; i++)
222 {
223 // prod_v(i,0)=v(op,1)*v(i,2)-v(op,2)*v(i,1);
224 //prod_v(i,1)=v(op,2)*v(i,0)-v(op,0)*v(i,2);
225 prod_v(i,2)=v(op,0)*v(i,1)-v(op,1)*v(i,0);
226 }
227 //Cerr<<prod_v<<finl;
228 double prod=0;
229 int i1=-1,i2=-1;
230 if (op==0)
231 {
232 i1=1;
233 i2=2;
234 }
235 else if (op==1)
236 {
237 i1=0;
238 i2=2;
239 }
240 else if (op==2)
241 {
242 i1=0;
243 i2=1;
244 }
245 for (int dir=0; dir<3; dir++)
246 prod+=(prod_v(i1,dir)*prod_v(i2,dir));
247 prod_[op]=prod;
248 if (prod<0)
249 {
250 if (opp!=-1)
251 {
252 op=2;
253 // on a deux produits negatifs on ne fait rien
254 }
255 opp=op;
256
257 }
258 }
259 if (opp!=2)
260 {
261 int i2=2;
262 int i1=1;
263 int i3=3;
264 int i2b=i2;
265 if (opp==0) i2b=i1;
266 int_t tmp=elem(num_poly,i2b);
267 elem(num_poly,i2b)=elem(num_poly,i3);
268 elem(num_poly,i3)=tmp;
269 Cerr << "Permutation of local nodes "<<i2b<<" and "<<i3<<" on the element " <<num_poly<<" prod "<<prod_<<finl;
270 }
271
272 }
273}
274
275/*! @brief voir ElemGeomBase::get_tab_faces_sommets_locaux
276 *
277 */
278template <typename _SIZE_>
280{
281 faces_som_local.resize(4,2);
282 for (int i=0; i<4; i++)
283 for (int j=0; j<2; j++)
284 faces_som_local(i,j) = faces_sommets_quadra[i][j];
285 return 1;
286}
287
288
289template class Quadrangle_VEF_32_64<int>;
290#if INT_is_64_ == 2
292#endif
double coord(int_t i, int j) const
Definition Domaine.h:110
Classe Elem_geom_base Cette classe est la classe de base pour la definition d'elements.
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
class Nom Une chaine de caractere pour nommer les objets de TRUST
Definition Nom.h:31
virtual Entree & readOn(Entree &)
Lecture d'un Objet_U sur un flot d'entree Methode a surcharger.
Definition Objet_U.cpp:293
static double precision_geom
Definition Objet_U.h:86
static int bidim_axi
Definition Objet_U.h:102
virtual Sortie & printOn(Sortie &) const
Ecriture de l'objet sur un flot de sortie Methode a surcharger.
Definition Objet_U.cpp:282
Classe Quadrangle_VEF Cette classe represente l'element geometrique Quadrangle_VEF.
DoubleVect_T< _SIZE_ > DoubleVect_t
void reordonner() override
Reordonne.
void calculer_volumes(DoubleVect_t &vols) const override
Calcule les volumes des elements du domaine associe.
static int dimension
Definition Objet_U.h:99
DoubleTab_T< _SIZE_ > DoubleTab_t
IntTab_T< _SIZE_ > IntTab_t
SmallArrOfTID_T< _SIZE_ > SmallArrOfTID_t
const Nom & nom_lml() const override
Renvoie le nom LML d'un Quadrangle_VEF = "GOLGOTH24".
int get_tab_faces_sommets_locaux(IntTab &faces_som_local) const override
voir ElemGeomBase::get_tab_faces_sommets_locaux
Domaine_32_64< _SIZE_ > Domaine_t
int contient(const ArrOfDouble &pos, int_t elem) const override
Renvoie 1 si l'element ielem du domaine associe a l'element geometrique contient le point.
Classe de base des flux de sortie.
Definition Sortie.h:52
_SIZE_ size_array() const
void resize(_SIZE_ n, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
Definition TRUSTTab.tpp:469
_SIZE_ size_totale() const
Definition TRUSTVect.tpp:61