TrioCFD 1.9.9_beta
TrioCFD documentation
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// Vertex numbering convention:
22// y
23// ^
24// |
25// 2-----3
26// | |
27// | |
28// | |
29// 0-----1--> x
30//
31// Face numbering convention for a 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 Returns the LML name of a Quadrangle_VEF = "GOLGOTH24".
63 *
64 * @return Always equal to "GOLGOTH24" (or "VOXEL8" / "QUADRANGLE_3D" depending on dimension).
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 Returns 1 if element "element" of the domain associated with this geometric element contains the point
77 *
78 * with coordinates specified by "pos". Returns 0 otherwise.
79 *
80 * @param pos Coordinates of the point to locate.
81 * @param element Index of the domain element in which to search for the point.
82 * @return 1 if the point belongs to element "element", 0 otherwise.
83 */
84template <typename _SIZE_>
85int Quadrangle_VEF_32_64<_SIZE_>::contient(const ArrOfDouble& pos, int_t element) const
86{
87 assert(pos.size_array()==2);
88 const Domaine_t& domaine=mon_dom.valeur();
89 const Domaine_t& dom=domaine;
90 int_t som0 = domaine.sommet_elem(element,0);
91 int_t som1 = domaine.sommet_elem(element,1);
92 int_t som2 = domaine.sommet_elem(element,2);
93 int_t som3 = domaine.sommet_elem(element,3);
94 // First check if the point is one of the quadrangle vertices
95 if( (est_egal(dom.coord(som0,0),pos[0]) && est_egal(dom.coord(som0,1),pos[1]))
96 || (est_egal(dom.coord(som1,0),pos[0]) && est_egal(dom.coord(som1,1),pos[1]))
97 || (est_egal(dom.coord(som2,0),pos[0]) && est_egal(dom.coord(som2,1),pos[1]))
98 || (est_egal(dom.coord(som3,0),pos[0]) && est_egal(dom.coord(som3,1),pos[1])) )
99 return 1;
100 double prod,p0,p1,p2,p3;
101 // Compute prod = 01 cross product 02 along z
102 prod = (dom.coord(som1,0)-dom.coord(som0,0))*(dom.coord(som2,1)-dom.coord(som0,1))
103 - (dom.coord(som1,1)-dom.coord(som0,1))*(dom.coord(som2,0)-dom.coord(som0,0));
104 double signe;
105 if (prod >= 0)
106 signe = 1;
107 else
108 signe = -1;
109 // Compute p0 = 0M cross product 1M along z
110 p0 = (pos[0]-dom.coord(som0,0))*(pos[1]-dom.coord(som1,1))
111 - (pos[1]-dom.coord(som0,1))*(pos[0]-dom.coord(som1,0));
112 p0 *= signe;
113 // Compute p1 = 1M cross product 3M along z
114 p1 = (pos[0]-dom.coord(som1,0))*(pos[1]-dom.coord(som3,1))
115 - (pos[1]-dom.coord(som1,1))*(pos[0]-dom.coord(som3,0));
116 p1 *= signe;
117 // Compute p2 = 3M cross product 2M along z
118 p2 = (pos[0]-dom.coord(som3,0))*(pos[1]-dom.coord(som2,1))
119 - (pos[1]-dom.coord(som3,1))*(pos[0]-dom.coord(som2,0));
120 p2 *= signe;
121 // Compute p3 = 2M cross product 0M along z
122 p3 = (pos[0]-dom.coord(som2,0))*(pos[1]-dom.coord(som0,1))
123 - (pos[1]-dom.coord(som2,1))*(pos[0]-dom.coord(som0,0));
124 p3 *= signe;
125 double epsilon=std::fabs(prod)*Objet_U::precision_geom;
126 if ((p0>-epsilon) && (p1>-epsilon) && (p2>-epsilon) && (p3>-epsilon))
127 return 1;
128 else
129 return 0;
130}
131
132
133/*! @brief Returns 1 if the vertices specified by parameter "som" are the vertices of element "element"
134 *
135 * in the domain associated with this geometric element. Returns 0 otherwise.
136 *
137 * @param som Vertex indices to compare with those of element "element".
138 * @param element Index of the domain element whose vertices are to be compared.
139 * @return 1 if the specified vertices are those of the given element, 0 otherwise.
140 */
141template <typename _SIZE_>
143{
144 const Domaine_t& domaine=mon_dom.valeur();
145 if((domaine.sommet_elem(element,0)==som[0])&&
146 (domaine.sommet_elem(element,1)==som[1])&&
147 (domaine.sommet_elem(element,2)==som[2])&&
148 (domaine.sommet_elem(element,3)==som[3]))
149 return 1;
150 else
151 return 0;
152}
153
154/*! @brief Computes the volumes of the elements of the associated domain.
155 *
156 * @param volumes Vector to fill with the volumes of domain elements.
157 */
158template <typename _SIZE_>
160{
161 const Domaine_t& domaine = mon_dom.valeur();
162 const DoubleTab_t& coord = domaine.coord_sommets();
163 const int_t size_tot = domaine.nb_elem_tot();
164 assert(volumes.size_totale() == size_tot);
165
166 for (int_t num_poly = 0; num_poly < size_tot; num_poly++)
167 {
168 const int_t S0 = domaine.sommet_elem(num_poly,0);
169 const int_t S1 = domaine.sommet_elem(num_poly,1);
170 const int_t S2 = domaine.sommet_elem(num_poly,2);
171 const int_t S3 = domaine.sommet_elem(num_poly,3);
172 const int_t S[4] = { S0, S1, S2, S3 };
173
174 // TRUST quadrangle local numbering is "butterfly-shaped": 0-1-2-3.
175 // The boundary (CCW) order is 0-1-3-2; use this for the shoelace formula.
176 static const int ord[4] = {0, 1, 3, 2};
177
178 const auto index_of = [&](int i) -> int_t { return S[ ord[i] ]; };
179 const Polygon_geom_data geom = compute_polygon_geom(coord, dimension, 4, index_of, Objet_U::bidim_axi);
180
182 volumes[num_poly] = geom.area_;
183 else
184 volumes[num_poly] = 2.0 * M_PI * std::fabs(geom.moment_r_);
185 }
186}
187
188
189/*! @brief Reorders the vertices of the quadrangle elements.
190 */
191template <typename _SIZE_>
193{
194 Domaine_t& domaine=mon_dom.valeur();
195 IntTab_t& elem=domaine.les_elems();
196
197 SmallArrOfTID_t S(4);
198 //ArrOfInt NS(4);
199 //DoubleTab co(4,2);
200 int_t num_poly;
201 const int_t nb_elem=domaine.nb_elem();
202 for (num_poly=0; num_poly<nb_elem; num_poly++)
203 {
204 for(int i=0; i<4; i++)
205 S[i] = elem(num_poly,i);
206
207 // adapted from Hexaedre_VEF::reordonne
208
209 const DoubleTab_t& coord=domaine.les_sommets();
210 DoubleTab v(3,3);
211 for (int i=1; i<4; i++)
212 for (int dir=0; dir<2; dir++)
213 v(i-1,dir)=coord(S[i],dir)-coord(S[0],dir);
214 ArrOfDouble prod_(3);
215 int opp=-1;
216 for (int op=0; op<3; op++)
217 {
218 DoubleTab prod_v(3,3);
219 for (int i=0; i<3; i++)
220 {
221 // prod_v(i,0)=v(op,1)*v(i,2)-v(op,2)*v(i,1);
222 //prod_v(i,1)=v(op,2)*v(i,0)-v(op,0)*v(i,2);
223 prod_v(i,2)=v(op,0)*v(i,1)-v(op,1)*v(i,0);
224 }
225 //Cerr<<prod_v<<finl;
226 double prod=0;
227 int i1=-1,i2=-1;
228 if (op==0)
229 {
230 i1=1;
231 i2=2;
232 }
233 else if (op==1)
234 {
235 i1=0;
236 i2=2;
237 }
238 else if (op==2)
239 {
240 i1=0;
241 i2=1;
242 }
243 for (int dir=0; dir<3; dir++)
244 prod+=(prod_v(i1,dir)*prod_v(i2,dir));
245 prod_[op]=prod;
246 if (prod<0)
247 {
248 if (opp!=-1)
249 {
250 op=2;
251 // two negative products: do nothing
252 }
253 opp=op;
254
255 }
256 }
257 if (opp!=2)
258 {
259 int i2=2;
260 int i1=1;
261 int i3=3;
262 int i2b=i2;
263 if (opp==0) i2b=i1;
264 int_t tmp=elem(num_poly,i2b);
265 elem(num_poly,i2b)=elem(num_poly,i3);
266 elem(num_poly,i3)=tmp;
267 Cerr << "Permutation of local nodes "<<i2b<<" and "<<i3<<" on the element " <<num_poly<<" prod "<<prod_<<finl;
268 }
269
270 }
271}
272
273/*! @brief See ElemGeomBase::get_tab_faces_sommets_locaux.
274 *
275 */
276template <typename _SIZE_>
278{
279 faces_som_local.resize(4,2);
280 for (int i=0; i<4; i++)
281 for (int j=0; j<2; j++)
282 faces_som_local(i,j) = faces_sommets_quadra[i][j];
283 return 1;
284}
285
286
287template class Quadrangle_VEF_32_64<int>;
288#if INT_is_64_ == 2
290#endif
double coord(int_t i, int j) const
Definition Domaine.h:110
Class Elem_geom_base This class is the base class for the definition of elements.
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
class Nom: a character string for naming TRUST objects.
Definition Nom.h:31
virtual Entree & readOn(Entree &)
Reads an Objet_U from an input stream. Virtual method to override.
Definition Objet_U.cpp:289
static double precision_geom
Definition Objet_U.h:81
static int bidim_axi
Definition Objet_U.h:97
virtual Sortie & printOn(Sortie &) const
Writes the object to an output stream. Virtual method to override.
Definition Objet_U.cpp:278
Quadrangle_VEF class — represents the Quadrangle_VEF geometric element.
DoubleVect_T< _SIZE_ > DoubleVect_t
void reordonner() override
Reorders the vertices of the quadrangle elements.
void calculer_volumes(DoubleVect_t &vols) const override
Computes the volumes of the elements of the associated domain.
static int dimension
Definition Objet_U.h:94
DoubleTab_T< _SIZE_ > DoubleTab_t
IntTab_T< _SIZE_ > IntTab_t
SmallArrOfTID_T< _SIZE_ > SmallArrOfTID_t
const Nom & nom_lml() const override
Returns the LML name of a Quadrangle_VEF = "GOLGOTH24".
int get_tab_faces_sommets_locaux(IntTab &faces_som_local) const override
See ElemGeomBase::get_tab_faces_sommets_locaux.
Domaine_32_64< _SIZE_ > Domaine_t
int contient(const ArrOfDouble &pos, int_t elem) const override
Returns 1 if element "element" of the domain associated with this geometric element contains the poin...
Base class for output streams.
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