TRUST 1.9.8
HPC thermohydraulic platform
Loading...
Searching...
No Matches
Source_PDF_base.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 <Domaine_Cl_dis_base.h>
17#include <Schema_Temps_base.h>
18#include <Source_PDF_base.h>
19#include <Equation_base.h>
20#include <Probleme_base.h>
21#include <Type_info.h>
22#include <SFichier.h>
23#include <Param.h>
24#include <Interpolation_IBM_elem_fluid.h>
25#include <Interpolation_IBM_mean_gradient.h>
26#include <Interpolation_IBM_hybrid.h>
27#include <Interpolation_IBM_power_law_tbl.h>
28#include <Interpolation_IBM_power_law_tbl_u_star.h>
29#include <Interpolation_IBM_thermal_wall_law.h>
30
31Implemente_base(Source_PDF_base,"Source_PDF_base",Source_dep_inco_base);
32// XD source_pdf source_base source_pdf BRACE Source term for Penalised Direct Forcing (PDF) method.
33
35{
36 Param param(que_suis_je());
37 param.ajouter("prepro_ibm", &prepro_lu_,Param::OPTIONAL); // XD_ADD_P Prepro_IBM_base
38 // XD_CONT to realise the PDF IBM preprocessing
39 param.ajouter("aire", &champ_aire_lu_,Param::OPTIONAL); // XD_ADD_P field_base
40 // XD_CONT volumic field: a boolean for the cell (0 or 1) indicating if the obstacle is in the cell
41 param.ajouter_flag("get_aire_from_prepro", &aire_from_prepro_); // XD_ADD_P rien
42 // XD_CONT get aire IBM from prepro.
43 param.ajouter("barycentre", &champ_barycentre_lu_,Param::OPTIONAL); // XD_ADD_P field_base
44 // XD_CONT volumic field with 3 components representing the face barycenters
45 param.ajouter_flag("get_barycenter_from_prepro", &barycentre_from_prepro_); // XD_ADD_P rien
46 // XD_CONT get aire IBM from prepro.
47 param.ajouter("rotation", &champ_rotation_lu_,Param::OPTIONAL); // XD_ADD_P field_base
48 // XD_CONT volumic field with 9 components representing the change of basis on cells (local to global). Used for
49 // XD_CONT rotating cases for example.
50 param.ajouter_flag("get_rotation_from_prepro", &rotation_from_prepro_); // XD_ADD_P rien
51 // XD_CONT get aire IBM from prepro.
52 param.ajouter_flag("transpose_rotation", &transpose_rotation_); // XD_ADD_P rien
53 // XD_CONT whether to transpose the basis change matrix.
54 param.ajouter("modele",&modele_lu_,Param::REQUIRED); // XD_ADD_P bloc_pdf_model
55 // XD_CONT model used for the Penalized Direct Forcing
56 temps_relax_ = modele_lu_.temps_relax_;
57 echelle_relax_ = modele_lu_.echelle_relax_;
58 param.ajouter("interpolation",&interpolation_lue_,Param::OPTIONAL); // XD_ADD_P interpolation_ibm_base
59 // XD_CONT interpolation method
60
61 param.lire_avec_accolades(s);
62 if (interpolation_lue_)
63 {
64 if (!(interpolation_lue_->que_suis_je() == "Interpolation_IBM_aucune"))
65 {
67 if ((interpolation_lue_->que_suis_je() == "Interpolation_IBM_power_law_tbl") || (interpolation_lue_->que_suis_je() == "Interpolation_IBM_power_law_tbl_u_star") ) imm_wall_law_ = true;
68 interpolation_lue_->set_source(*this);
69 }
70 }
71
72 if (!equation().probleme().que_suis_je().contient("_IBM"))
73 {
74 Cerr << "Error in the equation " << equation().que_suis_je() << " !" << finl;
75 Cerr << "You are using a " << que_suis_je() << " source term but your problem is not an IBM problem !" << finl;
76 Cerr << "Fix your data set and use one of the following problems : " << finl;
77
78 Noms noms_pb;
79 Type_info::les_sous_types(Nom("Probleme_base"), noms_pb);
80
81 for (auto &itr : noms_pb)
82 if (itr.contient("_IBM"))
83 Cerr << " - " << itr << finl;
84
85 Cerr << " - Pb_Couple_Optimisation_IBM" << finl;
86
88 }
89
90 return s;
91}
92
94{
95 return s << que_suis_je() ;
96}
97
99{
100 if (prepro_lu_)
101 {
102 prepro_lu_->associer_pb(pb);
103
104 // Verification eventuelle
105 if( prepro_lu_->verify_results_prepro() == 1) verify_results_prepro();
106 }
107
108 const Domaine_dis_base& le_dom_dis = pb.domaine_dis();
109
110 // Matrice Rotation
111 int dim_esp = Objet_U::dimension;
112 assert(dim_esp==3);
113 int nb_comp=dim_esp*dim_esp;
114 Noms nom_c(nb_comp);
115 Noms unites(nb_comp);
116 pb.discretisation().discretiser_champ("champ_elem",le_dom_dis,vectoriel,nom_c,unites,nb_comp,0.,champ_rotation_);
117 if (prepro_lu_ && rotation_from_prepro_)
118 {
119 champ_rotation_->valeurs() = prepro_lu_->get_champ_rotation();
120 }
121 else
122 {
123 if (champ_rotation_lu_)
124 {
125 champ_rotation_->affecter(champ_rotation_lu_);
126 }
127 else
128 {
129 Cerr<<"Source_PDF_base::associer_pb: rotation term is missing "<<finl;
130 exit();
131 }
132 }
133
134 // Barycentre
135 int nb_comp0=dim_esp;
136 Noms nom_c0(nb_comp0);
137 Noms unites0(nb_comp0);
138 pb.discretisation().discretiser_champ("champ_elem",le_dom_dis,vectoriel,nom_c0,unites0,nb_comp0,0.,champ_barycentre_);
139 if (prepro_lu_ && barycentre_from_prepro_)
140 {
141 champ_barycentre_->valeurs() = prepro_lu_->get_champ_barycentre();
142 }
143 else
144 {
145 if (champ_barycentre_lu_)
146 {
147 champ_barycentre_->affecter(champ_barycentre_lu_);
148 }
149 // else
150 // barycentres non requis sans prepro_ibm
151 // {
152 // Cerr<<"Source_PDF_base::associer_pb: barycenter term is missing "<<finl;
153 // exit();
154 // }
155 }
156
157 // Champ pour terme source PDF
158 if (equation().discretisation().is_ef())
159 pb.discretisation().discretiser_champ("champ_sommets",le_dom_dis,"","",1,0., champ_nodal_);
160 else
161 pb.discretisation().discretiser_champ("champ_face",le_dom_dis,"","",1,0., champ_nodal_);
162
163 // Aire
164 pb.discretisation().discretiser_champ("champ_elem",le_dom_dis ,"aire","m-1",1,0., champ_aire_);
165 if (prepro_lu_ && aire_from_prepro_)
166 {
167 champ_aire_->valeurs() = prepro_lu_->get_champ_aire();
168 }
169 else
170 {
171 if (champ_aire_lu_)
172 {
173 champ_aire_->affecter(champ_aire_lu_);
174 }
175 else
176 {
177 Cerr<<"Source_PDF_base::associer_pb: aire term is missing "<<finl;
178 exit();
179 }
180 }
181
182 // Vitesse Imposee Shape IB
183 if (get_modele().get_PDF_mobile())
184 {
185 nb_comp=dim_esp;
186 Noms nom_c11(nb_comp);
187 Noms unites11(nb_comp);
188 pb.discretisation().discretiser_champ("champ_elem",le_dom_dis,vectoriel,nom_c11,unites11,nb_comp,0.,modele_lu_.vitesse_shape_IBM_);
189 }
190
191 // Variable Imposee sur IB
192 const DoubleTab& variable=equation().inconnue().valeurs();
193 Motcle directive("temperature");
194 if (equation().inconnue().is_vectorial()) directive="vitesse";
195 nb_comp=variable.dimension(1);
196 assert(nb_comp==modele_lu_.dim_variable_);
197 Nom nom_c1(equation().inconnue().le_nom());
198 Nom unites1(equation().inconnue().unites()[0]);
199 type_variable_imposee_ = modele_lu_.type_variable_imposee_;
200 pb.discretisation().discretiser_champ(directive,le_dom_dis ,nom_c1,unites1,nb_comp,0.,modele_lu_.variable_imposee_);
201
203 {
204 Domaine_dis_base& le_dom_dis_base = ref_cast_non_const(Domaine_dis_base,le_dom_dis);
205 interpolation_lue_->discretise(pb.discretisation(),le_dom_dis_base);
206 }
207
208 // set variable imposee
210
211 // Rho
212 pb.discretisation().discretiser_champ("champ_elem",le_dom_dis ,"rho","kg.m-3",1,0., champ_rho_);
214
215 // Relaxation
216 temps_relax_ = modele_lu_.temps_relax_;
217 echelle_relax_ = modele_lu_.echelle_relax_;
218
220 if (temps_relax_ != 1.0e+12) matrice_pression_variable_bool_ = true;
221}
222
224{
225 int dim_esp = Objet_U::dimension;
226 const Probleme_base& pb = equation().probleme();
227 const Domaine_dis_base& le_dom_dis = pb.domaine_dis();
228
229 // Transposition Matrice Rotation
231 {
232 DoubleTab& val=champ_rotation_->valeurs();
233
234 int nb_case=val.dimension_tot(0);
235 for (int ele=0; ele<nb_case; ele++)
236 for (int k=0; k<dim_esp; k++)
237 for (int i=k+1; i<dim_esp; i++)
238 {
239 double tmp=val(ele,3*k+i);
240 val(ele,3*k+i)=val(ele,3*i+k);
241 val(ele,3*i+k)=tmp;
242 }
243 }
244
245 // Variable Imposee sur IB
246 const DoubleTab& variable=equation().inconnue().valeurs();
247 int nb_comp=variable.dimension(1);
248
249 if (interpolation_bool_) // interpolation
250 {
251 if (type_variable_imposee_ == 1) // fonction xyzt
252 {
253 if (interpolation_lue_->que_suis_je() == "Interpolation_IBM_gradient_moyen" || interpolation_lue_->que_suis_je() == "Interpolation_IBM_power_law_tbl_u_star")
254 {
255 const Interpolation_IBM_mean_gradient& interp = ref_cast(Interpolation_IBM_mean_gradient,interpolation_lue_.valeur());
256 this->compute_variable_imposee_projete(interp.solid_elems_->valeurs(), interp.solid_points_->valeurs(), -2.0, 1e-6);
257 }
258 else
259 {
260 const Interpolation_IBM_elem_fluid& interp = ref_cast(Interpolation_IBM_elem_fluid,interpolation_lue_.valeur());
261 compute_variable_imposee_projete(interp.fluid_elems_->valeurs(), interp.solid_points_->valeurs(), -2.0, 1e-6);
262 }
263 }
264 else // data
265 {
266 modele_lu_.variable_imposee_->affecter(modele_lu_.variable_imposee_lu_);
267 }
268 }
269 else // pas d'interpolation
270 {
271 if (type_variable_imposee_ != 1) // data
272 {
273 modele_lu_.variable_imposee_->affecter(modele_lu_.variable_imposee_lu_);
274 }
275 else // fonction xyzt
276 {
277 const DoubleTab& coords = le_dom_dis.domaine().coord_sommets();
278 Domaine_VF& le_dom_VF = ref_cast_non_const(Domaine_VF, pb.domaine_dis());
279 modele_lu_.affecter_variable_imposee(le_dom_VF, coords);
280 }
281 }
282 if (modele_lu_.local_ == 1)
283 {
284 if (nb_comp != dim_esp)
285 {
286 Cerr<<"Source_PDF_base::calcul_variable_imposee: dimension variable differente "<<dim_esp<<"! "<<finl;
287 abort();
288 }
289 rotate_imposed_velocity(modele_lu_.variable_imposee_->valeurs());
290 }
291
292 variable_imposee_ = modele_lu_.variable_imposee_->valeurs();
293
295}
296
298{
299 un_prepro.set_champ_aire(champ_aire_->valeurs());
300 un_prepro.set_champ_rotation(champ_rotation_->valeurs());
301 un_prepro.set_champ_barycentre(champ_barycentre_->valeurs());
302}
303
305{
306 champ_aire_->valeurs() = un_prepro.get_champ_aire();
307 champ_rotation_->valeurs() = un_prepro.get_champ_rotation();
308 champ_barycentre_->valeurs() = un_prepro.get_champ_barycentre();
309}
310
311void Source_PDF_base::compute_NeighNode_IBM_elem(DoubleTab& aireArray, IntLists& elem_voisins, bool all_elem_vois)
312{
313 const Probleme_base& pb = equation().probleme();
314 const Domaine_dis_base& le_dom_dis = pb.domaine_dis();
315 const Domaine_VF& the_dom_VF = ref_cast(Domaine_VF,le_dom_dis);
316 const Domaine& le_dom = le_dom_dis.domaine();
317 int nb_elem_tot = le_dom.nb_elem_tot();
318 int nb_som_elem = le_dom.nb_som_elem();
319 int nb_faces_elem = le_dom.nb_faces_elem();
320 const IntTab& face_voisins = the_dom_VF.face_voisins();
321 const IntTab& elems = le_dom.les_elems() ;
322 const IntTab& elem_face = the_dom_VF.elem_faces();
323
324 // On vide la Lists
325 assert (elem_voisins.size() == nb_elem_tot);
326 for (int num_elem = 0; num_elem < nb_elem_tot; num_elem++) elem_voisins[num_elem].vide();
327
328 for (int num_elem = 0; num_elem < nb_elem_tot; num_elem++) // inclus les elem ghost
329 {
330 if (aireArray(num_elem) > 0.)
331 {
332 if (!elem_voisins[num_elem].est_vide()) // Liste non vide !
333 {
334 Cerr<<"IBM : Source_PDF_base::compute_NeighNode_IBM_elem: Neighbour liste is not empty for element "<<num_elem<<" : Abort"<<finl;
335 exit();
336 }
337 // Cerr << "******Elem = "<<num_elem<<finl;
338
339 IntList node_of_elem;
340 node_of_elem.vide();
341 for (int nod=0; nod<nb_som_elem; nod++)
342 {
343 int nod_glob = elems(num_elem, nod);
344 node_of_elem.add_if_not(nod_glob);
345 }
346 for (int fac=0; fac<nb_faces_elem; fac++)
347 {
348 int num_fac = elem_face(num_elem, fac);
349 // Cerr << "face "<<fac<<" : num_face = "<<num_fac<<finl;
350 for (int voisin=0; voisin<2; voisin++) // Deux voisins seulement
351 {
352 int num_elem_v = face_voisins(num_fac,voisin);
353 if ( (num_elem_v!=-1) && (num_elem_v!=num_elem) )
354 {
355 if (aireArray(num_elem_v) > 0. || all_elem_vois) elem_voisins[num_elem].add_if_not(num_elem_v); // voisin de num_elem par une face
356 // Cerr << "voisin "<<voisin<<" : num_elem_v = "<<num_elem_v<<finl;
357 // Cerr<<"list elem_voisins => ";
358 // for (int v=0; v<elem_voisins[num_elem].size(); v++) Cerr<<(elem_voisins[num_elem])[v]<< " ";
359 // Cerr<<finl;
360
361 // element num_elem_v_v, voisin de num_elem_v par une face
362 for (int fac_v=0; fac_v<nb_faces_elem; fac_v++)
363 {
364 int num_fac_v = elem_face(num_elem_v, fac_v);
365 for (int voisin_v=0; voisin_v<2; voisin_v++)
366 {
367 int num_elem_v_v = face_voisins(num_fac_v,voisin_v);
368 if ( (num_elem_v_v!=-1) && (num_elem_v_v!=num_elem_v) && (num_elem_v_v!=num_elem) )
369 {
370 if (aireArray(num_elem_v_v) > 0. || all_elem_vois)
371 {
372 int iok = 0 ;
373 for (int nod_v_v=0; nod_v_v<nb_som_elem; nod_v_v++)
374 {
375 int num_nod_v_v = elems(num_elem_v_v, nod_v_v);
376 if (node_of_elem.contient(num_nod_v_v)) iok = 1;
377 }
378 // Cerr << "num_elem_v_v = "<<num_elem_v_v<<" iok = "<<iok<<finl;
379 if (iok == 1) elem_voisins[num_elem].add_if_not(num_elem_v_v); // voisin de num_elem par un noeud
380 }
381 }
382 }
383 }
384 }
385 }
386 }
387 // Cerr<<"=> "<<elem_voisins[num_elem].size()<<" voisins de "<<num_elem<<" : ";
388 // for (int voisin=0; voisin<elem_voisins[num_elem].size(); voisin++) Cerr<<(elem_voisins[num_elem])[voisin]<< " ";
389 // Cerr<<finl;
390 }
391 }
392 return;
393}
394
395double Source_PDF_base::aire_geometrique_IBM(DoubleTab& rotation, int elem)
396{
397 int dim_esp = Objet_U::dimension;
398 const Probleme_base& pb = equation().probleme();
399 const Domaine_dis_base& le_dom_dis = pb.domaine_dis();
400 const Domaine_VF& the_dom_VF = ref_cast(Domaine_VF,le_dom_dis);
401 const Domaine& dom = le_dom_dis.domaine();
402 const IntTab& elems = dom.les_elems() ;
403 const DoubleTab coordsDom3D=dom.les_sommets();
404 int nb_som_elem = dom.nb_som_elem();
405
406 DoubleTrav hmax(dim_esp);
407 for (int k=0; k < dim_esp; k++)
408 {
409 double xmin = 1.e30;
410 double xmax = -1.e30;
411 for (int id_loc=0; id_loc < nb_som_elem; id_loc++)
412 {
413 int id_glob = elems(elem,id_loc);
414 xmin = std::min(xmin, coordsDom3D(id_glob, k));
415 xmax = std::max(xmax, coordsDom3D(id_glob, k));
416 }
417 hmax(k) = xmax-xmin;
418 }
419 double hcharac = 0.;
420 for (int k=0; k<dim_esp; k++) hcharac += hmax(k) * abs(rotation(elem,3*k+(dim_esp-1)));
421 hcharac = abs(hcharac);
422 // hcharac = (prepro_lu_->get_h_max_elem())(e);
423 double aire = the_dom_VF.volumes(elem) / hcharac;
424
425 // Cerr<< "=> element: "<<elem<<" ; hmax "<< hmax<<finl;
426 // Cerr<< "normal "<<rotation(elem,3*0+(dim_esp-1))<<" "<<rotation(elem,3*1+(dim_esp-1))<<" "<<rotation(elem,3*2+(dim_esp-1))<<finl;
427 // Cerr<< "hcharac "<< hcharac<<" ; aire = "<<aire<<finl;
428
429 return aire;
430}
431
432void Source_PDF_base::update_pseudo_level_set_IBM(DoubleTab& vecteur_deplacement, double alpha)
433{
434 // Update a partir de la pseudo level set et vecteur deplacement vertex
435
436 if (!(getInterpolationBool() == true))
437 {
438 Cerr << "Source_PDF_base::update_pseudo_level_set_IBM: No Interpolation. Aborting..." << finl;
439 abort();
440 }
441 if (!prepro_lu_)
442 {
443 Cerr << "Source_PDF_base::update_pseudo_level_set_IBM: No IBM prepro. Aborting..." << finl;
444 abort();
445 }
446
447 int dim_esp = Objet_U::dimension;
448 assert(dim_esp == 3);
449 Interpolation_IBM_base& my_interp = ref_cast_non_const(Interpolation_IBM_base, getInterpolationLu());
450 DoubleTab& level_set = ref_cast_non_const(DoubleTab, my_interp.get_pseudo_level_set());
451 int nb_som = level_set.dimension(0);
452
453 DoubleTab& bary = champ_barycentre_->valeurs();
454 DoubleTab& rotation = champ_rotation_->valeurs();
455 DoubleTab& aire = champ_aire_->valeurs();
456 int nb_elem = aire.dimension(0);
457
458 const DoubleTab& nor = my_interp.get_normal_proj_solid();
459 assert (nor.dimension(0) == nb_som);
460 assert (nor.dimension(1) == dim_esp);
461
462 assert (vecteur_deplacement.dimension(0) == nb_som);
463 assert (vecteur_deplacement.dimension(1) == dim_esp);
464
465 const Probleme_base& pb = equation().probleme();
466 const Domaine_dis_base& le_dom_dis = pb.domaine_dis();
467 const Domaine& dom = le_dom_dis.domaine();
468 const IntTab& elems= dom.les_elems() ;
469 int nb_som_elem=dom.nb_som_elem();
470 const DoubleTab coordsDom3D=dom.les_sommets();
471
472 // Preparation de la level-set
473 double nor_nor = 0.;
474 for (int e=0; e<nb_elem; e++)
475 {
476 int nb_nor_nul = 0;
477 for (int il=0; il<nb_som_elem; il++)
478 {
479 int i = elems(e,il);
480 if (level_set(i) == -99999.) // level_set non initialise
481 {
482 nb_nor_nul += 1;
483 continue;
484 }
485 nor_nor = 0.;
486 for (int k=0; k<dim_esp; k++) nor_nor += nor(i, k)*nor(i, k);
487 if (nor_nor <= 1.e-10) nb_nor_nul += 1; // vertex non calcule PDF
488 }
489 if ( nb_nor_nul == nb_som_elem )
490 for (int il=0; il<nb_som_elem; il++) level_set(elems(e,il)) = -99999.;
491 }
492
493 // Gradient de phi par element (schema explicite) + sommet (robustesse)
494 DoubleTrav grad_phi_e_0(nb_elem,dim_esp) ;
495 DoubleTrav grad_phi_i_0(nb_som,dim_esp) ;
496 IntTrav contrib_i(nb_som);
497 int etarg = -1; // pour debug
498 // grad_phi par element (normee)
499 for (int e=0; e<nb_elem; e++)
500 {
501 int initialised_vertex_in_e = 1;
502 if (e == etarg) Cerr<<">>> elem = "<<e<<" : grad phi"<<finl;
503 // Ajout contributions dans l element
504 for (int il=0; il<nb_som_elem; il++)
505 {
506 int i = elems(e,il);
507 if (level_set(i) == -99999.) // level_set non initialisee => pas de contrib.
508 {
509 initialised_vertex_in_e = 0;
510 continue;
511 }
512 int dir_grad_phi_0 = (level_set(i)<0.?-1:(level_set(i)==0.?0.:1)); // grad_phi suivant phi croissant (dir_grad_phi * nor)
513 nor_nor = 0.;
514 for (int k=0; k<dim_esp; k++) nor_nor += nor(i, k)*nor(i, k);
515 if (e == etarg) Cerr<<"i = "<<i<<" norme carree normal = "<<nor_nor<<" dir_grad_phi_0 = "<<dir_grad_phi_0<<finl;
516 if (nor_nor > 1.e-10)
517 {
518 for (int k=0; k<dim_esp; k++) grad_phi_e_0(e,k) += dir_grad_phi_0*nor(i, k);
519 }
520 }
521 // normalisation grad_phi_e_0 par element si non null
522 // rem. : si level_set non initialisee pour tout noeud de l element => grad_phi_e_0 null
523 // Traitement initialised_vertex_in_e = 0 et Assemblage sommet
524 nor_nor = 0.;
525 for (int k=0; k<dim_esp; k++) nor_nor += grad_phi_e_0(e,k)*grad_phi_e_0(e,k);
526 if (nor_nor > 1.e-10)
527 {
528 for (int k=0; k<dim_esp; k++) grad_phi_e_0(e,k) /= sqrt(nor_nor);
529
530 // Si initialised_vertex_in_e = 0
531 // => initialisation de ces vertex a partir de grad_phi_e_0 et des autres vertex
532 if ( initialised_vertex_in_e == 0)
533 {
534 // boucle recherche vertex de reference
535 double level_set_ref = -99999.;
536 DoubleTrav XYZ_ref(dim_esp);
537 for (int il=0; il<nb_som_elem; il++)
538 {
539 int i = elems(e,il);
540 nor_nor = 0.;
541 for (int k=0; k<dim_esp; k++) nor_nor += nor(i, k)*nor(i, k);
542 if (level_set(i) != -99999. && nor_nor > 1.e-10)
543 {
544 level_set_ref = level_set(i) ;
545 for (int k=0; k<dim_esp; k++) XYZ_ref(k) = coordsDom3D(i,k);
546 break; // on a trouve
547 }
548 }
549 if (e == etarg) Cerr<<"Vertex non initialise : level_set_ref = "<<level_set_ref<<finl;
550 // boucle definition level_set vertex non initialises
551 for (int il=0; il<nb_som_elem; il++)
552 {
553 int i = elems(e,il);
554 if (level_set(i) == -99999.) // on initialise
555 {
556 double prod_sca = 0.;
557 for (int k=0; k<dim_esp; k++) prod_sca += (coordsDom3D(i,k)-XYZ_ref(k))*grad_phi_e_0(e,k);
558 level_set(i) = level_set_ref + prod_sca;
559 }
560 }
561 }
562
563 // Assemblage sommet
564 for (int il=0; il<nb_som_elem; il++)
565 {
566 int i = elems(e,il);
567 for (int k=0; k<dim_esp; k++) grad_phi_i_0(i,k) += grad_phi_e_0(e,k);
568 contrib_i(i) += 1;
569 }
570 }
571
572 if (e == etarg)
573 {
574 for (int il=0; il<nb_som_elem; il++)
575 {
576 int i = elems(e,il);
577 Cerr<<"i = "<<i<<" ; old level set = "<<level_set(i)<<" ; nor = ";
578 for (int k=0; k<dim_esp; k++) Cerr<<nor(i,k)<<" ";
579 Cerr<<" ; deplacement = ";
580 for (int k=0; k<dim_esp; k++) Cerr<<vecteur_deplacement(i,k)<<" ";
581 Cerr<<finl;
582 }
583 Cerr<<"grad_phi_e_0 = ";
584 for (int k=0; k<dim_esp; k++) Cerr<<grad_phi_e_0(e,k)<<" ";
585 Cerr<<finl;
586 }
587 }
588
589 // grad_phi par sommet (norme)
590 for (int i=0; i<nb_som; i++)
591 {
592 if (contrib_i(i) != 0)
593 {
594 for (int k=0; k<dim_esp; k++) grad_phi_i_0(i,k) /=contrib_i(i);
595
596 // normalisation
597 nor_nor = 0.;
598 for (int k=0; k<dim_esp; k++) nor_nor += grad_phi_i_0(i,k)*grad_phi_i_0(i,k);
599 if (nor_nor > 1.e-10)
600 for (int k=0; k<dim_esp; k++) grad_phi_i_0(i,k) /= sqrt(nor_nor);
601 }
602 }
603
604 // Advecte phi par sommet pour tous les sommets + new_bary pour element traverse par level set zero (moyenne arith)
605 // normale egale a grad_phi_e_0 pour ces elements
606 IntTrav advect_faite(nb_som) ;
607 aire = 0.; // Mise a zero champ aire IB
608 bary = 0.; // Mise a zero champ barycentre IB
609 DoubleTrav new_normal_e(bary);
610 for (int e=0; e<nb_elem; e++)
611 {
612 if (e == etarg) Cerr<<">>> elem = "<<e<<" : Advecte phi"<<finl;
613 double nor_nor_e_0 = 0.;
614 for (int k=0; k<dim_esp; k++) nor_nor_e_0 += grad_phi_e_0(e,k)*grad_phi_e_0(e,k);
615 if (nor_nor_e_0 <= 1.0e-10) continue; // element avec grad phi element non defini
616
617 double contrib_e = 0.;
618 for (int il=0; il<nb_som_elem; il++)
619 {
620 int i = elems(e,il);
621 // Advection phi pour le sommet i de l element (si pas deja fait)
622 if (advect_faite(i) == 0)
623 {
624 if (e == etarg)
625 {
626 Cerr<<" ** node = "<<i<<finl;
627 Cerr<<" vecteur_deplacement = ";
628 for (int k=0; k<dim_esp; k++) Cerr<<vecteur_deplacement(i,k)<<" ";
629 Cerr<<finl;
630 }
631
632 if (level_set(i) != -99999.)
633 {
634 double vdotnorm = 0.0 ;
635 for (int k=0; k<dim_esp; k++) vdotnorm += vecteur_deplacement(i,k)*grad_phi_i_0(i,k);
636 level_set(i) -= alpha*vdotnorm;
637 }
638 advect_faite(i) = (level_set(i)<0.?-1:1);
639
640
641 if (e == etarg)
642 {
643 Cerr<<" nor = ";
644 for (int k=0; k<dim_esp; k++) Cerr<<nor(i,k)<<" ";
645 Cerr<<finl;
646 Cerr<<" new level set : "<<level_set(i)<<" ; advect_faite = "<<advect_faite(i)<<finl;
647 Cerr<<" grad_phi_i_0 = ";
648 for (int k=0; k<dim_esp; k++) Cerr<<grad_phi_i_0(i,k)<<" ";
649 Cerr<<finl;
650 }
651 }
652
653 // calcul de la projection solide nodale et du barycentre (moyenne arith.)
654 for (int k=0; k<dim_esp; k++)
655 bary(e,k) += coordsDom3D(i,k)-(level_set(i)*grad_phi_i_0(i,k)); // OP^1 = OX - phi^1 grad_phi^0
656 contrib_e += 1.;
657 if (e == etarg)
658 {
659 Cerr<<" ** node = "<<i;
660 Cerr<<" ; new level set = "<<level_set(i);
661 Cerr<<" ; coords = ";
662 for (int k=0; k<dim_esp; k++) Cerr<<coordsDom3D(i,k)<<" ";
663 Cerr<<finl;
664 Cerr<<" Projection : ";
665 for (int k=0; k<dim_esp; k++) Cerr<<coordsDom3D(i,k)-(level_set(i)*grad_phi_i_0(i,k))<<" ";
666 Cerr<<finl;
667 }
668 }
669 if (contrib_e != 0.)
670 for (int k=0; k<dim_esp; k++) bary(e,k) /= contrib_e;
671
672 // Si element traverse par level set zero + grad_phi_e element OK => contribution au champ aire
673 int iok = 0;
674 // element avec level set differents signe ?
675 double level_ref = 0.;
676 for (int il=0; il<nb_som_elem; il++)
677 {
678 int i = elems(e,il);
679 if (level_set(i) != 0. && level_set(i) != -99999.)
680 {
681 level_ref = level_set(i); // reference 1er vertex avec phi<>0 et initialisee
682 break;
683 }
684 }
685 if (level_ref != 0.)
686 {
687 for (int il=0; il<nb_som_elem; il++)
688 {
689 int i = elems(e,il);
690 if (level_set(i) != 0. && level_set(i) != -99999.)
691 {
692 iok = (level_ref*level_set(i) < 0. ? 1:0) ;
693 if (iok == 1) break;
694 }
695 }
696 }
697 // grad_phi_e element OK ?
698 if (nor_nor_e_0 > 1.0e-10) iok += 1;
699 if (iok == 2)
700 {
701 // Definition de l aire a faire une fois les rotations mises a jour
702 aire(e) = 9999.;
703 // Definition de la normale element
704 for (int k=0; k<dim_esp; k++) new_normal_e(e, k) = grad_phi_e_0(e,k);
705 if (e == etarg)
706 {
707 Cerr<<"aire = "<<aire(e)<<finl;
708 Cerr<<"new_bary_e = ";
709 for (int k=0; k<dim_esp; k++) Cerr<<bary(e,k)<<" ";
710 Cerr<<finl;
711 Cerr<<"new_normal_e = ";
712 for (int k=0; k<dim_esp; k++) Cerr<<new_normal_e(e,k)<<" ";
713 Cerr<<finl;
714 }
715 }
716 else
717 for (int k=0; k<dim_esp; k++) bary(e,k) =0.;
718
719 }
720 level_set.echange_espace_virtuel();
721
722 // Modification champ rotation par element
723 rotation = 0.; // Mise a zero des rotations
724 rotation.echange_espace_virtuel();
725 DoubleTrav t1EulerArr(bary);
726 DoubleTrav t2EulerArr(bary);
727 for (int e=0; e<nb_elem; e++)
728 {
729 if(aire(e) == 9999.)
730 {
731 prepro_lu_->computeLocalFrame(new_normal_e, t1EulerArr, t2EulerArr, e);
732 prepro_lu_->computeMatRot(new_normal_e, t1EulerArr, t2EulerArr, e);
733 }
734 }
735 rotation = prepro_lu_->get_champ_rotation();
736
737 // Rotations à jour => modification possible du champ aire
738 for (int e=0; e<nb_elem; e++)
739 {
740 if(aire(e) == 9999.)
741 {
742 aire(e) = aire_geometrique_IBM(rotation, e);
743 if (e == etarg) Cerr<<"aire = "<<aire(e)<<finl;
744 }
745 }
746
749 rotation.echange_espace_virtuel();
750
751 // finalisation : mise a jour de l IB
752 set_fields_to_prepro(prepro_lu_);
753 prepro_lu_->compute_solid_fluid(1);
754
755 my_interp.set_fields_from_prepro_to_interp(prepro_lu_);
757 my_interp.set_pseudo_level_set(level_set);
758 // my_interp.definir_pseudo_level_set(); //re-initialisation phi
759
761 prepro_lu_-> Save_Med_File();
762
763}
764
765void Source_PDF_base::update_elem_IBM(DoubleTab& vecteur_deplacement, double alpha, double raid)
766{
767 // Update a partir des barycentres elementaires de Source_PDF_base
768
769 int dim_esp = Objet_U::dimension;
770 assert (dim_esp == 3);
771
772 DoubleTab& aire = ref_cast_non_const(DoubleTab, champ_aire_->valeurs());
773 DoubleTab& bary = ref_cast_non_const(DoubleTab, champ_barycentre_->valeurs());
774 DoubleTab& rotation = ref_cast_non_const(DoubleTab, champ_rotation_->valeurs());
775 const Probleme_base& pb = equation().probleme();
776 const Domaine_dis_base& le_dom_dis = pb.domaine_dis();
777 const Domaine& dom = le_dom_dis.domaine();
778 int nb_elem_tot = dom.nb_elem_tot();
779 const DoubleTab coordsDom3D=dom.les_sommets();
780
781 int nb_elem = aire.dimension(0);
782 assert (nb_elem == vecteur_deplacement.dimension(0));
783 assert (dim_esp == vecteur_deplacement.dimension(1));
784 IntTab indic_dead_cell(nb_elem);
785 indic_dead_cell = 0;
786
787 // calcul voisins de chaque element traverse
788 IntLists elem_voisins(nb_elem_tot);
789 compute_NeighNode_IBM_elem(aire, elem_voisins);
790
791 // update du champ barycentre
792 IntTrav toward_new_elem(nb_elem);
793
794 // stpe1 : prediction
795 DoubleTrav bary_zero(bary);
796 bary_zero = bary;
797 double norm_vd2;
798 for (int e=0; e<nb_elem; e++)
799 {
800 norm_vd2 = 0.;
801 for (int k=0; k<dim_esp; k++) norm_vd2 += vecteur_deplacement(e,k)*vecteur_deplacement(e,k);
802 if (aire(e)>0.)
803 {
804 for (int k=0; k<dim_esp; k++) bary(e,k) = bary_zero(e,k) + alpha * vecteur_deplacement(e,k) ;
805 if (elem_voisins[e].size() >= 2 && sqrt(norm_vd2) > 1.e-10)
806 {
807 for (int voi=0; voi<elem_voisins[e].size(); voi++)
808 {
809 for (int k=0; k<dim_esp; k++) bary(e,k) += alpha * raid * bary_zero((elem_voisins[e])[voi],k);
810 }
811 for (int k=0; k<dim_esp; k++) bary(e,k) /= (1 + alpha * raid * elem_voisins[e].size());
812 }
813 toward_new_elem(e) = dom.chercher_elements(bary(e,0),bary(e,1),bary(e,2));
814 if (aire(toward_new_elem(e)) <= 0. ) indic_dead_cell(toward_new_elem(e)) = 1;
815 }
816 else //pour eviter que null soit considere comme element numero o
817 {
818 toward_new_elem(e) =-2; // rien a deplacer
819 }
820 }
821 indicateur_dead_cell_ = indic_dead_cell;
822
823 // stpe2 : deplacement des champs vers des elements nouveaux
824 DoubleTrav new_aire(aire);
825 DoubleTrav new_bary(bary);
826 DoubleTrav new_rotation(rotation);
827 IntTrav contrib(nb_elem);
828
829 for (int e=0; e<nb_elem; e++)
830 {
831 if (toward_new_elem(e) == -1 ) //element non trouve
832 {
833 Cerr<<"Source_PDF_base::update_elem_IBM: element displacement is not valid."<<finl;
834 exit();
835 }
836 else if (toward_new_elem(e) == -2 ) // element non coupe par gamma
837 {
838 }
839 else //deplacement des donnees (barycentres et matrices rotation)
840 {
841 for (int k=0; k<dim_esp; k++) new_bary(toward_new_elem(e),k) += bary(e,k);
842 for (int k=0; k<rotation.dimension(1); k++) new_rotation(toward_new_elem(e),k) += rotation(e,k);
843 new_aire(toward_new_elem(e)) += aire(e);
844 contrib(toward_new_elem(e)) += 1;
845 }
846 }
847
848 // Moyenne arithmetique pour barycentres et matrices rotation; moyenne arithmetique ou definition geometrique pour aire
849
850 int aire_geometriq_ok = 1;
851
852 for (int e=0; e<nb_elem; e++)
853 {
854 if(contrib(e)>0)
855 {
856 for (int k=0; k<dim_esp; k++) new_bary(e,k) /= contrib(e);
857 for (int k=0; k<rotation.dimension(1); k++) new_rotation(e,k) /= contrib(e);
858
859 if (aire_geometriq_ok)
860 new_aire(e) = aire_geometrique_IBM(new_rotation, e);
861 else new_aire(e) /= contrib(e);
862
863 }
864 }
865
866 // Maj champs
867 for (int e=0; e<nb_elem; e++)
868 {
869 aire(e) = new_aire(e);
870 for (int k=0; k<dim_esp; k++) bary(e,k) = new_bary(e,k);
871 for (int k=0; k<rotation.dimension(1); k++) rotation(e,k) = new_rotation(e,k);
872 }
873
874 // Verification de la conservation de la topologie
875 // Traitement des elements elem ayant 0 ou 1 voisin
876 // les voisins de l'antecedent de elem doivent etre voisins de elem
877
878 // calcul voisins de chaque nouveau element traverse
879 IntLists elem_voisins_new(nb_elem_tot);
880 compute_NeighNode_IBM_elem(aire, elem_voisins_new);
881
882 // recherche des elements deplaces ayant moins de 2 voisins
883 for (int e=0; e<nb_elem_tot; e++)
884 {
885 if ( elem_voisins_new[e].size() < 2)
886 {
887 IntList antecedents;
888 antecedents.vide();
889 // list des elements (antecedents) s'etant deplace vers e
890 for (int e_old=0; e_old<nb_elem_tot; e_old++)
891 if (toward_new_elem(e_old) == e) antecedents.add_if_not(e_old);
892// if (antecedents.size() != 0) Cerr<<"element "<<e<<" => "<<finl;
893 IntList to_link;
894 to_link.vide();
895 // boucle sur les antecedents de e
896 for (int ant=0; ant<antecedents.size(); ant++)
897 {
898 // Cerr<<" voisins de antecedent = "<<antecedents[ant] <<" ";
899 // boucle sur les anciens voisins de chaque antecedent de e
900 int nb_vois_ant = elem_voisins[antecedents[ant]].size();
901 for (int vois_ant=0; vois_ant<nb_vois_ant; vois_ant++)
902 {
903 int old_vois = (elem_voisins[antecedents[ant]])[vois_ant];
904 // l'ancien voisin est il toujours voisin de e ?
905 int i_present = 0;
906 for (int vois_e=0; vois_e<elem_voisins_new[e].size(); vois_e++)
907 if ( (elem_voisins_new[e])[vois_e] == toward_new_elem(old_vois) ) i_present = 1;
908 if ( (!i_present) && (toward_new_elem(old_vois) != e) ) to_link.add_if_not(toward_new_elem(old_vois));
909 // Cerr<<old_vois<<" ";
910 }
911 // Cerr<<finl;
912
913 // if (to_link.size() != 0) Cerr<<"to_link ";
914 DoubleTrav Xtest(dim_esp);
915 for (int n=0; n <to_link.size(); n++)
916 {
917 // Cerr<<to_link[n]<<" ";
918 // Xdeb (bary(e,0),bary(e,1),bary(e,2));
919 // Xfin (bary(to_link[n],0),bary(to_link[n],1),bary(to_link[n],2));
920 int decoup = 5;
921 for (int nb_step=0; nb_step<(decoup-1); nb_step++)
922 {
923 for (int k=0; k<dim_esp; k++) Xtest(k) = bary(e,k) + (bary(to_link[n], k) - bary(e,k))/decoup*(nb_step+1);
924 int elem_Xtest = dom.chercher_elements(Xtest(0),Xtest(1),Xtest(2));
925 if (elem_Xtest != -1)
926 {
927 if (aire(elem_Xtest) <= 0.)
928 {
929 for (int k=0; k<dim_esp; k++) bary(elem_Xtest,k) = Xtest(k);
930 for (int k=0; k<rotation.dimension(1); k++) rotation(elem_Xtest,k) = (rotation(e,k) + rotation(to_link[n],k)) / 2.;
931 aire(elem_Xtest) = aire_geometrique_IBM(rotation, elem_Xtest);
932 }
933 }
934 }
935 }
936 // Cerr<<finl;
937 }
938 }
939
940 }
941
942 // finalisation
945 rotation.echange_espace_virtuel();
946
947
948 if (prepro_lu_)
949 {
950 set_fields_to_prepro(prepro_lu_);
951 prepro_lu_->compute_solid_fluid(1);
952 if(getInterpolationBool() == true)
953 {
954 Interpolation_IBM_base& my_interp = ref_cast_non_const(Interpolation_IBM_base, getInterpolationLu());
955 my_interp.set_fields_from_prepro_to_interp(prepro_lu_);
956 }
957 }
959}
960
962{
963 if (!prepro_lu_) return;
964 Cerr<<"(IBM) source PDF base: Prepro IBM verification if any ...."<<finl;
965
966 const DoubleTab& aireArray = prepro_lu_->champ_aire_->valeurs();
967 const DoubleTab& baryArray = prepro_lu_->champ_bary_->valeurs();
968 const DoubleTab& normalArray = prepro_lu_->champ_normal_->valeurs();
969 const DoubleTab& rotationArray = prepro_lu_->champ_rotation_->valeurs();
970 const DoubleTab& isNodeDirichletArray = prepro_lu_->isNodeDirichlet_->valeurs();
971 const DoubleTab& solideArray = prepro_lu_->solid_points_->valeurs();
972 const DoubleTab& fluidArray = prepro_lu_->fluid_points_->valeurs();
973
974 const DoubleTab& solid_elemsArray = prepro_lu_->solid_elems_->valeurs();
975 const DoubleTab& fluid_elemsArray = prepro_lu_->fluid_elems_->valeurs();
976 const DoubleTab& corresp_elemsArray = prepro_lu_->corresp_elems_->valeurs();
977
978 int dim_esp = Objet_U::dimension;
979
980 ///////////////////////////////// Champs de base /////////////////////////////////
981 // Aire
982 if (champ_aire_lu_)
983 {
984 const DoubleTab& aireArray_src_pdf = champ_aire_lu_->valeurs();
985 assert(aireArray_src_pdf.dimension(0)==aireArray.dimension(0));
986 Cerr<<"Prepro_IBM::verify_results_prepro: relative L2-norm and abs max-norm errors for aire :"<<finl;
987 comp_diff_L2_max(aireArray.dimension(0), aireArray.dimension(1), aireArray_src_pdf, aireArray);
988 }
989
990 // Barycentre
991 if (champ_barycentre_lu_)
992 {
993 const DoubleTab& baryArray_src_pdf = champ_barycentre_lu_->valeurs();
994 assert(baryArray_src_pdf.dimension(0)==baryArray.dimension(0));
995 assert(baryArray_src_pdf.dimension(1)==dim_esp);
996 Cerr<<"Prepro_IBM::verify_results_prepro: relative L2-norm and abs max-norm errors for barycenter :"<<finl;
997 comp_diff_L2_max(baryArray.dimension(0), dim_esp, baryArray_src_pdf, baryArray);
998 }
999
1000 // Normale
1001 if (champ_rotation_lu_)
1002 {
1003 const DoubleTab& rotArray_src_pdf = champ_rotation_lu_->valeurs();
1004 assert(rotArray_src_pdf.dimension(1)==dim_esp*dim_esp);
1005 assert(rotArray_src_pdf.dimension(0)==normalArray.dimension(0));
1006 assert(normalArray.dimension(1)==dim_esp);
1007 Cerr<<"Prepro_IBM::verify_results_prepro: relative L2-norm and abs max-norm errors for normal :"<<finl;
1008 for (int k = 0; k < dim_esp; k++)
1009 {
1010 double err_L2_norm =0.;
1011 double err_max_norm = 0.;
1012 double L2_norm = 0.;
1013 for (int elem = 0; elem <normalArray.dimension(0); elem++)
1014 if (aireArray(elem) > 0.)
1015 {
1016 double diff_norm = abs(normalArray(elem,k) - rotArray_src_pdf(elem,3*k+(dim_esp-1)));
1017 err_L2_norm += diff_norm * diff_norm ;
1018 L2_norm += rotArray_src_pdf(elem,3*k+(dim_esp-1)) * rotArray_src_pdf(elem,3*k+(dim_esp-1)) ;
1019 if (diff_norm > err_max_norm) err_max_norm = diff_norm;
1020 }
1021 if (L2_norm > 1.0e-12) err_L2_norm = sqrt(err_L2_norm / L2_norm);
1022
1023 Cerr<<" composant # "<<k<<" => "<<err_L2_norm<<" "<<err_max_norm;
1024 }
1025 Cerr<<finl;
1026 }
1027
1028 // Rotation
1029 if (champ_rotation_lu_)
1030 {
1031 const DoubleTab& rotArray_src_pdf = champ_rotation_lu_->valeurs();
1032 assert(rotArray_src_pdf.dimension(1)==dim_esp*dim_esp);
1033 assert(rotArray_src_pdf.dimension(0)==rotationArray.dimension(0));
1034 assert(rotationArray.dimension(1)==dim_esp*dim_esp);
1035 Cerr<<"Prepro_IBM::verify_results_prepro: relative L2-norm and abs max-norm errors for rotation :"<<finl;
1036 comp_diff_L2_max(rotationArray.dimension(0), dim_esp*dim_esp, rotArray_src_pdf, rotationArray);
1037 }
1038
1039 ///////////////////////////////// Interpolation /////////////////////////////////
1040
1042 {
1043 Cerr<<"Prepro_IBM::verify_results_prepro: Interpolation_IBM"<<finl;
1044
1045 // is_dirichlet
1046 if (interpolation_lue_->is_dirichlet_lu_)
1047 {
1048 const DoubleTab& isNodeDirichletArray_src_pdf = interpolation_lue_->is_dirichlet_lu_->valeurs();
1049 assert(isNodeDirichletArray_src_pdf.dimension(0)==isNodeDirichletArray.dimension(0));
1050 assert(isNodeDirichletArray_src_pdf.dimension(1)==isNodeDirichletArray.dimension(1));
1051 Cerr<<"Prepro_IBM::verify_results_prepro: relative L2-norm and abs max-norm errors for isNodeDirichlet :"<<finl;
1052 comp_diff_L2_max(isNodeDirichletArray.dimension(0), isNodeDirichletArray.dimension(1), isNodeDirichletArray_src_pdf, isNodeDirichletArray);
1053 }
1054
1055 // Projection solide
1056 if (interpolation_lue_->solid_points_lu_)
1057 {
1058 const DoubleTab& solideArray_src_pdf = interpolation_lue_->solid_points_lu_->valeurs();
1059 assert(solideArray_src_pdf.dimension(0)==solideArray.dimension(0));
1060 assert(solideArray_src_pdf.dimension(1)==dim_esp);
1061 Cerr<<"Prepro_IBM::verify_results_prepro: relative L2-norm and abs max-norm errors for solid projection :"<<finl;
1062 comp_diff_L2_max(solideArray.dimension(0), dim_esp, solideArray_src_pdf, solideArray);
1063 }
1064
1065 // correspondance elems
1066 if (interpolation_lue_->corresp_elems_lu_)
1067 {
1068 const DoubleTab& corresp_elems_src_pdf = interpolation_lue_->corresp_elems_lu_->valeurs();
1069 assert(corresp_elems_src_pdf.dimension(1)==1);
1070 assert(corresp_elems_src_pdf.dimension(0)==corresp_elemsArray.dimension(0));
1071 assert(corresp_elemsArray.dimension(1)==1);
1072 Cerr<<"Prepro_IBM::verify_results_prepro: relative L2-norm and abs max-norm errors for correspondance elems :"<<finl;
1073 comp_diff_L2_max(corresp_elemsArray.dimension(0), 1, corresp_elems_src_pdf, corresp_elemsArray);
1074 }
1075
1076 Cerr<<"interpolation_lue_->que_suis_je() = "<<interpolation_lue_->que_suis_je()<<finl;
1077 // Interpolation_IBM_mean_gradient
1078 if (interpolation_lue_->que_suis_je() == "Interpolation_IBM_gradient_moyen")
1079 {
1080 Cerr<<"Prepro_IBM::verify_results_prepro: >> mean_gradient"<<finl;
1081 Interpolation_IBM_mean_gradient& interp = ref_cast(Interpolation_IBM_mean_gradient,interpolation_lue_.valeur());
1082
1083 // Element projection solide
1084 if (interp.solid_elems_lu_)
1085 {
1086 const DoubleTab& solid_elemsArray_src_pdf = interp.solid_elems_lu_->valeurs();
1087 assert(solid_elemsArray_src_pdf.dimension(0)==solid_elemsArray.dimension(0));
1088 assert(solid_elemsArray_src_pdf.dimension(1)==solid_elemsArray.dimension(1));
1089 Cerr<<"Prepro_IBM::verify_results_prepro: relative L2-norm and abs max-norm errors for solid projection element :"<<finl;
1090 comp_diff_L2_max(solid_elemsArray.dimension(0), solid_elemsArray.dimension(1), solid_elemsArray_src_pdf, solid_elemsArray);
1091 }
1092 }
1093
1094 // Interpolation_IBM_elem_fluid
1095 if (interpolation_lue_->que_suis_je() == "Interpolation_IBM_element_fluide")
1096 {
1097 Cerr<<"Prepro_IBM::verify_results_prepro: >> elem_fluide"<<finl;
1098 Interpolation_IBM_elem_fluid& interp = ref_cast(Interpolation_IBM_elem_fluid,interpolation_lue_.valeur());
1099
1100 // Projection fluide
1101 if (interp.fluid_points_lu_)
1102 {
1103 const DoubleTab& fluidArray_src_pdf = interp.fluid_points_lu_->valeurs();
1104 assert(fluidArray_src_pdf.dimension(0)==fluidArray.dimension(0));
1105 assert(fluidArray_src_pdf.dimension(1)==dim_esp);
1106 Cerr<<"Prepro_IBM::verify_results_prepro: relative L2-norm and abs max-norm errors for fluid projection :"<<finl;
1107 comp_diff_L2_max(fluidArray.dimension(0), dim_esp, fluidArray_src_pdf, fluidArray);
1108 }
1109
1110 // Element projection fluide
1111 if (interp.fluid_elems_lu_)
1112 {
1113 const DoubleTab& fluid_elemsArray_src_pdf = interp.fluid_elems_lu_->valeurs();
1114 assert(fluid_elemsArray_src_pdf.dimension(0)==fluid_elemsArray.dimension(0));
1115 assert(fluid_elemsArray_src_pdf.dimension(1)==fluid_elemsArray.dimension(1));
1116 Cerr<<"Prepro_IBM::verify_results_prepro: relative L2-norm and abs max-norm errors for fluid projection element :"<<finl;
1117 comp_diff_L2_max(fluid_elemsArray.dimension(0), fluid_elemsArray.dimension(1), fluid_elemsArray_src_pdf, fluid_elemsArray);
1118 }
1119 }
1120
1121 }
1122}
1123
1124void Source_PDF_base::filtre_CLD(DoubleTab& filtre) const
1125{
1126 Cerr << "Source_PDF_base: Not implemented for current discretisation. Aborting..." << finl;
1127 abort();
1128}
1129
1130void Source_PDF_base::rotate_imposed_velocity(DoubleTab& vitesse_imposee)
1131{
1132 const Domaine_dis_base& Domaine_dis = equation().probleme().domaine_dis();
1133 int nb_elem_tot=Domaine_dis.domaine().nb_elem_tot();
1134 DoubleTab& rotation = champ_rotation_->valeurs();
1135
1136 // VDF/VEF by default
1137 const Domaine_VF& the_dom = ref_cast(Domaine_VF,Domaine_dis);
1138 const IntTab& elems = (equation().discretisation().is_ef() ? Domaine_dis.domaine().les_elems() : the_dom.elem_faces());
1139 int nb_som_tot = the_dom.nb_faces_tot();
1140 int nb_dof_elem = Domaine_dis.domaine().nb_faces_elem();
1141 if (equation().discretisation().is_ef())
1142 {
1143 nb_dof_elem = Domaine_dis.domaine().nb_som_elem();
1144 nb_som_tot= Domaine_dis.domaine().nb_som_tot();
1145 }
1146 else if (!(equation().discretisation().is_vdf()) && !(equation().discretisation().is_vef()))
1147 {
1148 Cerr<<"Source_PDF_base::rotate_imposed_velocit: discretisation is not EF, VEF, VDF : "<<equation().discretisation()<<finl;
1149 }
1150
1151 // COPIES
1152 DoubleTab vitesse = vitesse_imposee;
1153 assert(Objet_U::dimension==3);
1154 int dim_var=vitesse_imposee.dimension(1);
1155 assert(Objet_U::dimension==dim_var);
1156
1157 //vitesse_imposee.echange_espace_virtuel();
1158 DoubleTrav marqueur=equation().probleme().get_champ("vitesse").valeurs();
1159 vitesse_imposee = 0.;
1160 marqueur = 0.;
1161
1162 for (int num_elem=0; num_elem<nb_elem_tot; num_elem++)
1163 {
1164 double norm = sqrt(rotation(num_elem,0)*rotation(num_elem,0)
1165 +rotation(num_elem,1)*rotation(num_elem,1)
1166 +rotation(num_elem,2)*rotation(num_elem,2)
1167 +rotation(num_elem,3)*rotation(num_elem,3)
1168 +rotation(num_elem,4)*rotation(num_elem,4)
1169 +rotation(num_elem,5)*rotation(num_elem,5)
1170 +rotation(num_elem,6)*rotation(num_elem,6)
1171 +rotation(num_elem,7)*rotation(num_elem,7)
1172 +rotation(num_elem,8)*rotation(num_elem,8));
1173 if (norm > 1e-6)
1174 {
1175 for (int i=0; i<nb_dof_elem; i++)
1176 {
1177 int s = elems(num_elem,i);
1178 for (int c=0; c<dim_var; c++)
1179 {
1180 for (int k=0; k<dim_var; k++)
1181 {
1182 vitesse_imposee(s,c) += rotation(num_elem,3*c+k)*vitesse(s,k);
1183 //Cerr << "k = " << k << ", c = " << c << ", 3*c+k = " << 3*c+k << ", rotation = " << rotation(num_elem,3*c+k) << finl;
1184 }
1185 }
1186 marqueur(s,0) += 1.0;
1187 }
1188 }
1189 }
1190 for (int i=0; i<nb_som_tot; i++)
1191 {
1192 if(marqueur(i,0) > 0.)
1193 {
1194 for (int c=0; c<dim_var; c++)
1195 {
1196 vitesse_imposee(i,c) /= marqueur(i,0);
1197 }
1198 }
1199 }
1200}
1201
1202void Source_PDF_base::compute_variable_imposee_projete(const DoubleTab& marqueur, const DoubleTab& points, double val, double eps)
1203{
1204 const Domaine_dis_base& le_dom_dis = equation().probleme().domaine_dis();
1205
1206 int nb_som=le_dom_dis.domaine().nb_som();
1207 int dim = Objet_U::dimension;
1208 const DoubleTab& coords = le_dom_dis.domaine().coord_sommets();
1209 ArrOfDouble x(dim);
1210 int dim_var = equation().inconnue().valeurs().dimension(1);
1211 for (int i = 0; i < nb_som; i++)
1212 {
1213 if ((marqueur(i) >= val + eps) || (marqueur(i) <= val - eps))
1214 {
1215 for (int j = 0; j < dim; j++)
1216 {
1217 x[j] = points(i,j);
1218 }
1219 for (int j = 0; j < dim_var; j++)
1220 {
1221 modele_lu_.variable_imposee_->valeurs()(i,j) = modele_lu_.get_variable_imposee(x,j);
1222 }
1223 }
1224 else
1225 {
1226 for (int j = 0; j < dim; j++)
1227 {
1228 x[j] = coords(i,j);
1229 }
1230 for (int j = 0; j < dim_var; j++)
1231 {
1232 modele_lu_.variable_imposee_->valeurs()(i,j) = modele_lu_.get_variable_imposee(x,j);
1233 }
1234 }
1235 }
1236}
1237
1239 const Domaine_Cl_dis_base& domaine_Cl_dis)
1240{
1241 Cerr << "Source_PDF_base: Not implemented for current discretisation. Aborting..." << finl;
1242 abort();
1243}
1244
1246{
1247 // indicateur_nodal_champ_aire_ = 1 si sommet appartient a un element dont l'aire <> 0
1248 // 0 sinon
1249 const DoubleTab& aire=champ_aire_->valeurs();
1250 const Domaine_dis_base& Domaine_dis = equation().probleme().domaine_dis();
1251 int nb_elems=Domaine_dis.domaine().nb_elem_tot();
1252 int nb_nodes=Domaine_dis.domaine().nb_som_tot();
1253 int nb_som_elem=Domaine_dis.domaine().nb_som_elem();
1254 const IntTab& elems= Domaine_dis.domaine().les_elems() ;
1255
1256 DoubleTab indic(nb_nodes);
1257 indic = 0.;
1258 for (int num_elem=0; num_elem<nb_elems; num_elem++)
1259 {
1260 if (aire(num_elem)>0.)
1261 {
1262 for (int i=0; i<nb_som_elem; i++)
1263 {
1264 int s1=elems(num_elem,i);
1265 indic(s1) = 1.;
1266 }
1267 }
1268 }
1270}
1271
1272double Source_PDF_base::fonct_regul_PDF(const int elem, const double dist)
1273{
1274 double coeff = 1.;
1275
1276 int size_dead_cell_tab = indicateur_dead_cell_.size();
1277 if (size_dead_cell_tab == 0) return coeff;
1278 if (elem >= size_dead_cell_tab)
1279 {
1280 Cerr<<"Source_PDF_base::fonct_regul_PDF: element = "<<elem<<" >= size of tab indicateur_dead_cell = "<<size_dead_cell_tab<<finl;
1281 exit();
1282 }
1283 if (indicateur_dead_cell_(elem) != 1) return coeff;
1284
1285 const Probleme_base& pb = equation().probleme();
1286 const Domaine_dis_base& le_dom_dis = pb.domaine_dis();
1287 const Domaine_VF& the_dom_VF = ref_cast(Domaine_VF,le_dom_dis);
1288 DoubleTab& rotation = ref_cast_non_const(DoubleTab, champ_rotation_->valeurs());
1289
1290 double h_max_elem = the_dom_VF.volumes(elem) / aire_geometrique_IBM(rotation, elem);
1291 double coeff_regul_PDF = modele_lu_.regul_coeff_PDF_;
1292 double h_ref = coeff_regul_PDF * h_max_elem;
1293 coeff = max((h_ref - dist)/h_ref , 0.);
1294
1295 return coeff;
1296}
1297
1298double Source_PDF_base::fonct_coeff(const double rho_m, const double aire, const double dt) const
1299{
1300 // return = 0 si aire dans element <= 0
1301 // return = rho/dt * coeff_relax sinon
1302 double val_coeff = 0.;
1303 if (aire<=0.)
1304 {
1305 return val_coeff;
1306 }
1307
1308 double inv_dt = 1./dt;
1309 // Cerr<<"dt pour Source_PDF_base::fonct_coeff : "<< dt <<finl;
1310 val_coeff = rho_m * inv_dt;
1311 const double tps_cour = equation().probleme().schema_temps().temps_courant();
1312 if (temps_relax_ != 1.0e+12)
1313 {
1314 // double bco = 100.*(1.-exp(-0.1/echelle_relax_)); // tps_cour_intersection = 0.1 * temps_relax_
1315 double deltrel = tps_cour - temps_relax_;
1316 double coeff_relax = (1.+tanh(deltrel/(echelle_relax_ * temps_relax_)))/2.;
1317 // double coeff_relax = min (1., std::max(1.-bco*deltrel*deltrel/temps_relax_/temps_relax_, exp(deltrel/(echelle_relax_ * temps_relax_))));
1318 // double coeff_relax = 1.0 - exp(-tps_cour / temps_relax_);
1319 // double coeff_relax = tanh(tps_cour / temps_relax_);
1320 val_coeff *= coeff_relax ;
1321 // Cerr<< "coeff. relax. pour PDF = "<<coeff_relax<<" val_coeff = "<<val_coeff <<finl;
1322 }
1323 return val_coeff;
1324}
1325
1326// TENSOR CALCULATION
1327// Pour pouvoir eventuellement traiter differements les directions d'espace
1329{
1330 assert(Objet_U::dimension==3);
1331 ArrOfDouble tuvw(dimension) ;
1332 tuvw[0] = 1.0 / modele_lu_.eta_;
1333 tuvw[1] = 1.0 / modele_lu_.eta_;
1334 tuvw[2] = 1.0 / modele_lu_.eta_;
1335 return tuvw ;
1336}
1337
1338DoubleVect Source_PDF_base::diag_coeff_elem(ArrOfDouble& variable_elem, const DoubleTab& rotation, int num_elem) const
1339{
1340 assert(Objet_U::dimension==3);
1341 ArrOfDouble tuvw(dimension);
1342
1343 tuvw = get_tuvw_local();
1344
1345 ArrOfDouble sum_dir_loc(dimension) ;
1346 for (int i=0; i<dimension; i++)
1347 {
1348 sum_dir_loc[i]=0.;
1349 for (int k=0; k<dimension; k++)
1350 sum_dir_loc[i]+=rotation(num_elem,3*i+k);
1351 }
1352
1353 DoubleVect diag_coef(dimension);
1354 for (int comp=0; comp<dimension; comp++)
1355 {
1356 diag_coef(comp) = 0. ;
1357 for (int k=0; k<dimension; k++)
1358 diag_coef(comp)+=tuvw[k]*sum_dir_loc[k]*rotation(num_elem,3*k+comp);
1359 }
1360
1361 return diag_coef ;
1362}
1363
1365{
1366 // coeff = 1 si aire dans element <= 0
1367 // coeff = 1 + (Ksi/eta) * coeff_relax sinon
1368 const Domaine_dis_base& domaine_dis = equation().probleme().domaine_dis();
1369 const IntTab& elems= domaine_dis.domaine().les_elems() ;
1370 int nb_som_elem=domaine_dis.domaine().nb_som_elem();
1371 int nb_elems=domaine_dis.domaine().nb_elem_tot();
1372 const DoubleTab& rotation=champ_rotation_->valeurs();
1373 const DoubleTab& aire = champ_aire_->valeurs();
1374
1375 int dim_var = equation().inconnue().valeurs().dimension(1);
1376 ArrOfDouble variable_elem(dim_var);
1377 int dim_esp = Objet_U::dimension ;
1378 if (dim_var != 1 && dim_var != dim_esp)
1379 {
1380 Cerr<<"compute_coeff_elem: dimension variable differente 1 ou "<<dim_esp<<"! "<<finl;
1381 exit();
1382 }
1383 DoubleTab coeff(nb_elems, dim_var);
1384
1385 double dt = (ref_cast_non_const(Source_PDF_base, *this)).calcul_dt_pdf();
1386 const DoubleTab& rho_m=champ_rho_->valeurs();
1387 if (equation().probleme().schema_temps().temps_courant()==0)
1388 {
1389 dt = 1.0;
1390 }
1391 // Cerr<<"dt pour compute_coeff_elem : "<< dt <<finl;
1392
1393 double val_coeff ;
1394 DoubleVect val_diag_coef(dim_var);
1395 for (int num_elem=0; num_elem<nb_elems; num_elem++)
1396 {
1397 if (aire(num_elem)<=0.)
1398 {
1399 for (int comp=0; comp<dim_var; comp++) coeff(num_elem, comp) = 1. ;
1400 }
1401 else
1402 {
1403 const DoubleTab& variable=equation().inconnue().valeurs();
1404 variable_elem=0;
1405 for (int s=0; s<nb_som_elem; s++)
1406 {
1407 int som_glob=elems(num_elem,s);
1408 for (int comp=0; comp<dim_var; comp++)
1409 variable_elem[comp]+=variable(som_glob,comp);
1410 }
1411 // rho/dt * coeff_relax
1412 val_coeff = fonct_coeff(rho_m(num_elem), aire(num_elem), dt) ;
1413 // 1/eta
1414 if (dim_var == dim_esp)
1415 {
1416 val_diag_coef = diag_coeff_elem(variable_elem, rotation, num_elem) ;
1417 }
1418 else
1419 {
1420 val_diag_coef(0) = 1.0 / modele_lu_.eta_ ;
1421 }
1422 // coeff = 1 + (Ksi/eta) * coeff_relax
1423 for (int comp=0; comp<dim_esp; comp++)
1424 coeff(num_elem, comp) = 1.+ val_coeff * val_diag_coef(comp) * dt / rho_m(num_elem) ;
1425 }
1426 }
1427
1428 return coeff;
1429}
1430
1432{
1433 // coeff sommet = Sigma_elem coeff_elem / Nb contributions; avec :
1434 // coeff_elem = Ksi/eta * coeff_relax si element dont l'aire <>= 0
1435 // coeff_elem = 0 sinon
1436 const Domaine_dis_base& Domaine_dis = equation().probleme().domaine_dis();
1437 int nb_elems=Domaine_dis.domaine().nb_elem_tot();
1438
1439 // VDF/VEF by default
1440 const Domaine_VF& the_dom = ref_cast(Domaine_VF,Domaine_dis);
1441 const IntTab& elems = (equation().discretisation().is_ef() ? Domaine_dis.domaine().les_elems() : the_dom.elem_faces());
1442 int nb_dof_tot = the_dom.nb_faces_tot();
1443 int nb_dof_elem = Domaine_dis.domaine().nb_faces_elem();
1444 if (equation().discretisation().is_ef())
1445 {
1446 nb_dof_tot= Domaine_dis.domaine().nb_som_tot();
1447 nb_dof_elem = Domaine_dis.domaine().nb_som_elem();
1448 }
1449 else if (!(equation().discretisation().is_vdf()) && !(equation().discretisation().is_vef()))
1450 {
1451 Cerr<<"Source_PDF_base::compute_coeff_matrice: discretisation is not EF, VEF, VDF : "<<equation().discretisation()<<finl;
1452 }
1453
1454 const DoubleTab& rotation=champ_rotation_->valeurs();
1455 const DoubleTab& aire = champ_aire_->valeurs();
1456
1457 int dim_esp = Objet_U::dimension ;
1458 const DoubleTab& variable=equation().inconnue().valeurs();
1459 int dim_var = variable.dimension(1);
1460 if (dim_var != 1 && dim_var != dim_esp)
1461 {
1462 Cerr<<"compute_coeff_matrice: dimension variable differente 1 ou "<<dim_esp<<"! "<<finl;
1463 exit();
1464 }
1465 ArrOfDouble variable_elem(dim_var);
1466 DoubleTab coeff(variable);
1467 IntTab contrib(nb_dof_tot, dim_var);
1468 contrib = 0;
1469 coeff = 0.;
1470
1471 double dt = (ref_cast_non_const(Source_PDF_base, *this)).calcul_dt_pdf();
1472 const DoubleTab& rho_m=champ_rho_->valeurs();
1473 // Cerr<<"dt pour compute_coeff_matrice : "<< dt <<finl;
1474
1475 double val_coeff ;
1476 DoubleVect val_diag_coef(dim_var), coeff_el(dim_var) ;
1477 for (int num_elem=0; num_elem<nb_elems; num_elem++)
1478 {
1479 if (aire(num_elem)<=0.)
1480 {
1481 for (int comp=0; comp<dim_var; comp++) coeff_el(comp) = 0. ;
1482 }
1483 else
1484 {
1485 variable_elem=0.;
1486 for (int s=0; s<nb_dof_elem; s++)
1487 {
1488 int dof_glob=elems(num_elem,s);
1489 for (int comp=0; comp<dim_var; comp++)
1490 variable_elem[comp]+=variable(dof_glob,comp)/nb_dof_elem;
1491 }
1492 // rho/dt * coeff_relax
1493 val_coeff = fonct_coeff(rho_m(num_elem), aire(num_elem), dt) ;
1494 // 1/eta
1495 if (dim_var == dim_esp)
1496 {
1497 val_diag_coef = diag_coeff_elem(variable_elem, rotation, num_elem) ;
1498 }
1499 else
1500 {
1501 val_diag_coef(0) = 1.0 / modele_lu_.eta_ ;
1502 }
1503 // coeff = Ksi/eta * coeff_relax
1504 for (int comp=0; comp<dim_var; comp++)
1505 coeff_el(comp) = val_coeff * val_diag_coef(comp) * dt / rho_m(num_elem) ;
1506 }
1507 for (int i = 0; i<nb_dof_elem; i++)
1508 {
1509 int s = elems(num_elem,i);
1510 for (int comp=0; comp<dim_var; comp++)
1511 {
1512 if (coeff_el(comp) > 0.)
1513 {
1514 coeff(s,comp)+= coeff_el(comp);
1515 contrib(s, comp) += 1;
1516 }
1517 // Cerr<<"Source_PDF_EF: coeff_el ("<<comp<<"): "<<" "<<coeff_el(comp)<<finl;
1518 }
1519 }
1520 }
1521
1522 double val = 0.;
1523 for (int s = 0; s<nb_dof_tot; s++)
1524 {
1525 for (int comp=0; comp<dim_var; comp++)
1526 {
1527 val = 1.;
1528 if (contrib(s,comp) != 0)
1529 {
1530 val += coeff(s,comp)/contrib(s,comp);
1531 }
1532 coeff(s,comp) = val;
1533 // Cerr<<"Source_PDF_EF: contrib coeff ("<<s<<","<<comp<<"): "<<contrib(s,comp)<<" "<<coeff(s,comp)<<finl;
1534 }
1535 }
1536 // Cerr << "Coeff matrice" << coeff << finl;
1537 return coeff;
1538}
1539
1540void Source_PDF_base::multiply_coeff_volume(DoubleTab& coeff) const
1541{
1542 Cerr << "Source_PDF_base: Not implemented for current discretisation. Aborting..." << finl;
1543 abort();
1544}
1545
1546DoubleTab Source_PDF_base::compute_pond(const DoubleTab& rho_m, const DoubleTab& aire, const DoubleVect& volume, int& coef1, int& nb_elems) const
1547{
1548// return = 0 si aire dans element <= 0
1549// return = rho/dt * coeff_relax * volume / (coef1*coef1) sinon
1550 DoubleTab pond = rho_m;
1551 double inv_coef1 = 1. / coef1;
1552
1553 double dt = (ref_cast_non_const(Source_PDF_base, *this)).calcul_dt_pdf();
1554
1555 for (int num_elem=0; num_elem<nb_elems; num_elem++)
1556 {
1557 pond(num_elem) = fonct_coeff(rho_m(num_elem), aire(num_elem), dt) ;
1558 pond(num_elem) *= volume(num_elem)*inv_coef1*inv_coef1;
1559 }
1560
1561 return pond;
1562}
1563
1564DoubleTab& Source_PDF_base::ajouter(DoubleTab& secmem) const
1565{
1567 {
1568 ajouter_blocs({}, secmem);
1569 return secmem;
1570 }
1571 return ajouter_(variable_imposee_,secmem);
1572}
1573
1574DoubleTab& Source_PDF_base::ajouter_(const DoubleTab& variable, DoubleTab& resu) const
1575{
1576 const int i_traitement_special = 0 ;
1577 ajouter_(variable, resu, i_traitement_special) ;
1578 return resu;
1579}
1580
1581DoubleTab& Source_PDF_base::ajouter_(const DoubleTab& variable, DoubleTab& resu, const int i_traitement_special) const
1582{
1583 Cerr << "Source_PDF_base: Not implemented for current discretisation. Aborting..." << finl;
1584 abort();
1585 return resu;
1586}
1587
1588void Source_PDF_base::contribuer_a_avec(const DoubleTab& inco, Matrice_Morse& matrice) const
1589{
1590 Cerr << "Source_PDF_base: Not implemented for current discretisation. Aborting..." << finl;
1591 abort();
1592}
1593
1594DoubleTab& Source_PDF_base::calculer(DoubleTab& resu) const
1595{
1596 resu = 0;
1597 const DoubleTab& variable=equation().inconnue().valeurs();
1598 return ajouter_(variable,resu);
1599}
1600
1602{
1603 int i_traitement_special = 0;
1604 const DoubleTab& variable=equation().inconnue().valeurs();
1605 DoubleTrav add_zero_term(variable);
1606 add_zero_term = 0.;
1607 return compute_source_term_PDF(i_traitement_special, add_zero_term, bilan);
1608}
1609
1610DoubleVect& Source_PDF_base::compute_source_term_PDF(int i_traitement_special, DoubleTab& add_term, DoubleVect& bilan)
1611{
1612 assert(Objet_U::dimension <= 3);
1613 // double temps_corrige = temps_computation_pdf_ + dt_computation_pdf_;
1614 // Cerr<<"compute_source_term_PDF:: temps courant, temps computation_pdf et temps corrige = "<<equation().probleme().schema_temps().temps_courant() <<" "<<temps_computation_pdf_<<" "<<temps_corrige<<finl;
1615 DoubleTab& variable=equation().inconnue().valeurs();
1616 // Si temps courant n'a pas ete mis a jour, on prend temps futur pour inconnue
1617 if (equation().probleme().schema_temps().temps_courant() == temps_computation_pdf_) variable=equation().inconnue().futur();
1618 int nb_som= variable.dimension(0);
1619 int nb_comp = variable.dimension(1);
1620 assert(nb_comp == modele_lu_.dim_variable_);
1621
1622 DoubleTrav resu(variable);
1623 calculer(resu, i_traitement_special);
1624 // On s'assure d'avoir le meme dt que pour sec_mem_pdf (calculer_pdf)
1625 double dt_courant = calcul_dt_pdf();
1626 resu *= dt_courant/dt_computation_pdf_;
1627 DoubleTrav flag_cl(resu);
1628 filtre_CLD(flag_cl);
1629
1630 source_term_PDF.resize(sec_mem_pdf.dimension(0), sec_mem_pdf.dimension(1));
1631 source_term_PDF = 0.;
1632
1633 DoubleVect source_term[3];
1634 bilan.resize(equation().inconnue().nb_comp());
1635 bilan = 0.0;
1636 Cerr<<"(IBM) Source_PDF_base: Bilan terme PDF = ";
1637 for (int i=0; i<nb_comp; i++)
1638 {
1639 source_term[i] = champ_nodal_->valeurs();
1640 source_term[i] = 0.;
1641 for (int j=0; j<nb_som; j++)
1642 {
1643 double filter = (std::fabs(resu(j,i)) > 0?1.:0.);
1644 filter *= flag_cl(j,i);
1645 source_term[i](j) = (resu(j,i) - sec_mem_pdf(j,i) + add_term(j,i) )*filter;
1646 source_term_PDF(j,i) = source_term[i](j);
1647 // if( (abs(resu(j,i)) > 1.0) )
1648 // {
1649 // Cerr<<"i,j = "<<i<<" "<<j<<" ; resu = "<<resu(j,i)<<" ; sec_mem_pdf = "<<sec_mem_pdf(j,i)<<" ; bilan = "<<source_term[i](j)<<finl;
1650 // Cerr<<"added term (secmem_conv) = "<<add_term(j,i)<<finl;
1651 // }
1652 }
1653 bilan(i) = mp_somme_vect(source_term[i]);
1654 Cerr<< bilan(i)<<" ";
1655 }
1656 source_term_PDF.echange_espace_virtuel();
1657 Cerr<<finl;
1658 return bilan;
1659}
1660
1661void Source_PDF_base::volume_source_term_PDF(DoubleTab& volume_term_PDF)
1662{
1663}
1664
1665DoubleTab& Source_PDF_base::calculer(DoubleTab& resu, const int i_traitement_special) const
1666{
1667 resu = 0;
1668 const DoubleTab& variable=equation().inconnue().valeurs();
1669 return ajouter_(variable,resu, i_traitement_special);
1670}
1671
1673{
1674 Cerr << "Source_PDF_base: Not implemented for current discretisation. Aborting..." << finl;
1675 abort();
1676}
1677
1679{
1680 Cerr << "Source_PDF_base: Not implemented for current discretisation. Aborting..." << finl;
1681 abort();
1682}
1683
1685{
1686 Cerr << "Source_PDF_base: Not implemented for current discretisation. Aborting..." << finl;
1687 abort();
1688}
1689
1691{
1692 Cerr << "Source_PDF_base: Not implemented for current discretisation. Aborting..." << finl;
1693 abort();
1694}
1695
1697{
1698 Cerr << "Source_PDF_base: Not implemented for current discretisation. Aborting..." << finl;
1699 abort();
1700}
1701
1703{
1704 Cerr << "Source_PDF_base: Not implemented for current discretisation. Aborting..." << finl;
1705 abort();
1706}
1707
1709{
1711 {
1712 if (interpolation_lue_->que_suis_je() == "Interpolation_IBM_element_fluide")
1714 else if (interpolation_lue_->que_suis_je() == "Interpolation_IBM_gradient_moyen")
1716 else if (interpolation_lue_->que_suis_je() == "Interpolation_IBM_hybride")
1718 else if (interpolation_lue_->que_suis_je() == "Interpolation_IBM_power_law_tbl")
1720 else if (interpolation_lue_->que_suis_je() == "Interpolation_IBM_power_law_tbl_u_star")
1722 else if (interpolation_lue_->que_suis_je() == "Interpolation_IBM_thermal_wall_law")
1724 }
1725}
1726
1727DoubleTab& Source_PDF_base::calculer_pdf(DoubleTab& resu) const
1728{
1729 resu = 0;
1731
1732 double my_dt = (ref_cast_non_const(Source_PDF_base, *this)).calcul_dt_pdf();
1733 (ref_cast_non_const(Source_PDF_base, *this)).set_dt_computation_pdf(my_dt);
1734 double my_temps = equation().probleme().schema_temps().temps_courant();
1735 (ref_cast_non_const(Source_PDF_base, *this)).set_temps_computation_pdf(my_temps);
1736
1737 return resu;
1738}
1739
1741{
1742 double dt_ref = equation().probleme().schema_temps().pas_de_temps();
1743 double dt_min = equation().probleme().schema_temps().pas_temps_min();
1744 double my_dt = std::max(dt_ref,dt_min);
1745 if (equation().probleme().schema_temps().temps_courant()==0) my_dt = 1.;
1746 return my_dt;
1747}
1748
1750{
1751 //la_source->mettre_a_jour(temps);
1752}
1753
1754void Source_PDF_base::correct_variable(const DoubleTab& coeff_node, DoubleTab& variable) const
1755{
1756 int nb_data_vit = variable.size();
1757 int nb_node_2 = coeff_node.dimension(0) ;
1758 int ncomp = coeff_node.dimension(1) ;
1759 if (nb_data_vit != nb_node_2 * ncomp)
1760 {
1761 Cerr<<"Source_PDF_base: numbers of nodes are different for variable and coeff_node."<<finl;
1762 abort();
1763 }
1764 const DoubleTab& vit_dir=variable_imposee_;
1765 for(int i=0; i<nb_node_2; i++)
1766 {
1767 for (int j=0; j<ncomp; j++)
1768 {
1769 if (coeff_node(i,j)!= 1.0)
1770 {
1771 variable(i,j)=vit_dir(i,j);
1772 }
1773 // Cerr<<"Source_PDF_base: coeff_node variable("<<i<<","<<j<<"): "<<coeff_node(i,j)<<" "<<variable(i,j)<<finl;
1774 }
1775 }
1776}
1777
1779{
1780 Cerr << "Source_PDF_base: Not implemented for current discretisation. Aborting..." << finl;
1781 abort();
1782 return 0;
1783}
1784
1785void Source_PDF_base::ouvrir_fichier(SFichier& os, const Nom& type, const int flag=1) const
1786{
1787 // flag nul on n'ouvre pas le fichier
1788 if (flag==0)
1789 return ;
1790
1791 const Probleme_base& pb=equation().probleme();
1792 const Schema_Temps_base& sch=pb.schema_temps();
1793 const int precision=sch.precision_impr();
1794 Nom nomfichier(out_);
1795 if (type!="") nomfichier+=(Nom)"_"+type;
1796 nomfichier+=".out";
1797
1798 // On cree le fichier a la premiere impression avec l'en tete
1799 if (sch.nb_impr()==1 && !pb.reprise_effectuee())
1800 {
1801 os.ouvrir(nomfichier);
1802 SFichier& fic=os;
1803 Nom espace="\t\t";
1804 fic << (Nom)"# Printing of the source term "+que_suis_je()+" of the equation "+equation().que_suis_je()+" of the problem "+equation().probleme().le_nom() << finl;
1805 fic << "# " << description() << finl;
1806 if(modele_lu_.dim_variable_ == Objet_U::dimension)
1807 {
1808 // vector
1809 assert(Objet_U::dimension==3);
1810 fic << "# Time" << espace << "Fx" << espace << "Fy" << espace << "Fz";
1811 }
1812 else if(modele_lu_.dim_variable_ == 1)
1813 {
1814 // scalar
1815 fic << "# Time" << espace << "Sum";
1816 }
1817 else
1818 {
1819 Cerr << "Source_PDF_base: for scalar or vector only; dim = " << modele_lu_.dim_variable_ << finl;
1820 Process::exit();
1821 }
1822 fic << finl;
1823 }
1824 // Sinon on l'ouvre
1825 else
1826 os.ouvrir(nomfichier,ios::app);
1827
1828 os.precision(precision);
1829 os.setf(ios::scientific);
1830}
1831
1833{
1834 if (equation().probleme().que_suis_je() == "Pb_Melange")
1835 champ_rho_->affecter(equation().probleme().get_champ("masse_volumique_melange"));
1836 else
1837 champ_rho_->affecter(equation().probleme().get_champ("masse_volumique"));
1838}
1839
1840void Source_PDF_base::correct_incr_pressure(const DoubleTab& coeff_node, DoubleTab& correction_en_pression) const
1841{
1842 Cerr << "Source_PDF_NS_base: Not implemented for current discretisation. Aborting..." << finl;
1843 abort();
1844}
1845
1846void Source_PDF_base::correct_pressure(const DoubleTab& coeff_node, DoubleTab& pression, const DoubleTab& correction_en_pression) const
1847{
1848 Cerr << "Source_PDF_NS_base: Not implemented for current discretisation. Aborting..." << finl;
1849 abort();
1850}
1851
1853{
1854 const Probleme_base& pb = equation().probleme();
1855 const DoubleTab& variable=equation().inconnue().valeurs();
1856 int nb_comp = variable.dimension(1);
1857 Motcle directive("temperature");
1858 if (equation().inconnue().is_vectorial()) directive="vitesse";
1859 const Domaine_dis_base& le_dom_dis = equation().domaine_dis();
1860
1861 double temps=0.;
1862 if (motlu=="source_term_pdf" && !champ_source_term_PDF_)
1863 {
1864 if (nb_comp == 1)
1865 {
1866 Noms noms(1);
1867 noms[0]="source_term_PDF";
1868 Noms unites(1);
1869 unites[0] = "-";
1870 pb.discretisation().discretiser_champ(directive,le_dom_dis,scalaire,noms,unites,nb_comp,temps,champ_source_term_PDF_);
1871 }
1872 else if (nb_comp == Objet_U::dimension)
1873 {
1874 Noms noms(nb_comp);
1875 noms[0]="source_term_PDF";
1876 Noms unites(nb_comp);
1877 unites[0] = "-";
1878 pb.discretisation().discretiser_champ(directive,le_dom_dis,vectoriel,noms,unites,nb_comp,temps,champ_source_term_PDF_);
1879 }
1880 champs_compris_.ajoute_champ(champ_source_term_PDF_);
1881 }
1882
1883 if (motlu=="barycentre_IBM" && !champ_barycentre_IBM_)
1884 {
1885 nb_comp = Objet_U::dimension;
1886 Noms nomsb(nb_comp);
1887 nomsb[0]="barycentre_IBM";
1888 Noms unitesb(nb_comp);
1889 unitesb[0] = "m";
1890 pb.discretisation().discretiser_champ("champ_elem",le_dom_dis,vectoriel,nomsb,unitesb,nb_comp,0., champ_barycentre_IBM_);
1891 champs_compris_.ajoute_champ(champ_barycentre_IBM_);
1892 }
1893
1894 if (motlu=="normal_IBM" && !champ_normal_IBM_)
1895 {
1896 nb_comp = Objet_U::dimension;
1897 Noms nomsn(nb_comp);
1898 nomsn[0]="normal_IBM";
1899 Noms unitesn(nb_comp);
1900 unitesn[0] = "m";
1901 pb.discretisation().discretiser_champ("champ_elem",le_dom_dis,vectoriel,nomsn,unitesn,nb_comp,0., champ_normal_IBM_);
1902 champs_compris_.ajoute_champ(champ_normal_IBM_);
1903 }
1904
1905 if (motlu=="aire_IBM" && !champ_aire_IBM_)
1906 {
1907 pb.discretisation().discretiser_champ("champ_elem",le_dom_dis,"aire_IBM","m^2",1,0., champ_aire_IBM_);
1908 champs_compris_.ajoute_champ(champ_aire_IBM_);
1909 }
1910
1911 if (motlu=="velocity_shape_IBM" && !champ_vitesse_shape_IBM_)
1912 {
1913 nb_comp = Objet_U::dimension;
1914 Noms nomsv(nb_comp);
1915 for (int i=0; i< nb_comp; i++) nomsv[i]="velocity_shape_IBM";
1916 Noms unitesv(nb_comp);
1917 for (int i=0; i< nb_comp; i++) unitesv[i] = "m/s";
1918 pb.discretisation().discretiser_champ("champ_elem",le_dom_dis,vectoriel,nomsv,unitesv,nb_comp,0., champ_vitesse_shape_IBM_);
1919 champs_compris_.ajoute_champ(champ_vitesse_shape_IBM_);
1920 }
1921
1922 if (motlu=="pseudo_level_set_IBM" && !champ_pseudo_level_set_IBM_)
1923 {
1924 nb_comp = 1;
1925 Noms nompl(nb_comp);
1926 for (int i=0; i< nb_comp; i++) nompl[i]="pseudo_level_set_IBM";
1927 Noms unitepl(nb_comp);
1928 for (int i=0; i< nb_comp; i++) unitepl[i] = "m";
1929 Motcle directiveps("temperature");
1930 pb.discretisation().discretiser_champ(directive,le_dom_dis,scalaire,nompl,unitepl,nb_comp,0., champ_pseudo_level_set_IBM_);
1931 champs_compris_.ajoute_champ(champ_pseudo_level_set_IBM_);
1932 }
1933}
1934
1936{
1937 Noms noms_compris = champs_compris_.liste_noms_compris();
1938 noms_compris.add("source_term_pdf");
1939 noms_compris.add("barycentre_IBM");
1940 noms_compris.add("normal_IBM");
1941 noms_compris.add("aire_IBM");
1942 noms_compris.add("velocity_shape_IBM");
1943 noms_compris.add("pseudo_level_set_IBM");
1944 if (opt==DESCRIPTION)
1945 Cerr<<" Source_PDF_base : "<< noms_compris <<finl;
1946 else
1947 nom.add(noms_compris);
1948}
1949
1950bool Source_PDF_base::has_champ(const Motcle& nom, OBS_PTR(Champ_base) &ref_champ) const
1951{
1952 if (nom == "source_term_pdf" && champ_source_term_PDF_)
1953 {
1954 ref_champ = get_champ(nom);
1955 return true;
1956 }
1957 else if (nom == "barycentre_IBM" && champ_barycentre_IBM_)
1958 {
1959 ref_champ = get_champ(nom);
1960 return true;
1961 }
1962 else if (nom == "normal_IBM" && champ_normal_IBM_)
1963 {
1964 ref_champ = get_champ(nom);
1965 return true;
1966 }
1967 else if (nom == "aire_IBM" && champ_aire_IBM_)
1968 {
1969 ref_champ = get_champ(nom);
1970 return true;
1971 }
1972 else if (nom == "velocity_shape_IBM" && champ_vitesse_shape_IBM_)
1973 {
1974 ref_champ = get_champ(nom);
1975 return true;
1976 }
1977 else if (nom == "pseudo_level_set_IBM" && champ_pseudo_level_set_IBM_)
1978 {
1979 ref_champ = get_champ(nom);
1980 return true;
1981 }
1982 else
1983 return false; /* rien trouve */
1984}
1985
1987{
1988 if (nom == "source_term_pdf" && champ_source_term_PDF_)
1989 return true;
1990 else if (nom == "barycentre_IBM" && champ_barycentre_IBM_)
1991 return true;
1992 else if (nom == "normal_IBM" && champ_normal_IBM_)
1993 return true;
1994 else if (nom == "aire_IBM" && champ_aire_IBM_)
1995 return true;
1996 else if (nom == "velocity_shape_IBM" && champ_vitesse_shape_IBM_)
1997 return true;
1998 else if (nom == "pseudo_level_set_IBM" && champ_pseudo_level_set_IBM_)
1999 return true;
2000 else
2001 return false; /* rien trouve */
2002}
2003
2005{
2006 int dim_esp = Objet_U::dimension;
2007
2008 if (nom=="source_term_pdf")
2009 {
2010 if (!champ_source_term_PDF_)
2011 throw std::runtime_error(std::string("Field ") + nom.getString() + std::string(" not found !"));
2012
2013 // Initialisation a 0 du champ_source_term_PDF_
2014 DoubleTab& valeurs = champ_source_term_PDF_->valeurs();
2015 valeurs=0.;
2016 if (source_term_PDF.size_array()>0)
2017 {
2018 int nb_d0 = source_term_PDF.dimension(0);
2019 int nb_d1 = source_term_PDF.dimension(1);
2020 for (int num0=0; num0<nb_d0; num0++)
2021 for (int num1=0; num1<nb_d1; num1++)
2022 valeurs(num0,num1)=source_term_PDF(num0,num1);
2023 }
2024 valeurs.echange_espace_virtuel();
2025 champ_source_term_PDF_ ->mettre_a_jour(equation().probleme().schema_temps().temps_courant());
2026 return champs_compris_.get_champ(nom);
2027 }
2028 else if (nom=="barycentre_IBM")
2029 {
2030 if (!champ_barycentre_IBM_)
2031 throw std::runtime_error(std::string("Field ") + nom.getString() + std::string(" not found !"));
2032
2033 // Initialisation a 0 du champ_barycentre_IBM_
2034 DoubleTab& valeurs = champ_barycentre_IBM_->valeurs();
2035 valeurs=0.;
2037 {
2038 const DoubleTab& barycentre = champ_barycentre_->valeurs();
2039 int nb_d0 = barycentre.dimension(0);
2040 int nb_d1 = barycentre.dimension(1);
2041 for (int num0=0; num0<nb_d0; num0++)
2042 for (int num1=0; num1<nb_d1; num1++)
2043 valeurs(num0,num1)=barycentre(num0,num1);
2044 }
2045 valeurs.echange_espace_virtuel();
2046 champ_barycentre_IBM_->mettre_a_jour(equation().probleme().schema_temps().temps_courant());
2047 return champs_compris_.get_champ(nom);
2048 }
2049 else if (nom=="normal_IBM")
2050 {
2051 if (!champ_normal_IBM_)
2052 throw std::runtime_error(std::string("Field ") + nom.getString() + std::string(" not found !"));
2053
2054 // Initialisation a 0 du champ_normal_IBM_
2055 DoubleTab& valeurs = champ_normal_IBM_->valeurs();
2056 valeurs=0.;
2057 if (champ_rotation_)
2058 {
2059 const DoubleTab& rotation = champ_rotation_->valeurs();
2060 int nb_d0 = rotation.dimension(0);
2061 for (int num0=0; num0<nb_d0; num0++)
2062 for (int num1=0; num1<dim_esp; num1++)
2063 valeurs(num0,num1)=rotation(num0,3*num1+(dim_esp-1));
2064 }
2065 valeurs.echange_espace_virtuel();
2066 champ_normal_IBM_->mettre_a_jour(equation().probleme().schema_temps().temps_courant());
2067 return champs_compris_.get_champ(nom);
2068 }
2069 else if (nom=="aire_IBM")
2070 {
2071 if (!champ_aire_IBM_)
2072 throw std::runtime_error(std::string("Field ") + nom.getString() + std::string(" not found !"));
2073
2074 // Initialisation a 0 du champ_aire_IBM_
2075 DoubleTab& valeurs = champ_aire_IBM_->valeurs();
2076 valeurs=0.;
2077 if (champ_aire_)
2078 {
2079 const DoubleTab& aire = champ_aire_->valeurs();
2080 int nb_d0 = aire.dimension(0);
2081 int nb_d1 = aire.dimension(1);
2082 for (int num0=0; num0<nb_d0; num0++)
2083 for (int num1=0; num1<nb_d1; num1++)
2084 valeurs(num0,num1)=aire(num0,num1);
2085 }
2086 valeurs.echange_espace_virtuel();
2087 champ_aire_IBM_->mettre_a_jour(equation().probleme().schema_temps().temps_courant());
2088 return champs_compris_.get_champ(nom);
2089 }
2090 else if (nom=="velocity_shape_IBM")
2091 {
2092 if (!champ_vitesse_shape_IBM_)
2093 throw std::runtime_error(std::string("Field ") + nom.getString() + std::string(" not found !"));
2094
2095 // Initialisation a 0 du champ_vitesse_shape_IBM_
2096 DoubleTab& valeurs = champ_vitesse_shape_IBM_->valeurs();
2097 valeurs=0.;
2098 if (modele_lu_.vitesse_shape_IBM_)
2099 {
2100 const DoubleTab& vitesse = modele_lu_.get_vitesse_shape_IBM();
2101 int nb_d0 = vitesse.dimension(0);
2102 int nb_d1 = vitesse.dimension(1);
2103 for (int num0=0; num0<nb_d0; num0++)
2104 for (int num1=0; num1<nb_d1; num1++)
2105 valeurs(num0,num1)=vitesse(num0,num1);
2106 }
2107 valeurs.echange_espace_virtuel();
2108 champ_vitesse_shape_IBM_->mettre_a_jour(equation().probleme().schema_temps().temps_courant());
2109 return champs_compris_.get_champ(nom);
2110 }
2111 else if (nom=="pseudo_level_set_IBM")
2112 {
2113 if (!champ_pseudo_level_set_IBM_)
2114 throw std::runtime_error(std::string("Field ") + nom.getString() + std::string(" not found !"));
2115
2116 // Initialisation a 0 du champ_pseudo_level_set_IBM_
2117 DoubleTab& valeurs = champ_pseudo_level_set_IBM_->valeurs();
2118 valeurs=0.;
2120 {
2121 if (interpolation_lue_->pseudo_level_set_)
2122 {
2123 Interpolation_IBM_base& my_interp = ref_cast_non_const(Interpolation_IBM_base, getInterpolationLu());
2124 const DoubleTab& pseudo_level_set = my_interp.get_pseudo_level_set();
2125 int nb_d0 = pseudo_level_set.dimension(0);
2126 for (int num0=0; num0<nb_d0; num0++) valeurs(num0)=pseudo_level_set(num0);
2127 }
2128 }
2129 valeurs.echange_espace_virtuel();
2130 champ_pseudo_level_set_IBM_->mettre_a_jour(equation().probleme().schema_temps().temps_courant());
2131 return champs_compris_.get_champ(nom);
2132 }
2133 else
2134 return champs_compris_.get_champ(nom);
2135}
DoubleTab & futur(int i=1) override
Renvoie les valeurs du champs a l'instant t+i.
DoubleTab & valeurs() override
Renvoie le tableau des valeurs du champ au temps courant.
virtual DoubleTab & valeurs()=0
classe Champ_base Cette classe est la base de la hierarchie des champs.
Definition Champ_base.h:43
virtual bool is_ef() const
void discretiser_champ(const Motcle &directive, const Domaine_dis_base &z, const Nom &nom, const Nom &unite, int nb_comp, int nb_pas_dt, double temps, OWN_PTR(Champ_Inc_base)&champ, const Nom &sous_type=NOM_VIDE) const
int nb_som_elem() const
Renvoie le nombre de sommets des elements geometriques constituants le domaine.
Definition Domaine.h:474
int_t nb_elem_tot() const
Definition Domaine.h:132
SmallArrOfTID_t & chercher_elements(const DoubleTab &pos, SmallArrOfTID_t &elem, int reel=0) const
Recherche des elements contenant les points dont les coordonnees sont specifiees.
Definition Domaine.cpp:405
DoubleTab_t & les_sommets()
Definition Domaine.h:113
IntTab_t & les_elems()
Definition Domaine.h:129
int nb_faces_elem(int=0) const
Renvoie le nombre de face de type i des elements geometriques constituants le domaine.
Definition Domaine.h:484
const DoubleTab_t & coord_sommets() const
Definition Domaine.h:112
int_t nb_som_tot() const
Renvoie le nombre total de sommets du domaine i.e. le nombre de sommets reels et virtuels sur le proc...
Definition Domaine.h:123
int_t nb_som() const
Renvoie le nombre de sommets du domaine.
Definition Domaine.h:121
classe Domaine_Cl_dis_base Les objets Domaine_Cl_dis_base representent les conditions aux limites
class Domaine_VF
Definition Domaine_VF.h:44
int nb_faces_tot() const
renvoie le nombre total de faces.
Definition Domaine_VF.h:481
double volumes(int i) const
Definition Domaine_VF.h:113
int elem_faces(int i, int j) const
renvoie le numero de le ieme face de la maille num_elem la facon dont ces faces sont numerotees est
Definition Domaine_VF.h:543
int face_voisins(int num_face, int i) const
renvoie l'element voisin de numface dans la direction i.
Definition Domaine_VF.h:418
classe Domaine_dis_base Cette classe est la base de la hierarchie des domaines discretisees.
const Domaine & domaine() const
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
const Discretisation_base & discretisation() const
Renvoie la discretisation associee a l'equation.
virtual const Champ_Inc_base & inconnue() const =0
Probleme_base & probleme()
Renvoie le probleme associe a l'equation.
Domaine_dis_base & domaine_dis()
Renvoie le domaine discretise associe a l'equation.
const DoubleTab & get_pseudo_level_set()
virtual void set_fields_from_prepro_to_interp(Prepro_IBM_base &)
void set_pseudo_level_set(DoubleTab &it)
const DoubleTab & get_normal_proj_solid() const
Classe Matrice_Morse Represente une matrice M (creuse), non necessairement carree.
const Equation_base & equation() const
Renvoie la reference sur l'equation pointe par MorEqn::mon_equation.
Definition MorEqn.h:62
OBS_PTR(Equation_base) mon_equation
Une chaine de caractere (Nom) en majuscules.
Definition Motcle.h:26
class Nom Une chaine de caractere pour nommer les objets de TRUST
Definition Nom.h:31
const std::string & getString() const
Definition Nom.h:92
Un tableau de chaine de caracteres (VECT(Nom)).
Definition Noms.h:26
static int dimension
Definition Objet_U.h:99
friend class Sortie
Definition Objet_U.h:75
const Nom & que_suis_je() const
renvoie la chaine identifiant la classe.
Definition Objet_U.cpp:104
virtual Entree & readOn(Entree &)
Lecture d'un Objet_U sur un flot d'entree Methode a surcharger.
Definition Objet_U.cpp:293
virtual 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
@ OPTIONAL
Definition Param.h:115
@ REQUIRED
Definition Param.h:115
const DoubleTab & get_champ_rotation()
void set_champ_aire(DoubleTab &champ_aire)
const DoubleTab & get_champ_barycentre()
void set_champ_rotation(DoubleTab &champ_rotation)
const DoubleTab & get_champ_aire()
void set_champ_barycentre(DoubleTab &champ_bary)
const Nom & le_nom() const override
Donne le nom de l'Objet_U Methode a surcharger : renvoie "neant" dans cette implementation.
Definition Probleme_U.h:109
classe Probleme_base C'est un Probleme_U qui n'est pas un couplage.
const Champ_base & get_champ(const Motcle &nom) const override
const Discretisation_base & discretisation() const
Renvoie la discretisation associee au probleme.
bool & reprise_effectuee()
const Schema_Temps_base & schema_temps() const
Renvoie le schema en temps associe au probleme.
const Domaine_dis_base & domaine_dis() const
Renvoie le domaine discretise associe au probleme.
static void abort()
Routine de sortie de Trio-U sur une erreur abort().
Definition Process.cpp:570
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
Definition Process.cpp:455
Cette classe est a la classe C++ ofstream ce que la classe Sortie est a la classe C++ ostream Elle re...
Definition SFichier.h:27
class Schema_Temps_base
int nb_impr() const
Renvoie le nombre d'impressions effectuees.
double temps_courant() const
Renvoie le temps courant.
double pas_temps_min() const
Renvoie le pas de temps minimum.
double pas_de_temps() const
Renvoie le pas de temps (delta_t) courant.
virtual int ouvrir(const char *name, IOS_OPEN_MODE mode=ios::out)
void precision(int pre) override
void setf(IOS_FORMAT code) override
Classe de base des flux de sortie.
Definition Sortie.h:52
class Source_PDF_base Base class for the source terms for the penalisation of the momentum in the Imm...
virtual void calculer_vitesse_imposee_power_law_tbl_u_star()
ArrOfDouble get_tuvw_local() const
int impr(Sortie &) const override
void set_dt_computation_pdf(double dt)
const int & getInterpolationBool() const
bool matrice_pression_variable_bool_
double temps_computation_pdf_
void set_temps_computation_pdf(double temps_pdf)
DoubleTab compute_pond(const DoubleTab &rho_m, const DoubleTab &aire, const DoubleVect &volume_thilde, int &nb_som_elem, int &nb_elems) const
void creer_champ(const Motcle &motlu) override
virtual void calculer_variable_imposee_elem_fluid()
double aire_geometrique_IBM(DoubleTab &, int)
const PDF_model & get_modele() const
void get_noms_champs_postraitables(Noms &nom, Option opt=NONE) const override
DoubleVect & compute_source_term_PDF(int, DoubleTab &, DoubleVect &)
const Interpolation_IBM_base & getInterpolationLu() const
virtual void filtre_CLD(DoubleTab &) const
virtual void calculer_vitesse_imposee_power_law_tbl()
void comp_diff_L2_max(double dim0, double dim1, const DoubleTab &Array_src, const DoubleTab &Array_prep)
void compute_NeighNode_IBM_elem(DoubleTab &, IntLists &, bool all_elem_vois=false)
void mettre_a_jour(double) override
DOES NOTHING - to override in derived classes.
virtual void calculer_variable_imposee_mean_grad()
virtual void compute_variable_imposee_projete(const DoubleTab &, const DoubleTab &, double, double)
void update_elem_IBM(DoubleTab &, double, double)
double fonct_regul_PDF(const int, const double)
virtual void compute_indicateur_nodal_champ_aire()
void get_fields_from_prepro(Prepro_IBM_base &)
void rotate_imposed_velocity(DoubleTab &)
DoubleTab & calculer_pdf(DoubleTab &) const
virtual DoubleVect diag_coeff_elem(ArrOfDouble &, const DoubleTab &, int) const
void contribuer_a_avec(const DoubleTab &, Matrice_Morse &) const override
contribution a la matrice implicite des termes sources par defaut pas de contribution
DoubleTab source_term_PDF
virtual DoubleTab compute_coeff_matrice() const
virtual void volume_source_term_PDF(DoubleTab &)
void ouvrir_fichier(SFichier &, const Nom &, const int) const override
Ouverture/creation d'un fichier d'impression d'un terme source A surcharger dans les classes derivees...
virtual void correct_variable(const DoubleTab &, DoubleTab &) const
virtual void correct_pressure(const DoubleTab &, DoubleTab &, const DoubleTab &) const
virtual void multiply_coeff_volume(DoubleTab &) const
double fonct_coeff(const double, const double, const double) const
DoubleTab indicateur_nodal_champ_aire_
void set_fields_to_prepro(Prepro_IBM_base &)
virtual void calculer_variable_imposee_hybrid()
void associer_domaines(const Domaine_dis_base &, const Domaine_Cl_dis_base &) override
void update_pseudo_level_set_IBM(DoubleTab &, double)
DoubleTab & ajouter_(const DoubleTab &, DoubleTab &) const override
DoubleTab & calculer(DoubleTab &) const override
virtual void calculer_temperature_imposee_wall_law()
virtual DoubleTab compute_coeff_elem() const
DoubleTab & ajouter(DoubleTab &) const override
const Champ_base & get_champ(const Motcle &) const override
void associer_pb(const Probleme_base &) override
bool has_champ(const Motcle &nom, OBS_PTR(Champ_base) &ref_champ) const override
DoubleTab variable_imposee_
virtual void correct_incr_pressure(const DoubleTab &, DoubleTab &) const
Champs_compris champs_compris_
DoubleVect & bilan()
Definition Source_base.h:88
const Nom description() const
Definition Source_base.h:86
virtual int has_interface_blocs() const
Definition Source_base.h:68
virtual void ajouter_blocs(matrices_t matrices, DoubleTab &secmem, const tabs_t &semi_impl={ }) const
class Source_dep_inco_base Les sources heritant de cette clase doivent coder ajouter_ de facon a perm...
TRUSTList & add_if_not(_TYPE_)
Ajout d'un element a la liste ssi il n'existe pas deja.
int contient(_TYPE_) const
Verifie si un element appartient ou non a la liste.
void vide()
Vide la liste.
int size() const
Definition TRUSTList.h:68
int size() const
Definition TRUSTLists.h:86
_SIZE_ dimension_tot(int) const override
Definition TRUSTTab.tpp:160
_SIZE_ dimension(int d) const
Definition TRUSTTab.tpp:133
_SIZE_ size() const
Definition TRUSTVect.tpp:45
virtual void echange_espace_virtuel(IsExchangeBlocking exchange_type=IsExchangeBlocking::DefaultBlocking, const std::string kernel_name="noname")
static int les_sous_types(const Nom &, Noms &sous_types)
Donne les noms des sous-types, un type mere etant donne par son nom.