TRUST 1.9.8
HPC thermohydraulic platform
Loading...
Searching...
No Matches
Champ_Face_PolyMAC_MPFA.cpp
1/****************************************************************************
2* Copyright (c) 2026, 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 <Champ_Face_PolyMAC_MPFA.h>
17#include <Domaine.h>
18#include <Domaine_VF.h>
19#include <Champ_Uniforme.h>
20#include <Domaine_PolyMAC_MPFA.h>
21#include <Domaine_Cl_PolyMAC_family.h>
22#include <TRUSTLists.h>
23#include <Dirichlet.h>
24#include <Dirichlet_homogene.h>
25#include <Symetrie.h>
26#include <EChaine.h>
27#include <TRUSTTab_parts.h>
28#include <Linear_algebra_tools_impl.h>
29#include <Probleme_base.h>
30#include <Equation_base.h>
31#include <Schema_Temps_base.h>
32#include <Champ_Fonc_reprise.h>
33#include <array>
34#include <cmath>
35#include <Pb_Multiphase.h>
36
37namespace
38{
39inline void project_axis_face(const IntTab& f_s, const DoubleTab& xs, const DoubleTab& xp,
40 DoubleTrav& xfb, int f, int e)
41{
42 int s0 = -1, s1 = -1;
43 for (int i = 0; i < f_s.dimension(1) && s1 < 0; i++)
44 {
45 const int s = f_s(f, i);
46 if (s < 0) break;
47 if (s0 < 0) s0 = s;
48 else s1 = s;
49 }
50
51 assert(s0 >= 0 && s1 >= 0);
52 const double tx = xs(s1, 0) - xs(s0, 0), ty = xs(s1, 1) - xs(s0, 1);
53 const double nx = ty, ny = -tx;
54 const double n2 = nx * nx + ny * ny;
55
56 const double mx = 0.5 * (xs(s0, 0) + xs(s1, 0)), my = 0.5 * (xs(s0, 1) + xs(s1, 1));
57 const double dx = xp(e, 0) - mx, dy = xp(e, 1) - my;
58 const double coeff = (dx * nx + dy * ny) / n2;
59
60 xfb(f, 0) = xp(e, 0) - coeff * nx;
61 xfb(f, 1) = xp(e, 1) - coeff * ny;
62}
63}
64
65Implemente_instanciable(Champ_Face_PolyMAC_MPFA,"Champ_Face_PolyMAC_MPFA",Champ_Face_PolyMAC_HFV) ;
66
67Sortie& Champ_Face_PolyMAC_MPFA::printOn(Sortie& os) const { return os << que_suis_je() << " " << le_nom(); }
68
70
72{
73 // j'utilise le meme genre de code que dans Champ_Fonc_P0_base sauf que je recupere le nombre de faces au lieu du nombre d'elements
74 // je suis tout de meme etonne du code utilise dans Champ_Fonc_P0_base::fixer_nb_valeurs_nodales() pour recuperer le domaine discrete...
75
76 assert(n == domaine_PolyMAC_MPFA().nb_faces() || n < 0);
77
78 // Probleme: nb_comp vaut dimension mais on ne veut qu'une dimension !!!
79 // HACK :
80 int old_nb_compo = nb_compo_;
81 if(nb_compo_ != 1) nb_compo_ /= dimension;
82
83 /* variables : valeurs normales aux faces, puis valeurs aux elements par blocs -> pour que line_size() marche */
85 nb_compo_ = old_nb_compo;
86 return n;
87}
88
90{
91 for (int n = 0; n < nb_valeurs_temporelles(); n++)
92 {
93 DoubleTab& vals = futur(n);
94 vals.set_md_vector(MD_Vector()); //on enleve le MD_Vector...
95 vals.resize_dim0(domaine_PolyMAC_MPFA().mdv_ch_face->get_nb_items_tot()); //...on dimensionne a la bonne taille...
96 vals.set_md_vector(domaine_PolyMAC_MPFA().mdv_ch_face); //...et on remet le bon MD_Vector
97 update_ve(vals);
98 }
99}
100
102{
103 if (! via_ch_fonc_reprise()) return Champ_Inc_base::reprendre(fich); /* ie: resume last time ! */
104
105 const Pb_Multiphase * pbm = mon_equation_non_nul() ? (sub_type(Pb_Multiphase, equation().probleme()) ? &ref_cast(Pb_Multiphase, equation().probleme()) : nullptr) : nullptr;
106 if (pbm) return Champ_Inc_base::reprendre(fich);
107
108 // sinon on fait ca ...
109 const Domaine_PolyMAC_MPFA* domaine = le_dom_VF ? &ref_cast( Domaine_PolyMAC_MPFA,le_dom_VF.valeur()) : nullptr;
110 valeurs().set_md_vector(MD_Vector()); //on enleve le MD_Vector...
111 valeurs().resize(0);
112 int ret = Champ_Inc_base::reprendre(fich);
113 //et on remet le bon si on peut
114 if (domaine) valeurs().set_md_vector(valeurs().dimension_tot(0) > domaine->nb_faces_tot() ? domaine->mdv_faces_aretes : domaine->md_vector_faces());
115 return ret;
116}
117
119{
120 const DoubleTab& ch_val = ch.valeurs();
121 DoubleTab& val = valeurs();
122 const int N = val.line_size(), D = Objet_U::dimension;
123
124 if (sub_type(Champ_Fonc_reprise, ch))
125 {
126 if (val.dimension_tot(0) == ch_val.dimension_tot(0) && val.line_size() == ch_val.line_size())
127 val = ch_val;
128 else
129 {
131 for (int i = 0; i < ch_val.dimension_tot(0); i++)
132 for (int j = 0; j < ch_val.line_size(); j++)
133 val(i,j) = ch_val(i,j);
134 }
135 }
136 else
137 {
139 const DoubleVect& fs = domaine.face_surfaces();
140 const DoubleTab& nf = domaine.face_normales(), &xv = domaine.xv();
141 const int unif = sub_type(Champ_Uniforme, ch);
142 DoubleTab eval;
143
144 if (unif)
145 eval = ch_val;
146 else
147 eval.resize(val.dimension_tot(0), N * D), ch.valeur_aux(xv, eval);
148
149 for (int f = 0; f < domaine.nb_faces_tot(); f++)
150 for (int d = 0; d < D; d++)
151 for (int n = 0; n < N; n++)
152 if (fs(f) > 0)
153 val(f, n) += eval(unif ? 0 : f, N * d + n) * nf(f, d) / fs(f);
154
155 update_ve(val);
156 //copie dans toutes les cases
158 for (int i = 1; i < les_valeurs->nb_cases(); i++)
159 les_valeurs[i].valeurs() = val;
160 }
161 return *this;
162}
163
164/**
165 * @brief Interpolates face-based velocity to element centers using a first-order method.
166 *
167 * Computes the element-based velocity components by performing a weighted average
168 * of neighboring face velocities, projected onto the vector from face center to element center.
169 *
170 * This method uses a first-order accurate stencil and does not include boundary corrections.
171 *
172 * @param[out] val Output field containing element-centered velocity components
173 * in the last D * number_of_elements entries.
174 */
175void Champ_Face_PolyMAC_MPFA::update_ve(DoubleTab& val) const
176{
178 if (valeurs().get_md_vector() != domaine.mdv_ch_face)
179 return; //pas de variables auxiliaires -> rien a faire
180
181 const DoubleVect& fs = domaine.face_surfaces(), &ve = domaine.volumes(),
182 *pf = mon_equation_non_nul() ? &equation().milieu().porosite_face() : nullptr,
183 *pe = pf ? &equation().milieu().porosite_elem() : nullptr;
184
185 const DoubleTab& xp = domaine.xp(), &xv = domaine.xv();
186 const IntTab& e_f = domaine.elem_faces(), &f_e = domaine.face_voisins();
187 const int D = dimension, N = val.line_size(), ne_tot = domaine.nb_elem_tot(), nf_tot = domaine.nb_faces_tot();
188
189 double fac;
190 for (int e = 0; e < ne_tot; e++)
191 {
192 for (int d = 0; d < D; d++)
193 for (int n = 0; n < N; n++)
194 val(nf_tot + D * e + d, n) = 0;
195 for (int j = 0; j < e_f.dimension(1); j++)
196 {
197 const int f = e_f(e, j);
198 if (f < 0) continue;
199
200 fac = (e == f_e(f, 0) ? 1 : -1) * (pf ? (*pf)(f) : 1.0) * fs(f) / ((pe ? (*pe)(e) : 1.0) * ve(e));
201 for (int d = 0; d < D; d++)
202 for (int n = 0; n < N; n++)
203 val(nf_tot + D * e + d, n) += fac * (xv(f, d) - xp(e, d)) * val(f, n);
204 }
205 }
206}
207
208/**
209 * @brief Initializes second-order interpolation coefficients from faces to element centers.
210 *
211 * This routine computes the interpolation stencil and weights for reconstructing
212 * the velocity at element centers with second-order accuracy.
213 *
214 * - Builds a least-squares system to correct the first-order estimate.
215 * - Handles internal and boundary faces (Neumann, Dirichlet).
216 * - Uses extended connectivity (neighboring elements via shared vertices).
217 *
218 * Resulting coefficients are stored internally for later use in update_ve2().
219 */
221{
223
224 if (ve2d.dimension(0) || valeurs().get_md_vector() != domaine.mdv_ch_face)
225 return; //deja initialise ou pas de variables auxiliaires
226
227 const DoubleVect& pf = equation().milieu().porosite_face(),
228 &pe = equation().milieu().porosite_elem(),
229 &fs = domaine.face_surfaces(), &ve = domaine.volumes();
230 const DoubleTab& xp = domaine.xp(), &xv = domaine.xv(), &nf = domaine.face_normales(),
231 &xs = domaine.domaine().coord_sommets();
232 const IntTab& f_e = domaine.face_voisins(), &e_f = domaine.elem_faces(),
233 &e_s = domaine.domaine().les_elems(), &f_s = domaine.face_sommets();
234
235 int D = dimension, nl = D * (D + 1), infoo = 0, un = 1;
236 double eps = 1e-8, fac;
237 const double *xf;
238
239 init_fcl();
240
241 //position des points aux faces de bord : CG si interne ou Dirichlet, projection si Neumann
242 DoubleTrav xfb(domaine.nb_faces_tot(), D), ve2, ve2i, A, B, P, W(1);
243 IntTrav pvt;
244
245 const double tol_norm2 = 1e-24;
246 for (int f = 0; f < domaine.nb_faces_tot(); f++)
247 if (fcl_(f, 0) == 1 || fcl_(f, 0) == 2) //Neumann / Symetrie
248 {
249 const int e = f_e(f, 0);
250 const double nf_norm2 = domaine.dot(&nf(f, 0), &nf(f, 0));
251
252 if (!bidim_axi || nf_norm2 > tol_norm2)
253 {
254 double scal = domaine.dot(&xv(f, 0), &nf(f, 0), &xp(e, 0)) / (fs(f) * fs(f));
255 for (int d = 0; d < D; d++)
256 xfb(f, d) = xp(e, d) + scal * nf(f, d);
257 }
258 else
259 project_axis_face(f_s, xs, xp, xfb, f, e);
260 }
261 else if (fcl_(f, 0))
262 {
263 for (int d = 0; d < D; d++)
264 xfb(f, d) = xv(f, d); //Dirichlet
265 }
266
267 /* connectivites som-elem et elem-elem */
268 std::vector<std::set<int>> s_f(domaine.domaine().nb_som()), e_s_f(domaine.nb_elem());
269 for (int f = 0; f < domaine.nb_faces_tot(); f++)
270 for (int i = 0; i < f_s.dimension(1); i++)
271 {
272 const int s = f_s(f, i);
273 if (s < 0) continue;
274
275 if (s < domaine.domaine().nb_som())
276 s_f[s].insert(f);
277 }
278
279 for (int e = 0; e < domaine.nb_elem(); e++)
280 for (int i = 0; i < e_s.dimension(1); i++)
281 {
282 const int s = e_s(e, i);
283 if (s < 0) continue;
284
285 for (auto &&fa : s_f[s])
286 e_s_f[e].insert(fa);
287 }
288
289 ve2d.resize(1, 2);
290 ve2bj.resize(0, 2);
291 std::map<std::array<int, 2>, int> v_i; // v_i[{f, -1 (interne) ou composante }] = indice
292 std::vector<std::array<int, 2>> i_v; // v_i[i_v[f]] = f
293
294 for (int e = 0; e < domaine.nb_elem(); e++, v_i.clear(), i_v.clear())
295 {
296 /* stencil : faces de l'element et de ses voisins par som-elem + toutes composantes a ses faces de bord */
297 for (auto &&fa : e_s_f[e])
298 if (!v_i.count( { { fa, -1 } }))
299 v_i[ { { fa, -1 } }] = (int) i_v.size(), i_v.push_back( { { fa, -1 } });
300 for (int i = 0; i < e_f.dimension(1) ; i++)
301 {
302 const int f = e_f(e, i);
303 if (f < 0) continue;
304
305 if (fcl_(f, 0))
306 for (int d = 0; d < D; d++)
307 v_i[ { { f, d } }] = (int) i_v.size(), i_v.push_back( { { f, d } });
308 }
309
310 /* coeffs de l'interpolation d'ordre 1, ponderations (comme dans Domaine_PolyMAC_MPFA::{e,f}grad) */
311 const int nc = (int) i_v.size();
312
313 ve2.resize(nc, D);
314 A.resize(nc, nl);
315 B.resize(nc);
316 P.resize(nc);
317 pvt.resize(nc);
318 ve2 = 0.;
319
320 for (int i = 0; i < e_f.dimension(1); i++)
321 {
322 const int f = e_f(e, i);
323 if (f < 0) continue;
324
325 fac = (e == f_e(f, 0) ? 1 : -1) * fs(f) / ve(e);
326 int j = v_i.at( { { f, -1 } });
327
328 for (int d = 0; d < D; d++)
329 ve2(j, d) += fac * (xv(f, d) - xp(e, d));
330 }
331
332 for (int i = 0; i < nc; i++)
333 {
334 int f = i_v[i][0];
335 xf = i_v[i][1] < 0 ? &xv(f, 0) : &xfb(f, 0);
336 P(i) = 1. / sqrt(domaine.dot(xf, xf, &xp(e, 0), &xp(e, 0)));
337 }
338
339 /* par composante : correction pour etre d'ordre 2 */
340 for (int d = 0; d < D; d++)
341 {
342 /* systeme A.x = b */
343 B = 0;
344 pvt = 0;
345
346 for (int i = 0; i < nc; i++)
347 {
348 int f = i_v[i][0];
349 if (std::fabs(fs(f)) < 1e-20) continue;
350 int db = i_v[i][1];
351 xf = db < 0 ? &xv(f, 0) : &xfb(f, 0);
352
353 int jb = 0;
354 for (int j = 0; j < D; j++)
355 for (int k = 0; k <= D; k++, jb++)
356 {
357 fac = (db < 0 ? nf(f, j) / fs(f) : (db == j)) * (k < D ? xf[k] - xp(e, k) : 1);
358 A(i, jb) = fac * P(i);
359 if (k < D)
360 B(jb) -= fac * ve2(i, d); //erreur de l'interp d'ordre 1 a corriger
361 }
362 }
363
364 /* x de norme L2 minimale par dgels */
365 int nw = -1, rank=-1;
366
367 F77NAME(dgelsy)(&nl, &nc, &un, &A(0, 0), &nl, &B(0), &nc, &pvt(0), &eps, &rank, &W(0), &nw, &infoo);
368
369 W.resize(nw = (int) std::lrint(W(0)));
370
371 F77NAME(dgelsy)(&nl, &nc, &un, &A(0, 0), &nl, &B(0), &nc, &pvt(0), &eps, &rank, &W(0), &nw, &infoo);
372 assert(infoo == 0);
373
374 /* ajout dans ve2 */
375 for (int i = 0; i < nc; i++)
376 ve2(i, d) += P(i) * B(i);
377 }
378
379 /* implicitation des CLs de Neumann / Symetrie */
380 Matrice33 M(1, 0, 0, 0, 1, 0, 0, 0, 1), iM;
381
382 for (int i = 0; i < nc; i++)
383 if (i_v[i][1] >= 0 && fcl_(i_v[i][0], 0) < 2)
384 for (int j = 0; j < D; j++)
385 M(j, i_v[i][1]) -= ve2(i, j);
386
387 Matrice33::inverse(M, iM);
388 ve2i.resize(nc, D);
389
390 for (int i = 0; i < nc; i++)
391 for (int j = 0; j < D; j++)
392 {
393 ve2i(i, j) = 0;
394 for (int k = 0; k < D; k++)
395 ve2i(i, j) += iM(j, k) * ve2(i, k);
396 }
397
398 /* stockage */
399 for (int d = 0; d < D; d++, ve2d.append_line(ve2c.size(), ve2bc.size()))
400 for (int i = 0; i < nc; i++)
401 if (std::fabs(ve2i(i, d)) > 1e-6 && (i_v[i][1] < 0 || fcl_(i_v[i][0], 0) == 3))
402 {
403 i_v[i][1] < 0 ? ve2j.append_line(i_v[i][0]) : ve2bj.append_line(i_v[i][0], i_v[i][1]);
404 (i_v[i][1] < 0 ? &ve2c : &ve2bc)->append_line(ve2i(i, d) * pf(i_v[i][0]) / pe(e));
405 }
406 }
407
408 CRIMP(ve2d);
409 CRIMP(ve2j);
410 CRIMP(ve2bj);
411 CRIMP(ve2c);
412 CRIMP(ve2bc);
413}
414
415/**
416 * @brief Applies the second-order interpolation from face velocities to element centers.
417 *
418 * Uses coefficients computed by init_ve2() to interpolate the face-based velocity field
419 * into element-centered values. Supports both internal faces and Dirichlet boundary conditions.
420 *
421 * @param[out] val Interpolated velocity at element centers.
422 * The last D * number_of_elements entries are updated.
423 * @param[in] incr If non-zero, Dirichlet boundary contributions are ignored (for incremental updates).
424 */
425void Champ_Face_PolyMAC_MPFA::update_ve2(DoubleTab& val, int incr) const
426{
428 if (valeurs().get_md_vector() != domaine.mdv_ch_face)
429 return; //pas de variables auxiliaires -> on sort
430
432 const int D = dimension, N = val.line_size(), nf_tot = domaine.nb_faces_tot();
433
434 init_ve2();
435 init_fcl();
436
437 int ed = 0, i = nf_tot;
438
439 for (int e = 0 ; e < domaine.nb_elem(); e++)
440 for (int d = 0; d < D; d++, ed++, i++)
441 for (int n = 0; n < N; n++)
442 {
443 /* partie "interne" */
444 val(i, n) = 0;
445
446 for (int j = ve2d(ed, 0); j < ve2d(ed + 1, 0); j++)
447 val(i, n) += ve2c(j) * val(ve2j(j), n);
448
449 /* partie "faces de bord de Dirichlet" (sauf si on fait des increments) */
450 if (!incr)
451 for (int j = ve2d(ed, 1); j < ve2d(ed + 1, 1); j++)
452 if (sub_type(Dirichlet, cls[fcl_(ve2bj(j, 0), 1)].valeur()))
453 val(i, n) += ve2bc(j) * ref_cast(Dirichlet, cls[fcl_(ve2bj(j, 0), 1)].valeur()).val_imp(fcl_(ve2bj(j, 0), 2), N * ve2bj(j, 1) + n);
454 }
455
457}
458
459DoubleTab& Champ_Face_PolyMAC_MPFA::valeur_aux_elems(const DoubleTab& positions, const IntVect& les_polys, DoubleTab& val_elem) const
460{
461 if (valeurs().get_md_vector() != domaine_PolyMAC_MPFA().mdv_ch_face)
462 return Champ_Face_PolyMAC_HFV::valeur_aux_elems_(valeurs(), positions, les_polys, val_elem);
463 else
464 return valeur_aux_elems_(le_champ().valeurs(), positions, les_polys, val_elem);
465}
466
467DoubleTab& Champ_Face_PolyMAC_MPFA::valeur_aux_elems_passe(const DoubleTab& positions, const IntVect& les_polys, DoubleTab& val_elem) const
468{
469 if (valeurs().get_md_vector() != domaine_PolyMAC_MPFA().mdv_ch_face)
470 return Champ_Face_PolyMAC_HFV::valeur_aux_elems_(passe(), positions, les_polys, val_elem);
471 else
472 return valeur_aux_elems_(le_champ().passe(), positions, les_polys, val_elem);
473}
474
475DoubleTab& Champ_Face_PolyMAC_MPFA::valeur_aux_elems_(const DoubleTab& val_face, const DoubleTab& positions, const IntVect& les_polys, DoubleTab& val_elem) const
476{
478 int nb_compo = le_champ().nb_comp(), nf_tot = domaine.nb_faces_tot(), d, D = dimension, n, N = val_face.line_size();
479
480 assert((positions.dimension(0) == les_polys.size()) || (positions.dimension_tot(0) == les_polys.size()));
481
482 if (val_elem.nb_dim() > 2)
483 Process::exit("TRUST error in Champ_Face_PolyMAC_MPFA::valeur_aux_elems_ : The DoubleTab val has more than 2 entries !");
484
485 if (nb_compo == 1)
486 Process::exit("TRUST error in Champ_Face_PolyMAC_MPFA::valeur_aux_elems_ : A scalar field cannot be of Champ_Face type !");
487
488 for (int p = 0, e; p < les_polys.size(); p++)
489 for (e = les_polys(p), d = 0; e < domaine.nb_elem() && d < D; d++)
490 for (n = 0; n < N; n++)
491 val_elem(p, N * d + n) = val_face(nf_tot + D * e + d, n);
492 return val_elem;
493}
494
495DoubleVect& Champ_Face_PolyMAC_MPFA::valeur_aux_elems_compo(const DoubleTab& positions, const IntVect& polys, DoubleVect& val, int ncomp) const
496{
497 if (valeurs().get_md_vector() != domaine_PolyMAC_MPFA().mdv_ch_face)
498 return Champ_Face_PolyMAC_HFV::valeur_aux_elems_compo(positions, polys, val, ncomp);
499 int nf_tot = domaine_PolyMAC_MPFA().nb_faces_tot(), D = dimension, N = valeurs().line_size();
500 assert(val.size_totale() >= polys.size());
501
502 DoubleTab vfe(valeurs());
503 update_ve(vfe);
504
505 for (int p = 0, e; p < polys.size(); p++)
506 val(p) = (e = polys(p)) < 0 ? 0. : vfe.addr()[N * (nf_tot + D * e) + ncomp];
507
508 return val;
509}
510
511DoubleTab& Champ_Face_PolyMAC_MPFA::trace(const Frontiere_dis_base& fr, DoubleTab& x, double t, int distant) const
512{
513 assert(distant == 0);
515 if (valeurs().get_md_vector() != domaine.mdv_ch_face)
516 return Champ_Face_PolyMAC_HFV::trace(fr, x, t, distant);
517
518 const bool vectoriel = (le_champ().nb_comp() > 1);
519 const int dim = vectoriel ? dimension : 1, ne_tot = domaine.nb_elem_tot(), nf_tot = domaine.nb_faces_tot();
520 const Front_VF& fr_vf = ref_cast(Front_VF, fr);
521 const IntTab& face_voisins = domaine.face_voisins();
522 const DoubleTab& val = valeurs(t);
523
524 for (int i = 0; i < fr_vf.nb_faces(); i++)
525 {
526 const int face = fr_vf.num_premiere_face() + i, elem = face_voisins(face, 0);
527 for (int d = 0; d < dim; d++)
528 x(i, d) = val(vectoriel ? nf_tot + ne_tot * d + elem : face);
529 }
530
531 return x;
532}
virtual DoubleTab & valeur_aux_elems_(const DoubleTab &val_face, const DoubleTab &positions, const IntVect &les_polys, DoubleTab &valeurs) const
virtual Champ_base & le_champ()
: class Champ_Face_PolyMAC_HFV
DoubleTab & trace(const Frontiere_dis_base &, DoubleTab &, double, int distant) const override
Calcule la trace d'un champ sur une frontiere au temps tps.
: class Champ_Face_PolyMAC_MPFA
Champ_base & affecter_(const Champ_base &) override
const Domaine_PolyMAC_MPFA & domaine_PolyMAC_MPFA() const
DoubleTab & trace(const Frontiere_dis_base &, DoubleTab &, double, int distant) const override
Calcule la trace d'un champ sur une frontiere au temps tps.
DoubleTab & valeur_aux_elems_passe(const DoubleTab &positions, const IntVect &polys, DoubleTab &result) const override
int fixer_nb_valeurs_nodales(int n) override
DoubleVect & valeur_aux_elems_compo(const DoubleTab &positions, const IntVect &polys, DoubleVect &result, int ncomp) const override
provoque une erreur ! doit etre surchargee par les classes derivees
DoubleTab & valeur_aux_elems(const DoubleTab &positions, const IntVect &polys, DoubleTab &result) const override
provoque une erreur ! doit etre surchargee par les classes derivees
void update_ve(DoubleTab &val) const
Interpolates face-based velocity to element centers using a first-order method.
void init_ve2() const
Initializes second-order interpolation coefficients from faces to element centers.
int reprendre(Entree &fich) override
Reprise d'un Objet_U sur un flot d'entree Methode a surcharger.
void update_ve2(DoubleTab &val, int incr=0) const
Applies the second-order interpolation from face velocities to element centers.
void init_fcl() const
classe Champ_Fonc_reprise Cette classe permet de relire un champ sauvegarde dans un fichier xyz
const Domaine & domaine() const
virtual void creer_tableau_distribue(const MD_Vector &, RESIZE_OPTIONS=RESIZE_OPTIONS::COPY_INIT)
DoubleTab & futur(int i=1) override
Renvoie les valeurs du champs a l'instant t+i.
DoubleTab & passe(int i=1) override
Renvoie les valeurs du champs a l'instant t-i.
virtual int nb_valeurs_temporelles() const
Renvoie le nombre de valeurs temporelles actuellement conservees.
const Domaine_Cl_dis_base & domaine_Cl_dis() const
DoubleTab & valeurs() override
Renvoie le tableau des valeurs du champ au temps courant.
int reprendre(Entree &) override
Lecture d'un champ inconnue a partir d'un flot d'entree en vue d'une reprise.
bool via_ch_fonc_reprise() const
virtual DoubleTab & valeurs()=0
classe Champ_Uniforme Represente un champ constant dans l'espace et dans le temps.
classe Champ_base Cette classe est la base de la hierarchie des champs.
Definition Champ_base.h:43
virtual DoubleVect & valeur_aux_elems_compo(const DoubleTab &positions, const IntVect &les_polys, DoubleVect &valeurs, int ncomp) const
provoque une erreur ! doit etre surchargee par les classes derivees
virtual DoubleTab & valeur_aux(const DoubleTab &positions, DoubleTab &valeurs) const
Provoque une erreur ! Doit etre surchargee par les classes derivees.
classe Conds_lim Cette classe represente un vecteur de conditions aux limites.
Definition Conds_lim.h:32
classe Dirichlet Cette classe est la classe de base de la hierarchie des conditions aux limites de ty...
Definition Dirichlet.h:31
const Cond_lim & les_conditions_limites(int) const
Renvoie la i-ieme condition aux limites.
int nb_faces_tot() const
renvoie le nombre total de faces.
Definition Domaine_VF.h:481
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
virtual const Milieu_base & milieu() const =0
const Nom & le_nom() const override
Renvoie le nom du champ.
virtual int nb_comp() const
Definition Field_base.h:56
int nb_compo_
Definition Field_base.h:95
class Front_VF
Definition Front_VF.h:36
int nb_faces() const
Definition Front_VF.h:53
int num_premiere_face() const
Definition Front_VF.h:63
classe Frontiere_dis_base Classe representant une frontiere discretisee.
: Cette classe est un OWN_PTR mais l'objet pointe est partage entre plusieurs
Definition MD_Vector.h:48
une matrice 3x3.
Definition Matrice33.h:28
static double inverse(const Matrice33 &m, Matrice33 &resu, int exit_on_error=1)
calcul de l'inverse.
DoubleVect & porosite_elem()
Definition Milieu_base.h:58
DoubleVect & porosite_face()
Definition Milieu_base.h:62
int mon_equation_non_nul() const
Definition MorEqn.h:85
const Equation_base & equation() const
Renvoie la reference sur l'equation pointe par MorEqn::mon_equation.
Definition MorEqn.h:62
static int dimension
Definition Objet_U.h:99
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
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 Pb_Multiphase Cette classe represente un probleme de thermohydraulique multiphase de type "3*N...
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
_TYPE_ * addr()
void set_md_vector(const MD_Vector &) override
Definition TRUSTTab.tpp:673
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
void resize_dim0(_SIZE_ n, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
Definition TRUSTTab.tpp:459
_SIZE_ dimension(int d) const
Definition TRUSTTab.tpp:133
_SIZE_ size() const
Definition TRUSTVect.tpp:45
_SIZE_ size_totale() const
Definition TRUSTVect.tpp:61
int line_size() const
Definition TRUSTVect.tpp:67
virtual void echange_espace_virtuel(IsExchangeBlocking exchange_type=IsExchangeBlocking::DefaultBlocking, const std::string kernel_name="noname")