TrioCFD 1.9.8
TrioCFD documentation
Loading...
Searching...
No Matches
Table.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 <Table.h>
17#include <utility>
18
19Implemente_instanciable_sans_constructeur_ni_destructeur(Table,"Table",Objet_U);
20
21
22/*! @brief Constructeur par defaut.
23 *
24 * Table vide.
25 *
26 */
27Table::Table() : les_valeurs() , les_parametres() { }
28
30{
31 (*this)=t;
32}
33
34//Lecture d'une expression analytique dependant des valeurs (val) d'un champ parametre
35//isf est fixe a 1
36Entree& Table::lire_f(Entree& is, const int nb_comp)
37{
38 isf=1;
39 Nom tmp;
40
41 VECT(Parser_U)& fval=fonction();
42 fval.dimensionner(nb_comp);
43 for (int i = 0; i < nb_comp; i++)
44 {
45 is >> tmp;
46 Cerr << "Reading and interpretation of the function " << tmp << finl;
47 fval[i].setNbVar(1);
48 fval[i].setString(tmp);
49 fval[i].addVar("val");
50 fval[i].parseString();
51 }
52 Cerr << "Interpretation of the function " << tmp << " OK" << finl;
53
54 return is;
55}
56
57//Lecture d'une expression analytique dependant des valeurs (val) d'un champ parametre,
58//de l espace (x,y,z) et du temps (t)
59//isf est fixe a 2
60Entree& Table::lire_fxyzt(Entree& is,const int dim)
61{
62 isf=2;
63 Nom tmp;
64
65 VECT(Parser_U)& fval=fonction();
66 fval.dimensionner(dim);
67 for (int i=0; i<dim; i++)
68 {
69 is >> tmp;
70 fval[i].setNbVar(5);
71 fval[i].setString(tmp);
72 fval[i].addVar("t");
73 fval[i].addVar("x");
74 fval[i].addVar("y");
75 fval[i].addVar("z");
76 fval[i].addVar("val");
77 fval[i].parseString();
78 }
79 Cerr << "Interpretation of the function " << tmp << " OK" << finl;
80
81
82 return is;
83}
84
85/*! @brief Ecriture sur un flot de Sortie N'ecrit que le type et le nom de l'objet
86 *
87 * @param (Sortie& s) le flot de sortie a utiliser
88 * @return (Sortie&) le flot de sortie modifie
89 */
91{
92 return s << que_suis_je() << " " << le_nom();
93}
94
95
96
97/*! @brief Lecture sur un flot d'entree Lecture des parametres et des valeurs de la table.
98 *
99 * @param (Entree& s) le flot d'entree a utiliser
100 * @return (Entree&) le flot d'entree modifie
101 */
103{
104 s >> les_parametres;
105 s >> les_valeurs;
106 return s ;
107}
108
109// Computes the n-linear interpolant of data at point x inside a hyper-rectangle defined by gridpoints.
110// The shapes should be (n) for x, (n, 2) for gridpoints and (2, 2, 2, ..., 2) n times for data (stored as a single vector here)
111double nlinear_interpolation(const std::vector<double>& x, const std::vector<std::pair<double, double>>& gridpoints, const std::vector<double>& data)
112{
113 const int n = (int)x.size();
114
115 // on construit les poids pour chaque sommet de l'hyper-rectangle
116 std::vector<double> weight(n);
117 for (int i = 0; i < n; i++)
118 weight[i] = std::min(1.0, std::max(0.0, (x[i] - gridpoints[i].first) / (gridpoints[i].second - gridpoints[i].first)));
119
120 // le calcul est effecte en utilisant une representation en bit j (int) -> index (n valeurs 0 ou 1)
121 // j=0 -> index=00...000 ; j=1 -> index=00...001 ; j=2 -> index=00...010
122 double interpolant = 0.0, prod;
123 for (int j = 0, i; j < (1<<n); interpolant += prod, j++)
124 for (prod = data[j], i = 0; i < n; i++) prod *= (j >> (n - 1 - i)) & 1 ? weight[i] : 1.0 - weight[i];
125
126 return interpolant;
127}
128
129// n'utilise pas nlinear_interpolation : codage pour nb_comp = 1 et nb_param = 1
130double Table::val_simple(double vp) const
131{
132 assert(les_parametres.size() == 1);
133 const DoubleVect& p = les_parametres[0];
134 const int size = p.size();
135 if (p[0] >= vp) return les_valeurs(0);
136 else
137 {
138 for (int i = 1; i < size; i++)
139 if (p[i] == vp) return les_valeurs(i);
140 else if (p[i] > vp) return (les_valeurs(i - 1) + ((les_valeurs(i) - les_valeurs(i - 1)) / (p[i] - p[i - 1])) * (vp - p[i - 1]));
141 }
142 return les_valeurs(size - 1);
143}
144
145double Table::val(const double val_param, int ncomp) const
146{
147 std::vector<double> vals_param {val_param};
148 return val(vals_param, ncomp);
149}
150
151double Table::val(const std::vector<double>& vals_param, int ncomp) const
152{
153 const int nb_param = les_parametres.size();
154 int nb_comp = les_valeurs.size();
155 if (nb_param == (int)vals_param.size())
156 {
157 std::vector<double> data;
158 std::vector<int> icube;
159 std::vector<std::pair<double, double>> gridpoints;
160
161 for (int ip = 0; ip < nb_param; ip++)
162 {
163 const DoubleVect& p = les_parametres[ip];
164 if (p.size()==1)
165 {
166 Cerr << "Error, a table should have more than one single value." << finl;
168 }
169 nb_comp /= p.size();
170 int i_interval = p.size() - 1;
171 for (int i = 1; i < p.size(); i++)
172 if (vals_param[ip] < p[i])
173 {
174 i_interval = i;
175 break;
176 }
177 icube.push_back(i_interval - 1);
178 gridpoints.push_back({p[i_interval - 1], p[i_interval]});
179 }
180 for (int j = 0; j < (1 << nb_param); j++)
181 {
182 std::vector<int> index(nb_param, 0);
183 for (int k = 0; k < nb_param; k++) index[nb_param - 1 - k] = icube[nb_param - 1 - k] + ((j >> k) & 1);
184
185 // indice dans le tableau global des valeurs tabulees
186 int k = index[0];
187 for (int i = 1; i < nb_param; i++)
188 k = k * les_parametres[i].size() + index[i];
189 k = k * nb_comp + ncomp;
190
191 data.push_back(les_valeurs[k]);
192 }
193
194 return nlinear_interpolation(vals_param, gridpoints, data);
195 }
196 else if (isf == 1 && vals_param.size() == 1)
197 {
198 // Plus rapide que parser(0).setVar("val",val_param);
199 parser(ncomp).setVar(0,vals_param[0]);
200 return parser(ncomp).eval();
201 }
202 else Process::exit("Error in a Table::val : wrong number of parameters.");
203
204 return 0;
205}
206
207/*! @brief Pas encore code.
208 *
209 * Sort en erreur.
210 *
211 */
212double Table::val(const DoubleVect& val_param) const
213{
214 Cerr << "Table::val(const DoubleVect& ) is not coded yet." << finl;
215 exit();
216 return 0;
217}
218
219
220/*! @brief Retourne les valeurs calculees pour le point val_param (cas du tableau valeurs a 2 dimensions) Les valeurs sont exacteS si le point correspond a un parametre donne.
221 *
222 * Sinon, les valeurs sont interpolees (interp. lineaire d'ordre 1)
223 *
224 * @param (DoubleVect& x) vecteur des valeurs
225 * @param (const double& val_param) le point en lequel calculer la valeur
226 * @return (DoubleVect& x) x modifie
227 * @throws Sort en erreur s'il manque des parametres
228 */
229DoubleVect& Table::valeurs(DoubleVect& x, const double val_param) const
230{
231
232 if (les_parametres.size() == 1)
233 {
234 int size;
235 const DoubleVect& p = les_parametres[0];
236 int size_p=p.size();
237 if (p[0] >= val_param)
238 {
239 size=x.size();
240 for(int j=0; j<size; j++)
241 x[j] = les_valeurs(0,j);
242 }
243 else if (p[size_p-1] <= val_param)
244 {
245 size=x.size();
246 for(int j=0; j<size; j++)
247 x[j] = les_valeurs(size_p-1,j);
248 }
249 else
250 {
251 for (int i=1; i<size_p; i++)
252 if (p[i] == val_param)
253 {
254 size=x.size();
255 for(int j=0; j<size; j++)
256 x[j] = les_valeurs(i,j);
257 break;
258 }
259 else if (p[i] > val_param)
260 {
261 size=x.size();
262 for(int j=0; j<size; j++)
263 x[j] = les_valeurs(i-1,j)+
264 ((les_valeurs(i,j)-les_valeurs(i-1,j))/(p[i]-p[i-1]))
265 *(val_param-p[i-1]) ;
266 break;
267 }
268 }
269 }
270 else
271 {
272 Cerr << "Error in a Table : it misses some parameters." << finl;
273 exit();
274 }
275 return x;
276}
277
278/*! @brief Pas encore code.
279 *
280 * Sort en erreur.
281 *
282 */
283DoubleVect& Table::valeurs(DoubleVect& x, const DoubleVect& val_param) const
284{
285 Cerr << "Table::val(const DoubleVect& ) is not coded yet." << finl;
286 exit();
287 return x;
288}
289
290//Evaluation d un tableau de valeurs (val) a partir d une expression analytique fonction des valeurs (val_param)
291//d un champ parametre, de l espace (pos) et du temps (t)
292DoubleTab& Table::valeurs(const DoubleTab& val_param,const DoubleTab& pos,const double tps,DoubleTab& aval) const
293{
294 eval_fct(pos,tps,val_param,aval);
295 return aval;
296
297}
298
299/*! @brief Affecte les parametres et les valeurs de la table
300 *
301 * @param (const DoubleVect& param) les parametres
302 * @param (const DoubleTab& val) les valeurs
303 */
304void Table::remplir(const DoubleVect& param,const DoubleTab& aval)
305{
306 // on verifie que param est strictement monotone
307 double val_ = param[0];
308 for (int i = 1; i < param.size(); i++)
309 if (val_ < param[i]) val_ = param[i];
310 else Process::exit("A table is not strictly monotonic!");
311
312 les_valeurs.ref(aval);
313 les_parametres.dimensionner(1);
314 les_parametres[0].ref(param);
315}
316
317void Table::remplir(const DoubleVects& params, const DoubleVect& aval)
318{
319 // on verifie que les params sont strictement monotones
320 for (int n = 0; n < params.size(); n++)
321 {
322 double val_ = params[n][0];
323 for (int i = 1; i < params[n].size(); i++)
324 if (val_ < params[n][i]) val_ = params[n][i];
325 else Process::exit("A table is not strictly monotonic!");
326 }
327
328 les_valeurs = aval;
329 les_parametres.dimensionner(params.size());
330 for (int i = 0; i < params.size(); i++) les_parametres[i].ref(params[i]);
331}
332
333static bool checked=false;
335{
336 if (!checked)
337 {
338 for (int comp = 0; comp < les_valeurs.dimension(1); comp++)
339 {
340 double val_ = les_valeurs(0, comp);
341 for (int i = 1; i < les_valeurs.dimension(0); i++)
342 if (val_ != les_valeurs(i, comp))
343 instationnaire_ = true;
344 }
345 checked = true;
346 }
347 return instationnaire_;
348}
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
classe Objet_U Cette classe est la classe de base des Objets de TRUST
Definition Objet_U.h:73
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
Objet_U()
Constructeur par defaut : attribue un numero d'identifiant unique a l'objet (object_id_),...
Definition Objet_U.cpp:55
virtual const Nom & le_nom() const
Donne le nom de l'Objet_U Methode a surcharger : renvoie "neant" dans cette implementation.
Definition Objet_U.cpp:319
virtual Sortie & printOn(Sortie &) const
Ecriture de l'objet sur un flot de sortie Methode a surcharger.
Definition Objet_U.cpp:282
Classe Parser_Eval Cette classe a pour fonction d evaleur les valeurs prises par une fonction analyti...
Definition Parser_Eval.h:29
VECT(Parser_U) &fonction()
Definition Parser_Eval.h:31
Parser_U & parser(int i)
Definition Parser_Eval.h:32
void eval_fct(const DoubleTab &positions, DoubleTab &val) const
Definition Parser_Eval.h:36
classe Parser_U Version de la classe Parser, derivant de Objet_U.
Definition Parser_U.h:32
void setVar(const char *sv, double val)
Definition Parser_U.h:149
double eval()
Definition Parser_U.h:125
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
Definition Process.cpp:455
Classe de base des flux de sortie.
Definition Sortie.h:52
_SIZE_ size() const
Definition TRUSTVect.tpp:45
int size() const
Definition Table.h:29
Table()
Constructeur par defaut.
Definition Table.cpp:27
void remplir(const DoubleVect &param, const DoubleTab &val)
Affecte les parametres et les valeurs de la table.
Definition Table.cpp:304
double val_simple(double vals_param) const
Definition Table.cpp:130
double val(const double val_param, int ncomp=0) const
Definition Table.cpp:145
DoubleTab & valeurs(const DoubleTab &val_param, const DoubleTab &pos, const double tps, DoubleTab &val) const
Definition Table.cpp:292
Entree & lire_f(Entree &is, const int nb_comp)
Definition Table.cpp:36
Entree & lire_fxyzt(Entree &is, const int dim)
Definition Table.cpp:60
bool instationnaire() const
Definition Table.cpp:334