TrioCFD 1.9.9_beta
TrioCFD documentation
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 // Optional verification
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 // Rotation Matrix
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 // Barycenter
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 // barycenters not required without prepro_ibm
151 // {
152 // Cerr<<"Source_PDF_base::associer_pb: barycenter term is missing "<<finl;
153 // exit();
154 // }
155 }
156
157 // Field for PDF source term
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 // Area
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 // Imposed Shape IB Velocity
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 Imposed on 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 // Transpose Rotation Matrix
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 Imposed on 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 // no 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: variable dimension different from "<<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 // Clear the 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++) // includes ghost elements
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++) // Two neighbors only
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); // neighbor of num_elem via a 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, neighbor of num_elem_v through a 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); // neighbor of num_elem via a node
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 from the pseudo level set and vertex displacement vector
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 // Initialization of the 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 not initialized
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 not computed by 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 of phi per element (explicit scheme) + vertex (robustness)
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; // for debug
498 // grad_phi per element (normalized)
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 // Add contributions within the 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 not initialized => no contribution
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 along increasing phi direction (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 // normalization of grad_phi_e_0 per element if non-null
522 // note: if level_set not initialized for all nodes of the element => grad_phi_e_0 is null
523 // Treatment of initialised_vertex_in_e = 0 and vertex assembly
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 // If initialised_vertex_in_e = 0
531 // => initialize these vertices from grad_phi_e_0 and the other vertices
532 if ( initialised_vertex_in_e == 0)
533 {
534 // loop to find reference vertex
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; // found
547 }
548 }
549 if (e == etarg) Cerr<<"Vertex not initialized : level_set_ref = "<<level_set_ref<<finl;
550 // loop to define level_set for uninitialized vertices
551 for (int il=0; il<nb_som_elem; il++)
552 {
553 int i = elems(e,il);
554 if (level_set(i) == -99999.) // initialize
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 // Vertex assembly
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 per vertex (normalized)
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 // Advect phi per vertex for all vertices + new_bary for elements crossed by level set zero (arithmetic mean)
605 // normal equals grad_phi_e_0 for these elements
606 IntTrav advect_faite(nb_som) ;
607 aire = 0.; // Zero out the IB area field
608 bary = 0.; // Zero out the IB barycenter field
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 with undefined element grad phi
616
617 double contrib_e = 0.;
618 for (int il=0; il<nb_som_elem; il++)
619 {
620 int i = elems(e,il);
621 // Advect phi for vertex i of the element (if not already done)
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 // compute nodal solid projection and barycenter (arithmetic mean)
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 // If element crossed by level set zero + element grad_phi_e OK => contribution to area field
673 int iok = 0;
674 // element with level set of different sign?
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: first vertex with phi<>0 and initialized
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 // Area definition to be done once the rotations have been updated
702 aire(e) = 9999.;
703 // Definition of the element normal
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 // Update rotation field per element
723 rotation = 0.; // Zero out the 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 up to date => possible modification of the area field
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 // finalization: update of the 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 from the elemental barycenters of 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 // compute neighbors of each crossed element
788 IntLists elem_voisins(nb_elem_tot);
789 compute_NeighNode_IBM_elem(aire, elem_voisins);
790
791 // update the barycenter field
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 //to avoid null being considered as element number 0
817 {
818 toward_new_elem(e) =-2; // rien a deplacer
819 }
820 }
821 indicateur_dead_cell_ = indic_dead_cell;
822
823 // step2 : displacement of fields towards new elements
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 not crossed by gamma
837 {
838 }
839 else //displacement of data (barycenters and rotation matrices)
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 // Arithmetic mean for barycenters and rotation matrices; arithmetic mean or geometric definition for area
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 of topology conservation
875 // Treatment of elements having 0 or 1 neighbor
876 // the neighbors of the predecessor of elem must be neighbors of elem
877
878 // compute neighbors of each new crossed element
879 IntLists elem_voisins_new(nb_elem_tot);
880 compute_NeighNode_IBM_elem(aire, elem_voisins_new);
881
882 // find displaced elements with fewer than 2 neighbors
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 of elements (antecedents) that have moved towards 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 // loop over predecessors of e
896 for (int ant=0; ant<antecedents.size(); ant++)
897 {
898 // Cerr<<" voisins de antecedent = "<<antecedents[ant] <<" ";
899 // loop over old neighbors of each predecessor of 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 // is the old neighbor still a neighbor of 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 ///////////////////////////////// Base fields /////////////////////////////////
981 // Area
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 if vertex belongs to an element with non-zero area
1248 // 0 otherwise
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 if area in element <= 0
1301 // return = rho/dt * coeff_relax otherwise
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 for 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. for PDF = "<<coeff_relax<<" val_coeff = "<<val_coeff <<finl;
1322 }
1323 return val_coeff;
1324}
1325
1326// TENSOR CALCULATION
1327// To possibly handle space directions differently
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 if area in element <= 0
1367 // coeff = 1 + (Ksi/eta) * coeff_relax otherwise
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: variable dimension different from 1 or "<<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 for 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 vertex = Sigma_elem coeff_elem / Nb contributions; with:
1434 // coeff_elem = Ksi/eta * coeff_relax if element with area <>= 0
1435 // coeff_elem = 0 otherwise
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: variable dimension different from 1 or "<<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 for 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 if area in element <= 0
1549// return = rho/dt * coeff_relax * volume / (coef1*coef1) otherwise
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:: current time, temps computation_pdf and corrected time = "<<equation().probleme().schema_temps().temps_courant() <<" "<<temps_computation_pdf_<<" "<<temps_corrige<<finl;
1615 DoubleTab& variable=equation().inconnue().valeurs();
1616 // If the current time has not been updated yet, use the future time for the unknown
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 // Make sure we have the same dt as for 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 // null flag: do not open the file
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 // Create the file at the first output with the header
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; /* nothing found */
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; /* nothing found */
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 // Initialization to 0 of 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 // Initialization to 0 of 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 // Initialization to 0 of 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 // Initialization to 0 of 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 // Initialization to 0 of 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 // Initialization to 0 of 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
Returns field values at instant t+i.
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
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
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
SmallArrOfTID_t & chercher_elements(const DoubleTab &pos, SmallArrOfTID_t &elem, int reel=0) const
Searches for the elements containing the points whose coordinates are specified.
Definition Domaine.cpp:404
DoubleTab_t & les_sommets()
Definition Domaine.h:113
IntTab_t & les_elems()
Definition Domaine.h:129
int nb_faces_elem(int=0) const
Returns the number of faces of type i of the geometric elements that make up the domain.
Definition Domaine.h:484
const DoubleTab_t & coord_sommets() const
Definition Domaine.h:112
int_t nb_som_tot() const
Returns the total number of vertices of the domain i.e. the number of real and virtual vertices on th...
Definition Domaine.h:123
int_t nb_som() const
Returns the number of vertices of the domain.
Definition Domaine.h:121
class Domaine_Cl_dis_base Domaine_Cl_dis_base objects represent discretized boundary conditions
class Domaine_VF
Definition Domaine_VF.h:44
int nb_faces_tot() const
Returns the total number of faces.
Definition Domaine_VF.h:481
double volumes(int i) const
Definition Domaine_VF.h:113
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 face_voisins(int num_face, int i) const
Returns the neighbouring element of num_face in direction i.
Definition Domaine_VF.h:418
class Domaine_dis_base This class is the base of the hierarchy of discretized domains.
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
Returns the discretization associated with the equation.
virtual const Champ_Inc_base & inconnue() const =0
Probleme_base & probleme()
Returns the problem associated with the equation.
Domaine_dis_base & domaine_dis()
Returns the discretized domain associated with the 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
Matrice_Morse class - Represents a (sparse) matrix M, not necessarily square,.
const Equation_base & equation() const
Returns the reference to the equation pointed to by MorEqn::mon_equation.
Definition MorEqn.h:62
OBS_PTR(Equation_base) mon_equation
A character string (Nom) in uppercase.
Definition Motcle.h:26
class Nom: a character string for naming TRUST objects.
Definition Nom.h:31
const std::string & getString() const
Definition Nom.h:92
An array of character strings (VECT(Nom)).
Definition Noms.h:26
static int dimension
Definition Objet_U.h:94
friend class Sortie
Definition Objet_U.h:70
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
virtual const Nom & le_nom() const
Returns the name of the Objet_U. Virtual method to override: returns "neant" in this implementation.
Definition Objet_U.cpp:317
virtual Sortie & printOn(Sortie &) const
Writes the object to an output stream. Virtual method to override.
Definition Objet_U.cpp:278
@ 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
Returns the name of the Objet_U. Virtual method to override: returns "neant" in this implementation.
Definition Probleme_U.h:109
class Probleme_base It is a Probleme_U that is not a coupling.
const Champ_base & get_champ(const Motcle &nom) const override
const Discretisation_base & discretisation() const
Returns the discretization associated with the problem.
bool & reprise_effectuee()
const Schema_Temps_base & schema_temps() const
Returns the time scheme associated with the problem.
const Domaine_dis_base & domaine_dis() const
Returns the discretized domain associated with the problem (const version).
static void abort()
Abort routine for TRUST on a fatal error.
Definition Process.cpp:573
static void exit(int exit_code=-1)
Exit routine for TRUST within a Kokkos region.
Definition Process.cpp:466
SFichier is to the C++ ofstream class what Sortie is to the C++ ostream class.
Definition SFichier.h:29
class Schema_Temps_base
int nb_impr() const
Returns the number of outputs performed.
double temps_courant() const
Returns the current time.
double pas_temps_min() const
Returns the minimum time step.
double pas_de_temps() const
Returns the current time step (delta_t).
virtual int ouvrir(const char *name, IOS_OPEN_MODE mode=ios::out)
void precision(int pre) override
void setf(IOS_FORMAT code) override
Base class for output streams.
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 to the implicit matrix of source terms, by default no 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
Opening/creation of a file for printing a source term. To override in derived classes.
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 Sources inheriting from this class must implement ajouter_ in a way that a...
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)
Returns the names of the subtypes for a parent type identified by name.