TRUST 1.9.8
HPC thermohydraulic platform
Loading...
Searching...
No Matches
Pb_Couple_Optimisation_IBM.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 <Pb_Couple_Optimisation_IBM.h>
17#include <Terme_Derivee_Forme_base.h>
18#include <Operateur_Diff_base.h>
19#include <Equation_IBM_proto.h>
20#include <Prepro_IBM_base.h>
21#include <Probleme_base.h>
22#include <Operateur.h>
23#include <TRUSTTrav.h>
24
25Implemente_instanciable(Pb_Couple_Optimisation_IBM,"Pb_Couple_Optimisation_IBM",Probleme_Couple);
26
28{
29 int nb_pb_lu=0;
30 Cerr << "<<<<<< Reading of Probleme_Couple_Optimisation_IBM " << le_nom() << " >>>>>>>>>>"<<finl;
31 Motcle motlu;
32 is >> motlu;
33 if (motlu != Motcle("{"))
34 {
35 Cerr << "We expected { to start to read the Probleme_Couple" << finl;
36 exit();
37 }
38 is >> motlu;
39 while (motlu!=Motcle("}")) // fin du readOn
40 {
41 if (motlu=="groupes")
42 {
43 if (nb_problemes())
44 {
45 Cerr << "We can associate problems to Probleme_Couple" << finl;
46 Cerr << "* either by \"associer prob_couple pb\" (in which case they are all in the same group)" << finl;
47 Cerr << "* either by the keyword \"groupes\" while reading the object Probleme_Couple" << finl;
48 Cerr << "but not both!" << finl;
49 }
50 assert(nb_problemes()==0);
51
52 LIST(LIST(Nom)) les_noms;
53 is >> les_noms;
54
55 groupes.resize_array(les_noms.size());
56 for (int i=0; i<les_noms.size(); i++)
57 {
58 groupes[i]=les_noms[i].size();
59 for (int j=0; j<les_noms[i].size(); j++)
60 {
61 Nom nom_pb=les_noms[i][j];
62 Objet_U& ob=Interprete::objet(nom_pb);
63 Probleme_base& pb=ref_cast(Probleme_base,ob);
64 ajouter(pb);
65 }
66 }
67 }
68 else if (motlu=="state_problem")
69 {
70 Nom nom_pb;
71 is >> nom_pb;
72 Objet_U& ob=Interprete::objet(nom_pb);
73 Probleme_base& pb_lu=ref_cast(Probleme_base,ob);
74 pb_etat_opt_ = pb_lu;
75 nb_pb_lu += 1;
76 Cerr << "We define state problem as ... " << pb_etat_opt_->le_nom() << finl;
77 }
78
79 else if (motlu=="adjoint_problem")
80 {
81 Nom nom_pb;
82 is >> nom_pb;
83 Objet_U& ob=Interprete::objet(nom_pb);
84 Probleme_base& pb_lu=ref_cast(Probleme_base,ob);
85 pb_adjt_opt_ = pb_lu;
86 nb_pb_lu += 1;
87 Cerr << "We define adjoint problem as ... " << pb_adjt_opt_->le_nom() << finl;
88 }
89
90 else if (motlu=="projection_problem")
91 {
92 Nom nom_pb;
93 is >> nom_pb;
94 Objet_U& ob=Interprete::objet(nom_pb);
95 Probleme_base& pb_lu=ref_cast(Probleme_base,ob);
96 pb_projection_opt_ = pb_lu;
97 nb_pb_lu += 1;
98 Cerr << "We define projection problem as ... " << pb_projection_opt_->le_nom() << finl;
99 if ( (pb_projection_opt_->que_suis_je() != "Pb_Conduction") && (pb_projection_opt_->que_suis_je() != "Pb_Conduction_IBM"))
100 {
101 Cerr << "Projection problem is not of type Pb_Conduction or Pb_Conduction_IBM : "<<pb_projection_opt_->que_suis_je()<<finl;
102 abort();
103 }
104 if ( pb_projection_opt_->nombre_d_equations() != 1 )
105 {
106 Cerr<<"Pb_Couple_Optimisation_IBM : nb equation != 1 for projection problem."<<finl;
107 abort();
108 }
109
110 }
111 else if (motlu=="objective_function")
112 {
113 Motcle type;
114 is >> type;
115 fonction_cout_lu_.typer(type);
116 Champ_Don_base& ch_fonction_cout_lu = ref_cast(Champ_Don_base,fonction_cout_lu_.valeur());
117 is >> ch_fonction_cout_lu;
118 const int nb_comp = ch_fonction_cout_lu.nb_comp();
119 if (nb_comp != 1)
120 {
121 Cerr<<"Pb_Couple_Optimisation_IBM : dimension objective_function != 1 ."<<finl;
122 abort();
123 }
124 fonction_cout_lu_->fixer_nb_comp(nb_comp);
125 if (ch_fonction_cout_lu.le_nom()=="anonyme") ch_fonction_cout_lu.nommer("fonction_cout");
126 for (int n = 0; n < nb_comp; n++) fonction_cout_lu_->fixer_nom_compo(n, ch_fonction_cout_lu.le_nom() + (nb_comp > 1 ? Nom(n) :""));
127 }
128
129 else if (motlu=="objective_function_visualization")
130 {
131 is >> visu_cout_;
132 }
133
134 else if (motlu=="IBM_moving_parameter")
135 {
136 is >> alpha_;
137 Cerr << "IBM_moving_parameter = " << alpha_ << finl;
138 }
139
140 else if (motlu=="ponderation_shap_deriv_for_projection")
141 {
143 Cerr << "ponderation_shap_deriv_for_projection = " << pond_shap_deriv_for_proj_ << finl;
144 }
145
146 else if (motlu=="PDF_regularization_for_shape_deriv")
147 {
149 }
150
151 else if (motlu=="area_constraints_low_high")
152 {
153 is >> modif_aire_pc_low_;
155 }
156
157 else
158 {
159 Cerr << "We expected state_problem, adjoint_problem, projection_problem, objective_function, objective_function_visualization, IBM_moving_parameter, ponderation_shap_deriv_for_projection, PDF_regularization_for_shape_deriv, deplacement_vector_visualization or area_constraints_low_high" << finl;
160 exit();
161 }
162
163 is >> motlu;
164 }
165
166 if (nb_pb_lu != 3)
167 {
168 Cerr <<"We expected three problems: the state_problem, the adjoint_problem and the projection_problem" << finl;
169 exit();
170 }
171 Cerr << "<<<<<<<<< End of reading of Probleme_Couple_Optimisation_IBM >>>>>>>>>>"<<finl;
172 return is;
173}
174
176{
177 return Probleme_Couple::printOn(os);
178}
179
181{
183
184 if (!pb_etat_opt_)
185 {
186 Cerr<<"(IBM) Pb_Couple_Optimisation_IBM : no detected state problem."<<finl;
187 Cerr<<"Case not supported"<<finl;
188 Cerr<<"Aborting..."<<finl;
189 abort();
190 }
191
192 int nb_source_pdf = 0;
193 int nb_eq_IBM = 0;
194 int mobile = 1;
195 Cerr<<"(IBM) Pb_Couple_Optimisation_IBM : search for the Source_PDF in the "<<pb_etat_opt_->nombre_d_equations()<<" equation(s) of the state problem "<<pb_etat_opt_->le_nom()<<finl;
196 for (int i = 0; i <pb_etat_opt_->nombre_d_equations() ; i++)
197 {
198 Cerr<<"Equation : "<<pb_etat_opt_->equation(i).le_nom()<<finl;
199 if(pb_etat_opt_->equation(i).que_suis_je().finit_par("IBM"))
200 {
201 nb_eq_IBM++;
202 Equation_IBM_proto& eq_ibm = dynamic_cast<Equation_IBM_proto&>(pb_etat_opt_->equation(i));
203 int id_source_pdf = eq_ibm.get_i_source_pdf();
204 if (id_source_pdf == -1)
205 {
206 Cerr<<"Pb_Couple_Optimisation_IBM : Source_PDF not detected in IBM equation."<<finl;
207 Cerr << "Either this source term is missing or not read again !!!"<< finl;
208 Cerr<<"Aborting..."<<finl;
209 abort();
210 }
211 Equation_base& eq_i = pb_etat_opt_->equation(i);
212 Source_PDF_base& src = dynamic_cast<Source_PDF_base&>((eq_i.sources())[id_source_pdf].valeur());
213 my_source_PDF_opt_ = src;
214 PDF_model& pdf_mod_st = ref_cast_non_const(PDF_model, src.get_modele());
215 if (pdf_mod_st.pdf_bilan() != 0)
216 {
217 Cerr<<"Model_PDF with bilan_PDF <> 0. Exit."<<finl;
218 exit();
219 }
220 pdf_mod_st.set_PDF_mobile(mobile); // on declare l'IB mobile
221 pdf_mod_st.discretiser_vitesse_shape_IBM(pb_etat_opt_); // on discretise vitesse_shape_IBM_ (PDF_mobile)
223 nb_source_pdf++;
224 }
225 }
226
227 if (nb_eq_IBM==0)
228 {
229 Cerr<<"Pb_Couple_Optimisation_IBM : no IBM equation detected."<<finl;
230 Cerr<<"The state problem needs one IBM equation"<<finl;
231 Cerr<<"Aborting..."<<finl;
232 abort();
233 }
234
235 if (nb_source_pdf>1)
236 {
237 Cerr<<"Pb_Couple_Optimisation_IBM : more than one Source_PDF detected in state problem."<<finl;
238 Cerr<<"Case not supported"<<finl;
239 Cerr<<"Aborting..."<<finl;
240 abort();
241 }
242 else if (nb_source_pdf>0)
243 {
244 Cerr<<"(IBM) Pb_Couple_Optimisation_IBM : one Source_PDF detected in state problem."<<finl;
245 }
246 else
247 {
248 Cerr<<"Pb_Couple_Optimisation_IBM : no Source_PDF detected."<<finl;
249 Cerr<<"It needs one Source_PDF in state problem"<<finl;
250 Cerr<<"Aborting..."<<finl;
251 abort();
252 }
253
254 const int exist_interp = my_source_PDF_opt_->getInterpolationBool();
255 if (exist_interp) my_interpolation_opt_ = my_source_PDF_opt_->getInterpolationLu();
256 if (my_interpolation_opt_)
257 {
258 Cerr<<"(IBM) Pb_Couple_Optimisation_IBM : interpolation detected."<<finl;
259 my_interpolation_opt_->discretise_PDF_mobile(pb_etat_opt_->equation(Numero_eq_optimis_).discretisation(), pb_etat_opt_->equation(Numero_eq_optimis_).domaine_dis());
260 }
261 my_prepro_opt_ = my_source_PDF_opt_->getpreproLu();
262 if (my_prepro_opt_)
263 {
264 Cerr<<"(IBM) Pb_Couple_Optimisation_IBM : prepro_IBM detected for state equ."<<finl;
265 }
266 else
267 {
268 Cerr<<"(IBM) Pb_Couple_Optimisation_IBM : prepro_IBM is missing for state equ."<<finl;
269 exit();
270 }
271
272 if( pb_etat_opt_->equation(Numero_eq_optimis_).que_suis_je() != pb_adjt_opt_->equation(Numero_eq_optimis_).que_suis_je() )
273 {
274 Cerr<<"(IBM) Pb_Couple_Optimisation_IBM : the state pb and the adjoint pb are of different type."<<finl;
275 Cerr<<" pb_etat : "<<pb_etat_opt_->equation(Numero_eq_optimis_).que_suis_je() <<finl;
276 Cerr<<" pb_adjt : "<<pb_adjt_opt_->equation(Numero_eq_optimis_).que_suis_je() <<finl;
277 exit();
278 }
279
280 Equation_IBM_proto& eq_ibm_adj = dynamic_cast<Equation_IBM_proto&>(pb_adjt_opt_->equation(Numero_eq_optimis_));
281 int id_source_pdf_adj = eq_ibm_adj.get_i_source_pdf();
282 if (id_source_pdf_adj == -1)
283 {
284 Cerr<<"Pb_Couple_Optimisation_IBM : Source_PDF not detected in adjoint IBM equation."<<finl;
285 Cerr << "Either this source term is missing or not read again !!!"<< finl;
286 Cerr<<"Aborting..."<<finl;
287 abort();
288 }
289 Source_PDF_base& src_adj = dynamic_cast<Source_PDF_base&>((pb_adjt_opt_->equation(Numero_eq_optimis_).sources())[id_source_pdf_adj].valeur());
290 my_source_PDF_opt_adjt_ = src_adj;
291 PDF_model& pdf_mod_adj = ref_cast_non_const(PDF_model, src_adj.get_modele());
292 pdf_mod_adj.set_PDF_mobile(mobile);
293
294 const int exist_interp_adjt = my_source_PDF_opt_adjt_->getInterpolationBool();
295 if (exist_interp_adjt) my_interpolation_opt_adjt_ = my_source_PDF_opt_adjt_->getInterpolationLu();
296 if (my_interpolation_opt_adjt_)
297 {
298 Cerr<<"(IBM) Pb_Couple_Optimisation_IBM : interpolation detected for adjoint problem."<<finl;
299 my_interpolation_opt_adjt_->discretise_PDF_mobile(pb_adjt_opt_->equation(Numero_eq_optimis_).discretisation(), pb_adjt_opt_->equation(Numero_eq_optimis_).domaine_dis());
300 }
301
302 Equation_base& eqn_proj = pb_projection_opt_->equation(0);
303 Sources& sources_proj = eqn_proj.sources();
304 int size_s = sources_proj.size();
305 if(size_s == 0) { Cerr<<"Pb_Couple_Optimisation_IBM::solveTimeStep : no source for projection problem."<<finl; abort();};
306
308 Nom type = "Derivee_Forme";
309 if (eqn_proj.discretisation().is_vdf())
310 type += "_VDF";
311 else if (eqn_proj.discretisation().is_vef())
312 type += "_VEF";
313 else if (eqn_proj.discretisation().is_ef())
314 type += "_EF";
315
316 for (int nsrc=0; nsrc<size_s; nsrc++)
317 {
318 Source_base& ma_source = sources_proj(nsrc).valeur();
319 if (ma_source.que_suis_je() == type) Numero_src_deriv_form_ = nsrc;
320 }
321 if (Numero_src_deriv_form_ == -1)
322 {
323 Cerr<<"Pb_Couple_Optimisation_IBM : no source for projection problem is of type derivee_forme."<<finl;
324 abort();
325 }
326
327 const Domaine_dis_base& le_dom_dis = pb_projection_opt_->domaine_dis();
328
329 // source_derivee_forme : scalaire par element
330 pb_projection_opt_->discretisation().discretiser_champ("champ_elem",le_dom_dis,"source_derivee_forme","",1,0., source_derivee_forme_);
331 DoubleTab& sourceArray = source_derivee_forme_->valeurs();
332 sourceArray = 0.;
333
334 // normal_derivee_forme : normal par element
335 pb_projection_opt_->discretisation().discretiser_champ("champ_elem",le_dom_dis,"normal_derivee_forme","",3,0., normal_derivee_forme_);
336 DoubleTab& normSourceArray = normal_derivee_forme_->valeurs();
337 normSourceArray = 0.;
338
339 // Fonction cout scalaire par element
340
341 if (fonction_cout_lu_)
342 {
343 Champ_Don_base& ch_fonction_cout_lu = ref_cast(Champ_Don_base,fonction_cout_lu_.valeur());
344 const int nb_comp = ch_fonction_cout_lu.nb_comp();
345 pb_projection_opt_->discretisation().discretiser_champ("champ_elem",le_dom_dis,"fonction_cout","",nb_comp,0., fonction_cout_);
346 for (int n = 0; n < nb_comp; n++) fonction_cout_->fixer_nom_compo(n, ch_fonction_cout_lu.le_nom() + (nb_comp > 1 ? Nom(n) :""));
347 // PL: Il faut faire nommer_completer_champ_physique les 2 champs (plantage sinon pour une fonction de type Champ_fonc_tabule)
348 eqn_proj.discretisation().nommer_completer_champ_physique(eqn_proj.domaine_dis(),ch_fonction_cout_lu.le_nom(),"",fonction_cout_lu_,eqn_proj.probleme());
349 eqn_proj.discretisation().nommer_completer_champ_physique(eqn_proj.domaine_dis(),ch_fonction_cout_lu.le_nom(),"",fonction_cout_,eqn_proj.probleme());
350 fonction_cout_->valeurs() = 0.;
351 fonction_cout_->affecter(ch_fonction_cout_lu);
352 }
353 else
354 {
355 pb_projection_opt_->discretisation().discretiser_champ("champ_elem",le_dom_dis,"fonction_cout","",1,0., fonction_cout_);
356 DoubleTab& coutArray = fonction_cout_->valeurs();
357 coutArray = 0.;
358 }
359
360
361 Cerr<<"Shape optimization coupled problem :";
362 for (int ipb=0; ipb < nb_problemes(); ipb++) Cerr<<" "<<probleme(ipb).le_nom();
363 Cerr<<finl;
364
365}
366
368{
369 const Domaine_dis_base& le_dom_dis = pb_etat_opt_->domaine_dis();
370 int nb_elem = le_dom_dis.nb_elem();
371 const Schema_Temps_base& sch=pb_etat_opt_->schema_temps();
372 double temps=sch.temps_courant();
373 double pdtps = sch.pas_de_temps();
374 bool level_set = my_source_PDF_opt_->get_modele().get_use_pseudo_level_set_moving_PDF();
375
376 const Domaine& dom = le_dom_dis.domaine();
377 int nb_faces_elem = dom.nb_faces_elem();
378 const Domaine_VF& the_dom_VF = ref_cast(Domaine_VF,le_dom_dis);
379 const IntTab& elem_face = the_dom_VF.elem_faces();
380 const IntTab& face_voisins = the_dom_VF.face_voisins();
381 // VDF/VEF by default
382 int nb_dof_elem = nb_faces_elem;
383 // Formulation EF
384 if (pb_projection_opt_->equation(0).discretisation().is_ef())
385 {
386 nb_dof_elem = dom.nb_som_elem();
387 }
388 else if (!(pb_projection_opt_->equation(0).discretisation().is_vdf()) && !(pb_projection_opt_->equation(0).discretisation().is_vef()))
389 {
390 Cerr<<"(IBM) Pb_Couple_Optimisation_IBM::calcul_derivee_forme_IBM: discretisation is not EF, VEF or VDF. Aborting... "<<pb_projection_opt_->equation(0).discretisation()<<finl;
391 }
392 const IntTab& elems = (pb_projection_opt_->equation(0).discretisation().is_ef() ? dom.les_elems() : the_dom_VF.elem_faces());
393
394 // Mise a jour de la fonction cout (quantité élémentaire)
395 if (fonction_cout_lu_)
396 {
397 fonction_cout_lu_->mettre_a_jour(temps);
398 fonction_cout_->affecter(fonction_cout_lu_.valeur());
399 }
401
402 // Mise a jour de la frontiere IBM (quantité élémentaire): barycentre, normale et aire
403 DoubleTab& normSourceArray = normal_derivee_forme_->valeurs(); //vecteur normalise par element donnant le sens
404 const DoubleTab& deplacement_scalaire = pb_projection_opt_->equation(0).inconnue().valeurs();
405 int dim0 = (level_set ? deplacement_scalaire.dimension(0) : normSourceArray.dimension(0));
406 DoubleTab vecteur_deplacement(dim0, normSourceArray.dimension(1));
407 if (level_set) // <vecteur deplacement pour approche pseudo level set (par dof)
408 {
409 int relev_vois_e = 0; // copie ou non normSourceArray pour elements voisins par une face
410 // on boucle sur les cellules ayant normSourceArray non nul
411 vecteur_deplacement = 0.;
412 DoubleTrav contrib_i(dim0);
413 for (int e=0; e<normSourceArray.dimension(0); e++)
414 {
415 double norm = 0.;
416 for (int k=0; k<normSourceArray.dimension(1); k++) norm += normSourceArray(e,k)*normSourceArray(e,k);
417 if (norm > 1.e-10) // Existe normSourceArray non nul pour l element e
418 {
419 for (int il=0; il<nb_dof_elem; il++)
420 {
421 int i = elems(e,il);
422 for (int k=0; k<vecteur_deplacement.dimension(1); k++) vecteur_deplacement(i,k) += normSourceArray(e,k);
423 contrib_i(i) += 1.;
424 }
425 if (relev_vois_e)
426 {
427 // copie normSourceArray pour elements voisins par une face
428 for (int fac=0; fac<nb_faces_elem; fac++)
429 {
430 int num_fac = elem_face(e, fac);
431 for (int voisin=0; voisin<2; voisin++) // Deux voisins seulement
432 {
433 int elem_voi = face_voisins(num_fac,voisin);
434 if ( (elem_voi!=-1) && (elem_voi!=e) )
435 {
436 norm = 0.;
437 for (int k=0; k<normSourceArray.dimension(1); k++) norm += normSourceArray(elem_voi,k)*normSourceArray(elem_voi,k);
438 if (norm < 1.e-10) // N'existe pas normSourceArray chez le voisin elem_voi
439 {
440 for (int il_v=0; il_v<nb_dof_elem; il_v++)
441 {
442 int i_v = elems(elem_voi,il_v);
443 for (int k=0; k<vecteur_deplacement.dimension(1); k++) vecteur_deplacement(i_v,k) += normSourceArray(e,k);
444 contrib_i(i_v) += 1.;
445 }
446 }
447 }
448 }
449 }
450 }
451 }
452 }
453 for (int i=0; i<dim0; i++)
454 {
455 if (contrib_i(i) >0.)
456 {
457 double nor_nor = 0.;
458 for (int k=0; k<vecteur_deplacement.dimension(1); k++) nor_nor += (vecteur_deplacement(i,k)/contrib_i(i))*(vecteur_deplacement(i,k)/contrib_i(i));
459 if (nor_nor > 1.e-10)
460 for (int k=0; k<vecteur_deplacement.dimension(1); k++) vecteur_deplacement(i,k) /= sqrt(nor_nor);
461 }
462 }
463
464 }
465 else // <vecteur deplacement pour approche particulaire sous-contrainte (par elem)
466 {
467 for (int e=0; e<dim0; e++)
468 {
469 for (int k=0; k<vecteur_deplacement.dimension(1); k++) vecteur_deplacement(e,k) = normSourceArray(e,k);
470 }
471 }
472
473 bool iShapDeplOK = false;
474 double bilan = 0.;
475
476 if (temps >= pdtps && alpha_ > 0.)
477 {
478 Cerr<<"(IBM) Pb_Couple_Optimisation_IBM : updating the shape following shape displacements"<<finl;
479 const DoubleTab& aire = my_source_PDF_opt_->get_champ_aire().valeurs();
480 bilan = 0.;
481 for (int e=0; e<nb_elem; e++)
482 if (aire(e)>0.) bilan += aire(e);
483 Cerr<<"(IBM) Area balance before shape moving = "<<bilan<<finl;
484
485 // Appel au prepro IBM pour le champ h_max_elem (limitation du deplacement scalaire a une maille voisine si alpha_ = 1)
486 const DoubleTab& h_max_elem = (level_set ? my_prepro_opt_->get_h_max_node() : my_prepro_opt_->get_h_max_elem());
487
488 // Definition du vecteur deplacement elementaire suivant le sens de normal_derivee_forme_ (sens du deplacement)
489 double deplacement_scalaire_e;
490 for (int e=0; e<vecteur_deplacement.dimension(0); e++)
491 {
492 if (level_set) // deplacement pour approche pseudo level set
493 {
494 //on est aux dof de la projection (e = dof)
495 deplacement_scalaire_e = deplacement_scalaire(e);
496 }
497 else // deplacement pour approche particulaire sous-contrainte
498 {
499 //on est aux elements (e = elem)
500 deplacement_scalaire_e =0.;
501 for (int il=0; il<nb_dof_elem; il++)
502 {
503 int i = elems(e,il);
504 deplacement_scalaire_e += deplacement_scalaire(i) / nb_dof_elem;
505 }
506 }
507 double abs_depl = abs(deplacement_scalaire_e);
508 double sign_depl = 0.;
509 if (abs_depl > 1.e-10) sign_depl = deplacement_scalaire_e / abs_depl;
510 double min_en_depl = min(abs_depl * alpha_, h_max_elem(e)) * sign_depl;
511 for (int k=0; k<vecteur_deplacement.dimension(1); k++) vecteur_deplacement(e,k) *= min_en_depl;
512 }
513 iShapDeplOK = true;
514 }
515 else vecteur_deplacement *= 0.;
516
517 // Vitesse deplacement IB pour postraitement
518 DoubleTrav vitesse_deplacement(normSourceArray);
519 if (level_set) // projection aux elements
520 {
521 const DoubleTab& aire = my_source_PDF_opt_->get_champ_aire().valeurs();
522 for (int e=0; e<normSourceArray.dimension(0); e++)
523 {
524 for (int il=0; il<nb_dof_elem; il++)
525 {
526 int i = elems(e,il);
527 for (int k=0; k<vecteur_deplacement.dimension(1); k++) vitesse_deplacement(e,k) += vecteur_deplacement(i,k)*(aire(e)>0.?1.:0.) / nb_dof_elem;
528 }
529 }
530 }
531 else
532 {
533 for (int e=0; e<vecteur_deplacement.dimension(0); e++)
534 {
535 for (int k=0; k<vecteur_deplacement.dimension(1); k++) vitesse_deplacement(e,k) = vecteur_deplacement(e,k) ;
536 }
537 }
538 vitesse_deplacement /= pdtps;
539 PDF_model& pdf_mod_etat = ref_cast_non_const(PDF_model, my_source_PDF_opt_->get_modele());
540 pdf_mod_etat.set_vitesse_shape_IBM(vitesse_deplacement);
541
542 // Deplacement vectoriel elementaire des barycentres des faces IBM et maj prepro_IBM et interpolation de l'eq. etat
543 if (iShapDeplOK)
544 {
545 double raid = my_source_PDF_opt_->get_modele().raid();
546 if (level_set)
547 my_source_PDF_opt_->update_pseudo_level_set_IBM(vecteur_deplacement, 1.0);
548 else
549 my_source_PDF_opt_->update_elem_IBM(vecteur_deplacement, 1.0, raid);
550
551 const DoubleTab& aire = my_source_PDF_opt_->get_champ_aire().valeurs();
552 bilan = 0.;
553 for (int e=0; e<nb_elem; e++) bilan += aire(e);
554 if (!area_ref_set_)
555 {
556 area_ref_set_ = 1;
557 area_ref_ = bilan;
558 Cerr<<"(IBM) Reference area balance after first shape moving = "<<bilan<<finl;
559 }
560 else
561 {
562 Cerr<<"(IBM) Area balance after shape moving = "<<bilan<<finl;
563 if ( (bilan <= area_ref_ * (modif_aire_pc_low_)) || (bilan >= area_ref_ * (modif_aire_pc_high_)) )
564 {
565 alpha_ =-1.0; // Bloquage de la modification de la geometrie
566 Cerr<<"(IBM) Area constraint: shape moving is stopped. Percent = "<<(bilan/area_ref_ )<<finl;
567 }
568 }
569
570
571 // Appel au prepro IBM pour generer la nouvelle description discrete de la frontiere
572 // Eq. adjointe
573 my_source_PDF_opt_adjt_->get_fields_from_prepro(my_prepro_opt_);
574 if(my_source_PDF_opt_adjt_->getInterpolationBool() == true)
575 {
576 Interpolation_IBM_base& my_interp_adjt = ref_cast_non_const(Interpolation_IBM_base, my_source_PDF_opt_adjt_->getInterpolationLu());
577 my_interp_adjt.set_fields_from_prepro_to_interp(my_prepro_opt_);
578 }
579 my_source_PDF_opt_adjt_->set_variable_imposee();
580 }
581
582 bool ok = Probleme_Couple::initTimeStep(dt);
583 return ok;
584}
585
587{
588
589 bool ok;
590 suppProblem(pb_projection_opt_);
592
593 addProblem(pb_projection_opt_);
594 suppProblem(pb_etat_opt_);
595 suppProblem(pb_adjt_opt_);
596
597 const Schema_Temps_base& sch=pb_etat_opt_->schema_temps();
598 double temps=sch.temps_courant();
599 double pdtps = sch.pas_de_temps();
600 if (temps > pdtps)
601 {
602 // Calcul terme derivee de forme
603 Cerr<<"(IBM) Pb_Couple_Optimisation_IBM : update of shape derivative term in projection eq." <<finl;
604 DoubleVect my_bilan;
605 my_source_PDF_opt_->compute_source_term_PDF(my_bilan);
606 my_source_PDF_opt_adjt_->compute_source_term_PDF(my_bilan);
608
609 // derivee de forme dans le terme source de equation de projection
610 Source_base& ma_source = (pb_projection_opt_->equation(0).sources())(Numero_src_deriv_form_).valeur();
611 Terme_Derivee_Forme_base& ma_source_DF_eq = ref_cast(Terme_Derivee_Forme_base, ma_source);
612 DoubleTab& sourceEqArray = ref_cast_non_const(DoubleTab, ma_source_DF_eq.get_source_derivee_forme());
613 DoubleTab& sourceDFArray = source_derivee_forme_->valeurs();
614 assert(sourceEqArray.dimension(0) == sourceDFArray.dimension(0));
615 assert(sourceEqArray.dimension(1) == sourceDFArray.dimension(1));
616 for (int i=0; i<sourceEqArray.dimension(0); i++)
617 {
618 for (int j=0; j<sourceEqArray.dimension(1); j++) sourceEqArray(i,j) = 0.-sourceDFArray(i,j)*pond_shap_deriv_for_proj_;
619 }
620 sourceEqArray.echange_espace_virtuel();
621 ma_source_DF_eq.set_source_derivee_forme(sourceEqArray);
622 ma_source_DF_eq.mettre_a_jour(pb_projection_opt_->equation(0).probleme().schema_temps().temps_courant());
623 }
624
626
627 addProblem(pb_etat_opt_);
628 addProblem(pb_adjt_opt_);
629
630 return ok;
631}
632
634{
635
636 // Calcul terme derivee de forme à partir du source_pdf de pb_etat + pb_adjoint
637 DoubleTab& sourceArray = source_derivee_forme_->valeurs();
638 DoubleTab& normSourceArray = normal_derivee_forme_->valeurs();
639 DoubleTab& fonctCout = fonction_cout_->valeurs();
640 DoubleTab coutArray(fonctCout);
641 assert(fonctCout.dimension(1)==1);
642 assert(fonctCout.dimension(1)==sourceArray.dimension(1));
643 const Champ_Don_base& champ_aire = my_source_PDF_opt_->get_champ_aire();
644 const DoubleTab& aire = champ_aire.valeurs();
645 const DoubleTab& edp_val_i = my_source_PDF_opt_->get_source_pdf();
646 const DoubleTab& adjoint = pb_adjt_opt_->equation(Numero_eq_optimis_).inconnue().valeurs();
647 const int interp_adjoint = my_source_PDF_opt_adjt_->getInterpolationBool();
648
649 // dimentional verifications (0)
650 int nb_dof = edp_val_i.dimension(0);
651 // dimentional verifications (1)
652 int nb_comp = edp_val_i.dimension(1);
653 int dim_esp = Objet_U::dimension;
654 assert(nb_comp<=dim_esp);
655
656 const Domaine_dis_base& le_dom_dis = pb_etat_opt_->domaine_dis();
657 const Domaine& dom = le_dom_dis.domaine();
658 const Domaine_VF& the_dom_VF = ref_cast(Domaine_VF,le_dom_dis);
659 int nb_elem = le_dom_dis.nb_elem();
660 int nb_elem_tot = le_dom_dis.nb_elem_tot();
661 int nb_som_elem = dom.nb_som_elem();
662 int nb_faces_elem = dom.nb_faces_elem();
663
664 // VDF/VEF by default
665 const IntTab& faces_som = the_dom_VF.face_sommets();
666 int nb_som_face = the_dom_VF.nb_som_face();
667 int nb_dof_elem = nb_faces_elem;
668 int is_face_dis = 1;
669 const IntTab& elems = (pb_adjt_opt_->equation(Numero_eq_optimis_).discretisation().is_ef() ? le_dom_dis.domaine().les_elems() : the_dom_VF.elem_faces());
670 if (pb_adjt_opt_->equation(Numero_eq_optimis_).discretisation().is_ef())
671 {
672 // Formulation EF
673 nb_dof_elem = nb_som_elem;
674 is_face_dis = 0;
675 }
676 else if (!(pb_adjt_opt_->equation(Numero_eq_optimis_).discretisation().is_vdf()) && !(pb_adjt_opt_->equation(Numero_eq_optimis_).discretisation().is_vef()))
677 {
678 Cerr<<"(IBM) Pb_Couple_Optimisation_IBM::calcul_derivee_forme_IBM: discretisation is not EF, VEF or VDF. Aborting... "<<pb_adjt_opt_->equation(Numero_eq_optimis_).discretisation()<<finl;
679 }
680
681 DoubleTrav nor(nb_dof, dim_esp);
682 DoubleTrav dist(nb_dof);
683 my_prepro_opt_->calculer_normal_proj_solid(nor, dist);
684 IntLists elem_voisins(nb_elem_tot);
685 DoubleTab& aire_ncst = ref_cast_non_const(DoubleTab, aire);
686 bool all_elem_vois = true;
687 my_source_PDF_opt_->compute_NeighNode_IBM_elem(aire_ncst, elem_voisins, all_elem_vois);
688
689 // Loop on elements for weight computation on dof
690 DoubleTrav weight(nb_dof);
691 weight = 0.;
692 for (int e=0; e<nb_elem; e++)
693 {
694 if (aire(e)>0.)
695 {
696 for (int il=0; il<nb_dof_elem; il++)
697 {
698 int i = elems(e,il);
699 weight(i) += 1.;
700 }
701 }
702 }
703
704 // Loop on elements for shape derivative computation
705 sourceArray = 0.;
706 normSourceArray = 0.;
707 coutArray = 0.;
708 double regualpha_i=1.;
709 double eps = 1e-12;
710 double d1;
711 double PDF_contr_min = 1.e+30;
712 double PDF_contr_max = -1.e+30;
713 double cout_contr_min = 1.e+30;
714 double cout_contr_max = -1.e+30;
715 double lim_p = 0.5;
716 double lim_n = 0. - lim_p;
717 DoubleTrav nor_e(1, dim_esp);
718
719 for (int e=0; e<nb_elem; e++)
720 {
721 if (aire(e)>0.)
722 {
723 nor_e = 0.;
724 for (int il=0; il<nb_dof_elem; il++)
725 {
726 int i = elems(e,il);
727
728 // scalar PDF_source contribution at dof
729 double ps_edp_i = 0.;
730 if (regul_PDF_shape_deriv_) regualpha_i= my_source_PDF_opt_->fonct_regul_PDF(e, dist(i));
731 // Cerr<<"e, i, dist(i), regualpha_i = "<<e<<" "<<i<<" "<<dist(i)<<" "<<regualpha_i<<finl;
732 for (int nc=0; nc<nb_comp; nc++)
733 if(interp_adjoint) ps_edp_i += regualpha_i * edp_val_i(i,nc) * adjoint(i,nc) / weight(i);
734 else ps_edp_i += regualpha_i * edp_val_i(i,nc) / weight(i);
735
736 // sum of nodal normals weighted by nodal PDF_source
737 if (!(is_face_dis))
738 {
739 for (int k=0; k<dim_esp; k++) nor_e(0, k) += nor(i, k)*ps_edp_i;
740 }
741 else if (is_face_dis)
742 {
743 for (int no=0; no<nb_som_face; no++)
744 {
745 int inode = faces_som(i, no);
746 for (int k=0; k<dim_esp; k++) nor_e(0, k) += nor(inode, k)*ps_edp_i;
747 }
748 }
749 }
750
751 // arrith. mean of PDF weighted normal resulting in normalized vector folowing (-grad_gamma J) by element, from lower to higher PDF_source
752 d1 = 0.0;
753 for (int k=0; k<dim_esp; k++) d1 += nor_e(0, k)*nor_e(0, k);
754 d1 = sqrt(d1);
755 if (d1 > eps )
756 for (int k=0; k<dim_esp; k++) normSourceArray(e, k) = nor_e(0, k) / d1 ;
757
758 sourceArray(e,0) = std::min(d1, lim_p);
759 if (sourceArray(e,0) < PDF_contr_min) PDF_contr_min = sourceArray(e,0);
760 if (sourceArray(e,0) > PDF_contr_max) PDF_contr_max = sourceArray(e,0);
761
762 // Elementary cost function contribution
763
764 // boucle sur les voisin vois de e :
765 int nb_elem_voi = elem_voisins[e].size();
766 int ps_pos = 0; // nb element voisin ayant une contribution positive a prendre en compte
767 int ps_neg = 0; // nb element voisin ayant une contribution negative a prendre en compte
768 double meanCout_pos = 0.;
769 double meanCout_neg = 0.;
770 if (nb_elem_voi != 0)
771 {
772 for (int voi=0; voi<nb_elem_voi; voi++)
773 {
774 // Le voisin doit avoir aire() = 0
775 // Cerr<<"voisin = "<<(elem_voisins[e])[voi]<<" aire_voisin = "<<aire((elem_voisins[e])[voi])<<finl;
776 if (aire((elem_voisins[e])[voi]) <= 0.)
777 {
778 int elem_voi = (elem_voisins[e])[voi];
779 // pour les noeuds i de chaque voisin: ps nor(i, k) * normSourceArray(e,k) donne le signe
780 // de la contribution qui doit etre la meme pour tous les noeuds i de chaque voisin
781 double ps_voi_ref = 0.;
782 int iok = 0;
783 for (int il=0; il<nb_dof_elem; il++)
784 {
785 int i = elems(elem_voi,il);
786 double ps_voi_i =0.;
787 for (int k=0; k<dim_esp; k++) ps_voi_i += nor(i, k) * normSourceArray(e,k) ;
788 if (iok == 0 && ps_voi_i != 0.)
789 {
790 ps_voi_ref = ps_voi_i; // premier ps non nul
791 iok = 1;
792 }
793 if (ps_voi_ref*ps_voi_i < 0)
794 {
795 iok = 0;
796 break;
797 }
798 // Cerr<<"Element voisin = "<<elem_voi<<" , ps_voi_i = "<<ps_voi_i<<" , iok, ps_voi_ref = "<<iok<<" "<<ps_voi_ref<<finl;
799 }
800 // recuperer le signe du ps et faire une moyenne sur l'element voisin elem_voi
801 if (iok == 1 && ps_voi_ref > 0.)
802 {
803 ps_pos += 1;
804 meanCout_pos += fonctCout(elem_voi,0);
805 }
806 else if (iok == 1 && ps_voi_ref<0.)
807 {
808 ps_neg += 1;
809 meanCout_neg += fonctCout(elem_voi,0);
810 }
811 }
812 }
813 // Moyenne fct cout pour les contributions + et -
814 if (ps_pos != 0 && ps_neg != 0)
815 coutArray(e,0) = std::max(std::min(meanCout_pos/ps_pos - meanCout_neg/ps_neg, lim_p), lim_n);
816 else coutArray(e,0) = 0.;
817 }
818 if (coutArray(e,0) < cout_contr_min) cout_contr_min = coutArray(e,0);
819 if (coutArray(e,0) > cout_contr_max) cout_contr_max = coutArray(e,0);
820
821 // Cerr<<"element "<<e<<" : normSourceArray = ";
822 // for (int k=0; k<dim_esp; k++) Cerr<<normSourceArray(e, k) <<" ";
823 // Cerr<<" ; sourceArray = "<<sourceArray(e,0);
824 // Cerr<<" ; coutArray = "<<coutArray(e,0)<<" nb voisins ="<<nb_elem_voi<<" ; pos/neg = "<<ps_pos<<" "<<ps_neg<<finl;
825 }
826 }
827
828 //Normalisation eventuelle contribution PDF et cout entre 0 et +1
829 double bilan = 0.;
830 for (int e=0; e<nb_elem; e++)
831 {
832 if (aire(e)>0.)
833 {
834 // double source = (sourceArray(e,0) - PDF_contr_min) /(PDF_contr_max - PDF_contr_min + 1.e-6) ;
835 // double source = (log(sourceArray(e,0)) - log(PDF_contr_min)) /(log(PDF_contr_max) - log(PDF_contr_min) + 1.e-6);
836 // double coutsd = (coutArray(e,0) - cout_contr_min) /(cout_contr_max - cout_contr_min + 1.e-6) ;
837 double source = sourceArray(e,0) ;
838 double coutsd = coutArray(e,0) ;
839 sourceArray(e,0) = source - coutsd;
840 bilan += sourceArray(e,0);
841 }
842 }
843
844 sourceArray.echange_espace_virtuel();
845 normSourceArray.echange_espace_virtuel();
846 Cerr<<"(IBM) Pb_Couple_Optimisation_IBM::calcul_derivee_forme_IBM: Balance (// Balance) = ";
847 Cerr<<bilan<<" "<<mp_sum(bilan)<<finl;
848}
849
851{
852 const Domaine& le_dom = pb_projection_opt_.valeur().domaine();
853 const Schema_Temps_base& sch=pb_etat_opt_->schema_temps();
854 double temps=sch.temps_courant();
855 double temps_ecoule=sch.temps_calcul();
856 double dt_impr=sch.temps_impr();
857 int step=int(temps_ecoule/dt_impr);
858
859 Nom nom_fichier_med_Out_ = "objective_function.med";
860 if (sch.nb_pas_dt() < 1)
861 {
862 ecr_med_fonction_cout_.set_file_name_and_dom(nom_fichier_med_Out_, le_dom);
863 ecr_med_fonction_cout_.ecrire_domaine(false);
864 }
865 else if (step > nb_save_call_)
866 {
867 nb_save_call_ += 1;
868 const Nom& type_elem = le_dom.type_elem()->que_suis_je();
869 int nb_comp = fcout.dimension(1);
870 Noms nom_cout(nb_comp);
871 Noms unites_cout(nb_comp);
872 for (int k=0; k<nb_comp; k++) unites_cout[k] = "-";
873 for (int k=0; k<nb_comp; k++) nom_cout[k] = "-";
874 ecr_med_fonction_cout_.ecrire_champ("CHAMPMAILLE", "objective_function", fcout, unites_cout, nom_cout, type_elem, temps);
875 }
876}
classe Champ_Don_base classe de base des Champs donnes (non calcules)
DoubleTab & valeurs() override
Surcharge Champ_base::valeurs() Renvoie le tableau des valeurs.
const Probleme_U & probleme(int i) const
Definition Couplage_U.h:127
void suppProblem(Probleme_U &)
Definition Couplage_U.h:107
void addProblem(Probleme_U &)
Definition Couplage_U.h:112
int nb_problemes() const
Definition Couplage_U.h:117
void nommer_completer_champ_physique(const Domaine_dis_base &domaine_vdf, const Nom &nom_champ, const Nom &unite, Champ_base &champ, const Probleme_base &pbi) const
virtual bool is_ef() const
virtual bool is_vdf() const
virtual bool is_vef() const
int nb_som_elem() const
Renvoie le nombre de sommets des elements geometriques constituants le domaine.
Definition Domaine.h:474
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
class Domaine_VF
Definition Domaine_VF.h:44
int face_sommets(int i, int j) const
renvoie le numero du ieme sommet de la face num_face.
Definition Domaine_VF.h:583
int nb_som_face() const
renvoie le nombre de sommets par face.
Definition Domaine_VF.h:494
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.
int nb_elem_tot() const
const Domaine & domaine() const
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
classe Equation_base Le role d'une equation est le calcul d'un ou plusieurs champs....
Sources & sources()
Renvoie les termes sources asssocies a l'equation.
const Discretisation_base & discretisation() const
Renvoie la discretisation associee a l'equation.
Probleme_base & probleme()
Renvoie le probleme associe a l'equation.
Domaine_dis_base & domaine_dis()
Renvoie le domaine discretise associe a l'equation.
const Nom & le_nom() const override
Renvoie le nom du champ.
void nommer(const Nom &) override
Donne un nom au champ.
virtual int nb_comp() const
Definition Field_base.h:56
virtual void set_fields_from_prepro_to_interp(Prepro_IBM_base &)
static Objet_U & objet(const Nom &)
Voir Interprete_bloc::objet_global() BM: la classe Interprete n'est pas le meilleur endroit pour cett...
class Nom Une chaine de caractere pour nommer les objets de TRUST
Definition Nom.h:31
Un tableau de chaine de caracteres (VECT(Nom)).
Definition Noms.h:26
static int dimension
Definition Objet_U.h:99
const Nom & que_suis_je() const
renvoie la chaine identifiant la classe.
Definition Objet_U.cpp:104
virtual Entree & readOn(Entree &)
Lecture d'un Objet_U sur un flot d'entree Methode a surcharger.
Definition Objet_U.cpp:293
Objet_U()
Constructeur par defaut : attribue un numero d'identifiant unique a l'objet (object_id_),...
Definition Objet_U.cpp:55
virtual Sortie & printOn(Sortie &) const
Ecriture de l'objet sur un flot de sortie Methode a surcharger.
Definition Objet_U.cpp:282
: class PDF_model
Definition PDF_model.h:34
int pdf_bilan() const
Definition PDF_model.h:41
void set_PDF_mobile(bool the_flag)
Definition PDF_model.h:44
void discretiser_vitesse_shape_IBM(const Probleme_base &)
void set_vitesse_shape_IBM(DoubleTab &it)
Definition PDF_model.h:47
bool solveTimeStep() override
pour recodage eventuel et appel unifie en python
bool initTimeStep(double) override
This method allocates and initializes the unknown and given fields for the future time step.
void initialize() override
This method is called once at the beginning, before any other one of the interface Problem.
classe Probleme_Couple C'est la classe historique de couplage de TRUST.
bool initTimeStep(double dt) override
This method allocates and initializes the unknown and given fields for the future time step.
void initialize() override
This method is called once at the beginning, before any other one of the interface Problem.
bool solveTimeStep() override
pour recodage eventuel et appel unifie en python
void ajouter(Probleme_base &)
Ajoute un probleme a la liste des problemes couples.
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
static void abort()
Routine de sortie de Trio-U sur une erreur abort().
Definition Process.cpp:570
static double mp_sum(double)
Calcule la somme de x sur tous les processeurs du groupe courant.
Definition Process.cpp:146
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
Definition Process.cpp:455
class Schema_Temps_base
double temps_courant() const
Renvoie le temps courant.
double temps_impr() const
Renvoie une reference sur le temps d'impression.
double temps_calcul() const
Renvoie le temps de calcul ecoule i.
double pas_de_temps() const
Renvoie le pas de temps (delta_t) courant.
int nb_pas_dt() const
Renvoie le nombre de pas de temps effectues.
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...
const PDF_model & get_modele() const
classe Source_base Un objet Source_base est un terme apparaissant au second membre d'une
Definition Source_base.h:42
class Sources Sources represente une liste de Source.
Definition Sources.h:31
int size() const
Definition TRUSTLists.h:86
_SIZE_ dimension(int d) const
Definition TRUSTTab.tpp:133
virtual void echange_espace_virtuel(IsExchangeBlocking exchange_type=IsExchangeBlocking::DefaultBlocking, const std::string kernel_name="noname")
Classe Terme_Derivee_Forme_base Cette classe represente un terme source de l'equation de projection e...
void mettre_a_jour(double) override
DOES NOTHING - to override in derived classes.
void set_source_derivee_forme(DoubleTab &) const
const DoubleTab & get_source_derivee_forme() const