TrioCFD 1.9.8
TrioCFD documentation
Loading...
Searching...
No Matches
Champ_implementation_Q1.cpp
1/****************************************************************************
2* Copyright (c) 2022, 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 <Linear_algebra_tools_impl.h>
17#include <Champ_implementation_Q1.h>
18#include <Linear_algebra_tools.h>
19#include <Domaine.h>
20
21static int faces_sommets_quadra[4][2] =
22{
23 { 0, 2 },
24 { 0, 1 },
25 { 1, 3 },
26 { 2, 3 }
27};
28
29void calcul_plan_quadra(Vecteur3& coeff_plan, double& d, int cell, const IntTab& cells, const DoubleTab& nodes, int dir)
30{
31 // Plan 012
32 int s0 = cells(cell, faces_sommets_quadra[dir][0]);
33 int s1 = cells(cell, faces_sommets_quadra[dir][1]);
34 double S0x = nodes(s0, 0);
35 double S0y = nodes(s0, 1);
36 double SOS1x = nodes(s1, 0) - S0x;
37 double SOS1y = nodes(s1, 1) - S0y;
38 double len = sqrt(SOS1x * SOS1x + SOS1y * SOS1y);
39
40 coeff_plan.set(-SOS1y / len, SOS1x / len, 0);
41 d = -(S0x * coeff_plan[0] + S0y * coeff_plan[1]);
42
43}
44
45static int faces_sommets_hexa[6][4] =
46{
47 { 0, 2, 4, 6 },
48 { 0, 1, 4, 5 },
49 { 0, 1, 2, 3 },
50 { 1, 3, 5, 7 },
51 { 2, 3, 6, 7 },
52 { 4, 5, 6, 7 }
53};
54
55void calcul_plan_hexa(Vecteur3& coeff_plan, double& d, int cell, const IntTab& cells, const DoubleTab& nodes, int dir)
56{
57 // Plan 012
58 int s0 = cells(cell, faces_sommets_hexa[dir][0]);
59 int s1 = cells(cell, faces_sommets_hexa[dir][1]);
60 int s2 = cells(cell, faces_sommets_hexa[dir][2]);
61
62 Vecteur3 S0(nodes(s0, 0), nodes(s0, 1), nodes(s0, 2));
63 Vecteur3 S0S1(nodes(s1, 0) - S0[0], nodes(s1, 1) - S0[1], nodes(s1, 2) - S0[2]);
64 Vecteur3 S0S2(nodes(s2, 0) - S0[0], nodes(s2, 1) - S0[1], nodes(s2, 2) - S0[2]);
65 Vecteur3::produit_vectoriel(S0S1, S0S2, coeff_plan);
66 coeff_plan *= (1. / coeff_plan.length());
67 d = -Vecteur3::produit_scalaire(coeff_plan, S0);
68}
69
70void Champ_implementation_Q1::value_interpolation(const DoubleTab& positions, const ArrOfInt& cells, const DoubleTab& values, DoubleTab& resu, int ncomp) const
71{
72 const Domaine& domaine = get_domaine_geom();
73 const IntTab& les_elems = domaine.les_elems();
74 const DoubleTab& nodes = domaine.les_sommets();
75 const int nb_nodes_per_cell = les_elems.dimension(1);
76 ArrOfDouble position(Objet_U::dimension);
77
78 Vecteur3 coeff_plan;
79 double d;
80 IntTab cell3D;
81 Vecteur3 coord_bar;
82
83 resu = 0;
84 for (int ic = 0; ic < cells.size_array(); ic++)
85 {
86 int cell = cells[ic];
87 if (cell < 0)
88 continue;
89 for (int k = 0; k < Objet_U::dimension; k++)
90 position[k] = positions(ic, k);
91
92 if (nb_nodes_per_cell == 4)
93 {
94 if (Objet_U::dimension == 3)
95 {
96 cell3D.resize(1, 8);
97 for (int i = 0; i < 4; i++)
98 cell3D(0, 2 * i) = les_elems(cell, i);
99 calcul_plan_hexa(coeff_plan, d, 0, cell3D, nodes, 0);
100 double A = d;
101 for (int i = 0; i < Objet_U::dimension; i++)
102 A += coeff_plan[i] * position[i];
103 if (std::fabs(A) > std::fabs(d) * 1e-5)
104 {
105 Cerr << "Error point not in the plane " << finl;
107 }
108 coord_bar = 0.5;
109 }
110 else
111 for (int dir = 0; dir < 2; dir++)
112 {
113
114 calcul_plan_quadra(coeff_plan, d, cell, les_elems, nodes, dir);
115 double A = d;
116 for (int i = 0; i < Objet_U::dimension; i++)
117 A += coeff_plan[i] * position[i];
118 calcul_plan_quadra(coeff_plan, d, cell, les_elems, nodes, dir + 2);
119 double B = d;
120 for (int i = 0; i < Objet_U::dimension; i++)
121 B += coeff_plan[i] * position[i];
122 assert(inf_ou_egal((A * B), 0, 1e-10));
123 coord_bar[dir] = A / (A - B);
124 }
125 }
126 else
127 {
128 assert(Objet_U::dimension == 3);
129 for (int dir = 0; dir < 3; dir++)
130 {
131
132 calcul_plan_hexa(coeff_plan, d, cell, les_elems, nodes, dir);
133 double A = d;
134 for (int i = 0; i < 3; i++)
135 A += coeff_plan[i] * position[i];
136 calcul_plan_hexa(coeff_plan, d, cell, les_elems, nodes, dir + 3);
137 double B = d;
138 for (int i = 0; i < 3; i++)
139 B += coeff_plan[i] * position[i];
140 assert(inf_ou_egal((A * B), 0, 1e-10));
141 coord_bar[dir] = A / (A - B);
142 }
143 }
144 ArrOfDouble val(nb_nodes_per_cell);
145 int nb_dim = resu.nb_dim();
146 int nb_components = nb_dim == 1 ? 1 : resu.dimension_tot(1);
147 for (int k = 0; k < nb_components; k++)
148 {
149 if (ncomp != -1)
150 {
151 for (int j = 0; j < nb_nodes_per_cell; j++)
152 {
153 int node = les_elems(cell, j);
154 val[j] = values(node, ncomp);
155 }
156 }
157 else
158 {
159 if (values.nb_dim() == 1)
160 {
161 for (int j = 0; j < nb_nodes_per_cell; j++)
162 {
163 int node = les_elems(cell, j);
164 val[j] = values(node);
165 }
166 }
167 else
168 {
169 assert(values.nb_dim() == 2);
170 for (int j = 0; j < nb_nodes_per_cell; j++)
171 {
172 int node = les_elems(cell, j);
173 val[j] = values(node, k);
174 }
175 }
176 }
177 double res = 0;
178 if (nb_nodes_per_cell == 4)
179 {
180 const double i = coord_bar[0];
181 const double j = coord_bar[1];
182 double unmi = 1. - i;
183 double unmj = 1. - j;
184
185 res = unmj * (unmi * val[0] + i * val[1]) + j * (unmi * val[2] + i * val[3]);
186 }
187 else
188 {
189 assert(Objet_U::dimension == 3);
190 const double i = coord_bar[0];
191 const double j = coord_bar[1];
192 const double kk = coord_bar[2];
193 double unmi = 1. - i;
194 double unmj = 1. - j;
195 double unmk = 1. - kk;
196 res = unmk * (unmj * (unmi * val[0] + i * val[1]) + j * (unmi * val[2] + i * val[3])) + kk * (unmj * (unmi * val[4] + i * val[5]) + j * (unmi * val[6] + i * val[7]));
197 }
198 if (nb_dim == 1)
199 resu(ic) = res;
200 else
201 resu(ic, k) = res;
202 }
203 }
204}
205
206static int info = 0;
207
208double Champ_implementation_Q1::form_function(const ArrOfDouble& position, int cell, int ddl) const
209{
210 if (info == 0)
211 {
212 Cerr << "***********************************************************************" << finl;
213 Cerr << "Warning : shape functions of the Q1 elements are not coded !" << finl;
214 Cerr << finl;
215 Cerr << "For the moment, the value of the elements is not interpolated." << finl;
216 Cerr << "It returns the average value on the element, ie the point value" << finl;
217 Cerr << "at the barycenter of the element" << finl;
218 Cerr << finl;
219 Cerr << "It is therefore recommended to postprocess the Q1 fields only" << finl;
220 Cerr << "on mesh nodes." << finl;
221 Cerr << "***********************************************************************" << finl;
222 info = 1;
223 }
224
225 const Domaine& domaine_geom = get_domaine_geom();
226 int test_sommet = 1;
227 if (test_sommet)
228 {
229 const IntTab& cells = domaine_geom.les_elems();
230 const DoubleTab& nodes = domaine_geom.les_sommets();
231
232 int nb_nodes_per_cell = cells.dimension(1);
233 int sc = -1;
235 for (int s = 0; s < nb_nodes_per_cell; s++)
236 {
237 int som = cells(cell, s);
238 double dist = 0;
239 for (int j = 0; j < Objet_U::dimension; j++)
240 {
241 double dx = (nodes(som, j) - position[j]);
242 dist += dx * dx;
243 }
244 if (dist < l)
245 sc = s;
246 }
247 if (sc != -1)
248 {
249 //Cerr<< ddl<< " sc "<< sc <<finl;
250 if (ddl == sc)
251 return 1;
252 else
253 return 0;
254 }
255
256 }
257 double factor = 1. / domaine_geom.nb_som_elem();
258 return factor;
259}
void value_interpolation(const DoubleTab &positions, const ArrOfInt &cells, const DoubleTab &values, DoubleTab &resu, int ncomp=-1) const override
const Domaine & get_domaine_geom() const
int nb_som_elem() const
Renvoie le nombre de sommets des elements geometriques constituants le domaine.
Definition Domaine.h:474
DoubleTab_t & les_sommets()
Definition Domaine.h:113
IntTab_t & les_elems()
Definition Domaine.h:129
static int dimension
Definition Objet_U.h:99
static double precision_geom
Definition Objet_U.h:86
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
Definition Process.cpp:455
_SIZE_ size_array() const
int nb_dim() const
Definition TRUSTTab.h:199
void resize(_SIZE_ n, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
Definition TRUSTTab.tpp:469
_SIZE_ dimension_tot(int) const override
Definition TRUSTTab.tpp:160
_SIZE_ dimension(int d) const
Definition TRUSTTab.tpp:133
static double produit_scalaire(const Vecteur3 &x, const Vecteur3 &y)
static void produit_vectoriel(const Vecteur3 &x, const Vecteur3 &y, Vecteur3 &resu)
void set(double x, double y, double z)
Definition Vecteur3.h:36
double length() const
Definition Vecteur3.h:51