TrioCFD 1.9.9_beta
TrioCFD documentation
Loading...
Searching...
No Matches
Op_Diff_EF.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//static int transpose_=1;
17#include <Op_Diff_EF.h>
18#include <Domaine_EF.h>
19#include <Champ_Uniforme.h>
20#include <Milieu_base.h>
21#include <Debog.h>
22#include <TRUSTTrav.h>
23#include <Probleme_base.h>
24#include <Neumann_paroi.h>
25#include <Echange_global_impose.h>
26#include <Echange_interne_global_impose.h>
27#include <Echange_couplage_thermique.h>
28#include <Echange_interne_global_parfait.h>
29#include <Champ_front_calc_interne.h>
30
31#include <Param.h>
32#include <Op_Conv_EF.h>
33
34#include <vector>
35
36Implemente_instanciable_sans_constructeur(Op_Diff_EF,"Op_Diff_EF",Op_Diff_EF_base);
37
38Op_Diff_EF::Op_Diff_EF():transpose_(1),transpose_partout_(0),nouvelle_expression_(0)
39{
40}
41//// printOn
42//
44{
45 return s << que_suis_je() ;
46}
47
48//// readOn
49//
50
52{
53 return s ;
54}
55Implemente_instanciable(Op_Diff_option_EF,"Op_Diff_option_EF",Op_Diff_EF);
56
57
58//// printOn
59//
60
62{
63 return s << que_suis_je() ;
64}
65
66//// readOn
67//
68
70{
71 Param param(que_suis_je());
72 param.ajouter("grad_u_transpose", &transpose_ );
73 param.ajouter("grad_u_transpose_partout", &transpose_partout_ );
74 param.ajouter("nouvelle_expression",&nouvelle_expression_);
75 param.ajouter_condition("(value_of_grad_u_transpose_EQ_0)_OR_(value_of_grad_u_transpose_EQ_1)"," grad_u_transpose doit valoir 0 ou 1 ");
76 param.ajouter_condition("(value_of_grad_u_transpose_partout_EQ_0)_OR_(value_of_grad_u_transpose_partout_EQ_1)"," grad_u_transpose_partout doit valoir 0 ou 1 ");
77 param.ajouter_condition("(value_of_grad_u_transpose_partout_EQ_0)_OR_((value_of_grad_u_transpose_partout_EQ_1)_AND_(value_of_grad_u_transpose_EQ_1))"," si grad_u_transpose_partout vaut 1 alors grad_u_transpose doit valoir 1");
78 param.lire_avec_accolades_depuis(s);
79
80 return s ;
81}
82
83/*! @brief Associates the diffusivity field.
84 *
85 */
87{
88 diffusivite_ = diffu;
89}
90
92{
93 diffusivite_volumique_ = diffu;
94}
95
101
103{
104 return diffusivite_;
105}
106
108{
109 if (!diffusivite_volumique_)
110 {
111 Cerr << que_suis_je() << " has no volumic diffusivity associated." << finl;
113 }
114 return diffusivite_volumique_.valeur();
115}
116
117void Op_Diff_EF::remplir_nu(DoubleTab& nu) const
118{
119 const Domaine_EF& domaine_EF = le_dom_EF.valeur();
120 // Size nu
121 if (!nu.get_md_vector())
122 domaine_EF.domaine().creer_tableau_elements(nu);
123 const DoubleTab& diffu=diffusivite().valeurs();
124 if (diffu.size()==1)
125 nu = diffu(0,0);
126 else if (diffu.nb_dim()==1)
127 nu = diffu;
128 else
129 {
130 assert(diffu.dimension(1)==1);
131 for (int i=0; i<diffu.size_totale(); i++) nu(i)=diffu(i,0);
132 }
133
134// nu.echange_espace_virtuel();
135}
136
137void Op_Diff_EF::remplir_lambda(DoubleTab& lambda) const
138{
139 assert(diffusivite_volumique_);
140 const Domaine_EF& domaine_EF = le_dom_EF.valeur();
141 if (!lambda.get_md_vector())
142 domaine_EF.domaine().creer_tableau_elements(lambda);
143
144 const DoubleTab& diffu = diffusivite_volumique().valeurs();
145 if (diffu.size() == 1)
146 lambda = diffu(0, 0);
147 else if (diffu.nb_dim() == 1)
148 lambda = diffu;
149 else
150 {
151 assert(diffu.dimension(1) == 1);
152 for (int i = 0; i < diffu.size_totale(); i++) lambda(i) = diffu(i, 0);
153 }
154}
155
156void Op_Diff_EF::calculer_von_mises(const DoubleTab& deplacement, DoubleTab& deformation, DoubleTab& contraintes, DoubleTab& von_mises) const
157{
158 const Domaine_EF& domaine_ef = le_dom_EF.valeur();
159 const Domaine& domaine = domaine_ef.domaine();
160 const int nb_elem_tot = domaine.nb_elem_tot();
161 const int nb_som_elem = domaine.nb_som_elem();
162 const DoubleTab& Bij_thilde = domaine_ef.Bij_thilde();
163 const DoubleTab& iphi_thilde = domaine_ef.IPhi_thilde();
164 const DoubleVect& volumes_thilde = domaine_ef.volumes_thilde();
165 const IntTab& elems = domaine.les_elems();
166 const DoubleTab& xs = domaine_ef.domaine().les_sommets();
167 const double r_tol = 1e-12;
168
170 const bool have_lambda = bool(diffusivite_volumique_);
171 if (have_lambda) remplir_lambda(lambda_);
172
173 von_mises = 0.;
174
175 for (int elem = 0; elem < nb_elem_tot; elem++)
176 if (elem_contribue(elem))
177 {
178 double grad[3][3] = {{0., 0., 0.}, {0., 0., 0.}, {0., 0., 0.}};
179 double sum_ur_over_r = 0.;
180 double sum_w = 0.;
181
182 for (int j = 0; j < nb_som_elem; j++)
183 {
184 const int som = elems(elem, j);
185 for (int comp = 0; comp < dimension; comp++)
186 for (int dir = 0; dir < dimension; dir++)
187 grad[comp][dir] += deplacement(som, comp) * Bij_thilde(elem, j, dir);
188 if (bidim_axi)
189 {
190 const double r_s = xs(som, 0);
191 const double w = iphi_thilde(elem, j);
192 if (r_s > r_tol && w > 0.)
193 {
194 sum_ur_over_r += (deplacement(som, 0) / r_s) * w;
195 sum_w += w;
196 }
197 }
198 }
199
200 const double vol = volumes_thilde(elem);
201 double inv_vol = 1.0 / vol;
202 // In RZ: Bij_thilde carries r, volumes_thilde carries 2π r ⇒ the factor 2π must be accounted for
203 for (int comp = 0; comp < dimension; comp++)
204 for (int dir = 0; dir < dimension; dir++)
205 grad[comp][dir] *= inv_vol;
206
207 double eps_xx = grad[0][0];
208 double eps_yy = grad[1][1];
209 double eps_zz = (dimension == 3) ? grad[2][2] : 0.;
210 double gamma_xy = grad[0][1] + grad[1][0];
211 double gamma_yz = (dimension == 3) ? (grad[1][2] + grad[2][1]) : 0.;
212 double gamma_zx = (dimension == 3) ? (grad[2][0] + grad[0][2]) : 0.;
213
214 if (bidim_axi)
215 {
216 // hoop strain eps_theta = average of (u_r / r) over the element with IPhi_thilde weights
217 const double eps_theta = (sum_w > 0.) ? (sum_ur_over_r / sum_w) : eps_xx; // at the axis, fallback to eps_rr
218 eps_zz = eps_theta;
219 }
220
221 const double mu = nu_(elem);
222 const double lambda = have_lambda ? lambda_(elem) : 0.;
223 const double trace_eps = eps_xx + eps_yy + eps_zz;
224
225 const double sigma_xx = 2. * mu * eps_xx + lambda * trace_eps;
226 const double sigma_yy = 2. * mu * eps_yy + lambda * trace_eps;
227 const double sigma_zz = 2. * mu * eps_zz + lambda * trace_eps;
228 const double tau_xy = mu * gamma_xy;
229 const double tau_yz = mu * gamma_yz;
230 const double tau_zx = mu * gamma_zx;
231
232 const double vm2 = 0.5 * ((sigma_xx - sigma_yy) * (sigma_xx - sigma_yy) +
233 (sigma_yy - sigma_zz) * (sigma_yy - sigma_zz) +
234 (sigma_zz - sigma_xx) * (sigma_zz - sigma_xx)) +
235 3. * (tau_xy * tau_xy + tau_yz * tau_yz + tau_zx * tau_zx);
236 const double vm = (vm2 > 0.) ? std::sqrt(vm2) : 0.;
237
238 von_mises(elem, 0) = vm;
239 deformation(elem, 0) = eps_xx;
240 deformation(elem, 1) = eps_yy;
241 deformation(elem, 2) = eps_zz;
242 contraintes(elem, 0) = sigma_xx;
243 contraintes(elem, 1) = sigma_yy;
244 contraintes(elem, 2) = sigma_zz;
245 }
246}
247
248DoubleTab& Op_Diff_EF::ajouter(const DoubleTab& tab_inconnue, DoubleTab& resu) const
249{
250 if ((equation().nombre_d_operateurs()>1)&&sub_type(Op_Conv_EF,equation().operateur(1).l_op_base()))
251 ref_cast(Op_Conv_EF,equation().operateur(1).l_op_base()).ajouter_a_la_diffusion(tab_inconnue,resu);
252 // ref_cast(Op_Conv_EF,equation().operateur(1).l_op_base()).ajouter_sous_cond(tab_inconnue,resu,0,0,1);
254 return ajouter_new(tab_inconnue,resu);
255
257 // const Domaine_Cl_EF& domaine_Cl_EF = la_zcl_EF.valeur();
258 const Domaine_EF& domaine_ef = le_dom_EF.valeur();
259 int nb_som_elem=domaine_ef.domaine().nb_som_elem();
260
261 int N = resu.line_size();
262 Nature_du_champ nat= equation().inconnue().nature_du_champ();
263 if (nat==vectoriel)
264 {
265 if ((dimension==3)&&(nb_som_elem==8))
266 return ajouter_vectoriel_dim3_nbn_8(tab_inconnue,resu);
267 else if ((dimension==2)&&(nb_som_elem==4))
268 {
269 return ajouter_vectoriel_dim2_nbn_4(tab_inconnue,resu);
270 }
271 else
272 {
273 //Cerr<<__FILE__<<(int)__LINE__<< "cas non optimise "<<finl;
274 return ajouter_vectoriel_gen(tab_inconnue,resu);
275 }
276 }
277 else
278 {
279 if (N != 1)
280 {
281 Cerr<<__FILE__<<(int)__LINE__<< "cas non prevu "<<finl;
282 assert(0);
283 exit();
284 return ajouter(tab_inconnue,resu);
285 }
286 if ((dimension==3)&&(nb_som_elem==8))
287 return ajouter_scalaire_dim3_nbn_8(tab_inconnue,resu);
288 else if ((dimension==2)&&(nb_som_elem==4))
289 {
290 return ajouter_scalaire_dim2_nbn_4(tab_inconnue,resu);
291 }
292 else
293 {
294 //Cerr<<__FILE__<<(int)__LINE__<< "cas non optimise "<<finl;
295 return ajouter_scalaire_gen(tab_inconnue,resu);
296 }
297
298 }
299}
300
301DoubleTab& Op_Diff_EF::ajouter_vectoriel_gen(const DoubleTab& tab_inconnue, DoubleTab& resu) const
302{
303 return ajouter_vectoriel_template<AJOUTE_VECT::GEN>(tab_inconnue,resu);
304}
305
306DoubleTab& Op_Diff_EF::ajouter_vectoriel_dim2_nbn_4(const DoubleTab& tab_inconnue, DoubleTab& resu) const
307{
308 return ajouter_vectoriel_template<AJOUTE_VECT::D2_4>(tab_inconnue,resu);
309}
310
311DoubleTab& Op_Diff_EF::ajouter_vectoriel_dim3_nbn_8(const DoubleTab& tab_inconnue, DoubleTab& resu) const
312{
313 return ajouter_vectoriel_template<AJOUTE_VECT::D3_8>(tab_inconnue,resu);
314}
315
316DoubleTab& Op_Diff_EF::ajouter_scalaire_dim3_nbn_8(const DoubleTab& tab_inconnue, DoubleTab& resu) const
317{
318 return ajouter_scalaire_template<AJOUTE_SCAL::D3_8>(tab_inconnue,resu);
319}
320
321DoubleTab& Op_Diff_EF::ajouter_scalaire_dim2_nbn_4(const DoubleTab& tab_inconnue, DoubleTab& resu) const
322{
323 return ajouter_scalaire_template<AJOUTE_SCAL::D2_4>(tab_inconnue,resu);
324}
325
326DoubleTab& Op_Diff_EF::ajouter_scalaire_gen(const DoubleTab& tab_inconnue, DoubleTab& resu) const
327{
328 return ajouter_scalaire_template<AJOUTE_SCAL::GEN>(tab_inconnue,resu);
329}
330
331DoubleTab& Op_Diff_EF::ajouter_new(const DoubleTab& tab_inconnue, DoubleTab& resu) const
332{
333 Cerr<<"NEW"<<finl;
335 // const Domaine_Cl_EF& domaine_Cl_EF = la_zcl_EF.valeur();
336 //const Domaine_EF& domaine_EF = le_dom_EF.valeur();
337
338
339 const int N = resu.line_size();
340 ArrOfInt marqueur_neuman;
341 const Domaine_EF& domaine_ef=ref_cast(Domaine_EF,equation().domaine_dis());
342 if(N > 1)
343 remplir_marqueur_sommet_neumann( marqueur_neuman,domaine_ef,la_zcl_EF.valeur(),transpose_partout_ );
344
345 const DoubleVect& volumes= domaine_ef.volumes();
346
347 const DoubleTab& bij=domaine_ef.Bij();
348 const DoubleTab& bij_thilde=domaine_ef.Bij_thilde();
349 int nb_elem_tot=domaine_ef.domaine().nb_elem_tot();
350 int nb_som_elem=domaine_ef.domaine().nb_som_elem();
351 const IntTab& elems=domaine_ef.domaine().les_elems() ;
352
353 for (int elem=0; elem<nb_elem_tot; elem++)
354 if (elem_contribue(elem))
355 {
356 double pond=1./volumes(elem);
357 assert(N == dimension || N == 1);
358
359 for (int i1=0; i1<nb_som_elem; i1++)
360 {
361 int glob=elems(elem,i1);
362 int transpose = (marqueur_neuman[glob] == 1 || N == 1) ? 0 : transpose_;
363 for (int i2=0; i2<nb_som_elem; i2++)
364 {
365 int glob2=elems(elem,i2);
366 for (int n = 0; n < N; n++)
367 for (int d = 0; d < dimension; d++)
368 resu(glob, n) -= bij(elem, i1, d) * (bij_thilde(elem, i2, d) * tab_inconnue(glob2, n) + transpose * bij_thilde(elem, i2, n) * tab_inconnue(glob2, d)) * nu_(elem) * pond;
369 }
370 }
371 }
372
373 // add the contribution from boundaries
374 ajouter_bords(tab_inconnue,resu);
375 return resu;
376}
377
378DoubleTab& Op_Diff_EF::calculer(const DoubleTab& tab_inconnue, DoubleTab& resu) const
379{
380 resu = 0;
381 return ajouter(tab_inconnue,resu);
382}
383
384/////////////////////////////////////////
385// Method for the implicit scheme
386/////////////////////////////////////////
387
388// essai
389inline double& coeff_opt(Matrice_Morse& matrice,int i, int j)
390{
391 const auto& tab1_ = matrice.get_tab1();
392 const auto& tab2_ = matrice.get_tab2();
393 auto k1=tab1_[i]-1;
394 auto k2=tab1_[i+1]-1;
395 for (auto k=k1; k<k2; k++)
396 if (tab2_[k]-1 == j) return(matrice.get_set_coeff()(k));
397 Cerr << "i ou j ne conviennent pas " << finl;
398 Cerr << "i=" << i << finl;
399 Cerr << "j=" << j << finl;
400 Cerr << "n_lignes=" << matrice.nb_lignes() << finl;
401 Cerr << "n_colonnes=" << matrice.nb_colonnes() << finl;
403 return coeff_opt(matrice,i,j);
404}
405//#define matrice_coef(i,j) coeff_opt(matrice,i,j)
406#define matrice_coef(i,j) matrice.coef(i,j)
407void Op_Diff_EF::ajouter_contribution(const DoubleTab& transporte, Matrice_Morse& matrice ) const
408{
409 if (1)
410 if ((equation().nombre_d_operateurs()>1)&&sub_type(Op_Conv_EF,equation().operateur(1).l_op_base()))
411 ref_cast(Op_Conv_EF,equation().operateur(1).l_op_base()).ajouter_contribution_a_la_diffusion(transporte,matrice);
412
414 {
415 ajouter_contribution_new(transporte,matrice);
416 }
417 // Fill the nu array because matrix assembly with ajouter_contribution
418 // can happen before the first time step
420
421 const int N = transporte.line_size();
422 const Domaine_EF& domaine_ef=ref_cast(Domaine_EF,equation().domaine_dis());
423 const DoubleVect& volumes_thilde= domaine_ef.volumes_thilde();
424 const DoubleVect& volumes= domaine_ef.volumes();
425
426 const DoubleTab& bij=domaine_ef.Bij();
427 int nb_elem_tot=domaine_ef.domaine().nb_elem_tot();
428 int nb_som_elem=domaine_ef.domaine().nb_som_elem();
429 const IntTab& elems=domaine_ef.domaine().les_elems() ;
430 int nb_som=domaine_ef.domaine().nb_som();
431
432 ArrOfInt marqueur_neuman;
433 remplir_marqueur_sommet_neumann( marqueur_neuman,domaine_ef,la_zcl_EF.valeur(),transpose_partout_ );
434 for (int elem=0; elem<nb_elem_tot; elem++)
435 if (elem_contribue(elem))
436 {
437 double pond=volumes_thilde(elem)/volumes(elem)/volumes(elem);
438
439 for (int i1=0; i1<nb_som_elem; i1++)
440 {
441 int glob=elems(elem,i1);
442
443 int transpose = (marqueur_neuman[glob] == 1 || N == 1) ? 0 : transpose_;
444 if (glob<nb_som)
445 for (int i2=0; i2<nb_som_elem; i2++)
446 {
447 int glob2=elems(elem,i2);
448 double cb=0;
449 for (int b=0; b<dimension; b++)
450 cb+=bij(elem,i1,b)*bij(elem,i2,b);
451 for (int n = 0; n < N; n++)
452 {
453 matrice_coef(glob * N + n, glob2 * N + n) += cb * nu_(elem) * pond;
454 if (transpose)
455 for (int d = 0; d < dimension; d++)
456 matrice_coef(glob * N + n, glob2 * N + d) += bij(elem, i1, d) * bij(elem, i2, n) * nu_(elem) * pond;
457 }
458 }
459 }
460 }
461 if (N == 1) ajouter_contributions_bords(matrice);
462 else if (bidim_axi) ajouter_contribution_axisymetrique(N, matrice);
463
464 if (diffusivite_volumique_)
465 ajouter_contribution_diffusivite_volumique(N, matrice);
466}
467
468void Op_Diff_EF::ajouter_contribution_axisymetrique(int N, Matrice_Morse& matrice) const
469{
470 const Domaine_EF& domaine_ef = ref_cast(Domaine_EF, equation().domaine_dis());
471 const DoubleTab& IPhi_thilde = domaine_ef.IPhi_thilde();
472 const DoubleTab& xs = domaine_ef.domaine().les_sommets();
473 const IntTab& elems = domaine_ef.domaine().les_elems();
474 const int nb_elem_tot = domaine_ef.domaine().nb_elem_tot();
475 const int nb_som_elem = domaine_ef.domaine().nb_som_elem();
476 const int nb_som = domaine_ef.domaine().nb_som();
477
478 const double r_tol = 1e-12;
479 for (int elem = 0; elem < nb_elem_tot; elem++)
480 if (elem_contribue(elem))
481 for (int i1 = 0; i1 < nb_som_elem; i1++)
482 {
483 const int glob = elems(elem, i1);
484 if (glob >= nb_som) continue;
485 const double r_s = xs(glob, 0);
486 if (r_s <= r_tol) continue;
487 const double coeff = 2.0 * nu_(elem) / (r_s * r_s);
488 matrice_coef(glob * N, glob * N) += IPhi_thilde(elem, i1) * coeff;
489 }
490}
491
492void Op_Diff_EF::ajouter_contribution_diffusivite_volumique(int N, Matrice_Morse& matrice) const
493{
495 const double *lambda_ptr = lambda_.addr();
496
497 const Domaine_EF& domaine_ef = ref_cast(Domaine_EF, equation().domaine_dis());
498 const DoubleVect& volumes = domaine_ef.volumes();
499 const DoubleTab& bij = domaine_ef.Bij();
500 const DoubleTab& IPhi_thilde = domaine_ef.IPhi_thilde();
501 const IntTab& elems = domaine_ef.domaine().les_elems();
502 const int nb_elem_tot = domaine_ef.domaine().nb_elem_tot();
503 const int nb_som_elem = domaine_ef.domaine().nb_som_elem();
504 const int nb_som = domaine_ef.domaine().nb_som();
505
506 for (int elem = 0; elem < nb_elem_tot; elem++)
507 if (elem_contribue(elem))
508 {
509 double pond_lambda = lambda_ptr[elem] / volumes(elem);
510
511 for (int i1 = 0; i1 < nb_som_elem; i1++)
512 {
513 const int glob = elems(elem, i1);
514 if (glob >= nb_som) continue;
515 for (int i2 = 0; i2 < nb_som_elem; i2++)
516 {
517 const int glob2 = elems(elem, i2);
518 for (int n = 0; n < N; n++)
519 for (int d = 0; d < N; d++)
520 matrice_coef(glob * N + n, glob2 * N + d) += bij(elem, i1, n) * bij(elem, i2, d) * pond_lambda;
521 }
522 }
523
524 if (bidim_axi)
525 {
526 const DoubleTab& xs = domaine_ef.domaine().les_sommets();
527 const double r_tol = 1e-12;
528 for (int i1 = 0; i1 < nb_som_elem; i1++)
529 {
530 const int glob = elems(elem, i1);
531 if (glob >= nb_som) continue;
532 const double r_s1 = xs(glob, 0);
533 const double inv_r1 = (r_s1 > r_tol) ? (1.0 / r_s1) : 0.0;
534 const double m1 = IPhi_thilde(elem, i1) * inv_r1; // v_r / r
535
536 for (int i2 = 0; i2 < nb_som_elem; i2++)
537 {
538 const int glob2 = elems(elem, i2);
539 const double r_s2 = xs(glob2, 0);
540 const double inv_r2 = (r_s2 > r_tol) ? (1.0 / r_s2) : 0.0;
541 const double m2 = IPhi_thilde(elem, i2) * inv_r2; // u_r / r
542
543 for (int n = 0; n < N; n++)
544 matrice_coef(glob * N + n, glob2 * N + 0) += bij(elem, i1, n) * m2 * pond_lambda;
545
546 for (int n = 0; n < N; n++)
547 matrice_coef(glob * N + 0, glob2 * N + n) += m1 * bij(elem, i2, n) * pond_lambda;
548
549 matrice_coef(glob * N + 0, glob2 * N + 0) += m1 * m2 * pond_lambda;
550 }
551 }
552 }
553 }
554}
555
556void Op_Diff_EF::ajouter_contribution_new(const DoubleTab& transporte, Matrice_Morse& matrice ) const
557{
558 //Cerr<<" NEW"<<finl;
559 // Fill the nu array because matrix assembly with ajouter_contribution
560 // can happen before the first time step
562
563 const int N = transporte.line_size();
564 const Domaine_EF& domaine_ef=ref_cast(Domaine_EF,equation().domaine_dis());
565 //const DoubleVect& volumes_thilde= domaine_ef.volumes_thilde();
566 const DoubleVect& volumes= domaine_ef.volumes();
567
568 const DoubleTab& bij=domaine_ef.Bij();
569 const DoubleTab& bij_thilde=domaine_ef.Bij_thilde();
570 int nb_elem_tot=domaine_ef.domaine().nb_elem_tot();
571 int nb_som_elem=domaine_ef.domaine().nb_som_elem();
572 const IntTab& elems=domaine_ef.domaine().les_elems() ;
573 int nb_som=domaine_ef.domaine().nb_som();
574
575 ArrOfInt marqueur_neuman;
576 remplir_marqueur_sommet_neumann( marqueur_neuman,domaine_ef,la_zcl_EF.valeur(),transpose_partout_ );
577 for (int elem=0; elem<nb_elem_tot; elem++)
578 if (elem_contribue(elem))
579 {
580 double pond=1./volumes(elem);
581
582 for (int i1=0; i1<nb_som_elem; i1++)
583 {
584 int glob=elems(elem,i1);
585
586 int transpose = (marqueur_neuman[glob] == 1 || N == 1) ? 0 : transpose_;
587 if (glob<nb_som)
588 for (int i2=0; i2<nb_som_elem; i2++)
589 {
590 int glob2=elems(elem,i2);
591 double cb=0;
592 for (int b=0; b<dimension; b++)
593 cb+=bij(elem,i1,b)*bij_thilde(elem,i2,b);
594 for (int n = 0; n < N; n++)
595 {
596 matrice_coef(glob * N + n, glob2 * N + n) += cb * nu_(elem) * pond;
597 if (transpose)
598 for (int d = 0; d < dimension; d++)
599 matrice_coef(glob * N + n, glob2 * N + d) += bij(elem, i1, d) * bij_thilde(elem, i2, n) * nu_(elem) * pond;
600 }
601 }
602 }
603 }
604
605}
606void Op_Diff_EF::contribuer_au_second_membre(DoubleTab& resu ) const
607{
608
609 if ((equation().nombre_d_operateurs()>1)&&sub_type(Op_Conv_EF,equation().operateur(1).l_op_base()))
610 ref_cast(Op_Conv_EF,equation().operateur(1).l_op_base()).contribue_au_second_membre_a_la_diffusion(resu);
611 const DoubleTab& tab_inconnue=equation().inconnue().valeurs();
612 ajouter_bords(tab_inconnue,resu,0);
613}
614void Op_Diff_EF::ajouter_bords(const DoubleTab& tab_inconnue,DoubleTab& resu, int contrib_interne ) const
615{
616 // to be moved to calculer_flux_bord....
617
618 const Domaine_Cl_EF& domaine_Cl_EF = la_zcl_EF.valeur();
619 const Domaine_EF& domaine_EF = le_dom_EF.valeur();
620 flux_bords_=0.;
621 // const DoubleTab& tab_inconnue=equation().inconnue().valeurs();
622 // iterate over all boundary faces and compute lambda*gradT
623 const Domaine_EF& domaine_ef=ref_cast(Domaine_EF,equation().domaine_dis());
624 const IntTab& face_voisins=domaine_ef.face_voisins();
625 const DoubleTab& bij=domaine_ef.Bij();
626 int nb_som_elem=domaine_ef.domaine().nb_som_elem();
627 const IntTab& elems=domaine_ef.domaine().les_elems() ;
628 const DoubleTab& face_normales=domaine_ef.face_normales();
629 const DoubleVect& volumes_thilde= domaine_ef.volumes_thilde();
630 const DoubleVect& volumes= domaine_ef.volumes();
631 const int nb_som = domaine_ef.domaine().nb_som();
632
633 const IntTab& face_sommets=domaine_ef.face_sommets();
634 int nb_som_face=domaine_ef.nb_som_face();
635
636 const int N = resu.line_size();
637
638 if (N > 1)
639 {
640 bool has_traction_bc = false;
641 for (int n_bord = 0; n_bord < domaine_Cl_EF.nb_cond_lim(); n_bord++)
642 if (Motcle(domaine_Cl_EF.les_conditions_limites(n_bord)->que_suis_je()) == Motcle("Paroi_pression_imposee"))
643 {
644 has_traction_bc = true;
645 break;
646 }
647
648 if (!has_traction_bc)
649 {
650 modifier_flux(*this);
651 return;
652 }
653
654 flux_bords_ = 0.;
655 for (int n_bord = 0; n_bord < domaine_Cl_EF.nb_cond_lim(); n_bord++)
656 {
657 const Cond_lim& la_cl = domaine_Cl_EF.les_conditions_limites(n_bord);
658 if (Motcle(la_cl->que_suis_je()) != Motcle("Paroi_pression_imposee")) continue;
659
660 const Front_VF& le_bord = ref_cast(Front_VF, la_cl->frontiere_dis());
661 const Neumann& la_cl_paroi = ref_cast(Neumann, la_cl.valeur());
662 for (int i = 0; i < le_bord.nb_faces_tot(); i++)
663 {
664 const int face=le_bord.num_face(i);
665 const double val = la_cl_paroi.flux_impose(i);
666 for (int i1 = 0; i1 < nb_som_face; i1++)
667 {
668 const int glob = face_sommets(face, i1);
669 if (glob < nb_som)
670 for (int comp = 0; comp < N; comp++)
671 resu(glob, comp) -= val * face_normales(face, comp) / nb_som_face;
672 }
673 }
674 }
675
676 modifier_flux(*this);
677 return;
678 }
679 int premiere_face_int=domaine_ef.premiere_face_int();
680 for (int face=0; face<premiere_face_int; face++)
681 {
682 int elem=face_voisins(face,0);
683 if (elem==-1) face_voisins(face,1);
684
685 double pond= volumes_thilde(elem)/volumes(elem)/volumes(elem);
686
687 for (int i1=0; i1<nb_som_elem; i1++)
688 {
689
690 int glob2=elems(elem,i1);
691 {
692
693 for (int a=0; a<dimension; a++)
694 {
695 flux_bords_(face,0)+=face_normales(face,a)*bij(elem,i1,a)*tab_inconnue(glob2)*nu_(elem)*pond;
696 }
697 }
698 }
699
700 }
701
702 // Neumann :
703 int n_bord;
704 int nb_bords=domaine_Cl_EF.nb_cond_lim();
705
706 for (n_bord=0; n_bord<nb_bords; n_bord++)
707 {
708 const Cond_lim& la_cl = domaine_Cl_EF.les_conditions_limites(n_bord);
709 const Front_VF& le_bord = ref_cast(Front_VF,la_cl->frontiere_dis());
710 int ndeb = le_bord.num_premiere_face();
711 int nfin = ndeb + le_bord.nb_faces();
712
713 if (sub_type(Neumann_paroi,la_cl.valeur()))
714 {
715 const Neumann_paroi& la_cl_paroi = ref_cast(Neumann_paroi, la_cl.valeur());
716 for (int face=ndeb; face<nfin; face++)
717 {
718
719 double flux=la_cl_paroi.flux_impose(face-ndeb)*domaine_EF.surface(face);
720 for (int i1=0; i1<nb_som_face; i1++)
721 {
722 int glob2=face_sommets(face,i1);
723 {
724
725 resu[glob2] += flux/nb_som_face;
726 }
727 flux_bords_(face,0) = flux;
728 }
729 }
730 }
731 else if (sub_type(Echange_couplage_thermique, la_cl.valeur()))
732 {
733 const Echange_couplage_thermique& la_cl_paroi = ref_cast(Echange_couplage_thermique, la_cl.valeur());
734 for (int face=ndeb; face<nfin; face++)
735 {
736
737 double h=la_cl_paroi.h_imp(face-ndeb);
738 double Text=la_cl_paroi.T_ext(face-ndeb);
739 double phiext=la_cl_paroi.flux_exterieur_impose(face-ndeb);
740
741 double tm=0;
742 if (contrib_interne)
743 {
744 for (int i1=0; i1<nb_som_face; i1++)
745 {
746 int glob2=face_sommets(face,i1);
747 tm+=tab_inconnue(glob2);
748 }
749 tm/=nb_som_face;
750 }
751 double flux=(phiext+h*(Text-tm))*domaine_EF.surface(face);
752 flux_bords_(face,0) = flux;
753 flux/=nb_som_face;
754 for (int i1=0; i1<nb_som_face; i1++)
755 {
756 int glob2=face_sommets(face,i1);
757 resu[glob2] += flux;
758 }
759 }
760 }
761 else if (sub_type(Echange_interne_global_parfait, la_cl.valeur()))
762 {
763 if (contrib_interne)
764 {
765 const Echange_interne_global_parfait& la_cl_paroi = ref_cast(Echange_interne_global_parfait, la_cl.valeur());
766 const Champ_front_calc_interne& Text = ref_cast(Champ_front_calc_interne, la_cl_paroi.T_ext());
767 const IntVect& fmap = Text.face_map();
768 std::vector<bool> hit(nfin-ndeb);
769 std::fill(hit.begin(), hit.end(), false);
770 for (int face=ndeb; face<nfin; face++)
771 {
772 int opp_face = fmap(face-ndeb)+ndeb; // face on the other side of the inner wall:
773
774 // STRONG assumption : 1D, only one node per face:
775 int som=face_sommets(face,0);
776 int som_opp=face_sommets(opp_face,0);
777 if (!hit[face-ndeb]) // first time we encounter one of the face of the pair
778 {
779 // This where we write the heat equation skipping duplicated face: -A.T(i-1) + (A*T(i)+B.T(i)) - B.T(i+2)
780 // By default, we just have -A.T(i-1) + A*T(i)
781 // Recompute the extra bit of flux coming from the other side:
782 // Get opposite element
783 int elem1 = domaine_EF.face_voisins(opp_face, 0);
784 int elem_opp = (elem1 != -1) ? elem1 : domaine_EF.face_voisins(opp_face, 1);
785 // Other face of the opposite element (i.e. face "after" opp_face)
786 int f1 = domaine_EF.elem_faces(elem_opp, 0);
787 int face_plus_2 = f1 != opp_face ? f1 : domaine_EF.elem_faces(elem_opp, 1); // 2 faces per elem max - 1D
788 int som_p2 = face_sommets(face_plus_2, 0);
789
790 double pond = volumes_thilde(elem_opp)/volumes(elem_opp)/volumes(elem_opp); // taken from ajouter() ...
791 double B = nu_(elem_opp)*pond;
792 resu[som] -= B*(tab_inconnue[som]-tab_inconnue[som_p2]);
793 }
794 else
795 {
796 // This is where we set a Dirichlet T(face) = T(opposite_face)
797 // Initially, flux for this som is -B.T(i+1) + B.T(i+2) with B = nu(i+1) (nu being the diffusivity)
798 // -> We want to have B.T(i) - B.T(i+1)
799 int elem = domaine_EF.face_voisins(face, 0);
800 int f1 = domaine_EF.elem_faces(elem, 0);
801 int face_p2 = f1 != face ? f1 : domaine_EF.elem_faces(elem, 1); // other face of the current elem
802 int som_p2=face_sommets(face_p2,0);
803
804 double pond = volumes_thilde(elem)/volumes(elem)/volumes(elem); // taken from ajouter() ...
805 double B = nu_(elem)*pond;
806 resu[som] += B*(-tab_inconnue[som_p2] + tab_inconnue[som_opp]); // remove B.T(i+2) and add B.T(i)
807 }
808 hit[face-ndeb] = true;
809 hit[opp_face-ndeb] = true;
810 }
811 }
812 else // contrib_interne=0 --> implicit
813 {
814 for (int face=ndeb; face<nfin; face++)
815 {
816 flux_bords_(face,0) = 0.0;
817 }
818 }
819 }
820 else if (sub_type(Echange_interne_global_impose, la_cl.valeur()))
821 {
822 const Echange_interne_global_impose& la_cl_paroi = ref_cast(Echange_interne_global_impose, la_cl.valeur());
823 const DoubleVect& surface_gap = la_cl_paroi.surface_gap();
824 for (int face=ndeb; face<nfin; face++)
825 {
826 double h=la_cl_paroi.h_imp(face-ndeb);
827 const Champ_front_calc_interne& Text = ref_cast(Champ_front_calc_interne, la_cl_paroi.T_ext());
828 const IntVect& fmap = Text.face_map();
829 int opp_face = fmap(face-ndeb)+ndeb;
830
831 double tm=0.0;
832 double to=0.0; // opposite temp.
833 double flux=0.0;
834 if (contrib_interne) // explicit case
835 {
836 for (int i1=0; i1<nb_som_face; i1++)
837 {
838 int glob2=face_sommets(face,i1);
839 int glob3 =face_sommets(opp_face,i1);
840 tm+=tab_inconnue(glob2);
841 to+=tab_inconnue(glob3);
842 }
843 tm/=nb_som_face;
844 to/=nb_som_face;
845 //flux=h*(to-tm)*domaine_EF.surface(face);
846 flux=h*(to-tm)*surface_gap(face-ndeb);
847 }
848 else // implicit case via contribuer_au_second_membre()
849 {
850 flux = 0.0;
851 }
852 flux_bords_(face,0) = flux;
853 flux/=nb_som_face;
854 for (int i1=0; i1<nb_som_face; i1++)
855 {
856 int glob2=face_sommets(face,i1);
857 resu[glob2] += flux;
858 }
859 }
860 }
861 else if (sub_type(Echange_global_impose, la_cl.valeur()))
862 {
863 const Echange_global_impose& la_cl_paroi = ref_cast(Echange_global_impose, la_cl.valeur());
864 for (int face=ndeb; face<nfin; face++)
865 {
866
867 double h=la_cl_paroi.h_imp(face-ndeb);
868 double Text=la_cl_paroi.T_ext(face-ndeb);
869
870
871 double tm=0;
872 if (contrib_interne)
873 {
874 for (int i1=0; i1<nb_som_face; i1++)
875 {
876 int glob2=face_sommets(face,i1);
877 {
878 tm+=tab_inconnue(glob2);
879 }
880 }
881 tm/=nb_som_face;
882 }
883 double flux=h*(Text-tm)*domaine_EF.surface(face);
884 flux_bords_(face,0) = flux;
885 flux/=nb_som_face;
886 for (int i1=0; i1<nb_som_face; i1++)
887 {
888 int glob2=face_sommets(face,i1);
889 {
890 resu[glob2] += flux;
891 }
892
893 }
894 }
895 }
896
897
898 }
899 modifier_flux(*this);
900}
901
902
903
904
906{
907 const Domaine_Cl_EF& domaine_Cl_EF = la_zcl_EF.valeur();
908 const Domaine_EF& domaine_EF = le_dom_EF.valeur();
909 const Domaine_EF& domaine_ef=ref_cast(Domaine_EF,equation().domaine_dis());
910
911 const IntTab& face_sommets=domaine_ef.face_sommets();
912 int nb_som_face=domaine_ef.nb_som_face();
913
914 int N = equation().inconnue().valeurs().line_size();
915
916 if (N > 1)
917 {
918 // Cerr<<__PRETTY_FUNCTION__<<" non code pour les vecteurs"<<finl;
919 throw;
920 }
921
922 // Neumann :
923 int n_bord;
924 int nb_bords=domaine_Cl_EF.nb_cond_lim();
925
926 for (n_bord=0; n_bord<nb_bords; n_bord++)
927 {
928 const Cond_lim& la_cl = domaine_Cl_EF.les_conditions_limites(n_bord);
929 const Front_VF& le_bord = ref_cast(Front_VF,la_cl->frontiere_dis());
930 int ndeb = le_bord.num_premiere_face();
931 int nfin = ndeb + le_bord.nb_faces();
932
933 if (sub_type(Echange_couplage_thermique, la_cl.valeur()))
934 {
935 // matrice.imprimer(Cout);
936 const Echange_couplage_thermique& la_cl_paroi = ref_cast(Echange_couplage_thermique, la_cl.valeur());
937 for (int face=ndeb; face<nfin; face++)
938 {
939
940 double h=la_cl_paroi.h_imp(face-ndeb);
941 double dphi_dT=la_cl_paroi.derivee_flux_exterieur_imposee(face-ndeb);
942
943 double tm=1./(nb_som_face*nb_som_face);
944 double flux=(dphi_dT+h)*domaine_EF.surface(face)*tm;
945
946 for (int i1=0; i1<nb_som_face; i1++)
947 {
948 int glob2=face_sommets(face,i1);
949 for (int j1=0; j1<nb_som_face; j1++)
950 {
951 int glob1=face_sommets(face,j1);
952 matrice.coef(glob1,glob2) += flux;
953 }
954 }
955 }
956 // matrice.imprimer(Cout);exit();
957 }
958 else if (sub_type(Echange_interne_global_parfait, la_cl.valeur()))
959 {
960 const Echange_interne_global_parfait& la_cl_paroi = ref_cast(Echange_interne_global_parfait, la_cl.valeur());
961 const Champ_front_calc_interne& Text = ref_cast(Champ_front_calc_interne, la_cl_paroi.T_ext());
962 const IntVect& fmap = Text.face_map();
963 std::vector<bool> hit(nfin-ndeb);
964 std::fill(hit.begin(), hit.end(), false);
965 for (int face=ndeb; face<nfin; face++)
966 {
967 // face on the other side of the inner wall:
968 int opp_face = fmap(face-ndeb)+ndeb;
969 // element attached to it
970 int elem1 = domaine_EF.face_voisins(opp_face, 0);
971 int elem_opp = (elem1 != -1) ? elem1 : domaine_EF.face_voisins(opp_face, 1);
972 // other face of the opposite element (i.e. face "after" opp_face)
973 int f1 = domaine_EF.elem_faces(elem_opp, 0);
974 int face_plus_2 = f1 != opp_face ? f1 : domaine_EF.elem_faces(elem_opp, 1); // 2 faces per elem max - 1D
975 // other face of the current elem
976 int elem = domaine_EF.face_voisins(face, 0);
977 f1 = domaine_EF.elem_faces(elem, 0);
978 int face_min_1 = f1 != face ? f1 : domaine_EF.elem_faces(elem, 1);
979
980 for (int i1=0; i1<nb_som_face; i1++)
981 {
982 int som=face_sommets(face,i1);
983 int som_opp=face_sommets(opp_face,i1);
984 if (!hit[face-ndeb]) // first time we encounter one of the face of the pair
985 {
986 for (int j1=0; j1<nb_som_face; j1++)
987 {
988 // heat equation skipping duplicated face: -T(i-1) + 2*T(i) - T(i+2)
989 int som_p2=face_sommets(face_plus_2,j1);
990 matrice.coef(som,som_p2) -= matrice.coef(som_opp, som_opp);
991 matrice.coef(som, som) += matrice.coef(som_opp, som_opp);
992 }
993 hit[face-ndeb] = true;
994 hit[opp_face-ndeb] = true;
995 }
996 else // we have already handled the opposite side of the wall
997 for (int j1=0; j1<nb_som_face; j1++)
998 {
999 // Dirichlet T(face) = T(opposite_face) and cancelling right term in the tri-band
1000 int som_m1=face_sommets(face_min_1, j1);
1001 matrice.coef(som,som_opp) = -matrice.coef(som,som);
1002 matrice.coef(som,som_m1) = 0;
1003 }
1004 }
1005 }
1006// matrice.imprimer(Cout);
1007 }
1008 else if (sub_type(Echange_interne_global_impose, la_cl.valeur()))
1009 {
1010 const Echange_interne_global_impose& la_cl_paroi = ref_cast(Echange_interne_global_impose, la_cl.valeur());
1011 const Champ_front_calc_interne& Text = ref_cast(Champ_front_calc_interne, la_cl_paroi.T_ext());
1012 const IntVect& fmap = Text.face_map();
1013 const DoubleVect& surface_gap = la_cl_paroi.surface_gap();
1014 for (int face=ndeb; face<nfin; face++)
1015 {
1016 double h=la_cl_paroi.h_imp(face-ndeb);
1017 double tm=1./(nb_som_face*nb_som_face);
1018 //double flux=h*domaine_EF.surface(face)*tm;
1019 double flux=h*surface_gap(face-ndeb)*tm;
1020 int opp_face = fmap(face-ndeb)+ndeb;
1021
1022 for (int i1=0; i1<nb_som_face; i1++)
1023 {
1024 int glob2=face_sommets(face,i1);
1025 int glob3=face_sommets(opp_face,i1);
1026 for (int j1=0; j1<nb_som_face; j1++)
1027 {
1028 int glob1=face_sommets(face,j1);
1029 matrice.coef(glob1,glob2) += flux;
1030 matrice.coef(glob1,glob3) -= flux;
1031 }
1032 }
1033 }
1034// matrice.imprimer(Cout);
1035 }
1036 else if (sub_type(Echange_global_impose, la_cl.valeur()))
1037 {
1038 // matrice.imprimer(Cout);
1039 const Echange_global_impose& la_cl_paroi = ref_cast(Echange_global_impose, la_cl.valeur());
1040 for (int face=ndeb; face<nfin; face++)
1041 {
1042 double h=la_cl_paroi.h_imp(face-ndeb);
1043 double tm=1./(nb_som_face*nb_som_face);
1044 double flux=h*domaine_EF.surface(face)*tm;
1045 for (int i1=0; i1<nb_som_face; i1++)
1046 {
1047 int glob2=face_sommets(face,i1);
1048 for (int j1=0; j1<nb_som_face; j1++)
1049 {
1050 int glob1=face_sommets(face,j1);
1051 matrice.coef(glob1,glob2) += flux;
1052 }
1053 }
1054 }
1055 }
1056 }
1057}
1059{
1060 static int testee=0;
1061 if(testee)
1062 return;
1063 testee=1;
1064}
DoubleTab & valeurs() override
Returns the array of field values at the current time.
virtual DoubleTab & valeurs()=0
class Champ_base This class is the base of the fields hierarchy.
Definition Champ_base.h:43
class Champ_front_calc_interne Derived class of Champ_front_calc representing
const IntVect & face_map() const
class Cond_lim Generic class used to represent any class
Definition Cond_lim.h:31
int nb_som_elem() const
Returns the number of vertices of the geometric elements that make up the domain.
Definition Domaine.h:474
int_t nb_elem_tot() const
Definition Domaine.h:132
virtual void creer_tableau_elements(Array_base &, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT) const
Creates a parallel array of values at elements.
Definition Domaine.cpp:850
DoubleTab_t & les_sommets()
Definition Domaine.h:113
IntTab_t & les_elems()
Definition Domaine.h:129
int_t nb_som() const
Returns the number of vertices of the domain.
Definition Domaine.h:121
int nb_cond_lim() const
Returns the number of boundary conditions.
const Cond_lim & les_conditions_limites(int) const
Returns the i-th boundary condition.
class Domaine_EF
Definition Domaine_EF.h:56
const DoubleTab & IPhi_thilde() const
Definition Domaine_EF.h:92
const DoubleTab & Bij() const
Definition Domaine_EF.h:89
const DoubleTab & Bij_thilde() const
Definition Domaine_EF.h:90
const DoubleVect & volumes_thilde() const
Definition Domaine_EF.h:82
virtual double face_normales(int face, int comp) const
Definition Domaine_VF.h:47
double volumes(int i) const
Definition Domaine_VF.h:113
int face_sommets(int i, int j) const
Returns the index of the i-th vertex of face num_face.
Definition Domaine_VF.h:582
virtual double surface(int i) const
Definition Domaine_VF.h:53
int nb_som_face() const
Returns the number of vertices per face.
Definition Domaine_VF.h:493
int elem_faces(int i, int j) const
Returns the index of the i-th face of element num_elem; the face numbering convention is.
Definition Domaine_VF.h:542
int premiere_face_int() const
A face is internal if and only if it separates two elements.
Definition Domaine_VF.h:463
int face_voisins(int num_face, int i) const
Returns the neighbouring element of num_face in direction i.
Definition Domaine_VF.h:418
const Domaine & domaine() const
: class Echange_couplage_thermique
double flux_exterieur_impose(int i) const override
Classe Echange_global_impose This class represents the special case of the class.
virtual double derivee_flux_exterieur_imposee(int i) const
virtual double h_imp(int num) const
Returns the value of the imposed heat exchange coefficient on the i-th component.
virtual double T_ext(int num) const
Returns the value of the imposed temperature on the i-th component of the boundary field.
Class Echange_interne_global_impose: This class represents the special case of.
Class Echange_interne_global_parfait: Special case of a perfect internal exchange (h=+inf).
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
virtual const Champ_Inc_base & inconnue() const =0
virtual Nature_du_champ nature_du_champ() const
Definition Field_base.h:77
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
int nb_faces_tot() const
Definition Front_VF.h:58
int num_face(const int) const
Definition Front_VF.h:68
Matrice_Morse class - Represents a (sparse) matrix M, not necessarily square,.
const auto & get_tab2() const
const auto & get_tab1() const
auto & get_set_coeff()
double coef(int i, int j) const
int nb_colonnes() const override
Return local number of columns (=size on the current proc).
int nb_lignes() const override
Return local number of lines (=size on the current proc).
const Equation_base & equation() const
Returns the reference to the equation pointed to by MorEqn::mon_equation.
Definition MorEqn.h:62
A character string (Nom) in uppercase.
Definition Motcle.h:26
Classe Neumann_paroi This boundary condition corresponds to an imposed flux for the.
Classe Neumann This class is the base class of the hierarchy of Neumann-type boundary conditions.
Definition Neumann.h:31
virtual double flux_impose(int i) const
Returns the value of the imposed flux on the i-th component of the field representing the flux at the...
Definition Neumann.cpp:35
static int dimension
Definition Objet_U.h:94
const Nom & que_suis_je() const
Returns the string identifying the class.
Definition Objet_U.cpp:104
virtual Entree & readOn(Entree &)
Reads an Objet_U from an input stream. Virtual method to override.
Definition Objet_U.cpp:289
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
class Op_Conv_EF Represents the convection operator associated with a scalar transport equation.
Definition Op_Conv_EF.h:38
class Op_Diff_EF_base Base class for EF diffusion operators.
class Op_Diff_EF Represents the diffusion operator.
Definition Op_Diff_EF.h:37
DoubleTab lambda_
Definition Op_Diff_EF.h:88
void ajouter_contribution_new(const DoubleTab &, Matrice_Morse &) const
void verifier() const
DoubleTab & ajouter_vectoriel_dim3_nbn_8(const DoubleTab &, DoubleTab &) const
DoubleTab & ajouter_scalaire_template(const DoubleTab &, DoubleTab &) const
Definition Op_Diff_EF.h:101
DoubleTab & ajouter_vectoriel_gen(const DoubleTab &, DoubleTab &) const
DoubleTab & ajouter_vectoriel_dim2_nbn_4(const DoubleTab &, DoubleTab &) const
const Champ_base & diffusivite() const override
void remplir_lambda(DoubleTab &) const
DoubleTab & ajouter_new(const DoubleTab &, DoubleTab &) const
DoubleTab & calculer(const DoubleTab &, DoubleTab &) const override
int nouvelle_expression_
Definition Op_Diff_EF.h:70
DoubleTab & ajouter(const DoubleTab &, DoubleTab &) const override
void contribuer_au_second_membre(DoubleTab &) const override
DOES NOTHING - to override in derived classes.
int transpose_
Definition Op_Diff_EF.h:68
DoubleTab & ajouter_scalaire_gen(const DoubleTab &, DoubleTab &) const
void remplir_nu(DoubleTab &) const override
void completer() override
Associates the operator with the domaine_dis, the domaine_Cl_dis, and the unknown of its equation.
int transpose_partout_
Definition Op_Diff_EF.h:69
void ajouter_contribution(const DoubleTab &, Matrice_Morse &) const
void ajouter_bords(const DoubleTab &, DoubleTab &, int contrib_interne=1) const
DoubleTab & ajouter_scalaire_dim3_nbn_8(const DoubleTab &, DoubleTab &) const
void associer_diffusivite_volumique(const Champ_base &) override
void associer_diffusivite(const Champ_base &) override
Associates the diffusivity field.
const Champ_base & diffusivite_volumique() const
DoubleTab & ajouter_vectoriel_template(const DoubleTab &, DoubleTab &) const
Definition Op_Diff_EF.h:163
DoubleTab & ajouter_scalaire_dim2_nbn_4(const DoubleTab &, DoubleTab &) const
void calculer_von_mises(const DoubleTab &deplacement, DoubleTab &deformation, DoubleTab &contraintes, DoubleTab &von_mises) const override
void ajouter_contributions_bords(Matrice_Morse &matrice) const
void marque_elem(const Equation_base &eqn)
int elem_contribue(const int elem) const
void modifier_flux(const Operateur_base &) const
Multiplies the boundary flux by rho cp or rho if necessary.
DoubleTab flux_bords_
virtual void completer()
Associates the operator with the domaine_dis, the domaine_Cl_dis, and the unknown of its equation.
static void exit(int exit_code=-1)
Exit routine for TRUST within a Kokkos region.
Definition Process.cpp:466
Base class for output streams.
Definition Sortie.h:52
int nb_dim() const
Definition TRUSTTab.h:199
_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 const MD_Vector & get_md_vector() const
Definition TRUSTVect.h:123