16#include <Parametre_implicite.h>
17#include <Navier_Stokes_FT_Disc.h>
18#include <Probleme_FT_Disc_gen.h>
19#include <Modele_turbulence_hyd_null.h>
20#include <Discret_Thyd.h>
21#include <Operateur_Diff_base.h>
22#include <Transport_Interfaces_FT_Disc.h>
23#include <Fluide_Diphasique.h>
24#include <Fluide_Incompressible.h>
25#include <Assembleur_base.h>
26#include <TRUST_Vector.h>
27#include <Schema_Temps_base.h>
28#include <Domaine_VDF.h>
30#include <Domaine_VF.h>
31#include <Terme_Source_Constituant_Vortex_VEF_Face.h>
33#include <Matrice_Morse_Sym.h>
34#include <Matrice_Bloc.h>
37#include <Domaine_Cl_VDF.h>
38#include <Connex_components.h>
39#include <EcritureLectureSpecial.h>
55static void FT_disc_calculer_champs_rho_mu_nu_dipha(
const Domaine_dis_base& domaine_dis_base,
const Fluide_Diphasique& fluide,
const DoubleVect& indicatrice_elem, DoubleVect& rho_elem,
56 DoubleVect& nu_elem, DoubleVect& mu_elem, DoubleVect& rho_faces)
62 const double rho_phase_0 = tab_rho_phase_0(0, 0);
63 const double rho_phase_1 = tab_rho_phase_1(0, 0);
64 const double delta_rho = rho_phase_1 - rho_phase_0;
67 const double nu_phase_0 = tab_nu_phase_0(0, 0);
68 const double nu_phase_1 = tab_nu_phase_1(0, 0);
69 const double delta_nu = nu_phase_1 - nu_phase_0;
70 const double mu_phase_0 = nu_phase_0 * rho_phase_0;
71 const double mu_phase_1 = nu_phase_1 * rho_phase_1;
72 const double delta_mu = mu_phase_1 - mu_phase_0;
78 const int n = indicatrice_elem.
size();
79 assert(n == rho_elem.
size());
80 assert(n == nu_elem.
size());
81 assert(n == mu_elem.
size());
82 for (
int i = 0; i < n; i++)
84 const double indic = indicatrice_elem[i];
85 const double rho = indic * delta_rho + rho_phase_0;
87 double nu = indic * delta_nu + nu_phase_0;
97 mu = indic * delta_mu + mu_phase_0;
102 mu = (mu_phase_0 * mu_phase_1) / (mu_phase_1 - indic * delta_mu);
107 Cerr <<
"The method specified for formule_mu in not recognized. \n" << finl;
108 Cerr <<
"you can choose : standard, arithmetic or harmonic. \n" << finl;
123 assert(rho_elem.
size() == domaine_dis_base.
nb_elem());
124 const IntTab& face_voisins = domaine_dis_base.
face_voisins();
125 const int nfaces = face_voisins.
dimension(0);
126 assert(rho_faces.
size() == nfaces);
127 for (
int i = 0; i < nfaces; i++)
129 const int elem0 = face_voisins(i, 0);
130 const int elem1 = face_voisins(i, 1);
133 rho = rho_elem[elem0];
135 rho += rho_elem[elem1];
136 if (elem0 >= 0 && elem1 >= 0)
151 const double rho = tab_rho_phase_0(0, 0);
153 const double nu = tab_nu_phase_0(0, 0);
154 const double mu = nu * rho;
155 champ_rho_elem_.
valeurs() = rho;
158 champ_rho_faces.
valeurs() = rho;
165 const DoubleVect& vol = zvf.
volumes();
166 const int nb_faces = zvf.
nb_faces();
171 IntVect les_polys(nb_el);
172 for (
int i = 0; i < nb_el; i++)
175 const DoubleTab& cg = zvf.
xp();
176 DoubleTab& val_rho = champ_rho_elem_.
valeurs();
177 DoubleTab& val_nu = champ_nu_.
valeurs();
178 DoubleTab& val_mu = champ_mu_.
valeurs();
179 DoubleTab& val_rho_faces = champ_rho_faces.
valeurs();
186 for (
int el = 0; el < nb_el; el++)
187 val_nu(el) = val_mu(el) / val_rho(el);
190 for (
int fac = 0; fac < nb_faces; fac++)
192 elem1 = face_vois(fac, 0);
193 elem2 = face_vois(fac, 1);
194 val_rho_faces(fac) = 0.;
198 val_rho_faces(fac) += val_rho(elem1) * vol(elem1);
199 volume += vol(elem1);
203 val_rho_faces(fac) += val_rho(elem2) * vol(elem2);
204 volume += vol(elem2);
206 val_rho_faces(fac) /= volume;
232 std::vector<YAML_data> particles = particles_eulerian_id_number_post_->data_a_sauvegarder();
233 data.insert(data.end(), particles.begin(), particles.end());
243 bytes += particles_eulerian_id_number_post_->sauvegarder(os);
253 Nom ident_id_part(particles_eulerian_id_number_post_->le_nom());
254 ident_id_part += particles_eulerian_id_number_post_->
que_suis_je();
256 ident_id_part +=
Nom(temps,
probleme().reprise_format_temps());
257 avancer_fichier(is, ident_id_part);
258 particles_eulerian_id_number_post_->reprendre(is);
259 DoubleTab& particles_eulerian_id_number_post = particles_eulerian_id_number_post_->valeurs();
260 int nb_elem_tot=particles_eulerian_id_number_post.
dimension(0);
261 for (
int elem=0; elem<nb_elem_tot; elem++) particles_eulerian_id_number_(elem)= static_cast<int>(particles_eulerian_id_number_post(elem));
270 param.
ajouter_flag(
"boussinesq_approximation", &variables_internes().is_boussinesq_);
271 param.
ajouter_flag(
"new_mass_source", &variables_internes().new_mass_source_);
272 param.
ajouter_flag(
"shift_secmem2", &variables_internes().shift_secmem2_);
273 param.
ajouter_flag(
"matrice_pression_invariante", &variables_internes().matrice_pression_invariante);
276 param.
ajouter_non_std(
"equation_interfaces_proprietes_fluide", (
this));
277 param.
ajouter(
"clipping_courbure_interface", &variables_internes().clipping_courbure_interface);
281 param.
ajouter(
"equations_concentration_source_vortex", &variables_internes().equations_concentration_source_fluide_);
284 param.
ajouter_flag(
"mpoint_inactif_sur_qdm", &variables_internes().mpoint_inactif);
285 param.
ajouter_flag(
"mpoint_vapeur_inactif_sur_qdm", &variables_internes().mpointv_inactif);
286 param.
ajouter(
"correction_courbure_ordre", &variables_internes().correction_courbure_ordre_);
289 param.
ajouter_flag(
"correction_diffusion_pch", &correction_diffusion_pch_);
294 if (mot ==
"diffusion")
297 Cerr <<
"Reading and typing of the diffusion operator : " << finl;
300 if (le_modele_turbulence
306 Cerr <<
" WARNING : standard diffusion operator used for front_tracking\n";
307 Cerr <<
" the transposed term grad(v) is missing !!!" << finl;
315 terme_diffusif->associer_champ_masse_volumique(champ_rho_elem_.valeur());
318 if (le_modele_turbulence)
319 le_modele_turbulence->associer_champ_masse_volumique(champ_rho_elem_.valeur());
322 else if ((mot ==
"equation_interfaces_vitesse_imposee") || (mot ==
"equation_interfaces_proprietes_fluide"))
326 Cerr << mot <<
" equation : " << nom_equation << finl;
329 if (mot ==
"equation_interfaces_vitesse_imposee")
331 if (variables_internes().ref_eq_interf_vitesse_imposee.size() > 0)
333 Cerr <<
"Error: You have already a equation_interfaces_vitesse_imposee defined." << finl;
334 Cerr <<
"Since 1.6.4 TRUST version, you need to use the following syntax when" << finl;
335 Cerr <<
"using several equation_interfaces_vitesse_imposee equations:" << finl;
336 Cerr <<
"equations_interfaces_vitesse_imposee number_of_equations equation_name_one equation_name_two ..." << finl;
341 Cerr <<
"===============================================================================" << finl;
342 Cerr <<
"Warning: You are using a future obsolete syntax for defining a solid interface:" << finl;
343 Cerr <<
"equation_interfaces_vitesse_imposee " << nom_equation << finl;
344 Cerr <<
"Should be written:" << finl;
345 Cerr <<
"equations_interfaces_vitesse_imposee 1 " << nom_equation << finl;
346 Cerr <<
"===============================================================================" << finl;
348 variables_internes().ref_eq_interf_vitesse_imposee.add(eq);
350 else if (mot ==
"equation_interfaces_proprietes_fluide")
351 variables_internes().ref_eq_interf_proprietes_fluide = eq;
354 else if (mot ==
"equations_interfaces_vitesse_imposee")
358 variables_internes().ref_eq_interf_vitesse_imposee.reset();
359 for (
int i = 0; i < na.size(); i++)
362 variables_internes().ref_eq_interf_vitesse_imposee.add(eq);
366 else if (mot ==
"equation_temperature_mpoint")
370 Cerr <<
" equation : " << nom_equation << finl;
374 Cerr <<
" Error : equation is not of type Convection_Diffusion_Temperature_FT_Disc" << finl;
380 else if (mot ==
"equation_temperature_mpoint_vapeur")
384 Cerr <<
" equation : " << nom_equation << finl;
388 Cerr <<
" Error : equation is not of type Convection_Diffusion_Temperature_FT_Disc" << finl;
394 else if (mot ==
"terme_gravite")
401 Cerr <<
"Reading terme_gravite : " << motbis << finl;
402 const int r = mots.
search(motbis);
412 Cerr <<
"Error " << mots <<
"was expected whereas " << motbis <<
" has been found." << finl;
418 else if (mot ==
"repulsion_aux_bords")
424 Cerr <<
"Interfaces repulsion on the boundaries for : " << minx <<
" " << maxx << finl;
427 else if (mot ==
"penalisation_forcage")
429 variables_internes().is_penalized = 1;
430 variables_internes().is_explicite = 0;
431 variables_internes().eta = 1.e-12;
432 Cerr <<
"Navier_Stokes_FT_Disc : option penalisation_forcage" << finl;
434 mots.add(
"pression_reference");
435 mots.add(
"domaine_flottant_fluide");
438 Motcle accouverte =
"{", accfermee =
"}";
439 if (motbis == accouverte)
442 while (motbis != accfermee)
444 int rang = mots.
search(motbis);
449 is >> variables_internes().p_ref_pena;
450 Cerr <<
"Lecture de la pression de reference : " << variables_internes().p_ref_pena << finl;
455 variables_internes().is_pfl_flottant = 1;
456 is >> variables_internes().x_pfl_imp;
457 is >> variables_internes().y_pfl_imp;
459 is >> variables_internes().z_pfl_imp;
460 Cerr <<
"Domaine flottant fluide" << finl;
461 Cerr <<
"Lecture de la position du point de reference pression fluide : " << variables_internes().x_pfl_imp <<
" " << variables_internes().y_pfl_imp <<
" "
462 << variables_internes().z_pfl_imp << finl;
466 Cerr <<
"Erreur, on attendait " << mots <<
"On a trouve : " << motbis << finl;
475 Cerr <<
"Erreur a la lecture des parametres de la penalisation du forcage " << finl;
476 Cerr <<
"On attendait : " << accouverte << finl;
480 else if (mot ==
"interpol_indic_pour_dI_dt")
483 motcles2[0] =
"interp_standard";
484 motcles2[1] =
"interp_modifiee";
485 motcles2[2] =
"interp_ai_based";
486 motcles2[3] =
"interp_standard_uvext";
487 motcles2[4] =
"interp_modifiee_uvext";
488 motcles2[5] =
"interp_ai_based_uvext";
489 motcles2[6] =
"interp_standard_uiext";
490 motcles2[7] =
"interp_modifiee_uiext";
491 motcles2[8] =
"interp_ai_based_uiext";
494 Cerr << mot <<
" " << motlu << finl;
495 Cout <<
"Setting the type of interpolation for calculer_dI_dt to " << motlu <<
"." << finl;
496 int rang = motcles2.
search(motlu);
503 Cerr <<
" The interpolation of indicatrice to faces in calculer_dI_dt is based on the historical way" <<
" where a mean value + upwind is used." << finl;
510 Cerr <<
" The interpolation of indicatrice to faces in calculer_dI_dt is based on the field indicatrice_faces" <<
" as defined by the interfacial transport option." << finl;
517 Cerr <<
" The interpolation of indicatrice to faces in calculer_dI_dt is based on the interfacial area" <<
" and on the normal to the interface." << finl;
524 Cerr <<
" The interpolation of indicatrice to faces in calculer_dI_dt is based on the historical way" <<
" where a mean value + upwind is used." <<
" Additionally, uv_ext is used."
532 Cerr <<
" The interpolation of indicatrice to faces in calculer_dI_dt is based on the field indicatrice_faces" <<
" as defined by the interfacial transport option."
533 <<
" Additionally, uv_ext is used." << finl;
540 Cerr <<
" The interpolation of indicatrice to faces in calculer_dI_dt is based on the interfacial area" <<
" and on the normal to the interface." <<
" Additionally, uv_ext is used."
548 Cerr <<
" The interpolation of indicatrice to faces in calculer_dI_dt is based on the historical way" <<
" where a mean value + upwind is used." <<
" Additionally, ui_ext is used."
556 Cerr <<
" The interpolation of indicatrice to faces in calculer_dI_dt is based on the field indicatrice_faces" <<
" as defined by the interfacial transport option."
557 <<
" Additionally, ui_ext is used." << finl;
564 Cerr <<
" The interpolation of indicatrice to faces in calculer_dI_dt is based on the interfacial area" <<
" and on the normal to the interface." <<
" Additionally, ui_ext is used."
569 Cerr <<
"Transport_Interfaces_FT_Disc::lire\n" <<
"The options for methode_transport are :\n" << motcles2;
573 else if (mot ==
"OutletCorrection_pour_dI_dt")
576 motcles2[0] =
"no_correction";
577 motcles2[1] =
"CORRECTION_GHOST_INDIC";
578 motcles2[2] =
"zero_net_flux_on_mixed_cells";
579 motcles2[3] =
"zero_out_flux_on_mixed_cells";
582 Cerr << mot <<
" " << motlu << finl;
583 Cout <<
"Setting the type of correction at outlet BC for calculer_dI_dt to " << motlu <<
"." << finl;
584 int rang = motcles2.
search(motlu);
591 Cerr <<
" No correction of div(chi u) at exit (historical way)" << finl;
598 Cerr <<
" Correction of chi in ghost cells (virtually)" << finl;
605 Cerr <<
" correction of div(chi u) at exit : zero divergence on cells touching outlet." << finl;
613 Cerr <<
" correction of div(chi u) at exit : zero vapour mass flux on cells touching outlet." << finl;
614 Cerr <<
" This is a bad option because it does not let vapour get out explicitly (prevents interface contact)" << finl;
615 Cerr <<
" Should not be used or with great care." << finl;
621 Cerr <<
"Transport_Interfaces_FT_Disc::lire\n" <<
"The options for methode_transport are :\n" << motcles2;
638 Cerr <<
"Error for the method Navier_Stokes_FT_Disc::associer_pb_base\n";
639 Cerr <<
" Navier_Stokes_FT_Disc equation must be associated to\n";
640 Cerr <<
" a Probleme_FT_Disc_gen problem type\n";
652 Cerr <<
"Error for the method Navier_Stokes_FT_Disc::fluide_diphasique()\n";
653 Cerr <<
" The fluid has not been associated\n";
654 Cerr <<
" (check that the fluid is of Fluide_Diphasique type)" << finl;
658 return fluide_dipha.valeur();
664 variables_internes().ref_fluide_diphasique = ref_cast(
Fluide_Diphasique, un_fluide);
671 if (variables_internes().ref_fluide_diphasique)
672 return variables_internes().ref_fluide_diphasique.valeur();
679 if (variables_internes().ref_fluide_diphasique)
680 return variables_internes().ref_fluide_diphasique.valeur();
701 dis.
discretiser_champ(
"champ_elem", mon_dom_dis,
"diffusivite",
"m^2/s", 1 , temps, champ_nu_);
702 champs_compris.add(champ_nu_.valeur());
706 dis.
discretiser_champ(
"champ_elem", mon_dom_dis,
"viscosite_dynamique",
"kg/m.s", 1 , temps, champ_mu_);
707 champs_compris.add(champ_mu_.valeur());
710 dis.
discretiser_champ(
"champ_elem", mon_dom_dis,
"masse_volumique",
"kg/m3", 1 , temps, champ_rho_elem_);
711 champs_compris.add(champ_rho_elem_.valeur());
715 dis.
discretiser_champ(
"vitesse", mon_dom_dis,
"masse_volumique_vnodes",
"kg/m3", 1 , temps, champ_rho_faces_);
716 champs_compris.add(champ_rho_faces_.valeur());
720 dis.
discretiser_champ(
"pression", mon_dom_dis,
"second_membre_projection",
"", 1 , temps, variables_internes().second_membre_projection);
721 champs_compris.add(variables_internes().second_membre_projection.valeur());
722 champs_compris_.ajoute_champ(variables_internes().second_membre_projection);
723 dis.
discretiser_champ(
"champ_elem", mon_dom_dis,
"second_membre_projection_jump",
"", 1 , temps, variables_internes().second_membre_projection_jump_);
724 champs_compris.add(variables_internes().second_membre_projection_jump_.valeur());
725 champs_compris_.ajoute_champ(variables_internes().second_membre_projection_jump_);
726 dis.
discretiser_champ(
"vitesse", mon_dom_dis,
"gradient_pression_interne",
"m/s2", -1 , temps, variables_internes().gradient_pression);
727 champs_compris.add(variables_internes().gradient_pression.valeur());
729 dis.
discretiser_champ(
"vitesse", mon_dom_dis,
"derivee_u_etoile",
"", -1 , temps, variables_internes().derivee_u_etoile);
730 champs_compris.add(variables_internes().derivee_u_etoile.valeur());
732 dis.
discretiser_champ(
"vitesse", mon_dom_dis,
"terme_diffusion_vitesse",
"", -1 , temps, variables_internes().terme_diffusion);
733 champs_compris.add(variables_internes().terme_diffusion.valeur());
735 dis.
discretiser_champ(
"vitesse", mon_dom_dis,
"terme_convection_vitesse",
"", -1 , temps, variables_internes().terme_convection);
736 champs_compris.add(variables_internes().terme_convection.valeur());
738 dis.
discretiser_champ(
"vitesse", mon_dom_dis,
"terme_source_vitesse",
"", -1 , temps, variables_internes().terme_source);
739 champs_compris.add(variables_internes().terme_source.valeur());
741 dis.
discretiser_champ(
"vitesse", mon_dom_dis,
"terme_source_interfaces",
"", -1 , temps, variables_internes().terme_source_interfaces);
742 champs_compris.add(variables_internes().terme_source_interfaces.valeur());
743 champs_compris_.ajoute_champ(variables_internes().terme_source_interfaces);
746 dis.
discretiser_champ(
"pression", mon_dom_dis,
"indicatrice_p1b",
"", 1 , temps, variables_internes().indicatrice_p1b);
747 champs_compris.add(variables_internes().indicatrice_p1b.valeur());
751 dis.
discretiser_champ(
"vitesse", mon_dom_dis,
"gradient_indicatrice",
"", -1 , temps, variables_internes().gradient_indicatrice);
752 champs_compris.add(variables_internes().gradient_indicatrice.valeur());
753 champs_compris_.ajoute_champ(variables_internes().gradient_indicatrice);
754 dis.
discretiser_champ(
"vitesse", mon_dom_dis,
"potentiel_faces",
"", 1 , temps, variables_internes().potentiel_faces);
755 champs_compris.add(variables_internes().potentiel_faces.valeur());
757 dis.
discretiser_champ(
"champ_elem", mon_dom_dis,
"potentiel_elements",
"", 1 , temps, variables_internes().potentiel_elements);
758 champs_compris.add(variables_internes().potentiel_elements.valeur());
760 dis.
discretiser_champ(
"vitesse", mon_dom_dis,
"vitesse_delta_interface",
"m/s", -1 , 1, temps, variables_internes().delta_u_interface);
762 variables_internes().delta_u_interface->associer_eqn(*
this);
763 champs_compris.add(variables_internes().delta_u_interface.valeur());
765 dis.
discretiser_champ(
"pression", mon_dom_dis,
"pression_laplacien_d",
"", 1 , temps, variables_internes().laplacien_d);
766 champs_compris.add(variables_internes().laplacien_d.valeur());
768 dis.
discretiser_champ(
"temperature", mon_dom_dis,
"temperature_mpoint",
"", 1 , temps, variables_internes().mpoint);
769 champs_compris.add(variables_internes().mpoint.valeur());
771 dis.
discretiser_champ(
"temperature", mon_dom_dis,
"temperature_mpointv",
"", 1 , temps, variables_internes().mpoint_vap);
772 champs_compris.add(variables_internes().mpoint_vap.valeur());
775 dis.
discretiser_champ(
"pression", mon_dom_dis,
"derivee_temporelle_indicatrice",
"", 1 , temps, variables_internes().derivee_temporelle_indicatrice);
776 champs_compris.add(variables_internes().derivee_temporelle_indicatrice.valeur());
777 champs_compris_.ajoute_champ(variables_internes().derivee_temporelle_indicatrice);
780 dis.
discretiser_champ(
"champ_elem", mon_dom_dis,
"interfacial_area",
"m2", 1 , temps, variables_internes().ai);
781 champs_compris.add(variables_internes().ai.valeur());
786 dis.
discretiser_champ(
"vitesse", mon_dom_dis, nom,
"m/s", -1 , 1, temps, variables_internes().vitesse_jump0_);
787 variables_internes().vitesse_jump0_->associer_eqn(*
this);
788 champs_compris.add(variables_internes().vitesse_jump0_.valeur());
806 schema_temps().temps_courant(),particles_eulerian_id_number_post_);
807 particles_eulerian_id_number_post_->nommer(
"PARTICLES_EULERIAN_ID_NUMBER");
808 champs_compris.add(particles_eulerian_id_number_post_.valeur());
812 "contact_force_source_term",
"",
814 variables_internes().contact_force_source_term);
815 champs_compris.add(variables_internes().contact_force_source_term.valeur());
816 champs_compris_.ajoute_champ(variables_internes().contact_force_source_term);
819 dis.
discretiser_champ(
"vitesse", mon_dom_dis, nom1,
"m/s", -1 , 1, temps, variables_internes().vitesse_jump1_);
820 variables_internes().vitesse_jump1_->associer_eqn(*
this);
821 champs_compris.add(variables_internes().vitesse_jump1_.valeur());
837 assembleur_pression_.typer(
"Assembleur_P_VDF");
842 assembleur_pression_.typer(
"Assembleur_P_VEFPreP1B");
861 Cerr <<
"Navier_Stokes_FT_Disc::projeter does nothing" << finl;
877 Cerr <<
"Initialisation of the physical properties (rho, mu, ...)\n" <<
" based on the indicatrice field of the equation " << ref_equation->le_nom() << finl;
883 champ_rho_elem_->
valeurs(), champ_nu_->
valeurs(), champ_mu_->
valeurs(), champ_rho_faces_->valeurs());
890 FT_disc_calculer_champs_rho_mu_nu_mono(zdis, phase_0, champ_rho_elem_, champ_mu_, champ_nu_, champ_rho_faces_);
899 Cerr <<
"Navier_Stokes_FT_Disc::preparer_calcul()" << finl;
902 le_modele_turbulence->preparer_calcul();
920 Cerr <<
"Initialisation of the physical properties (rho, mu, ...)\n" <<
" based on the indicatrice field of the equation " << ref_equation->le_nom() << finl;
924 champ_rho_elem_->
valeurs(), champ_nu_->
valeurs(), champ_mu_->
valeurs(), champ_rho_faces_->valeurs());
934 ref_equation.valeur().get_post_process_hydro_forces();
938 "vitesse_stokes_th",
"m/s",
940 velocity_field_Stokes_th_);
941 champs_compris.add(velocity_field_Stokes_th_.valeur());
945 "pression_stokes_th",
"pa",
947 pressure_field_Stokes_th_);
948 champs_compris.add(pressure_field_Stokes_th_.valeur());
960 FT_disc_calculer_champs_rho_mu_nu_mono(zdis, phase_0, champ_rho_elem_, champ_mu_, champ_nu_, champ_rho_faces_);
973 assembleur_pression()->assembler_rho_variable(
matrice_pression_, champ_rho_faces_.valeur());
979 DoubleTab& secmem = variables_internes().second_membre_projection->valeurs();
983 assembleur_pression_->modifier_secmem(secmem);
990 assembleur_pression_->modifier_solution(
la_pression->valeurs());
992 DoubleTab& gradP = variables_internes().gradient_pression->valeurs();
994 solveur_masse->appliquer(gradP);
999 const DoubleTab& rho_faces = champ_rho_faces_->valeurs();
1003 for (i = 0; i < n; i++)
1004 for (j = 0; j < m; j++)
1005 tab_vitesse(i, j) -= gradP(i, j) / rho_faces(i);
1010 if (le_traitement_particulier)
1012 if (le_traitement_particulier->support_ok())
1013 le_traitement_particulier->associer_champ_masse_volumique(champ_rho_faces_.valeur());
1014 le_traitement_particulier->preparer_calcul_particulier();
1023 return variables_internes().is_penalized;
1028 return variables_internes().shift_secmem2_;
1033 return variables_internes().new_mass_source_;
1038 return variables_internes().ai->valeurs();
1043 return variables_internes().ai->valeurs();
1048 return variables_internes().mpoint->valeurs();
1053 return variables_internes().mpoint->valeurs();
1066 champ_rho_faces_->mettre_a_jour(temps);
1071 particles_eulerian_id_number_post_->mettre_a_jour(temps);
1072 DoubleTab& tab = particles_eulerian_id_number_post_->valeurs();
1103 const int nb_faces = domaine_vf.
nb_faces();
1106 assert(champ.valeurs().dimension(0) == nb_faces);
1113 ArrOfDouble potentiel_sommets;
1122 const double sigma = fluide_dipha.
sigma();
1129 const double clipping_courbure_max = variables_internes().clipping_courbure_interface;
1130 int clip_counter = 0;
1131 for (i = 0; i < n; i++)
1133 double c = courbure_sommets[i];
1137 if (std::fabs(c) > clipping_courbure_max)
1140 c = ((c > 0) ? 1. : -1.) * clipping_courbure_max;
1142 potentiel_sommets[i] = c * sigma;
1147 Cerr <<
"Navier_Stokes_FT_Disc::calculer_champ_forces_superficielles : clip_count " << clip_counter << finl;
1153 if (
milieu().a_gravite())
1157 const double delta_rho = rho_1 - rho_0;
1163 Cerr <<
"Error for the method calculer_champ_forces_superficielles\n";
1164 Cerr <<
"gravite.dimension(1) != Objet_U::dimension" << finl;
1167 const DoubleTab& sommets = maillage.
sommets();
1169 for (i = 0; i < n; i++)
1172 for (
int j = 0; j < dim; j++)
1173 p += sommets(i, j) * gravite(0, j);
1178 double px = sommets(i, 0);
1185 double py = sommets(i, 1);
1191 p += sqrt(dx * dx + dy * dy) * pente;
1194 potentiel_sommets[i] -= p * delta_rho;
1201 DoubleTab poids(potentiel_elements.
valeurs());
1204 const IntTab& facettes = maillage.
facettes();
1206 DoubleTab& valeurs_potentiel_elements = potentiel_elements.
valeurs();
1210 valeurs_potentiel_elements = 0.;
1216 const ArrOfInt& index_facette_elem = intersections.
index_facette();
1217 double pot[3] = { 0., 0., 0. };
1222 for (fa7 = 0; fa7 < nb_facettes; fa7++)
1225 pot[0] = potentiel_sommets[facettes(fa7, 0)];
1226 pot[1] = potentiel_sommets[facettes(fa7, 1)];
1228 pot[2] = potentiel_sommets[facettes(fa7, 2)];
1230 int index = index_facette_elem[fa7];
1231 const double surface_facette = surface_facettes[fa7];
1238 for (i = 0; i < 3; i++)
1241#ifdef AVEC_BUG_SURFACES
1242 const double surf = data.surface_intersection_;
1250 valeurs_potentiel_elements(element) += p;
1251 poids(element) += surf;
1260 if (champ.valeurs().line_size() > 1)
1267 const int nb_elements = poids.
dimension(0);
1268 const IntTab& face_voisins = le_dom_dis->face_voisins();
1270 const IntTab& elem_faces = domainevf.
elem_faces();
1271 const int nb_faces_par_element = elem_faces.
line_size();
1272 DoubleVect copie_valeurs_potentiel_elements(valeurs_potentiel_elements);
1273 DoubleVect copie_poids(poids);
1274 for (element = 0; element < nb_elements; element++)
1276 double potential = 0.;
1279 for (i_face = 0; i_face < nb_faces_par_element; i_face++)
1281 const int face = elem_faces(element, i_face);
1282 const int elem_voisin_0 = face_voisins(face, 0);
1283 const int elem_voisin_1 = face_voisins(face, 1);
1284 const int elem_voisin = elem_voisin_0 + elem_voisin_1 - element;
1285 if (elem_voisin >= 0)
1287 potential += copie_valeurs_potentiel_elements(elem_voisin);
1288 p += copie_poids(elem_voisin);
1291 const double old_weight = copie_poids(element);
1293 if (p > 0. && old_weight == 0.)
1297 static double reduction_factor = 0.1;
1298 potential = potential * reduction_factor;
1299 p = p * reduction_factor;
1301 valeurs_potentiel_elements(element) = potential;
1307 Debog::verifier(
"Navier_Stokes_FT_Disc::calculer_champ_forces_superficielles poids:", poids);
1313 interfacial_area = poids;
1317 DoubleTab& valeurs_potentiel_faces = potentiel_faces.
valeurs();
1318 valeurs_potentiel_faces = 0.;
1319 const DoubleTab& valeurs_potentiel_elements = potentiel_elements.
valeurs();
1320 const int nb_faces_pot = valeurs_potentiel_faces.
dimension(0);
1321 const IntTab& face_voisins = le_dom_dis->face_voisins();
1322 for (face = 0; face < nb_faces_pot; face++)
1327 for (
int i = 0; i < 2; i++)
1329 int element = face_voisins(face, i);
1333 p += poids(element);
1334 pot += valeurs_potentiel_elements(element);
1338 valeurs_potentiel_faces(face) = pot / p;
1341 Debog::verifier(
"Navier_Stokes_FT_Disc::calculer_champ_forces_superficielles valeurs_potentiel_faces:", valeurs_potentiel_faces);
1347 const DoubleTab& valeurs_potentiel_faces = potentiel_faces.
valeurs();
1348 const DoubleTab& valeurs_gradient_i = gradient_indicatrice.
valeurs();
1349 DoubleTab& valeurs_champ = champ.valeurs();
1350 const int nb_compo = valeurs_champ.
line_size();
1352 for (
int face = 0; face < nb_faces; face++)
1354 const double p = valeurs_potentiel_faces(face);
1355 for (
int i = 0; i < nb_compo; i++)
1356 valeurs_champ(face, i) = valeurs_gradient_i(face, i) * p;
1360 Debog::verifier(
"Navier_Stokes_FT_Disc::calculer_champ_forces_superficielles valeurs_champ:", valeurs_champ);
1364double compute_indic_ghost(
const int elem,
const int num_face,
const double indic,
const int normale_sortante_au_domaine,
const Domaine_VF& domVF,
const Maillage_FT_Disc& maillage)
1366 double indic_ghost = 0.;
1367 ArrOfDouble normale(3), normale_face(3);
1369 if (est_egal(face_surface, 0.))
1375 normale_face[i] = domVF.
face_normales(num_face, i) / face_surface;
1377 if (est_egal(norm, 0.))
1381 const double prodscal = normale_sortante_au_domaine * dotproduct_array(normale, normale_face);
1382 double val = 1. / sqrt(2.);
1383 if (prodscal < -val)
1385 else if (prodscal < 0)
1387 indic_ghost = indic * (1 + prodscal / val);
1388 else if (prodscal < val)
1389 indic_ghost = indic + (1. - indic) * (prodscal / val);
1410#include<Neumann_sortie_libre.h>
1411#include<Dirichlet.h>
1412#include<Dirichlet_homogene.h>
1413#include<Periodique.h>
1415#include<Sortie_libre_rho_variable.h>
1418 if (gradient_i.
que_suis_je() ==
"Champ_Fonc_Face")
1426 const Domaine& domaine = domaine_vf.
domaine();
1433 DoubleTab& indic_p1b = variables_internes().indicatrice_p1b->valeurs();
1437 Cerr <<
"The method Navier_Stokes_FT_Disc::calculer_gradient_indicatrice is developped" << finl;
1438 Cerr <<
"only for an indicatrice field discretized like P0+P1 for the 2D dimension case." << finl;
1439 Cerr <<
"Please change the discretization." << finl;
1442 if (
dimension == 3 && indic_p1b.
size_totale() != nb_elem_tot + domaine.nb_som_tot() + domaine.nb_aretes_tot() && indic_p1b.
size_totale() != nb_elem_tot + domaine.nb_som_tot())
1444 Cerr <<
"The method Navier_Stokes_FT_Disc::calculer_gradient_indicatrice is developped" << finl;
1445 Cerr <<
"only for an indicatrice field discretized like P0+P1 or P0+P1+Pa for the 3D dimension case." << finl;
1446 Cerr <<
"Please change the discretization." << finl;
1458 for (i = 0; i < nb_elem_tot; i++)
1460 indic_p1b(i) = indicatrice.
valeurs()(i);
1469 if (ghost_correction)
1472 const DoubleTab& inco = indicatrice.
valeurs();
1473 DoubleTab& resu = gradient_i.
valeurs();
1484 int ndeb, nfin, num_face;
1485 for (
int n_bord = 0; n_bord < zvf.
nb_front_Cl(); n_bord++)
1500 for (num_face = ndeb; num_face < nfin; num_face++)
1502 n0 = face_voisins(num_face, 0);
1503 n1 = face_voisins(num_face, 1);
1504 if (!est_egal(n0, n1))
1506 Cerr <<
"Periodic boundary condition with FT is not supported yet." << finl;
1509 coef = face_surfaces(num_face);
1510 for (
int k = 0; k < nbdimr; k++)
1512 const int normale_sortante_au_domaine = (n0 == -1) ? 1 : -1;
1513 const double dSk = normale_sortante_au_domaine * zvf.
face_normales(num_face, k);
1516 Cerr <<
"Check if sign of nk is compatible with the expression" << finl;
1518 Cerr <<
"Check if sign of nk is compatible with the expression" << finl;
1519 Cerr <<
"nk=" << nk << finl;
1520 Cerr <<
"dSk=" << dSk << finl;
1521 Cerr <<
"num_face=" << num_face << finl;
1523 Cerr <<
"code to validate" << finl;
1525 resu(num_face, k) = dSk * (inco(n1) - inco(n0));
1529 else if (sub_type(
Symetrie, la_cl.valeur())) { }
1536 const ArrOfInt& index_elem = intersections.
index_elem();
1537 for (num_face = ndeb; num_face < nfin; num_face++)
1539 n0 = face_voisins(num_face, 0);
1540 n1 = face_voisins(num_face, 1);
1541 int elem = n0 + n1 + 1;
1543 for (
int k = 0; k < nbdimr; k++)
1544 resu(num_face, k) = 0.;
1545 if (index_elem[elem] < 0)
1549 const double indic = inco(elem);
1550 int normale_sortante_au_domaine = (n0 == -1) ? -1 : 1;
1551 const double indic_ghost = compute_indic_ghost(elem, num_face, indic, normale_sortante_au_domaine, zvf, maillage);
1554 coef = face_surfaces(num_face);
1557 resu(num_face) = coef * normale_sortante_au_domaine * (indic_ghost - indic);
1562 for (
int k = 0; k < nbdimr; k++)
1564 normale_sortante_au_domaine = 1;
1565 const double dSk = normale_sortante_au_domaine * zvf.
face_normales(num_face, k);
1568 Cerr <<
"Check if sign of nk is compatible with the expression" << finl;
1569 Cerr <<
"nk=" << dSk / coef << finl;
1570 Cerr <<
"num_face=" << num_face << finl;
1573 resu(num_face, k) = dSk * (indic_ghost - indic);
1593 for (
int n_bord = 0; n_bord < zvf.
nb_front_Cl(); n_bord++)
1601 const int nfin = ndeb + le_bord.
nb_faces();
1606 const int nb_faces = elem_faces.
dimension(1);
1607 for (
int num_face = ndeb; num_face < nfin; num_face++)
1609 const int elem = face_voisins(num_face, 0) + face_voisins(num_face, 1) + 1;
1610 int idx_face_de_lelem = 0;
1611 for (idx_face_de_lelem = 0; idx_face_de_lelem < nb_faces; idx_face_de_lelem++)
1613 if (elem_faces(elem, idx_face_de_lelem) == num_face)
1616 if (nb_faces == idx_face_de_lelem)
1618 Cerr <<
"Face is not found!! " << finl;
1621 const int num_face_den_face = elem_faces(elem, (idx_face_de_lelem +
Objet_U::dimension) % nb_faces);
1628 for (
int c = 0; c < u0.
line_size(); c++)
1629 u0(num_face, c) = u0(num_face_den_face, c);
1635int get_num_face_den_face(
const int num_face,
const int elem,
const IntTab& elem_faces)
1637 const int nb_faces = elem_faces.
dimension(1);
1638 int idx_face_de_lelem = 0;
1639 for (idx_face_de_lelem = 0; idx_face_de_lelem < nb_faces; idx_face_de_lelem++)
1641 if (elem_faces(elem, idx_face_de_lelem) == num_face)
1644 if (nb_faces == idx_face_de_lelem)
1646 Cerr <<
"Face is not found!! " << finl;
1649 const int num_face_den_face = elem_faces(elem, (idx_face_de_lelem +
Objet_U::dimension) % nb_faces);
1650 return num_face_den_face;
1665 DoubleTab& u0 = future_or_past ? champ_u0.
futur() : champ_u0.
valeurs();
1671 const double rho_0 = tab_rho_phase_0(0, 0);
1672 const double rho_1 = tab_rho_phase_1(0, 0);
1674 const double un_sur_rho_0 = 1. / rho_0;
1675 const double un_sur_rho_1 = 1. / rho_1;
1682 const int nn = variables_internes().second_membre_projection->valeurs().
dimension(0);
1687 if (variables_internes().ref_equation_mpoint_)
1689 const DoubleTab& mp = variables_internes().ref_equation_mpoint_->get_mpoint();
1691 if (!variables_internes().mpoint_inactif)
1694 if (variables_internes().ref_equation_mpoint_vap_)
1696 const DoubleTab& mpv = variables_internes().ref_equation_mpoint_vap_->get_mpoint();
1698 if (!variables_internes().mpointv_inactif)
1705 if ((variables_internes().new_mass_source_))
1707 assert(future_or_past ==
false);
1709 const DoubleTab& interfacial_area = variables_internes().ai->valeurs();
1710 const Champ_base& ch_indic = refeq_transport->get_indicatrice();
1711 const DoubleTab& indicatrice = ch_indic.
valeurs();
1713 const IntTab& face_voisins = domaine_vf.
face_voisins();
1714 const int nb_faces = face_voisins.
dimension(0);
1715 const int nb_elem_reel = interfacial_area.
size_reelle();
1717 const DoubleTab& xp = domaine_vf.
xp();
1718 const DoubleTab& xv = domaine_vf.
xv();
1721 DoubleTab u_aux(u0);
1730 Cerr <<
"Using option new_mass_source is not possible yet in VEF. Contact us. " << finl;
1732 for (
int face = 0; face < nb_faces; face++)
1733 for (
int j = 0; j < dim; j++)
1743 for (
int face = 0; face < nb_faces; face++)
1745 const int dir = orientation[face];
1747 const int e1 = face_voisins(face, 0);
1748 const int e2 = face_voisins(face, 1);
1749 const double xf = xv(face, dir);
1759 double nb_elem_effective = 0.;
1761 if (e1 >= 0 && e1< nb_elem_reel )
1763 const double nx = -normale_elements(e1, dir);
1765 const double ai = interfacial_area(e1);
1767 if ((fabs(ai) > DMINFLOAT) && (fabs(nx) > DMINFLOAT))
1772 nb_elem_effective += 1.;
1773 const double d = (xf - xp(e1, dir)) * nx;
1774 switch(phase_pilote)
1784 xx = - un_sur_rho_1 * mpoint[e1] * nx;
1785 xx_aux = - un_sur_rho_0 * mpoint[e1] * nx;
1789 const double un_sur_rho = (d > 0.) ? un_sur_rho_0 : un_sur_rho_1;
1790 xx = - un_sur_rho * mpoint[e1] * nx;
1801 xx = (un_sur_rho_1 - un_sur_rho_0)* mpoint[e1] * nx;
1806 const double p = (d > 0.) ? 0. : (un_sur_rho_1 - un_sur_rho_0);
1807 xx = p * mpoint[e1] * nx;
1819 xx_aux = (un_sur_rho_0 - un_sur_rho_1)* mpoint[e1] * nx;
1823 const double p = (d > 0.) ? (un_sur_rho_0 - un_sur_rho_1) : 0.;
1824 xx = p * mpoint[e1] * nx;
1830 Cerr <<
"Error for the method Navier_Stokes_FT_Disc::calculer_delta_u_interface phase_pilote" << finl;
1836 if (e2 >= 0 && e1< nb_elem_reel)
1838 const double nx = -normale_elements(e2, dir);
1840 const double ai = interfacial_area(e2);
1841 if ((fabs(ai) > DMINFLOAT) && (fabs(nx) > DMINFLOAT))
1843 nb_elem_effective += 1.;
1845 const double d = (xf - xp(e2, dir)) * nx;
1846 switch(phase_pilote)
1856 xx += -un_sur_rho_1 * mpoint[e2] * nx;
1857 xx_aux += -un_sur_rho_0 * mpoint[e2] * nx;
1861 const double un_sur_rho = (d > 0.) ? un_sur_rho_0 : un_sur_rho_1;
1862 xx += -un_sur_rho * mpoint[e2] * nx;
1873 xx += (un_sur_rho_1 - un_sur_rho_0) * mpoint[e2] * nx;
1878 const double p = (d > 0.) ? 0. : (un_sur_rho_1 - un_sur_rho_0);
1879 xx += p * mpoint[e2] * nx;
1891 xx_aux += (un_sur_rho_0 - un_sur_rho_1) * mpoint[e2] * nx;
1895 const double p = (d > 0.) ? (un_sur_rho_0 - un_sur_rho_1) : 0.;
1896 xx += p * mpoint[e2] * nx;
1902 Cerr <<
"Error for the method Navier_Stokes_FT_Disc::calculer_delta_u_interface phase_pilote" << finl;
1908 xx = est_egal(nb_elem_effective, 0.) ? 0. : xx/ nb_elem_effective;
1909 xx_aux = est_egal(nb_elem_effective, 0.) ? 0. : xx_aux/ nb_elem_effective;
1911 u_aux(face) = xx_aux;
1923 const ArrOfInt& index_facette = intersections.
index_facette();
1926 const int nb_faces_per_elem = elem_faces.
line_size();
1927 for (
int facette = 0; facette < mesh.
nb_facettes(); facette++)
1929 int index = index_facette[facette];
1936 for (
int idx_face_de_lelem = 0; idx_face_de_lelem < nb_faces_per_elem; idx_face_de_lelem++)
1938 const int face_of_elem = elem_faces(elem, idx_face_de_lelem);
1940 const int e1 = face_voisins(face_of_elem, 0) + face_voisins(face_of_elem, 1) - elem;
1941 if ((e1 >= 0) && (fabs(interfacial_area(e1)) < DMINFLOAT))
1945 const int num_face_den_face = get_num_face_den_face(face_of_elem, e1, elem_faces);
1946 if (fabs(u0(num_face_den_face)) < DMINFLOAT)
1952 u0(num_face_den_face) = est_egal(indicatrice(e1), 0.) ? u_aux(face_of_elem) : u0(face_of_elem);
1954 u0(num_face_den_face) = u0(face_of_elem);
1969 assert(future_or_past ==
false);
1974 for (
int i = 0; i < n; i++)
1980 const double div_n = phi(i);
1983 const double mp = mpoint[i];
1992 p = d * (1. - 0.5 * div_n * d) * mp;
1996 p = d * (1. - 0.5 * div_n * d + div_n * div_n * d * d / 6.) * mp;
1999 Cerr <<
"Error for the method Navier_Stokes_FT_Disc::calculer_delta_u_interface ordre" << finl;
2002 switch(phase_pilote)
2018 p *= (un_sur_rho_0 - un_sur_rho_1);
2024 p *= (un_sur_rho_1 - un_sur_rho_0);
2029 Cerr <<
"Error for the method Navier_Stokes_FT_Disc::calculer_delta_u_interface phase_pilote" << finl;
2046 Cerr <<
"Error for the method Navier_Stokes_FT_Disc::calculer_delta_u_interface\n" <<
" Non code pour " << champ_u0.
que_suis_je() << finl;
2054 const IntTab& face_voisins = domaine_vf.
face_voisins();
2055 const int nb_faces = domaine_vf.
nb_faces();
2057 for (
int i = 0; i < nb_faces; i++)
2059 for (
int j = 0; j < 2; j++)
2061 const int elem = face_voisins(i, j);
2062 if (elem >= 0 && dist(elem) < -1e20)
2071 solveur_masse->appliquer(u0);
2077 DoubleTab secmem2_loc(secmem2);
2078 DoubleTab secmem2_tmp(secmem2);
2097 DoubleTab nb_voisions_vap(secmem2);
2098 nb_voisions_vap = 0.;
2103 const IntTab& face_voisins = domaine_vf.
face_voisins();
2104 const IntTab& elem_faces = domaine_vf.
elem_faces();
2107 const int nb_elem = elem_faces.
dimension(0);
2109 ArrOfInt list_bc_elems;
2110 ArrOfInt list_bc_faces;
2111 for (
int i=0; i< nb_elem; i++)
2113 if (!est_egal(indicatrice[i],0) && !est_egal(indicatrice[i],1))
2115 secmem2_loc[i] = secmem2[i];
2116 const int nb_voisins = elem_faces.
dimension(1);
2117 for (
int iv=0; iv < nb_voisins; iv++)
2119 const int num_face2 = elem_faces(i,iv);
2120 int elem_voisin = face_voisins(num_face2, 0) + face_voisins(num_face2, 1) - i;
2128 if ( est_egal(indicatrice[elem_voisin],0) )
2130 nb_voisions_vap[i] += 1;
2140 ArrOfInt list_bc_elems_nv;
2143 for (
int iv=0; iv < list_bc_elems.
size_array(); iv++)
2145 const int elem_loc = list_bc_elems[iv];
2146 if (est_egal(nb_voisions_vap[elem_loc],0))
2148 const int face_loc = list_bc_faces[iv];
2149 const int dir = orientation[face_loc];
2150 const double nx = normale_elements(elem_loc, 1-dir);
2156 int num_face_next = elem_faces(elem_loc,iface);
2157 int elem = elem_loc;
2159 bool found_elem = 0;
2161 for (
int count = 0; count<5; count++)
2163 elem = face_voisins(num_face_next, 0) + face_voisins(num_face_next, 1) - elem;
2168 if (!est_egal(nb_voisions_vap[elem],0))
2170 secmem2_loc[elem] += secmem2_loc[elem_loc];
2171 secmem2_loc[elem_loc] = 0.;
2185 for (
int iv=0; iv < list_bc_elems_nv.
size_array(); iv++)
2187 const int elem_loc = list_bc_elems_nv[iv];
2188 nb_voisions_vap[elem_loc] += 1;
2199 double sum_loc = 0.;
2200 double sum_orig = 0.;
2204 for (
int i=0; i< nb_elem; i++)
2206 sum_loc += secmem2_loc[i];
2207 sum_orig += secmem2[i];
2213 if (abs(sum_loc-sum_orig) > 0.01*abs(sum_orig) )
2215 Cerr<<
"Balance of seconde memeber 2: "<<finl;
2216 Cerr<<
" sum been pre-restributed-0: "<< sum_loc <<
" origianl sum: "<<sum_orig<<finl;
2217 Process::exit(
"[Navier_Stokes_FT_Disc::shift_secmem2]: !!! shift second member failed");
2223 for (
int i=nb_reel; i<nb_tot; i++)
2224 secmem2_loc[i] = 0.;
2228 for (
int i=0; i< nb_elem; i++)
2230 if (!est_egal(indicatrice[i],0) && !est_egal(indicatrice[i],1))
2232 if ( est_egal(nb_voisions_vap[i],0) && !est_egal(secmem2_loc[i],0))
2234 int nb_voisin_mix_usefuel = 0;
2235 ArrOfInt list_useful_elems;
2236 const int nb_voisins = elem_faces.
dimension(1);
2237 for (
int iv=0; iv < nb_voisins; iv++)
2239 const int num_face2 = elem_faces(i,iv);
2240 int elem_voisin = face_voisins(num_face2, 0) + face_voisins(num_face2, 1) - i;
2244 if (!est_egal(nb_voisions_vap[elem_voisin],0) )
2246 nb_voisin_mix_usefuel += 1;
2252 if (est_egal(nb_voisin_mix_usefuel,0))
2254 Process::exit(
"[Navier_Stokes_FT_Disc::shift_secmem2]: !!! ALL neigher of one elem has no vap neighers" );
2257 for (
int iv=0; iv < list_useful_elems.
size_array(); iv++)
2259 const int elem_loc = list_useful_elems[iv];
2260 secmem2_loc[elem_loc] += secmem2_loc[i]/nb_voisin_mix_usefuel;
2274 for (
int i=0; i< nb_elem; i++)
2277 sum_loc += secmem2_loc[i];
2278 if ( (!est_egal(secmem2_loc[i],0)) && est_egal(nb_voisions_vap[i],0))
2280 Cerr<<
" secmem2_loc non nulle: "<< secmem2_loc[i] <<
" nb_voisions_vap "<<nb_voisions_vap[i]<<finl;
2281 Process::exit(
"[Navier_Stokes_FT_Disc::shift_secmem2]: !!! shift second member failed");
2287 if (abs(sum_loc-sum_orig) > 0.01*abs(sum_orig) )
2289 Cerr<<
"Balance of seconde memeber 2: "<<finl;
2290 Cerr<<
" sum been pre-restributed-1: "<< sum_loc <<
" origianl sum: "<<sum_orig<<finl;
2291 Process::exit(
"[Navier_Stokes_FT_Disc::shift_secmem2]: !!! shift second member failed");
2310 for (
int i=0; i< nb_elem; i++)
2312 if (!est_egal(indicatrice[i],0) && !est_egal(indicatrice[i],1))
2314 if ( !est_egal(nb_voisions_vap[i],0) )
2316 const int nb_voisins = elem_faces.
dimension(1);
2317 for (
int iv=0; iv < nb_voisins; iv++)
2319 const int num_face2 = elem_faces(i,iv);
2320 int elem_voisin = face_voisins(num_face2, 0) + face_voisins(num_face2, 1) - i;
2323 if (est_egal(indicatrice[elem_voisin],0) )
2325 secmem2_tmp[elem_voisin] += secmem2_loc[i]/nb_voisions_vap[i];
2333 for (
int iv=0; iv < list_bc_elems_nv.
size_array(); iv++)
2335 const int elem_loc = list_bc_elems_nv[iv];
2336 secmem2_tmp[elem_loc] += secmem2_loc[elem_loc]/nb_voisions_vap[elem_loc];
2342 double sum_tmp = 0.;
2346 for (
int i=0; i< nb_elem; i++)
2348 sum_tmp += secmem2_tmp[i];
2354 if (abs(sum_tmp-sum_orig) > 0.01*abs(sum_orig) )
2356 Cerr<<
"Balance of seconde memeber 2: "<<finl;
2357 Cerr<<
" sum been restributed: "<< sum_tmp <<
" origianl sum: "<<sum_orig<<finl;
2358 Process::exit(
"[Navier_Stokes_FT_Disc::shift_secmem2]: !!! shift second member failed");
2361 secmem2 = secmem2_tmp;
2365double calculer_indicatrice_face_privilegie_pure(
const DoubleTab& indicatrice,
const IntTab& face_voisins,
const int num_face)
2367 const int elem0 = face_voisins(num_face, 0);
2368 const int elem1 = face_voisins(num_face, 1);
2369 double indic_0 = (elem0 >= 0) ? indicatrice[elem0] : indicatrice[elem1];
2370 double indic_1 = (elem1 >= 0) ? indicatrice[elem1] : indicatrice[elem0];
2373 if (indic_0 == 0. || indic_0 == 1.)
2375 if (indic_1 == 0. || indic_1 == 1.)
2377 const double indic_face = (indic_0 + indic_1) * 0.5;
2381double calculer_indicatrice_face_based_on_ai(
const DoubleTab& indicatrice,
const DoubleTab& indicatrice_faces,
const IntTab& face_voisins,
const Domaine_VF& domaine_vf,
2382 const DoubleTab& interfacial_area,
const DoubleTab& normale_elements,
const int face,
const int dim)
2384 double indic_face = 0.;
2386 for (v = 0; v < 2; v++)
2388 const int elem = face_voisins(face, v);
2392 const double indic = indicatrice[elem];
2394 if (indic <= 5e-3 || indic >= 1. - 5e-3)
2396 indic_face = 1 - indic;
2403 const double ai = interfacial_area(elem);
2404 if (fabs(ai) > DMINFLOAT)
2409 for (
int j = 0; j < dim; j++)
2412 const double nx = normale_elements(elem, j);
2417 indic_face += 1 - x;
2419 Cerr <<
"Never tested. To be verified. It should depend on a scalar product with the vect (xp-xv)" << finl;
2428 const int dir = orientation[face];
2429 const double nx = normale_elements(elem, dir);
2433 x = ai / surface * nx;
2436 indic_face += 1 - x;
2444 indic_face += (1. - indicatrice_faces[face]);
2450 Cerr <<
" WTF, c'est impossible" << finl;
2458 const int elem_voisin = face_voisins(face, 1 - v);
2459 const double indic = indicatrice[elem_voisin];
2460 indic_face = 1 - indic;
2472 if (indic_face > 1.)
2477void correct_indicatrice_face_bord(
const int num_face,
const Maillage_FT_Disc& maillage,
const Domaine_VF& zvf,
const IntTab& face_voisins,
const DoubleTab& indicatrice,
const bool privilegie_pure,
2481 const int n0 = face_voisins(num_face, 0);
2482 const int n1 = face_voisins(num_face, 1);
2483 if ((n0 == -1) or (n1 == -1))
2486 const int outward_normal = (n0 == -1) ? -1 : 1;
2487 const int elem = n0 + n1 + 1;
2488 const double indic_ghost = compute_indic_ghost(elem, num_face, indicatrice(elem), outward_normal, zvf, maillage);
2489 indic_face = indic_ghost;
2490 if ((privilegie_pure) && (est_egal(indicatrice(elem), 1.) || est_egal(indicatrice(elem), 0.)))
2492 indic_face = indicatrice(elem);
2508 const double delta_rho = rho_0 - rho_1;
2510 double rho_0_sur_delta_rho = 0.;
2512 rho_0_sur_delta_rho = rho_0 / delta_rho;
2523 DoubleTab tmp(tab_vitesse);
2524 const int dim = tab_vitesse.
line_size();
2529 resu.
copy(variables_internes().second_membre_projection->valeurs(), RESIZE_OPTIONS::NOCOPY_NOINIT);
2546 if (variables_internes().ref_equation_mpoint_ || variables_internes().ref_equation_mpoint_vap_)
2551 tmp += variables_internes().vitesse_jump0_->valeurs();
2560 if (variables_internes().ref_equation_mpoint_ || variables_internes().ref_equation_mpoint_vap_)
2565 tmp -= variables_internes().delta_u_interface->valeurs();
2574 resu[i] *= indicatrice[i];
2584 tmp += variables_internes().vitesse_jump1_->valeurs();
2589 switch(variables_internes_.type_interpol_indic_pour_dI_dt_)
2594 for (
int i = 0; i < n; i++)
2596 double indic_face = calculer_indicatrice_face_privilegie_pure(indicatrice, face_voisins, i);
2597 if (ghost_correction)
2598 correct_indicatrice_face_bord(i, maillage, domVF, face_voisins, indicatrice,
true , indic_face);
2599 const double x = rho_0_sur_delta_rho - indic_face;
2600 for (
int j = 0; j < dim; j++)
2607 for (
int i = 0; i < n; i++)
2609 double indic_face = calculer_indicatrice_face_privilegie_pure(indicatrice, face_voisins, i);
2610 if (ghost_correction)
2611 correct_indicatrice_face_bord(i, maillage, domVF, face_voisins, indicatrice,
true , indic_face);
2612 const double x = -indic_face;
2613 for (
int j = 0; j < dim; j++)
2621 refeq_transport->update_indicatrice_faces();
2622 const DoubleTab& indicatrice_faces = refeq_transport->get_indicatrice_faces().valeurs();
2623 for (
int i = 0; i < n; i++)
2625 double indic_face = indicatrice_faces(i);
2626 if (ghost_correction)
2627 correct_indicatrice_face_bord(i, maillage, domVF, face_voisins, indicatrice,
false, indic_face);
2628 const double x = rho_0_sur_delta_rho - indic_face;
2629 for (
int j = 0; j < dim; j++)
2636 refeq_transport->update_indicatrice_faces();
2637 const DoubleTab& indicatrice_faces = refeq_transport->get_indicatrice_faces().valeurs();
2638 for (
int i = 0; i < n; i++)
2640 double indic_face = indicatrice_faces(i);
2641 if (ghost_correction)
2642 correct_indicatrice_face_bord(i, maillage, domVF, face_voisins, indicatrice,
false, indic_face);
2643 const double x = -indic_face;
2644 for (
int j = 0; j < dim; j++)
2653 refeq_transport->update_indicatrice_faces();
2654 const DoubleTab& indicatrice_faces = refeq_transport->get_indicatrice_faces().valeurs();
2657 Cerr <<
" The interpolation of indicatrice to faces in calculer_dI_dt is based on the interfacial area" <<
" and on the normal to the interface." << finl;
2660 const DoubleTab& interfacial_area = variables_internes().ai->valeurs();
2663 const DoubleTab& xp = domaine_vf.
xp();
2664 const DoubleTab& xv = domaine_vf.
xv();
2668 for (
int face = 0; face < n; face++)
2670 double indic_face = calculer_indicatrice_face_based_on_ai(indicatrice, indicatrice_faces, face_voisins, domaine_vf, interfacial_area, normale_elements, face, dim);
2671 if (ghost_correction)
2672 correct_indicatrice_face_bord(face, maillage, domVF, face_voisins, indicatrice,
false, indic_face);
2675 const double val = 1.-indicatrice_faces[face];
2676 if (fabs(indic_face-val)>DMINFLOAT)
2678 const int elem0 = face_voisins(face, 0);
2679 const int elem1 = face_voisins(face, 1);
2680 double indic_0 = (elem0 >= 0) ? indicatrice[elem0] : indicatrice[elem1];
2681 double indic_1 = (elem1 >= 0) ? indicatrice[elem1] : indicatrice[elem0];
2683 Cerr <<
"xp0["<< elem0<<
"]: " << xp(elem0, 0) <<
" " << xp(elem0, 1) <<
" " << finl;
2685 Cerr <<
"xp0: bord!" <<finl;
2687 Cerr <<
"xp1["<< elem1<<
"]: " << xp(elem1, 0) <<
" " << xp(elem1, 1) <<
" " << finl;
2689 Cerr <<
"xp1: bord!" <<finl;
2691 Cerr <<
"xv: " << xv(face, 0) <<
" " << xv(face, 1) <<
" " << finl;
2692 Cerr <<
"voisins (ou ghost): " << indic_0 <<
" " << indic_1 << finl;
2693 Cerr <<
"GB whats up?face="<< face <<
" indic / val / diff " << indic_face <<
" " << val <<
" " << indic_face-val << finl;
2697 for (
int j = 0; j < dim; j++)
2698 tmp(face, j) *= indic_face;
2703 Cerr <<
" Navier_Stokes_FT_Disc::calculer_dI_dt \n" <<
" unknown case?" << finl;
2734 switch(variables_internes_.OutletCorrection_pour_dI_dt_)
2750 for (
int n_bord = 0; n_bord < zvdf.
nb_front_Cl(); n_bord++)
2766 for (
int num_face = ndeb; num_face < nfin; num_face++)
2768 const int n0 = face_voisins(num_face, 0);
2769 const int n1 = face_voisins(num_face, 1);
2770 const int elem = n0 + n1 + 1;
2771 const double indic = indicatrice(elem);
2772 if (indic * (1 - indic) > 1e-6)
2774 const double coef = face_surfaces(num_face);
2779 for (
int j = 0; j < dim; j++)
2781 const int outward_normal = (n0 == -1) ? -1 : 1;
2782 double flux_bord_calcule_par_operateur_div = 0.;
2783 flux_bord_calcule_par_operateur_div = outward_normal * coef * tmp(num_face, j);
2784 resu(elem) -= flux_bord_calcule_par_operateur_div;
2800 Cerr <<
"unexpected" << finl;
2806 assert(nb_elem == dI_dt.
size());
2819 Cerr <<
"[BEFORE-PCH] Locally, the maximum of dI_dt is : " << dI_dt.
mp_max_abs_vect() << finl;
2822 for (
int i=0; i< nb_elem; i++)
2824 Cerr <<
"[BEFORE-PCH] " << temps <<
" The sum is : " << sum <<
" [not valid in //]" << finl;
2828 switch(variables_internes_.type_interpol_indic_pour_dI_dt_)
2841 Cerr <<
"Checking if secmem2 is correctly filled in that case. Check it if you need it..." <<finl;
2843 DoubleTab& secmem2 = variables_internes().second_membre_projection_jump_.valeurs();
2855 const double rho_phase_0 = tab_rho_phase_0(0,0);
2856 const double rho_phase_1 = tab_rho_phase_1(0,0);
2857 const double jump_inv_rho = 1./rho_phase_1 - 1./rho_phase_0;
2859 const DoubleTab& interfacial_area = variables_internes().ai->valeurs();
2862 DoubleTab mpoint = variables_internes().ref_equation_mpoint_->get_mpoint();
2863 if (variables_internes().ref_equation_mpoint_vap_)
2866 const DoubleTab& mpointv = variables_internes().ref_equation_mpoint_vap_->get_mpoint();
2867 for (
int elem = 0; elem < nb_elem; elem++)
2868 mpoint[elem] += mpointv[elem];
2870 for (
int elem = 0; elem < nb_elem; elem++)
2872 double diff = (secmem2[elem] - jump_inv_rho*interfacial_area[elem]*mpoint[elem]);
2873 if (fabs(diff)>DMINFLOAT)
2875 Cerr <<
"Problem, secmem2 is not filled properly in that case? "
2876 <<
"elem= " << elem <<
" diff=" << diff <<finl;
2882 if ((
bool(variables_internes().ref_equation_mpoint_)) && !variables_internes().mpoint_inactif)
2886 const double un_sur_rho_0 = 1. / rho_0;
2890 const DoubleTab& interfacial_area = variables_internes().ai->valeurs();
2893 DoubleTab mpoint = variables_internes().ref_equation_mpoint_->get_mpoint();
2894 if (variables_internes().ref_equation_mpoint_vap_)
2898 const DoubleTab& mpointv = variables_internes().ref_equation_mpoint_vap_->get_mpoint();
2899 for (
int elem = 0; elem < nb_elem; elem++)
2900 mpoint[elem] += mpointv[elem];
2916 Cerr <<
"[TCL] Contact line model activated in volume correction" << finl;
2920 for (
int elem = 0; elem < nb_elem; elem++)
2927 const double x = mpoint[elem] * interfacial_area[elem] * un_sur_rho_0;
2939 const double un_sur_rho_0 = 1. / rho_0;
2940 const DoubleTab& interfacial_area = variables_internes().ai->valeurs();
2941 Cerr <<
"[TCL] Contact line model activated in volume correction" << finl;
2945 for (
int idx = 0; idx < tcl_elems.
size_array(); idx++)
2947 const int elem = tcl_elems[idx];
2953 const double x = tcl_mp[idx] * interfacial_area[elem] * un_sur_rho_0;
2965 Cerr <<
"[AFTER-PCH] Locally, the maximum of dI_dt is : " << dI_dt.
mp_max_abs_vect() << finl;
2968 for (
int i=0; i< nb_elem; i++)
2970 Cerr <<
"[AFTER-PCH] " << temps <<
" The sum is : " << sum <<
" [not valid in //]" << finl;
2976 const double un_sur_rho_1 = 1. / rho_1;
2977 const DoubleTab& interfacial_area = variables_internes().ai->valeurs();
2978 DoubleTab mpoint(interfacial_area);
2980 if (variables_internes().ref_equation_mpoint_)
2982 const DoubleTab& mp = variables_internes().ref_equation_mpoint_->get_mpoint();
2984 if (!variables_internes().mpoint_inactif)
2987 if (variables_internes().ref_equation_mpoint_vap_)
2989 const DoubleTab& mpv = variables_internes().ref_equation_mpoint_vap_->get_mpoint();
2991 if (!variables_internes().mpointv_inactif)
2994 for (
int i = 0; i < nb_elem; i++)
2995 dI_dt[i] += mpoint[i]*un_sur_rho_1*interfacial_area[i];
3005void compute_normale_barycenter_area_in_cell(
const int elem,
const Maillage_FT_Disc& mesh,
Vecteur3& normale,
Vecteur3& bary_facettes_dans_elem,
double& surface_tot)
3008 const IntTab& facettes = mesh.
facettes();
3009 const DoubleTab& sommets = mesh.
sommets();
3015 bary_facettes_dans_elem = 0.;
3018 int index = intersections.
index_elem()[elem];
3029 const double surface_facette = surface_facettes[fa7];
3035 Vecteur3 coord_barycentre_fraction(0., 0., 0.);
3036 for (
int dir = 0; dir < 3; dir++)
3038 const double nx = normale_facettes(fa7, dir);
3039 normale[dir] += nx * surf;
3041 for (
int isom = 0; isom < 3; isom++)
3043 const int num_som = facettes(fa7, isom);
3045 for (
int dir = 0; dir < 3; dir++)
3046 coord_barycentre_fraction[dir] += bary_som * sommets(num_som, dir);
3049 coord_barycentre_fraction *= surf;
3050 surface_tot += surf;
3051 bary_facettes_dans_elem += coord_barycentre_fraction;
3056 if (surface_tot > 0.)
3058 normale *= 1. / surface_tot;
3059 bary_facettes_dans_elem *= 1. / surface_tot;
3064 Cerr <<
" Error in compute_normale_barycenter_area_in_cell (Navier_Stokes_FT_Disc.cpp)." << finl;
3065 Cerr <<
"The element " << elem <<
" only contains facettes of surface=0, so that surface_totale is zero!" << finl;
3066 Cerr <<
"What a mess for the barycentre? ..." << finl;
3069 bary_facettes_dans_elem = 0.;
3072 const double norm = normale[0]*normale[0] + normale[1]*normale[1] + normale[2]*normale[2];
3075 Cerr <<
" In Navier_Stokes_FT_Disc.cpp compute_normale_barycenter_area_in_cell." << finl;
3076 Cerr <<
"Small normal : " << count <<
" facettes dans l'element " << elem
3077 <<
". surface_tot = "<< surface_tot <<
"Norm**2 = " << norm << finl;
3084 const DoubleVect& volumes_entrelaces,
const IntVect& orientation,
const DoubleTab& indicatrice,
const ArrOfDouble& g,
3085 DoubleTab& gravite_face)
const
3090 const DoubleTab& tab_beta_th_phase_eq = fluide_phase_eq.
beta_t().
valeurs();
3091 const double beta_th_phase_eq = tab_beta_th_phase_eq(0, 0);
3093 for (
int face = 0; face < gravite_face.
dimension(0); face++)
3095 const int elem0 = face_voisins(face, 0);
3096 const int elem1 = face_voisins(face, 1);
3107 double chi = (2 * phase_eq - 1) * indicatrice[elem0] + 1 - phase_eq;
3108 double T_eq = temperature_eq[elem0];
3113 double chi = (2 * phase_eq - 1) * indicatrice[elem1] + 1 - phase_eq;
3114 double T_eq = temperature_eq[elem1];
3117 if (elem0 >= 0 && elem1 >= 0)
3119 gravite_face(face) -= volumes_entrelaces(face) * g(orientation[face]) * coef * beta_th_phase_eq;
3143 terme_diffusif.calculer(la_vitesse->valeurs(), variables_internes().terme_diffusion->valeurs());
3144 if (correction_diffusion_pch_)
3146 DoubleTab& diffusion = variables_internes().terme_diffusion->valeurs();
3147 DoubleTab diffusion_liq(diffusion);
3148 DoubleTab diffusion_vap(diffusion);
3150 variables_internes().ref_eq_interf_proprietes_fluide;
3151 if (refeq_transport)
3156 if (variables_internes().ref_equation_mpoint_)
3163 if (variables_internes().ref_equation_mpoint_vap_)
3171 if ((phase_liq == 1) && (phase_vap == 0))
3177 Cerr <<
"error bad weighting below" << finl;
3180 refeq_transport->update_indicatrice_faces();
3181 const DoubleTab& indicatrice_faces = refeq_transport->get_indicatrice_faces().valeurs();
3182 const DoubleTab& dist_faces = refeq_transport.valeur().get_update_distance_interface_faces().valeurs();
3183 for (
int i = 0; i < diffusion.dimension(0) ; i++)
3185 const double indic_f = indicatrice_faces(i);
3187 if (std::fabs(dist_faces(i))< 3.*1.414e-6)
3189 diffusion(i) = (indic_f)* diffusion_liq(i) + (1-indic_f)* diffusion_vap(i) ;
3194 solveur_masse->appliquer(variables_internes().terme_diffusion->valeurs());
3207 if (refeq_transport)
3209 const Champ_base& indicatrice = refeq_transport->get_indicatrice();
3210 Champ_base& gradient_i = variables_internes().gradient_indicatrice.valeur();
3219 calculer_champ_forces_superficielles(maillage, gradient_i, variables_internes().potentiel_elements, variables_internes().potentiel_faces, variables_internes().terme_source_interfaces);
3225 variables_internes().terme_source_interfaces->valeurs() = 0.;
3228 solveur_masse->appliquer(variables_internes().terme_source_interfaces->valeurs());
3229 if (
is_solid_particle_) solveur_masse->appliquer(variables_internes().contact_force_source_term->valeurs());
3237 variables_internes().terme_source->valeurs() = 0.;
3238 les_sources.ajouter(variables_internes().terme_source->valeurs());
3239 solveur_masse->appliquer(variables_internes().terme_source->valeurs());
3247 DoubleTab& terme_convection_valeurs = variables_internes().terme_convection->valeurs();
3248 bool calcul_explicite =
false;
3254 if (
schema_temps().diffusion_implicite() && !calcul_explicite)
3256 terme_convection_valeurs = 0;
3261 terme_convectif.calculer(la_vitesse->valeurs(), terme_convection_valeurs);
3263 solveur_masse->appliquer(variables_internes().terme_convection->valeurs());
3266 const DoubleTab& tab_rho_faces = champ_rho_faces_->valeurs();
3268 const DoubleTab& tab_diffusion = variables_internes().terme_diffusion->valeurs();
3269 const DoubleTab& termes_sources_interf = variables_internes().terme_source_interfaces->valeurs();
3270 const DoubleTab& termes_sources = variables_internes().terme_source->valeurs();
3271 const DoubleTab& tab_convection = variables_internes().terme_convection->valeurs();
3272 const DoubleTab& contact_force_source_term = variables_internes().contact_force_source_term->valeurs();
3274 const int nbdim1 = (vpoint.
line_size() == 1);
3277 DoubleTab gravite_face(
inconnue().valeurs());
3278 if (
milieu().a_gravite())
3285 Cerr <<
"Error for calculer_champ_forces_superficielles\n";
3286 Cerr <<
" gravite.line_size() != Objet_U::dimension" << finl;
3290 g[j] = gravite(0, j);
3296 const IntTab& face_voisins = le_dom_dis->face_voisins();
3300 for (
int face = 0; face < n; face++)
3301 gravite_face(face, 0) = volumes_entrelaces(face) * g[orientation[face]];
3308 if (variables_internes().is_boussinesq_)
3311 if (!refeq_transport)
3313 Cerr <<
"Trying to use Boussinesq approximation on a 2phase flow when the transport equation is not specified" << finl;
3316 const DoubleTab& indicatrice = refeq_transport->get_indicatrice().valeurs();
3318 if (variables_internes().ref_equation_mpoint_)
3325 if (variables_internes().ref_equation_mpoint_vap_)
3337 if (variables_internes().is_boussinesq_)
3339 Cerr <<
"Trying to use Boussinesq approximation on a 2phase flow in VEF? Not yet available. Ask TRUST support." << finl;
3344 for (
int face = 0; face < n; face++)
3345 for (
int dim = 0; dim < m; dim++)
3346 gravite_face(face, dim) = volumes_entrelaces(face) * g[dim];
3353 solveur_masse->appliquer(gravite_face);
3361 IntTab flag_gradP(n);
3365 DoubleTab& gradP = variables_internes().gradient_pression->valeurs();
3370 solveur_masse->appliquer(gradP);
3372 if (variables_internes().is_penalized)
3379 if (!variables_internes().is_explicite && !calcul_explicite)
3390 bool interf_vitesse_imposee_ok =
false;
3391 int nb_eqs = variables_internes().ref_eq_interf_vitesse_imposee.
size();
3392 int nb_eq_non_nul = 0;
3393 for (
int k = 0; k < nb_eqs; k++)
3397 if (refeq_transport)
3400 DoubleTab terme_mul;
3401 if (nb_eq_non_nul == nb_eqs && nb_eqs != 0)
3403 interf_vitesse_imposee_ok =
true;
3404 terme_mul.
copy(champ_rho_faces_->valeurs(), RESIZE_OPTIONS::COPY_INIT);
3409 if (refeq_transport_2pha && interf_vitesse_imposee_ok && variables_internes().is_penalized)
3413 const IntTab& face_voisins = domaine_vf.
face_voisins();
3414 const IntTab& elem_faces = domaine_vf.
elem_faces();
3415 const IntVect& orientation = domaine_vdf.
orientation();
3416 const int nb_faces_elem = elem_faces.
line_size();
3417 for (
int k = 0; k < nb_eqs; k++)
3420 const DoubleTab& indicatrice_faces = refeq_transport->get_indicatrice_faces().valeurs();
3421 for (
int i = 0; i < face_voisins.
dimension(0); i++)
3423 if (indicatrice_faces(i) > 0.)
3427 const int ori = orientation(i);
3428 const int voisin0 = face_voisins(i, 0);
3431 int face_visavi = elem_faces(voisin0, ori) + elem_faces(voisin0, ori +
Objet_U::dimension) - i;
3432 for (
int i_face = 0; i_face < nb_faces_elem; i_face++)
3434 const int face = elem_faces(voisin0, i_face);
3435 if (indicatrice_faces(face) == 0. && face == face_visavi)
3437 flag_gradP(face) = 0;
3442 const int voisin1 = face_voisins(i, 1);
3445 int face_visavi = elem_faces(voisin1, ori) + elem_faces(voisin1, ori +
Objet_U::dimension) - i;
3446 for (
int i_face = 0; i_face < nb_faces_elem; i_face++)
3448 const int face = elem_faces(voisin1, i_face);
3449 if (indicatrice_faces(face) == 0. && face == face_visavi)
3451 flag_gradP(face) = 0;
3462 for (
int i = 0; i < n; i++)
3464 const double rho_face = tab_rho_faces(i);
3466 for (
int j = 0; j < m; j++)
3467 vpoint(i, j) = (-flag_gradP(i) * gradP(i, j) + flag_diff * tab_diffusion(i, j) + coef_TSF(i) * termes_sources_interf(i, j)+
is_solid_particle_*contact_force_source_term(i))
3468 / rho_face + tab_convection(i, j) + termes_sources(i, j) + gravite_face(i, j);
3473 if (
schema_temps().diffusion_implicite() && !calcul_explicite && variables_internes().is_explicite)
3475 DoubleTab derivee(la_vitesse->valeurs());
3477 solveur_masse->set_name_of_coefficient_temporel(champ_rho_faces_->le_nom());
3479 DoubleTrav tt(vpoint);
3484 solveur_masse->set_name_of_coefficient_temporel(
"no_coeff");
3488 for (
int i = 0; i < n; i++)
3489 for (
int j = 0; j < m; j++)
3490 vpoint(i, j) += gradP(i, j) / tab_rho_faces(i);
3495 if (interf_vitesse_imposee_ok)
3497 int compteur_vimp_regul = 0;
3498 DoubleTrav vpoint0(vpoint);
3502 DoubleTrav forces_tot(vpoint);
3503 int nb_eqs_bis = variables_internes().ref_eq_interf_vitesse_imposee.size();
3504 for (
int k = 0; k < nb_eqs_bis; k++)
3511 const DoubleTab& rho_faces = champ_rho_faces_->valeurs();
3512 DoubleTab& source_val = variables_internes().terme_source->valeurs();
3518 eq_transport.
modifier_vpoint_pour_imposer_vit(inco_val, vpoint0, vpoint, rho_faces, source_val, temps, dt, variables_internes().is_explicite, variables_internes().eta);
3520 forces_tot += source_val;
3525 compteur_vimp_regul++;
3527 if (!variables_internes().is_explicite)
3529 const DoubleTab& indicatrice_faces = refeq_transport->get_indicatrice_faces().valeurs();
3530 for (
int i = 0; i < nfaces; i++)
3532 if ((eq_transport.
get_vimp_regul() == 0 && indicatrice_faces(i) > 0.) || (eq_transport.
get_vimp_regul() == 1 && indicatrice_faces(i) == 1.))
3533 terme_mul(i) += 1. / variables_internes().eta;
3538 Debog::verifier(
"Navier_Stokes_FT_Disc::derivee_en_temps_inco terme_mul:", terme_mul);
3544 if (!variables_internes().is_explicite && !calcul_explicite)
3546 const DoubleTab& rho_faces = champ_rho_faces_->valeurs();
3547 const DoubleTab& diffusion = variables_internes().terme_diffusion->valeurs();
3549 for (
int i = 0; i < vpoint.
dimension(0); i++)
3550 for (
int j = 0; j < vpoint.
line_size(); j++)
3551 vpoint(i, j) -= diffusion(i, j) / rho_faces(i);
3554 DoubleTab derivee(la_vitesse->valeurs());
3557 solveur_masse->set_name_of_coefficient_temporel(champ_rho_faces_->le_nom());
3559 DoubleTrav tt(vpoint);
3563 solveur_masse->set_name_of_coefficient_temporel(
"no_coeff");
3570 for (
int i = 0; i < nbis; i++)
3571 for (
int j = 0; j < mbis; j++)
3572 vpoint(i, j) += (flag_gradP(i) * gradP(i, j)) / rho_faces(i);
3580 if (!variables_internes().is_explicite)
3584 for (
int i = 0; i < nfaces; i++)
3585 for (
int j = 0; j < mbis; j++)
3586 vpoint(i, j) /= terme_mul(i);
3592 Debog::verifier(
"Navier_Stokes_FT_Disc::derivee_en_temps_inco vpoint:", vpoint);
3597 if (!variables_internes().is_explicite && compteur_vimp_regul)
3601 DoubleTrav forces_totbis(vpoint);
3602 for (
int k = 0; k < nb_eqs_bis; k++)
3609 const DoubleTab& rho_faces = champ_rho_faces_->valeurs();
3610 DoubleTab& source_val = variables_internes().terme_source->valeurs();
3618 forces_totbis += source_val;
3627 const DoubleTab& tab_rho_facesbis = champ_rho_faces_->valeurs();
3628 for (
int k = 0; k < nb_eqs_bis; k++)
3642 if (!interf_vitesse_imposee_ok)
3644 if (!variables_internes().matrice_pression_invariante)
3646 assembleur_pression()->assembler_rho_variable(
matrice_pression_, champ_rho_faces_.valeur());
3667 DoubleTab& secmem = variables_internes().second_membre_projection->valeurs();
3668 DoubleTab& secmem2 = variables_internes().second_membre_projection_jump_->valeurs();
3669 const int nb_elem = secmem2.
dimension(0);
3679 double int_sec_mem = 0;
3680 for (
int elem = 0; elem < secmem.
dimension(0); elem++)
3681 int_sec_mem +=secmem(elem);
3682 Cerr <<
"Secmem before tcl= " << int_sec_mem << finl;
3687 const Noms& noms_eq = variables_internes().equations_concentration_source_fluide_;
3688 for (
int i_eq = 0; i_eq < noms_eq.size(); i_eq++)
3691 for (
int i_source = 0; i_source < eq.
sources().size(); i_source++)
3704 if (variables_internes().ref_equation_mpoint_ || variables_internes().ref_equation_mpoint_vap_)
3715 if (variables_internes().ref_equation_mpoint_)
3716 variables_internes().ref_equation_mpoint_->calculer_mpoint(variables_internes().mpoint.valeur());
3717 if (variables_internes().ref_equation_mpoint_vap_)
3718 variables_internes().ref_equation_mpoint_vap_->calculer_mpoint(variables_internes().mpoint_vap.valeur());
3721 DoubleTab mpoint = variables_internes().ref_equation_mpoint_->get_mpoint();
3722 if (variables_internes().ref_equation_mpoint_vap_)
3724 const DoubleTab& mpointv = variables_internes().ref_equation_mpoint_vap_->get_mpoint();
3725 for (
int elem = 0; elem < nb_elem; elem++)
3726 mpoint[elem] += mpointv[elem];
3740 const double rho_phase_0 = tab_rho_phase_0(0, 0);
3741 const double rho_phase_1 = tab_rho_phase_1(0, 0);
3742 const double jump_inv_rho = 1. / rho_phase_1 - 1. / rho_phase_0;
3743 if (variables_internes().new_mass_source_)
3746 const DoubleTab& interfacial_area = variables_internes().ai->valeurs();
3747 for (
int elem = 0; elem < nb_elem; elem++)
3748 secmem2[elem] = jump_inv_rho * interfacial_area[elem] * mpoint[elem];
3753 const IntTab& face_voisins = domaine_vf.
face_voisins();
3754 const IntTab& elem_faces = domaine_vf.
elem_faces();
3755 const int nb_faces_elem = elem_faces.
line_size();
3763 divergence.calculer(variables_internes().delta_u_interface->valeurs(), secmem2);
3765 for (
int elem = 0; elem < nb_elem; elem++)
3767 const double dist = distance(elem);
3772 i_face = nb_faces_elem;
3777 for (i_face = 0; i_face < nb_faces_elem; i_face++)
3779 const int face = elem_faces(elem, i_face);
3780 const int voisin = face_voisins(face, 0) + face_voisins(face, 1) - elem;
3783 const double d = distance(voisin);
3784 if (d > -1e20 && d * dist < 0.)
3787 Cerr <<
"Compa "<< secmem2[elem] <<
" " << jump_inv_rho*interfacial_area[elem]*mpoint[elem] << finl;
3794 if (i_face == nb_faces_elem)
3799 if(interfacial_area[elem]>DMINFLOAT)
3801 Cerr <<
"[WARNING] secmem2 is set to zero in element whereas phase is not pure (indic= "
3802 << indicatrice[elem] <<
"). This is because the choice is based on the signs of distance." << finl;
3832 Cerr <<
"[TCL] Contact line model is activated" << finl;
3836 const ArrOfInt& elems_with_CL_contrib = tcl.
elems();
3838 const ArrOfDouble& Q_from_CL = tcl.
Q();
3860 const double coef = jump_inv_rho / Lvap;
3862 if (!variables_internes().mpoint_inactif)
3865 const int check_consistency = 1;
3866 if (check_consistency)
3868 Cerr <<
"Verifying Contact line model consistency" << finl;
3870 const int nb_contact_line_contribution = elems_with_CL_contrib.
size_array();
3871 for (
int idx = 0; idx < nb_contact_line_contribution; idx++)
3873 const int elem = elems_with_CL_contrib[idx];
3874 const double sec = secmem2(elem);
3877 for (
int idx2 = 0; idx2 < nb_contact_line_contribution; idx2++)
3879 if (elem == elems_with_CL_contrib[idx2])
3881 Q += Q_from_CL[idx2];
3884 const double value = coef * Q;
3887 error += fabs(sec - value);
3888 if (fabs(sec - value) > 1.e-12)
3890 Cerr <<
"local difference sec-value=" << sec <<
" - " << value <<
" = " << (sec - value) << finl;
3896 Cerr <<
"Final error : " << error <<
" is fatal!" << finl;
3905 if (variables_internes().shift_secmem2_)
3912 double int_sec_mem2 = 0;
3913 double int_sec_mem = 0;
3914 for (
int elem = 0; elem < nb_elem; elem++)
3916 int_sec_mem2 +=secmem2(elem);
3917 int_sec_mem +=secmem(elem);
3919 Cerr <<
"Integral of secmem2 after TCL and /DT : " << int_sec_mem2 << finl;
3920 Cerr <<
"Integral of secmem after TCL and /DT : " << int_sec_mem << finl;
3925 DoubleTab& rho_faces_modifie = champ_rho_faces_modifie->valeurs();
3927 if (interf_vitesse_imposee_ok)
3931 int compteur_vimp_regul = 0;
3932 int nb_eqs_bis = variables_internes().ref_eq_interf_vitesse_imposee.size();
3933 for (
int k = 0; k < nb_eqs_bis; k++)
3939 compteur_vimp_regul++;
3948 int modif_rho_true = 0;
3949 if (variables_internes().is_penalized && (compteur_vimp_regul == 0 || refeq_transport_2pha))
3951 for (
int i = 0; i < nfaces; i++)
3953 if (compteur_vimp_regul != 0)
3955 for (
int k = 0; k < nb_eqs; k++)
3960 if (eq_transport.
get_vimp_regul() == 1 && indicatrice_faces(i) > 0.0 && indicatrice_faces(i) != 1.)
3961 terme_mul(i) += 1.0 / variables_internes().eta;
3964 rho_faces_modifie(i) *= terme_mul(i);
3969 Debog::verifier(
"Navier_Stokes_FT_Disc::derivee_en_temps_inco rho_faces_modifie:", rho_faces_modifie);
3974 assembleur_pression()->assembler_rho_variable(
matrice_pression_, champ_rho_faces_modifie.valeur());
3977 if (modif_rho_true == 1 && variables_internes().p_ref_pena != -1.e40)
3987 const IntTab& elem_faces = domaine_vf.
elem_faces();
3988 const int nb_faces_elem = elem_faces.
line_size();
3990 int numero_global_som, ligne_mat;
3991 int point_fluide_dirichlet = -1;
3992 if (variables_internes().is_pfl_flottant)
3996 point_fluide_dirichlet = mon_dom.
chercher_elements(variables_internes().x_pfl_imp, variables_internes().y_pfl_imp, variables_internes().z_pfl_imp);
4000 point_fluide_dirichlet = mon_dom.
chercher_elements(variables_internes().x_pfl_imp, variables_internes().y_pfl_imp);
4002 if (
mp_max(point_fluide_dirichlet) == -1)
4004 Cerr <<
"Point de reference pression fluide situe en dehors du domaine !" << finl;
4008 for (
int e = 0; e < nb_elem; e++)
4012 for (
int f = 0; f < nb_faces_elem; f++)
4014 int fglob = elem_faces(e, f);
4019 for (
int k = 0; k < nb_eqs_bis && dejafait == 0; k++)
4022 const DoubleTab& indicatrice_faces = refeq_transport->get_indicatrice_faces().valeurs();
4023 if (indicatrice_faces(fglob) > 0.0)
4031 if (nbfpena == nbfglob && nbfpena != 0)
4033 matrice_valeurs(e, e) += 1.0 / variables_internes().eta;
4034 secmem(e) += variables_internes().p_ref_pena / variables_internes().eta;
4035 pressu(e) = variables_internes().p_ref_pena;
4038 for (
int somloc = 0; somloc < nb_sommet; somloc++)
4040 numero_global_som = mon_dom.
sommet_elem(e, somloc);
4041 ligne_mat = nb_elem + numero_global_som;
4043 pressu(ligne_mat) = 0.0;
4047 if (point_fluide_dirichlet == e)
4049 if (nbfpena != nbfglob && nbfpena != 0)
4052 secmem(e) += matrice_valeurs(e, e) * variables_internes().p_ref_pena / (float(nbfglob - nbfpena));
4053 matrice_valeurs(e, e) *= float(nbfglob - nbfpena + 1) / (float(nbfglob - nbfpena));
4057 Cerr <<
"Point de reference pression fluide non situe dans une cellule fluide voisin d'une IBC !" << finl;
4058 Cerr <<
"Nb faces IBC = " << nbfpena << finl;
4072 assembleur_pression_->modifier_secmem(secmem);
4075 statistics().begin_count(STD_COUNTERS::system_solver,statistics().get_last_opened_counter_level()+1);
4077 statistics().end_count(STD_COUNTERS::system_solver);
4079 assembleur_pression_->modifier_solution(
la_pression->valeurs());
4082 solveur_masse->appliquer(gradP);
4089 for (
int i = 0; i < nbis; i++)
4090 for (
int j = 0; j < mbis; j++)
4091 vpoint(i, j) -= gradP(i, j) / rho_faces_modifie(i);
4097 if (interf_vitesse_imposee_ok &&
limpr())
4099 const DoubleTab& rho = champ_rho_faces_->valeurs();
4101 DoubleTrav forces_tot_2(vpoint);
4102 DoubleTrav pressure_part(vpoint);
4103 DoubleTrav diffusion_part(vpoint);
4104 DoubleTrav diffusion_part2(vpoint);
4107 DoubleTab vv(vpoint);
4112 terme_diffusif.calculer(vv, variables_internes().terme_diffusion->valeurs());
4113 variables_internes().terme_diffusion->valeurs().echange_espace_virtuel();
4114 solveur_masse->appliquer(variables_internes().terme_diffusion->valeurs());
4115 const DoubleTab& diffusion = variables_internes().terme_diffusion->valeurs();
4117 DoubleTrav trav(variables_internes().terme_convection->valeurs());
4119 variables_internes().terme_convection->valeurs() = trav;
4120 solveur_masse->appliquer(variables_internes().terme_convection->valeurs());
4121 const DoubleTab& convection = variables_internes().terme_convection->valeurs();
4125 for (
int i = 0; i < nbis; i++)
4126 for (
int j = 0; j < mbis; j++)
4128 pressure_part(i, j) = gradP(i, j);
4129 diffusion_part(i, j) = -rho(i) * convection(i, j) - diffusion(i, j);
4130 diffusion_part2(i, j) = - diffusion(i, j);
4131 forces_tot_2(i, j) = pressure_part(i, j) + diffusion_part(i, j);
4134 int nb_eqs_bis = variables_internes().ref_eq_interf_vitesse_imposee.size();
4135 for (
int k = 0; k < nb_eqs_bis; k++)
4149 return probleme_ft_.valeur();
4154 return probleme_ft_.valeur();
4167 return variables_internes_;
4171 return variables_internes_;
4183 if (variables_internes().ref_equation_mpoint_ ||
4184 variables_internes().ref_equation_mpoint_vap_)
4185 return &(variables_internes().delta_u_interface.valeur());
4198 DoubleTab& phi = variables_internes().laplacien_d->valeurs();
4199 DoubleTab u0(
inconnue().valeurs());
4204 for (
int i = 0; i < n; i++)
4212 solveur_masse->appliquer(u0);
4218 for (
int i = 0; i < n; i++)
4220 const double p = phi(i);
4223 const double v = volumes[i];
4228 return variables_internes().laplacien_d.valeur();
4233 return champ_rho_faces_;
4260 const int nb_elem=domaine_vf.
nb_elem();
4262 ref_eq_interf_proprietes_fluide;
4263 const DoubleTab& volumic_phase_indicator_function = refeq_transport->\
4264 get_indicatrice().valeurs();
4267 for (
int elem = 0; elem < nb_elem; elem++)
4269 if (collision_model_ptr &&
4272 == id_fluid_phase) ? -1 : 1;
4275 != 1 - id_fluid_phase ) ? -1 : 1;
4278 const IntTab& elem_faces = domaine_vf.
elem_faces();
4280 const int nb_local_connex_components = search_connex_components_local(elem_faces,
4290 const int nb_particles_tot=gravity_center_elem.
size_array();
4299 IntVect particle_lagrangian_id_number(nb_particles_tot);
4300 particle_lagrangian_id_number=0;
4301 for (
int id_number=0; id_number<nb_particles_tot; id_number++)
4303 int elem=gravity_center_elem(id_number);
4305 if (elem>-1 && elem < nb_elem_tot)
4312 for (
int elem = 0; elem < nb_elem; elem++)
4326 Cerr <<
"Navier_Stokes_FT_Disc::compute_eulerian_field_contact_forces" << finl;
4328 statistics().create_custom_counter(
"compute_eulerian_field_contact_forces",3,
"FrontTracking");
4329 statistics().begin_count(
"compute_eulerian_field_contact_forces",statistics().get_last_opened_counter_level()+1);
4331 auto& eq_transport=variables_internes().ref_eq_interf_proprietes_fluide.valeur();
4332 const auto& eq_transport_const=variables_internes().ref_eq_interf_proprietes_fluide.valeur();
4336 const DoubleTab& particles_position=eq_transport.get_particles_position();
4337 const DoubleTab& particles_velocity=eq_transport.get_particles_velocity();
4348 if (nb_dt_Verlet >= nb_dt_compute_Verlet_ || nb_dt == 0)
4374 const DoubleTab& volumic_phase_indicator_function_face =
4375 eq_transport.get_indicatrice_faces().valeurs();
4376 DoubleTab& contact_force = variables_internes().contact_force_source_term->valeurs();
4379 volumic_phase_indicator_function_face,
4384 statistics().end_count(
"compute_eulerian_field_contact_forces");
int set_resoudre_en_u(int flag)
Definit la valeur du drapeau resoudre_en_u__.
virtual void associer_domaine_dis_base(const Domaine_dis_base &)=0
int set_resoudre_increment_pression(int flag)
Definit la valeur du drapeau resoudre_increment_pression_.
classe Champ_Don_base classe de base des Champs donnes (non calcules)
void mettre_a_jour(double temps) override
Mise a jour en temps.
DoubleTab & valeurs() override
Surcharge Champ_base::valeurs() Renvoie le tableau des valeurs.
classe Champ_Fonc_base Classe de base des champs qui sont fonction d'une grandeur calculee
void mettre_a_jour(double temps) override
Mise a jour en temps du champ.
DoubleTab & valeurs() override
Renvoie le tableau des valeurs du champ au temps courant.
virtual DoubleTab & futur(int i=1)
virtual DoubleTab & valeurs()=0
classe Champ_base Cette classe est la base de la hierarchie des champs.
virtual DoubleTab & valeur_aux_elems(const DoubleTab &positions, const IntVect &les_polys, DoubleTab &valeurs) const
provoque une erreur ! doit etre surchargee par les classes derivees
: class Collision_Model_FT
int & get_set_nb_dt_Verlet()
const int & get_nb_dt_compute_Verlet() const
virtual void discretize_contact_forces_eulerian_field(const DoubleTab &volumic_phase_indicator_function, const Domaine_VF &domain_vf, const IntTab &particles_eulerian_id_number, DoubleTab &contact_force_source_term)=0
void research_collision_pairs_Verlet(const Navier_Stokes_FT_Disc &eq_ns, const Transport_Interfaces_FT_Disc &eq_transport)
virtual void compute_lagrangian_contact_forces(const Fluide_Diphasique &two_phase_fluid, const DoubleTab &particles_position, const DoubleTab &particles_velocity, const double &deltat_simu)=0
const int & get_is_force_on_two_phase_elem() const
bool is_Verlet_activated()
classe Cond_lim Classe generique servant a representer n'importe quelle classe
const Champ_base & vitesse_pour_transport() const override
const Champ_Inc_base & inconnue() const override
static void verifier(const char *const msg, double)
Classe Dirichlet_homogene Cette classe est la classe de base de la hierarchie des conditions aux limi...
classe Dirichlet Cette classe est la classe de base de la hierarchie des conditions aux limites de ty...
classe Discretisation_base Cette classe represente un schema de discretisation en espace,...
void discretiser_champ(const Motcle &directive, const Domaine_dis_base &z, const Nom &nom, const Nom &unite, int nb_comp, int nb_pas_dt, double temps, OWN_PTR(Champ_Inc_base)&champ, const Nom &sous_type=NOM_VIDE) const
int nb_som_elem() const
Renvoie le nombre de sommets des elements geometriques constituants le domaine.
int_t nb_elem_tot() const
SmallArrOfTID_t & chercher_elements(const DoubleTab &pos, SmallArrOfTID_t &elem, int reel=0) const
Recherche des elements contenant les points dont les coordonnees sont specifiees.
virtual void creer_tableau_elements(Array_base &, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT) const
creation d'un tableau parallele de valeurs aux elements.
int_t sommet_elem(int_t i, int j) const
Renvoie le numero (global) du j-ieme sommet du i-ieme element.
classe Domaine_Cl_dis_base Les objets Domaine_Cl_dis_base representent les conditions aux limites
const Cond_lim & les_conditions_limites(int) const
Renvoie la i-ieme condition aux limites.
int orientation(int) const override
inline DoubleVect& Domaine_VDF::porosite_face() {
virtual const DoubleVect & face_surfaces() const
int nb_faces() const
renvoie le nombre global de faces.
virtual double face_normales(int face, int comp) const
double xv(int num_face, int k) const
double volumes(int i) const
virtual const IntVect & orientation() const
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
double xp(int num_elem, int k) const
int face_voisins(int num_face, int i) const
renvoie l'element voisin de numface dans la direction i.
const Nom & le_nom() const override
Donne le nom de l'Objet_U Methode a surcharger : renvoie "neant" dans cette implementation.
classe Domaine_dis_base Cette classe est la base de la hierarchie des domaines discretisees.
virtual IntTab & face_voisins()
const Domaine & domaine() const
Class defining operators and methods for all reading operation in an input flow (file,...
classe Equation_base Le role d'une equation est le calcul d'un ou plusieurs champs....
const Nom & le_nom() const override
Renvoie le nom de l'equation.
virtual void associer_milieu_base(const Milieu_base &)=0
virtual const Milieu_base & milieu() const =0
DoubleTab & derivee_en_temps_conv(DoubleTab &, const DoubleTab &)
Add convection term In: solution is the unknown I.
Sources & sources()
Renvoie les termes sources asssocies a l'equation.
const Discretisation_base & discretisation() const
Renvoie la discretisation associee a l'equation.
LIST(RefObjU) liste_modeles_
virtual int preparer_calcul()
Tout ce qui ne depend pas des autres problemes eventuels.
virtual Domaine_Cl_dis_base & domaine_Cl_dis()
Renvoie le domaine des conditions aux limite discretisee associee a l'equation.
Probleme_base & probleme()
Renvoie le probleme associe a l'equation.
int limpr() const
Demande au schema en temps si il faut effectuer une impression.
Schema_Temps_base & schema_temps()
Renvoie le schema en temps associe a l'equation.
void Gradient_conjugue_diff_impl(DoubleTrav &secmem, DoubleTab &solution)
virtual void discretiser()
Discretise l'equation.
Champs_compris champs_compris_
Domaine_dis_base & domaine_dis()
Renvoie le domaine discretise associe a l'equation.
double chaleur_latente() const
const Fluide_Incompressible & fluide_phase(int la_phase) const
const int & get_id_fluid_phase() const
classe Fluide_Incompressible Cette classe represente un d'un fluide incompressible ainsi que
const Champ_Don_base & viscosite_dynamique() const
const Champ_Don_base & viscosite_cinematique() const
int num_premiere_face() const
int index_element_suivant_
double fraction_surface_intersection_
int index_facette_suivante_
: class Intersections_Elem_Facettes
const ArrOfInt & index_elem() const
Renvoie un tableau de taille domaine.
const ArrOfInt & index_facette() const
Renvoie un tableau de taille "nombre de facettes de l'interface" pour un element 0 <= facette < nb_fa...
const Intersections_Elem_Facettes_Data & data_intersection(int index) const
Renvoie les donnees de l'intersection stockee a l'indice "index" dans le tableau "data" ( 0 <= index ...
: class Maillage_FT_Disc Cette classe decrit un maillage:
int nb_sommets() const
renvoie le nombre de sommets (reels et virtuels) (egal a sommets().
const DoubleTab & sommets() const
renvoie le tableau des sommets (reels et virtuels) dimension(0) = nombre de sommets,
int nb_facettes() const
renvoie le nombre de facettes (reelles et virtuelles) (egal a facettes().
virtual const DoubleTab & get_update_normale_facettes() const
Calcule la grandeur demandee, stocke le resultat dans un tableau interne a la classe et renvoie le re...
virtual double compute_normale_element(const int elem, const bool normalize, ArrOfDouble &normale) const
const Intersections_Elem_Facettes & intersections_elem_facettes() const
virtual const ArrOfDouble & get_update_surface_facettes() const
Calcule la grandeur demandee, stocke le resultat dans un tableau interne a la classe et renvoie le re...
virtual const ArrOfDouble & get_update_courbure_sommets() const
Calcule la grandeur demandee, stocke le resultat dans un tableau interne a la classe et renvoie le re...
const IntTab & facettes() const
renvoie le tableau des facettes (reelles et virtuelles) dimension(0) = nombre de facettes,
Classe Matrice_Morse_Sym Represente une matrice M (creuse) symetrique stockee au format Morse.
classe Milieu_base Cette classe est la base de la hierarchie des milieux (physiques)
virtual const Champ_Don_base & beta_t() const
Renvoie beta_t du milieu.
virtual const Champ_base & masse_volumique() const
Renvoie la masse volumique du milieu.
virtual const Champ_Don_base & gravite() const
Renvoie la gravite du milieu si elle a ete associe provoque une erreur sinon.
void associer_eqn(const Equation_base &)
Associe une equation a l'objet.
Une chaine de caractere (Nom) en majuscules.
Un tableau d'objets de la classe Motcle.
int search(const Motcle &t) const
@ ZERO_OUT_FLUX_ON_MIXED_CELLS
@ ZERO_NET_FLUX_ON_MIXED_CELLS
const DoubleTab & get_mpoint() const
void associer_milieu_base(const Milieu_base &fluide) override
virtual void calculer_gradient_indicatrice(const Champ_base &indicatrice, const DoubleTab &distance_interface_sommets, Champ_base &gradient_i)
Calcul du gradient de l'indicatrice.
DoubleTab & derivee_en_temps_inco(DoubleTab &vpoint) override
Calcul de la derivee en temps de la vitesse.
void projeter() override
methode appelee par Navier_Stokes_std::preparer_calcul.
const SolveurSys & get_solveur_pression() const
virtual const Champ_base * get_delta_vitesse_interface() const
Si le champ de vitesse est discontinu (calcul avec changement de phase), renvoie un pointeur vers le ...
void discretiser_assembleur_pression() override
Methode surchargee de Navier_Stokes_std, appelee par Navier_Stokes_std::discretiser().
void set_id_fluid_phase(const int &id_fluid_phase)
void calculer_delta_u_interface(Champ_base &u0, int phase_pilote, int ordre, const bool future_or_past=false)
Calcul du saut de vitesse a l'interface du au changement de phase.
virtual void calculer_champ_forces_superficielles(const Maillage_FT_Disc &maillage, const Champ_base &gradient_indicatrice, Champ_base &potentiel_elements, Champ_base &potentiel_faces, Champ_base &champ)
Calcul des forces de tension superficielles (F_sigma) et de la partie a rotationnel non nul de la gra...
void compute_particles_eulerian_id_number(const OWN_PTR(Collision_Model_FT_base)&collision_model_ptr)
const DoubleTab & get_interfacial_area() const
void mettre_a_jour(double temps) override
La valeur de l'inconnue sur le pas de temps a ete calculee.
int preparer_calcul() override
methode appelee par Probleme_base::preparer_calcul()
void associer_pb_base(const Probleme_base &probleme) override
S'associe au Probleme passe en parametre.
const int & get_is_penalized() const
void compute_boussinesq_additional_gravity(const Convection_Diffusion_Temperature_FT_Disc &eq, const Fluide_Diphasique &fluide_diphasique, const IntTab &face_voisins, const DoubleVect &volumes_entrelaces, const IntVect &orientation, const DoubleTab &indicatrice, const ArrOfDouble &g, DoubleTab &gravite_face) const
OWN_PTR(Champ_Fonc_base) champ_rho_elem_
const Milieu_base & milieu() const override
OBS_PTR(Probleme_FT_Disc_gen) probleme_ft_
virtual const Probleme_FT_Disc_gen & probleme_ft() const
bool get_new_mass_source() const
bool get_is_solid_particle() const
IntTab particles_eulerian_id_number_
int is_terme_gravite_rhog() const
void shift_secmem2(DoubleTab &shift_secmem2)
void compute_eulerian_field_contact_forces(const Maillage_FT_Disc &mesh, const Champ_base &field_volumic_phase_indicator_function)
int reprendre(Entree &) override
On reprend l'inconnue a partir d'un flot d'entree.
void set_param(Param &titi) const override
virtual void calculer_dI_dt(DoubleVect &dI_dt, const DoubleTab &tab_vitesse)
virtual const Fluide_Diphasique & fluide_diphasique() const
int sauvegarder(Sortie &) const override
On sauvegarde l'inconnue, puis les sources sur un flot de sortie.
const Champ_Don_base & diffusivite_pour_transport() const override
void set_is_solid_particle(const bool &is_solid_particle)
void calculer_la_pression_en_pa() override
In Front Tracking, pression is in Pa and so pression_pa field <=> pression field.
void discretiser() override
Discretisation des champs utilises dans cette equation.
virtual const Champ_base & calculer_div_normale_interface()
void correct_at_exit_bad_gradient(DoubleTab &u0) const
bool is_shift_secmem2_activated() const
friend class Post_Processing_Hydrodynamic_Forces
std::vector< YAML_data > data_a_sauvegarder() const override
for PDI IO: retrieve name, type and dimensions of the fields to save/restore
void mettre_a_jour_physical_properties(double temps)
void swap_particles_eulerian_id_number(const ArrOfInt &gravity_center_elem)
const Champ_Fonc_base & champ_rho_faces() const
DoubleTab & get_set_interfacial_area()
DoubleTab & get_set_mpoint()
int lire_motcle_non_standard(const Motcle &, Entree &) override
Lecture des parametres de type non simple d'un objet_U a partir d'un flot d'entree.
classe Navier_Stokes_Turbulent Cette classe represente l'equation de la dynamique pour un fluide
std::vector< YAML_data > data_a_sauvegarder() const override
for PDI IO: retrieve name, type and dimensions of the fields to save/restore
void mettre_a_jour(double) override
Effecttue une mise a jour en temps de l'equation.
int sauvegarder(Sortie &) const override
Sauvegarde l'equation (et son modele de turbulence) sur un flot de sortie.
int reprendre(Entree &) override
Reprise de l'equation et de son modele de turbulence a partir d'un flot d'entree.
void set_param(Param &titi) const override
int lire_motcle_non_standard(const Motcle &, Entree &) override
Lecture des parametres de type non simple d'un objet_U a partir d'un flot d'entree.
Entree & lire_op_diff_turbulent(Entree &is)
Operateur_Diff terme_diffusif
Operateur_Conv terme_convectif
const Champ_Inc_base & inconnue() const override
Renvoie la vitesse (champ inconnue de l'equation) (version const).
const Fluide_base & fluide() const
Renvoie le fluide incompressible (milieu physique de l'equation) associe a l'equation.
Matrice matrice_pression_
void associer_pb_base(const Probleme_base &) override
S'associe au probleme: apelle Equation_base::associer_pb_base(const Probleme_base&).
virtual int projection_a_faire()
SolveurSys & solveur_pression()
Renvoie le solveur en pression (version const).
SolveurSys solveur_pression_
classe Neumann_sortie_libre Cette classe represente une frontiere ouverte sans vitesse imposee
class Nom Une chaine de caractere pour nommer les objets de TRUST
Un tableau de chaine de caracteres (VECT(Nom)).
const Nom & que_suis_je() const
renvoie la chaine identifiant la classe.
virtual Entree & readOn(Entree &)
Lecture d'un Objet_U sur un flot d'entree Methode a surcharger.
static double precision_geom
virtual Sortie & printOn(Sortie &) const
Ecriture de l'objet sur un flot de sortie Methode a surcharger.
classe Operateur_Div Classe generique de la hierarchie des operateurs calculant la divergence
Operateur_base & l_op_base() override
Renvoie l'objet sous-jacent upcaste en Operateur_base.
void typer() override
Type l'operateur: se type "Op_div_"+discretisation()+.
DoubleTab & calculer(const DoubleTab &, DoubleTab &) const override
Initialise le tableau passe en parametre avec la contribution de l'operateur.
DoubleTab & ajouter(const DoubleTab &, DoubleTab &) const override
Ajoute la contribution de l'operateur au tableau passe en parametre.
void associer_eqn(const Equation_base &)
Associe une equation a l'operateur.
virtual void completer()
Met a jour les references des objets associes a l'operateur.
Helper class to factorize the readOn method of Objet_U classes.
void ajouter_flag(const char *keyword, const bool *value)
Register a boolean flag whose mere presence switches it to true.
void ajouter(const char *keyword, const int *value, Param::Nature nat=Param::OPTIONAL)
Register an integer parameter.
void ajouter_non_std(const char *keyword, const Objet_U *value, Param::Nature nat=Param::OPTIONAL)
Register a keyword handled by Objet_U::lire_motcle_non_standard.
classe Parametre_implicite Un objet Parametre_implicite est un objet regroupant les differentes
bool & calcul_explicite()
classe Periodique Cette classe represente une condition aux limites periodique.
bool get_is_compute_forces_Stokes_th() const
virtual const Transport_Interfaces_FT_Disc & equation_interfaces(const Motcle &nom) const
const Equation_base & get_equation_by_name(const Nom &le_nom) const override
(B. Math): Methode virtuelle ajoutee pour les problemes ayant plusieurs equations de meme type (Probl...
const Triple_Line_Model_FT_Disc & tcl() const
classe Probleme_base C'est un Probleme_U qui n'est pas un couplage.
const Domaine & domaine() const
Renvoie le domaine associe au probleme.
virtual const Equation_base & get_equation_by_name(const Nom &) const
(B. Math): Methode virtuelle ajoutee pour les problemes ayant plusieurs equations de meme type (Probl...
static void mp_max_for_each_item(TRUSTArray< _TYPE_ > &x, int n=-1)
static int check_int_overflow(trustIdType)
static void mp_sum_for_each(T &arg1, T &arg2)
C++14 compatible mp_sum_for_each: combine multiple mp_sum calls into one collective operation Usage: ...
static double mp_max(double)
static double mp_sum(double)
Calcule la somme de x sur tous les processeurs du groupe courant.
static void barrier()
Synchronise tous les processeurs du groupe courant (attend que tous les processeurs soient arrives a ...
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
static int je_suis_maitre()
renvoie 1 si on est sur le processeur maitre du groupe courant (c'est a dire me() == 0),...
double temps_courant() const
Renvoie le temps courant.
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.
class SolveurSys Un SolveurSys represente n'importe qu'elle classe
Classe de base des flux de sortie.
classe Symetrie Sur les faces de symetrie on a les proprietes suivantes:
void append_array(_TYPE_ valeur)
_SIZE_ size_array() const
TRUSTArray & inject_array(const TRUSTArray &source, _SIZE_ nb_elements=-1, _SIZE_ first_element_dest=0, _SIZE_ first_element_source=0)
void resize_array(_SIZE_ new_size, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
void resize(_SIZE_ n, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
_SIZE_ dimension_tot(int) const override
void copy(const TRUSTTab &, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
_SIZE_ dimension(int d) const
_SIZE_ size_totale() const
_TYPE_ mp_max_abs_vect(Mp_vect_options opt=VECT_REAL_ITEMS) const
_SIZE_ size_reelle() const
virtual void echange_espace_virtuel(IsExchangeBlocking exchange_type=IsExchangeBlocking::DefaultBlocking, const std::string kernel_name="noname")
void ajouter_terme_div_u(DoubleVect &secmem_pression, double dt) const
virtual const Champ_base & get_indicatrice_faces()
virtual const DoubleTab & get_update_distance_interface_sommets() const
Renvoi de la distance signee entre l'interface et les sommets du maillage eulerien.
void impr_effort_fluide_interface(DoubleTab &source_val, DoubleTab &pressure_part, DoubleTab &friction_part, DoubleTab &diff_part)
const Champ_Inc_base & inconnue() const override
virtual const Champ_base & get_normale_interface() const
const Maillage_FT_Disc & maillage_interface() const
void calcul_effort_fluide_interface(const DoubleTab &vpoint, const DoubleTab &rho_faces, DoubleTab &source_val, const int is_explicite, const double eta)
virtual const Champ_base & get_distance_interface() const
void modifier_vpoint_pour_imposer_vit(const DoubleTab &inco_val, DoubleTab &vpoint0, DoubleTab &vpoint, const DoubleTab &rho_faces, DoubleTab &terme_source, const double temps, const double dt, const int is_explicite, const double eta) override
const int & get_vimp_regul() const
void corriger_secmem(const double coef, DoubleTab &secmem2) const
void corriger_mpoint(DoubleTab &mpoint) const