TRUST 1.9.8
HPC thermohydraulic platform
Loading...
Searching...
No Matches
Orienter_Simplexes.cpp
1/****************************************************************************
2* Copyright (c) 2024, 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 <Orienter_Simplexes.h>
17#include <Scatter.h>
18#include <Domaine.h>
19#include <Motcle.h>
20
21Implemente_instanciable(Orienter_Simplexes,"Orienter_Simplexes_old",Interprete_geometrique_base) ;
22
24{
26 return os;
27}
28
30{
32 return is;
33}
34
35static void choose_internal_diagonal_for_triangle(Domaine& domain)
36{
37 // nothing to do
38}
39
40static void choose_internal_diagonal_for_tetrahedron(Domaine& domain)
41{
42 const DoubleTab& nodes = domain.les_sommets();
43 IntTab& cells = domain.les_elems();
44
45 ArrOfDouble lengths(3);
46
47 const int nb_cells = cells.dimension(0);
48 for (int cell=0; cell<nb_cells; ++cell)
49 {
50 const int s0 = cells(cell,0);
51 const int s1 = cells(cell,1);
52 const int s2 = cells(cell,2);
53 const int s3 = cells(cell,3);
54
55 const double x0 = nodes(s0,0);
56 const double x1 = nodes(s1,0);
57 const double x2 = nodes(s2,0);
58 const double x3 = nodes(s3,0);
59
60 const double y0 = nodes(s0,1);
61 const double y1 = nodes(s1,1);
62 const double y2 = nodes(s2,1);
63 const double y3 = nodes(s3,1);
64
65 const double z0 = nodes(s0,2);
66 const double z1 = nodes(s1,2);
67 const double z2 = nodes(s2,2);
68 const double z3 = nodes(s3,2);
69
70 const double x01 = 0.5 * (x0+x1);
71 const double x02 = 0.5 * (x0+x2);
72 const double x03 = 0.5 * (x0+x3);
73 const double x12 = 0.5 * (x1+x2);
74 const double x13 = 0.5 * (x1+x3);
75 const double x23 = 0.5 * (x2+x3);
76
77 const double y01 = 0.5 * (y0+y1);
78 const double y02 = 0.5 * (y0+y2);
79 const double y03 = 0.5 * (y0+y3);
80 const double y12 = 0.5 * (y1+y2);
81 const double y13 = 0.5 * (y1+y3);
82 const double y23 = 0.5 * (y2+y3);
83
84 const double z01 = 0.5 * (z0+z1);
85 const double z02 = 0.5 * (z0+z2);
86 const double z03 = 0.5 * (z0+z3);
87 const double z12 = 0.5 * (z1+z2);
88 const double z13 = 0.5 * (z1+z3);
89 const double z23 = 0.5 * (z2+z3);
90
91 lengths[0] = (x23-x01)*(x23-x01) + (y23-y01)*(y23-y01) + (z23-z01)*(z23-z01);
92 lengths[1] = (x13-x02)*(x13-x02) + (y13-y02)*(y13-y02) + (z13-z02)*(z13-z02);
93 lengths[2] = (x12-x03)*(x12-x03) + (y12-y03)*(y12-y03) + (z12-z03)*(z12-z03);
94
95 Cerr<<"ici" <<lengths<<finl;
96 const int id = imin_array(lengths);
97
98 if (id == 0)
99 {
100 // on echange les sommets 1 et 2
101 cells(cell,1) = s2;
102 cells(cell,2) = s1;
103 }
104 else if (id == 1)
105 {
106 // rien a faire
107 }
108 else if (id == 2)
109 {
110 // on echange les sommets 2 et 3
111 cells(cell,2) = s3;
112 cells(cell,3) = s2;
113 }
114 else
115 {
116 Cerr << "Error in Orienter_Simplexes 'choose_internal_diagonal_for_tetrahedron()'" << finl;
117 Cerr << " Internal error in 'imin_array()'" << finl;
119 }
120 }
121}
122
123static void choose_internal_diagonal(Domaine& domain)
124{
125 const Nom& cell_type = domain.type_elem()->que_suis_je();
126
127 Motcles understood_keywords(2);
128 understood_keywords[0] = "Triangle";
129 understood_keywords[1] = "Tetraedre";
130
131 int rank = understood_keywords.search(cell_type);
132 switch(rank)
133 {
134 case 0 :
135 choose_internal_diagonal_for_triangle(domain);
136 break;
137 case 1 :
138 choose_internal_diagonal_for_tetrahedron(domain);
139 break;
140 default :
141 Cerr << "Error in Orienter_Simplexes.cpp 'choose_internal_diagonal()'" << finl;
142 Cerr << " Unknown cell type : " << cell_type << finl;
143 Cerr << " Orienter_Simplexes can only orient Triangles and Tetrahedrons" << finl;
145 }
146}
147
148static void ensure_positive_volumes_for_triangle(Domaine& domain)
149{
150 const DoubleTab& nodes = domain.les_sommets();
151 IntTab& cells = domain.les_elems();
152
153 const int nb_cells = cells.dimension(0);
154 for (int cell=0; cell<nb_cells; ++cell)
155 {
156 const int s0 = cells(cell,0);
157 const int s1 = cells(cell,1);
158 const int s2 = cells(cell,2);
159
160 const double x0 = nodes(s0,0);
161 const double x1 = nodes(s1,0);
162 const double x2 = nodes(s2,0);
163
164 const double y0 = nodes(s0,1);
165 const double y1 = nodes(s1,1);
166 const double y2 = nodes(s2,1);
167
168 const double area = 0.5 * ((x1-x0)*(y2-y0) - (x2-x0)*(y1-y0));
169 if ( area < 0.)
170 {
171 // on echange les sommets 0 et 2
172 cells(cell,0) = s2;
173 cells(cell,2) = s0;
174 }
175 }
176}
177
178static void ensure_positive_volumes_for_tetrahedron(Domaine& domain)
179{
180 const DoubleTab& nodes = domain.les_sommets();
181 IntTab& cells = domain.les_elems();
182
183 const int nb_cells = cells.dimension(0);
184 for (int cell=0; cell<nb_cells; ++cell)
185 {
186 const int s0 = cells(cell,0);
187 const int s1 = cells(cell,1);
188 const int s2 = cells(cell,2);
189 const int s3 = cells(cell,3);
190
191 const double x0 = nodes(s0,0);
192 const double x1 = nodes(s1,0);
193 const double x2 = nodes(s2,0);
194 const double x3 = nodes(s3,0);
195
196 const double y0 = nodes(s0,1);
197 const double y1 = nodes(s1,1);
198 const double y2 = nodes(s2,1);
199 const double y3 = nodes(s3,1);
200
201 const double z0 = nodes(s0,2);
202 const double z1 = nodes(s1,2);
203 const double z2 = nodes(s2,2);
204 const double z3 = nodes(s3,2);
205
206 const double volume = (1./6.) * ( (x1-x0) * (y2-y0) * (z3-z0) +
207 (x2-x0) * (y3-y0) * (z1-z0) +
208 (x3-x0) * (y1-y0) * (z2-z0) -
209 (z1-z0) * (y2-y0) * (x3-x0) -
210 (x2-x0) * (z3-z0) * (y1-y0) -
211 (y3-y0) * (x1-x0) * (z2-z0) );
212
213 if (volume < 0.)
214 {
215 // on echange les sommets 0 et 2
216 cells(cell,0) = s2;
217 cells(cell,2) = s0;
218 }
219 }
220}
221
222
223static void ensure_positive_volumes(Domaine& domain)
224{
225 const Nom& cell_type = domain.type_elem()->que_suis_je();
226
227 Motcles understood_keywords(2);
228 understood_keywords[0] = "Triangle";
229 understood_keywords[1] = "Tetraedre";
230
231 int rank = understood_keywords.search(cell_type);
232 switch(rank)
233 {
234 case 0 :
235 ensure_positive_volumes_for_triangle(domain);
236 break;
237 case 1 :
238 ensure_positive_volumes_for_tetrahedron(domain);
239 break;
240 default :
241 Cerr << "Error in Orienter_Simplexes.cpp 'ensure_positive_volumes()'" << finl;
242 Cerr << " Unknown cell type : " << cell_type << finl;
243 Cerr << " Orienter_Simplexes can only orient Triangles and Tetrahedrons" << finl;
245 }
246}
247
249{
250 choose_internal_diagonal(domain);
251 ensure_positive_volumes(domain);
252}
253
255{
257
258 Domaine& domain = domaine();
260 orient_domain(domain);
262
263 return is;
264}
DoubleTab_t & les_sommets()
Definition Domaine.h:113
IntTab_t & les_elems()
Definition Domaine.h:129
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
Un tableau d'objets de la classe Motcle.
Definition Motcle.h:63
class Nom Une chaine de caractere pour nommer les objets de TRUST
Definition Nom.h:31
friend class Entree
Definition Objet_U.h:76
const Nom & que_suis_je() const
renvoie la chaine identifiant la classe.
Definition Objet_U.cpp:104
virtual Entree & readOn(Entree &)
Lecture d'un Objet_U sur un flot d'entree Methode a surcharger.
Definition Objet_U.cpp:293
virtual Sortie & printOn(Sortie &) const
Ecriture de l'objet sur un flot de sortie Methode a surcharger.
Definition Objet_U.cpp:282
: class Orienter_Simplexes
Entree & interpreter_(Entree &is) override
static void orient_domain(Domaine &domaine)
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
Definition Process.cpp:455
static void init_sequential_domain(Domaine_32_64< _SIZE_ > &dom)
Create parallel descriptors for the vertex and element arrays of the domain (necessary because Scatte...
Definition Scatter.cpp:2742
static void uninit_sequential_domain(Domaine_32_64< _SIZE_ > &dom)
methode utilisee par les interpretes qui modifient le domaine (sequentiel), detruit les descripteurs ...
Definition Scatter.cpp:2757
Classe de base des flux de sortie.
Definition Sortie.h:52
_SIZE_ dimension(int d) const
Definition TRUSTTab.tpp:133