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>
57static 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,
58 DoubleVect& nu_elem, DoubleVect& mu_elem, DoubleVect& rho_faces)
64 const double rho_phase_0 = tab_rho_phase_0(0, 0);
65 const double rho_phase_1 = tab_rho_phase_1(0, 0);
66 const double delta_rho = rho_phase_1 - rho_phase_0;
69 const double nu_phase_0 = tab_nu_phase_0(0, 0);
70 const double nu_phase_1 = tab_nu_phase_1(0, 0);
71 const double delta_nu = nu_phase_1 - nu_phase_0;
72 const double mu_phase_0 = nu_phase_0 * rho_phase_0;
73 const double mu_phase_1 = nu_phase_1 * rho_phase_1;
74 const double delta_mu = mu_phase_1 - mu_phase_0;
80 const int n = indicatrice_elem.
size();
81 assert(n == rho_elem.
size());
82 assert(n == nu_elem.
size());
83 assert(n == mu_elem.
size());
84 for (
int i = 0; i < n; i++)
86 const double indic = indicatrice_elem[i];
87 const double rho = indic * delta_rho + rho_phase_0;
89 double nu = indic * delta_nu + nu_phase_0;
99 mu = indic * delta_mu + mu_phase_0;
104 mu = (mu_phase_0 * mu_phase_1) / (mu_phase_1 - indic * delta_mu);
109 Cerr <<
"The method specified for formule_mu in not recognized. \n" << finl;
110 Cerr <<
"you can choose : standard, arithmetic or harmonic. \n" << finl;
125 assert(rho_elem.
size() == domaine_dis_base.
nb_elem());
126 const IntTab& face_voisins = domaine_dis_base.
face_voisins();
127 const int nfaces = face_voisins.
dimension(0);
128 assert(rho_faces.
size() == nfaces);
129 for (
int i = 0; i < nfaces; i++)
131 const int elem0 = face_voisins(i, 0);
132 const int elem1 = face_voisins(i, 1);
135 rho = rho_elem[elem0];
137 rho += rho_elem[elem1];
138 if (elem0 >= 0 && elem1 >= 0)
153 const double rho = tab_rho_phase_0(0, 0);
155 const double nu = tab_nu_phase_0(0, 0);
156 const double mu = nu * rho;
157 champ_rho_elem_.
valeurs() = rho;
160 champ_rho_faces.
valeurs() = rho;
167 const DoubleVect& vol = zvf.
volumes();
168 const int nb_faces = zvf.
nb_faces();
173 IntVect les_polys(nb_el);
174 for (
int i = 0; i < nb_el; i++)
177 const DoubleTab& cg = zvf.
xp();
178 DoubleTab& val_rho = champ_rho_elem_.
valeurs();
179 DoubleTab& val_nu = champ_nu_.
valeurs();
180 DoubleTab& val_mu = champ_mu_.
valeurs();
181 DoubleTab& val_rho_faces = champ_rho_faces.
valeurs();
188 for (
int el = 0; el < nb_el; el++)
189 val_nu(el) = val_mu(el) / val_rho(el);
192 for (
int fac = 0; fac < nb_faces; fac++)
194 elem1 = face_vois(fac, 0);
195 elem2 = face_vois(fac, 1);
196 val_rho_faces(fac) = 0.;
200 val_rho_faces(fac) += val_rho(elem1) * vol(elem1);
201 volume += vol(elem1);
205 val_rho_faces(fac) += val_rho(elem2) * vol(elem2);
206 volume += vol(elem2);
208 val_rho_faces(fac) /= volume;
234 std::vector<YAML_data> particles = particles_eulerian_id_number_post_->data_a_sauvegarder();
235 data.insert(data.end(), particles.begin(), particles.end());
245 bytes += particles_eulerian_id_number_post_->sauvegarder(os);
255 Nom ident_id_part(particles_eulerian_id_number_post_->le_nom());
256 ident_id_part += particles_eulerian_id_number_post_->
que_suis_je();
258 ident_id_part +=
Nom(temps,
probleme().reprise_format_temps());
259 avancer_fichier(is, ident_id_part);
260 particles_eulerian_id_number_post_->reprendre(is);
261 DoubleTab& particles_eulerian_id_number_post = particles_eulerian_id_number_post_->valeurs();
262 int nb_elem_tot=particles_eulerian_id_number_post.
dimension(0);
263 for (
int elem=0; elem<nb_elem_tot; elem++) particles_eulerian_id_number_(elem)= static_cast<int>(particles_eulerian_id_number_post(elem));
272 param.
ajouter_flag(
"boussinesq_approximation", &variables_internes().is_boussinesq_);
274 param.
ajouter_flag(
"new_mass_source", &variables_internes().new_mass_source_);
276 param.
ajouter_flag(
"shift_secmem2", &variables_internes().shift_secmem2_);
278 param.
ajouter_flag(
"matrice_pression_invariante", &variables_internes().matrice_pression_invariante);
293 param.
ajouter_non_std(
"equation_interfaces_proprietes_fluide", (
this));
298 param.
ajouter(
"clipping_courbure_interface", &variables_internes().clipping_courbure_interface);
321 param.
ajouter(
"equations_concentration_source_vortex", &variables_internes().equations_concentration_source_fluide_);
328 param.
ajouter_flag(
"mpoint_inactif_sur_qdm", &variables_internes().mpoint_inactif);
330 param.
ajouter_flag(
"mpoint_vapeur_inactif_sur_qdm", &variables_internes().mpointv_inactif);
332 param.
ajouter(
"correction_courbure_ordre", &variables_internes().correction_courbure_ordre_);
337 param.
ajouter_flag(
"correction_diffusion_pch", &correction_diffusion_pch_);
342 if (mot ==
"diffusion")
345 Cerr <<
"Reading and typing of the diffusion operator : " << finl;
348 if (le_modele_turbulence
354 Cerr <<
" WARNING : standard diffusion operator used for front_tracking\n";
355 Cerr <<
" the transposed term grad(v) is missing !!!" << finl;
363 terme_diffusif->associer_champ_masse_volumique(champ_rho_elem_.valeur());
366 if (le_modele_turbulence)
367 le_modele_turbulence->associer_champ_masse_volumique(champ_rho_elem_.valeur());
370 else if ((mot ==
"equation_interfaces_vitesse_imposee") || (mot ==
"equation_interfaces_proprietes_fluide"))
374 Cerr << mot <<
" equation : " << nom_equation << finl;
377 if (mot ==
"equation_interfaces_vitesse_imposee")
379 if (variables_internes().ref_eq_interf_vitesse_imposee.size() > 0)
381 Cerr <<
"Error: You have already a equation_interfaces_vitesse_imposee defined." << finl;
382 Cerr <<
"Since 1.6.4 TRUST version, you need to use the following syntax when" << finl;
383 Cerr <<
"using several equation_interfaces_vitesse_imposee equations:" << finl;
384 Cerr <<
"equations_interfaces_vitesse_imposee number_of_equations equation_name_one equation_name_two ..." << finl;
389 Cerr <<
"===============================================================================" << finl;
390 Cerr <<
"Warning: You are using a future obsolete syntax for defining a solid interface:" << finl;
391 Cerr <<
"equation_interfaces_vitesse_imposee " << nom_equation << finl;
392 Cerr <<
"Should be written:" << finl;
393 Cerr <<
"equations_interfaces_vitesse_imposee 1 " << nom_equation << finl;
394 Cerr <<
"===============================================================================" << finl;
396 variables_internes().ref_eq_interf_vitesse_imposee.add(eq);
398 else if (mot ==
"equation_interfaces_proprietes_fluide")
399 variables_internes().ref_eq_interf_proprietes_fluide = eq;
402 else if (mot ==
"equations_interfaces_vitesse_imposee")
406 variables_internes().ref_eq_interf_vitesse_imposee.reset();
407 for (
int i = 0; i < na.size(); i++)
410 variables_internes().ref_eq_interf_vitesse_imposee.add(eq);
414 else if (mot ==
"equation_temperature_mpoint")
418 Cerr <<
" equation : " << nom_equation << finl;
422 Cerr <<
" Error : equation is not of type Convection_Diffusion_Temperature_FT_Disc" << finl;
428 else if (mot ==
"equation_temperature_mpoint_vapeur")
432 Cerr <<
" equation : " << nom_equation << finl;
436 Cerr <<
" Error : equation is not of type Convection_Diffusion_Temperature_FT_Disc" << finl;
442 else if (mot ==
"terme_gravite")
449 Cerr <<
"Reading terme_gravite : " << motbis << finl;
450 const int r = mots.
search(motbis);
460 Cerr <<
"Error " << mots <<
"was expected whereas " << motbis <<
" has been found." << finl;
466 else if (mot ==
"repulsion_aux_bords")
472 Cerr <<
"Interfaces repulsion on the boundaries for : " << minx <<
" " << maxx << finl;
475 else if (mot ==
"penalisation_forcage")
477 variables_internes().is_penalized = 1;
478 variables_internes().is_explicite = 0;
479 variables_internes().eta = 1.e-12;
480 Cerr <<
"Navier_Stokes_FT_Disc : option penalisation_forcage" << finl;
482 mots.add(
"pression_reference");
483 mots.add(
"domaine_flottant_fluide");
486 Motcle accouverte =
"{", accfermee =
"}";
487 if (motbis == accouverte)
490 while (motbis != accfermee)
492 int rang = mots.
search(motbis);
497 is >> variables_internes().p_ref_pena;
498 Cerr <<
"Lecture de la pression de reference : " << variables_internes().p_ref_pena << finl;
503 variables_internes().is_pfl_flottant = 1;
504 is >> variables_internes().x_pfl_imp;
505 is >> variables_internes().y_pfl_imp;
507 is >> variables_internes().z_pfl_imp;
508 Cerr <<
"Domaine flottant fluide" << finl;
509 Cerr <<
"Lecture de la position du point de reference pression fluide : " << variables_internes().x_pfl_imp <<
" " << variables_internes().y_pfl_imp <<
" "
510 << variables_internes().z_pfl_imp << finl;
514 Cerr <<
"Erreur, on attendait " << mots <<
"On a trouve : " << motbis << finl;
523 Cerr <<
"Erreur a la lecture des parametres de la penalisation du forcage " << finl;
524 Cerr <<
"On attendait : " << accouverte << finl;
528 else if (mot ==
"interpol_indic_pour_dI_dt")
531 motcles2[0] =
"interp_standard";
532 motcles2[1] =
"interp_modifiee";
533 motcles2[2] =
"interp_ai_based";
534 motcles2[3] =
"interp_standard_uvext";
535 motcles2[4] =
"interp_modifiee_uvext";
536 motcles2[5] =
"interp_ai_based_uvext";
537 motcles2[6] =
"interp_standard_uiext";
538 motcles2[7] =
"interp_modifiee_uiext";
539 motcles2[8] =
"interp_ai_based_uiext";
542 Cerr << mot <<
" " << motlu << finl;
543 Cout <<
"Setting the type of interpolation for calculer_dI_dt to " << motlu <<
"." << finl;
544 int rang = motcles2.
search(motlu);
551 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;
558 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;
565 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;
572 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."
580 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."
581 <<
" Additionally, uv_ext is used." << finl;
588 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."
596 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."
604 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."
605 <<
" Additionally, ui_ext is used." << finl;
612 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."
617 Cerr <<
"Transport_Interfaces_FT_Disc::lire\n" <<
"The options for methode_transport are :\n" << motcles2;
621 else if (mot ==
"OutletCorrection_pour_dI_dt")
624 motcles2[0] =
"no_correction";
625 motcles2[1] =
"CORRECTION_GHOST_INDIC";
626 motcles2[2] =
"zero_net_flux_on_mixed_cells";
627 motcles2[3] =
"zero_out_flux_on_mixed_cells";
630 Cerr << mot <<
" " << motlu << finl;
631 Cout <<
"Setting the type of correction at outlet BC for calculer_dI_dt to " << motlu <<
"." << finl;
632 int rang = motcles2.
search(motlu);
639 Cerr <<
" No correction of div(chi u) at exit (historical way)" << finl;
646 Cerr <<
" Correction of chi in ghost cells (virtually)" << finl;
653 Cerr <<
" correction of div(chi u) at exit : zero divergence on cells touching outlet." << finl;
661 Cerr <<
" correction of div(chi u) at exit : zero vapour mass flux on cells touching outlet." << finl;
662 Cerr <<
" This is a bad option because it does not let vapour get out explicitly (prevents interface contact)" << finl;
663 Cerr <<
" Should not be used or with great care." << finl;
669 Cerr <<
"Transport_Interfaces_FT_Disc::lire\n" <<
"The options for methode_transport are :\n" << motcles2;
686 Cerr <<
"Error for the method Navier_Stokes_FT_Disc::associer_pb_base\n";
687 Cerr <<
" Navier_Stokes_FT_Disc equation must be associated to\n";
688 Cerr <<
" a Probleme_FT_Disc_gen problem type\n";
700 Cerr <<
"Error for the method Navier_Stokes_FT_Disc::fluide_diphasique()\n";
701 Cerr <<
" The fluid has not been associated\n";
702 Cerr <<
" (check that the fluid is of Fluide_Diphasique type)" << finl;
706 return fluide_dipha.valeur();
712 variables_internes().ref_fluide_diphasique = ref_cast(
Fluide_Diphasique, un_fluide);
719 if (variables_internes().ref_fluide_diphasique)
720 return variables_internes().ref_fluide_diphasique.valeur();
727 if (variables_internes().ref_fluide_diphasique)
728 return variables_internes().ref_fluide_diphasique.valeur();
749 dis.
discretiser_champ(
"champ_elem", mon_dom_dis,
"diffusivite",
"m^2/s", 1 , temps, champ_nu_);
750 champs_compris.add(champ_nu_.valeur());
754 dis.
discretiser_champ(
"champ_elem", mon_dom_dis,
"viscosite_dynamique",
"kg/m.s", 1 , temps, champ_mu_);
755 champs_compris.add(champ_mu_.valeur());
758 dis.
discretiser_champ(
"champ_elem", mon_dom_dis,
"masse_volumique",
"kg/m3", 1 , temps, champ_rho_elem_);
759 champs_compris.add(champ_rho_elem_.valeur());
763 dis.
discretiser_champ(
"vitesse", mon_dom_dis,
"masse_volumique_vnodes",
"kg/m3", 1 , temps, champ_rho_faces_);
764 champs_compris.add(champ_rho_faces_.valeur());
768 dis.
discretiser_champ(
"pression", mon_dom_dis,
"second_membre_projection",
"", 1 , temps, variables_internes().second_membre_projection);
769 champs_compris.add(variables_internes().second_membre_projection.valeur());
770 champs_compris_.ajoute_champ(variables_internes().second_membre_projection);
771 dis.
discretiser_champ(
"champ_elem", mon_dom_dis,
"second_membre_projection_jump",
"", 1 , temps, variables_internes().second_membre_projection_jump_);
772 champs_compris.add(variables_internes().second_membre_projection_jump_.valeur());
773 champs_compris_.ajoute_champ(variables_internes().second_membre_projection_jump_);
774 dis.
discretiser_champ(
"vitesse", mon_dom_dis,
"gradient_pression_interne",
"m/s2", -1 , temps, variables_internes().gradient_pression);
775 champs_compris.add(variables_internes().gradient_pression.valeur());
777 dis.
discretiser_champ(
"vitesse", mon_dom_dis,
"derivee_u_etoile",
"", -1 , temps, variables_internes().derivee_u_etoile);
778 champs_compris.add(variables_internes().derivee_u_etoile.valeur());
780 dis.
discretiser_champ(
"vitesse", mon_dom_dis,
"terme_diffusion_vitesse",
"", -1 , temps, variables_internes().terme_diffusion);
781 champs_compris.add(variables_internes().terme_diffusion.valeur());
783 dis.
discretiser_champ(
"vitesse", mon_dom_dis,
"terme_convection_vitesse",
"", -1 , temps, variables_internes().terme_convection);
784 champs_compris.add(variables_internes().terme_convection.valeur());
786 dis.
discretiser_champ(
"vitesse", mon_dom_dis,
"terme_source_vitesse",
"", -1 , temps, variables_internes().terme_source);
787 champs_compris.add(variables_internes().terme_source.valeur());
789 dis.
discretiser_champ(
"vitesse", mon_dom_dis,
"terme_source_interfaces",
"", -1 , temps, variables_internes().terme_source_interfaces);
790 champs_compris.add(variables_internes().terme_source_interfaces.valeur());
791 champs_compris_.ajoute_champ(variables_internes().terme_source_interfaces);
794 dis.
discretiser_champ(
"pression", mon_dom_dis,
"indicatrice_p1b",
"", 1 , temps, variables_internes().indicatrice_p1b);
795 champs_compris.add(variables_internes().indicatrice_p1b.valeur());
799 dis.
discretiser_champ(
"vitesse", mon_dom_dis,
"gradient_indicatrice",
"", -1 , temps, variables_internes().gradient_indicatrice);
800 champs_compris.add(variables_internes().gradient_indicatrice.valeur());
801 champs_compris_.ajoute_champ(variables_internes().gradient_indicatrice);
802 dis.
discretiser_champ(
"vitesse", mon_dom_dis,
"potentiel_faces",
"", 1 , temps, variables_internes().potentiel_faces);
803 champs_compris.add(variables_internes().potentiel_faces.valeur());
805 dis.
discretiser_champ(
"champ_elem", mon_dom_dis,
"potentiel_elements",
"", 1 , temps, variables_internes().potentiel_elements);
806 champs_compris.add(variables_internes().potentiel_elements.valeur());
808 dis.
discretiser_champ(
"vitesse", mon_dom_dis,
"vitesse_delta_interface",
"m/s", -1 , 1, temps, variables_internes().delta_u_interface);
810 variables_internes().delta_u_interface->associer_eqn(*
this);
811 champs_compris.add(variables_internes().delta_u_interface.valeur());
813 dis.
discretiser_champ(
"pression", mon_dom_dis,
"pression_laplacien_d",
"", 1 , temps, variables_internes().laplacien_d);
814 champs_compris.add(variables_internes().laplacien_d.valeur());
816 dis.
discretiser_champ(
"temperature", mon_dom_dis,
"temperature_mpoint",
"", 1 , temps, variables_internes().mpoint);
817 champs_compris.add(variables_internes().mpoint.valeur());
819 dis.
discretiser_champ(
"temperature", mon_dom_dis,
"temperature_mpointv",
"", 1 , temps, variables_internes().mpoint_vap);
820 champs_compris.add(variables_internes().mpoint_vap.valeur());
823 dis.
discretiser_champ(
"pression", mon_dom_dis,
"derivee_temporelle_indicatrice",
"", 1 , temps, variables_internes().derivee_temporelle_indicatrice);
824 champs_compris.add(variables_internes().derivee_temporelle_indicatrice.valeur());
825 champs_compris_.ajoute_champ(variables_internes().derivee_temporelle_indicatrice);
828 dis.
discretiser_champ(
"champ_elem", mon_dom_dis,
"interfacial_area",
"m2", 1 , temps, variables_internes().ai);
829 champs_compris.add(variables_internes().ai.valeur());
834 dis.
discretiser_champ(
"vitesse", mon_dom_dis, nom,
"m/s", -1 , 1, temps, variables_internes().vitesse_jump0_);
835 variables_internes().vitesse_jump0_->associer_eqn(*
this);
836 champs_compris.add(variables_internes().vitesse_jump0_.valeur());
854 schema_temps().temps_courant(),particles_eulerian_id_number_post_);
855 particles_eulerian_id_number_post_->nommer(
"PARTICLES_EULERIAN_ID_NUMBER");
856 champs_compris.add(particles_eulerian_id_number_post_.valeur());
860 "contact_force_source_term",
"",
862 variables_internes().contact_force_source_term);
863 champs_compris.add(variables_internes().contact_force_source_term.valeur());
864 champs_compris_.ajoute_champ(variables_internes().contact_force_source_term);
867 dis.
discretiser_champ(
"vitesse", mon_dom_dis, nom1,
"m/s", -1 , 1, temps, variables_internes().vitesse_jump1_);
868 variables_internes().vitesse_jump1_->associer_eqn(*
this);
869 champs_compris.add(variables_internes().vitesse_jump1_.valeur());
885 assembleur_pression_.typer(
"Assembleur_P_VDF");
890 assembleur_pression_.typer(
"Assembleur_P_VEFPreP1B");
909 Cerr <<
"Navier_Stokes_FT_Disc::projeter does nothing" << finl;
925 Cerr <<
"Initialisation of the physical properties (rho, mu, ...)\n" <<
" based on the indicatrice field of the equation " << ref_equation->le_nom() << finl;
931 champ_rho_elem_->
valeurs(), champ_nu_->
valeurs(), champ_mu_->
valeurs(), champ_rho_faces_->valeurs());
938 FT_disc_calculer_champs_rho_mu_nu_mono(zdis, phase_0, champ_rho_elem_, champ_mu_, champ_nu_, champ_rho_faces_);
947 Cerr <<
"Navier_Stokes_FT_Disc::preparer_calcul()" << finl;
950 le_modele_turbulence->preparer_calcul();
968 Cerr <<
"Initialisation of the physical properties (rho, mu, ...)\n" <<
" based on the indicatrice field of the equation " << ref_equation->le_nom() << finl;
972 champ_rho_elem_->
valeurs(), champ_nu_->
valeurs(), champ_mu_->
valeurs(), champ_rho_faces_->valeurs());
982 ref_equation.valeur().get_post_process_hydro_forces();
986 "vitesse_stokes_th",
"m/s",
988 velocity_field_Stokes_th_);
989 champs_compris.add(velocity_field_Stokes_th_.valeur());
993 "pression_stokes_th",
"pa",
995 pressure_field_Stokes_th_);
996 champs_compris.add(pressure_field_Stokes_th_.valeur());
1008 FT_disc_calculer_champs_rho_mu_nu_mono(zdis, phase_0, champ_rho_elem_, champ_mu_, champ_nu_, champ_rho_faces_);
1021 assembleur_pression()->assembler_rho_variable(
matrice_pression_, champ_rho_faces_.valeur());
1027 DoubleTab& secmem = variables_internes().second_membre_projection->valeurs();
1031 assembleur_pression_->modifier_secmem(secmem);
1038 assembleur_pression_->modifier_solution(
la_pression->valeurs());
1040 DoubleTab& gradP = variables_internes().gradient_pression->valeurs();
1042 solveur_masse->appliquer(gradP);
1047 const DoubleTab& rho_faces = champ_rho_faces_->valeurs();
1051 for (i = 0; i < n; i++)
1052 for (j = 0; j < m; j++)
1053 tab_vitesse(i, j) -= gradP(i, j) / rho_faces(i);
1058 if (le_traitement_particulier)
1060 if (le_traitement_particulier->support_ok())
1061 le_traitement_particulier->associer_champ_masse_volumique(champ_rho_faces_.valeur());
1062 le_traitement_particulier->preparer_calcul_particulier();
1071 return variables_internes().is_penalized;
1076 return variables_internes().shift_secmem2_;
1081 return variables_internes().new_mass_source_;
1086 return variables_internes().ai->valeurs();
1091 return variables_internes().ai->valeurs();
1096 return variables_internes().mpoint->valeurs();
1101 return variables_internes().mpoint->valeurs();
1114 champ_rho_faces_->mettre_a_jour(temps);
1119 particles_eulerian_id_number_post_->mettre_a_jour(temps);
1120 DoubleTab& tab = particles_eulerian_id_number_post_->valeurs();
1151 const int nb_faces = domaine_vf.
nb_faces();
1154 assert(champ.valeurs().dimension(0) == nb_faces);
1161 ArrOfDouble potentiel_sommets;
1170 const double sigma = fluide_dipha.
sigma();
1177 const double clipping_courbure_max = variables_internes().clipping_courbure_interface;
1178 int clip_counter = 0;
1179 for (i = 0; i < n; i++)
1181 double c = courbure_sommets[i];
1185 if (std::fabs(c) > clipping_courbure_max)
1188 c = ((c > 0) ? 1. : -1.) * clipping_courbure_max;
1190 potentiel_sommets[i] = c * sigma;
1195 Cerr <<
"Navier_Stokes_FT_Disc::calculer_champ_forces_superficielles : clip_count " << clip_counter << finl;
1201 if (
milieu().a_gravite())
1205 const double delta_rho = rho_1 - rho_0;
1211 Cerr <<
"Error for the method calculer_champ_forces_superficielles\n";
1212 Cerr <<
"gravite.dimension(1) != Objet_U::dimension" << finl;
1215 const DoubleTab& sommets = maillage.
sommets();
1217 for (i = 0; i < n; i++)
1220 for (
int j = 0; j < dim; j++)
1221 p += sommets(i, j) * gravite(0, j);
1226 double px = sommets(i, 0);
1233 double py = sommets(i, 1);
1239 p += sqrt(dx * dx + dy * dy) * pente;
1242 potentiel_sommets[i] -= p * delta_rho;
1249 DoubleTab poids(potentiel_elements.
valeurs());
1252 const IntTab& facettes = maillage.
facettes();
1254 DoubleTab& valeurs_potentiel_elements = potentiel_elements.
valeurs();
1258 valeurs_potentiel_elements = 0.;
1264 const ArrOfInt& index_facette_elem = intersections.
index_facette();
1265 double pot[3] = { 0., 0., 0. };
1270 for (fa7 = 0; fa7 < nb_facettes; fa7++)
1273 pot[0] = potentiel_sommets[facettes(fa7, 0)];
1274 pot[1] = potentiel_sommets[facettes(fa7, 1)];
1276 pot[2] = potentiel_sommets[facettes(fa7, 2)];
1278 int index = index_facette_elem[fa7];
1279 const double surface_facette = surface_facettes[fa7];
1286 for (i = 0; i < 3; i++)
1289#ifdef AVEC_BUG_SURFACES
1290 const double surf = data.surface_intersection_;
1298 valeurs_potentiel_elements(element) += p;
1299 poids(element) += surf;
1308 if (champ.valeurs().line_size() > 1)
1315 const int nb_elements = poids.
dimension(0);
1316 const IntTab& face_voisins = le_dom_dis->face_voisins();
1318 const IntTab& elem_faces = domainevf.
elem_faces();
1319 const int nb_faces_par_element = elem_faces.
line_size();
1320 DoubleVect copie_valeurs_potentiel_elements(valeurs_potentiel_elements);
1321 DoubleVect copie_poids(poids);
1322 for (element = 0; element < nb_elements; element++)
1324 double potential = 0.;
1327 for (i_face = 0; i_face < nb_faces_par_element; i_face++)
1329 const int face = elem_faces(element, i_face);
1330 const int elem_voisin_0 = face_voisins(face, 0);
1331 const int elem_voisin_1 = face_voisins(face, 1);
1332 const int elem_voisin = elem_voisin_0 + elem_voisin_1 - element;
1333 if (elem_voisin >= 0)
1335 potential += copie_valeurs_potentiel_elements(elem_voisin);
1336 p += copie_poids(elem_voisin);
1339 const double old_weight = copie_poids(element);
1341 if (p > 0. && old_weight == 0.)
1345 static double reduction_factor = 0.1;
1346 potential = potential * reduction_factor;
1347 p = p * reduction_factor;
1349 valeurs_potentiel_elements(element) = potential;
1355 Debog::verifier(
"Navier_Stokes_FT_Disc::calculer_champ_forces_superficielles poids:", poids);
1361 interfacial_area = poids;
1365 DoubleTab& valeurs_potentiel_faces = potentiel_faces.
valeurs();
1366 valeurs_potentiel_faces = 0.;
1367 const DoubleTab& valeurs_potentiel_elements = potentiel_elements.
valeurs();
1368 const int nb_faces_pot = valeurs_potentiel_faces.
dimension(0);
1369 const IntTab& face_voisins = le_dom_dis->face_voisins();
1370 for (face = 0; face < nb_faces_pot; face++)
1375 for (
int i = 0; i < 2; i++)
1377 int element = face_voisins(face, i);
1381 p += poids(element);
1382 pot += valeurs_potentiel_elements(element);
1386 valeurs_potentiel_faces(face) = pot / p;
1389 Debog::verifier(
"Navier_Stokes_FT_Disc::calculer_champ_forces_superficielles valeurs_potentiel_faces:", valeurs_potentiel_faces);
1395 const DoubleTab& valeurs_potentiel_faces = potentiel_faces.
valeurs();
1396 const DoubleTab& valeurs_gradient_i = gradient_indicatrice.
valeurs();
1397 DoubleTab& valeurs_champ = champ.valeurs();
1398 const int nb_compo = valeurs_champ.
line_size();
1400 for (
int face = 0; face < nb_faces; face++)
1402 const double p = valeurs_potentiel_faces(face);
1403 for (
int i = 0; i < nb_compo; i++)
1404 valeurs_champ(face, i) = valeurs_gradient_i(face, i) * p;
1408 Debog::verifier(
"Navier_Stokes_FT_Disc::calculer_champ_forces_superficielles valeurs_champ:", valeurs_champ);
1412double 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)
1414 double indic_ghost = 0.;
1415 ArrOfDouble normale(3), normale_face(3);
1417 if (est_egal(face_surface, 0.))
1423 normale_face[i] = domVF.
face_normales(num_face, i) / face_surface;
1425 if (est_egal(norm, 0.))
1429 const double prodscal = normale_sortante_au_domaine * dotproduct_array(normale, normale_face);
1430 double val = 1. / sqrt(2.);
1431 if (prodscal < -val)
1433 else if (prodscal < 0)
1435 indic_ghost = indic * (1 + prodscal / val);
1436 else if (prodscal < val)
1437 indic_ghost = indic + (1. - indic) * (prodscal / val);
1458#include<Neumann_sortie_libre.h>
1459#include<Dirichlet.h>
1460#include<Dirichlet_homogene.h>
1461#include<Periodique.h>
1463#include<Sortie_libre_rho_variable.h>
1466 if (gradient_i.
que_suis_je() ==
"Champ_Fonc_Face")
1474 const Domaine& domaine = domaine_vf.
domaine();
1481 DoubleTab& indic_p1b = variables_internes().indicatrice_p1b->valeurs();
1485 Cerr <<
"The method Navier_Stokes_FT_Disc::calculer_gradient_indicatrice is developped" << finl;
1486 Cerr <<
"only for an indicatrice field discretized like P0+P1 for the 2D dimension case." << finl;
1487 Cerr <<
"Please change the discretization." << finl;
1490 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())
1492 Cerr <<
"The method Navier_Stokes_FT_Disc::calculer_gradient_indicatrice is developped" << finl;
1493 Cerr <<
"only for an indicatrice field discretized like P0+P1 or P0+P1+Pa for the 3D dimension case." << finl;
1494 Cerr <<
"Please change the discretization." << finl;
1506 for (i = 0; i < nb_elem_tot; i++)
1508 indic_p1b(i) = indicatrice.
valeurs()(i);
1517 if (ghost_correction)
1520 const DoubleTab& inco = indicatrice.
valeurs();
1521 DoubleTab& resu = gradient_i.
valeurs();
1532 int ndeb, nfin, num_face;
1533 for (
int n_bord = 0; n_bord < zvf.
nb_front_Cl(); n_bord++)
1548 for (num_face = ndeb; num_face < nfin; num_face++)
1550 n0 = face_voisins(num_face, 0);
1551 n1 = face_voisins(num_face, 1);
1552 if (!est_egal(n0, n1))
1554 Cerr <<
"Periodic boundary condition with FT is not supported yet." << finl;
1557 coef = face_surfaces(num_face);
1558 for (
int k = 0; k < nbdimr; k++)
1560 const int normale_sortante_au_domaine = (n0 == -1) ? 1 : -1;
1561 const double dSk = normale_sortante_au_domaine * zvf.
face_normales(num_face, k);
1564 Cerr <<
"Check if sign of nk is compatible with the expression" << finl;
1566 Cerr <<
"Check if sign of nk is compatible with the expression" << finl;
1567 Cerr <<
"nk=" << nk << finl;
1568 Cerr <<
"dSk=" << dSk << finl;
1569 Cerr <<
"num_face=" << num_face << finl;
1571 Cerr <<
"code to validate" << finl;
1573 resu(num_face, k) = dSk * (inco(n1) - inco(n0));
1577 else if (sub_type(
Symetrie, la_cl.valeur())) { }
1584 const ArrOfInt& index_elem = intersections.
index_elem();
1585 for (num_face = ndeb; num_face < nfin; num_face++)
1587 n0 = face_voisins(num_face, 0);
1588 n1 = face_voisins(num_face, 1);
1589 int elem = n0 + n1 + 1;
1591 for (
int k = 0; k < nbdimr; k++)
1592 resu(num_face, k) = 0.;
1593 if (index_elem[elem] < 0)
1597 const double indic = inco(elem);
1598 int normale_sortante_au_domaine = (n0 == -1) ? -1 : 1;
1599 const double indic_ghost = compute_indic_ghost(elem, num_face, indic, normale_sortante_au_domaine, zvf, maillage);
1602 coef = face_surfaces(num_face);
1605 resu(num_face) = coef * normale_sortante_au_domaine * (indic_ghost - indic);
1610 for (
int k = 0; k < nbdimr; k++)
1612 normale_sortante_au_domaine = 1;
1613 const double dSk = normale_sortante_au_domaine * zvf.
face_normales(num_face, k);
1616 Cerr <<
"Check if sign of nk is compatible with the expression" << finl;
1617 Cerr <<
"nk=" << dSk / coef << finl;
1618 Cerr <<
"num_face=" << num_face << finl;
1621 resu(num_face, k) = dSk * (indic_ghost - indic);
1641 for (
int n_bord = 0; n_bord < zvf.
nb_front_Cl(); n_bord++)
1649 const int nfin = ndeb + le_bord.
nb_faces();
1654 const int nb_faces = elem_faces.
dimension(1);
1655 for (
int num_face = ndeb; num_face < nfin; num_face++)
1657 const int elem = face_voisins(num_face, 0) + face_voisins(num_face, 1) + 1;
1658 int idx_face_de_lelem = 0;
1659 for (idx_face_de_lelem = 0; idx_face_de_lelem < nb_faces; idx_face_de_lelem++)
1661 if (elem_faces(elem, idx_face_de_lelem) == num_face)
1664 if (nb_faces == idx_face_de_lelem)
1666 Cerr <<
"Face is not found!! " << finl;
1669 const int num_face_den_face = elem_faces(elem, (idx_face_de_lelem +
Objet_U::dimension) % nb_faces);
1676 for (
int c = 0; c < u0.
line_size(); c++)
1677 u0(num_face, c) = u0(num_face_den_face, c);
1683int get_num_face_den_face(
const int num_face,
const int elem,
const IntTab& elem_faces)
1685 const int nb_faces = elem_faces.
dimension(1);
1686 int idx_face_de_lelem = 0;
1687 for (idx_face_de_lelem = 0; idx_face_de_lelem < nb_faces; idx_face_de_lelem++)
1689 if (elem_faces(elem, idx_face_de_lelem) == num_face)
1692 if (nb_faces == idx_face_de_lelem)
1694 Cerr <<
"Face is not found!! " << finl;
1697 const int num_face_den_face = elem_faces(elem, (idx_face_de_lelem +
Objet_U::dimension) % nb_faces);
1698 return num_face_den_face;
1713 DoubleTab& u0 = future_or_past ? champ_u0.
futur() : champ_u0.
valeurs();
1719 const double rho_0 = tab_rho_phase_0(0, 0);
1720 const double rho_1 = tab_rho_phase_1(0, 0);
1722 const double un_sur_rho_0 = 1. / rho_0;
1723 const double un_sur_rho_1 = 1. / rho_1;
1730 const int nn = variables_internes().second_membre_projection->valeurs().
dimension(0);
1735 if (variables_internes().ref_equation_mpoint_)
1737 const DoubleTab& mp = variables_internes().ref_equation_mpoint_->get_mpoint();
1739 if (!variables_internes().mpoint_inactif)
1742 if (variables_internes().ref_equation_mpoint_vap_)
1744 const DoubleTab& mpv = variables_internes().ref_equation_mpoint_vap_->get_mpoint();
1746 if (!variables_internes().mpointv_inactif)
1753 if ((variables_internes().new_mass_source_))
1755 assert(future_or_past ==
false);
1757 const DoubleTab& interfacial_area = variables_internes().ai->valeurs();
1758 const Champ_base& ch_indic = refeq_transport->get_indicatrice();
1759 const DoubleTab& indicatrice = ch_indic.
valeurs();
1761 const IntTab& face_voisins = domaine_vf.
face_voisins();
1762 const int nb_faces = face_voisins.
dimension(0);
1763 const int nb_elem_reel = interfacial_area.
size_reelle();
1765 const DoubleTab& xp = domaine_vf.
xp();
1766 const DoubleTab& xv = domaine_vf.
xv();
1769 DoubleTab u_aux(u0);
1778 Cerr <<
"Using option new_mass_source is not possible yet in VEF. Contact us. " << finl;
1780 for (
int face = 0; face < nb_faces; face++)
1781 for (
int j = 0; j < dim; j++)
1791 for (
int face = 0; face < nb_faces; face++)
1793 const int dir = orientation[face];
1795 const int e1 = face_voisins(face, 0);
1796 const int e2 = face_voisins(face, 1);
1797 const double xf = xv(face, dir);
1807 double nb_elem_effective = 0.;
1809 if (e1 >= 0 && e1< nb_elem_reel )
1811 const double nx = -normale_elements(e1, dir);
1813 const double ai = interfacial_area(e1);
1815 if ((fabs(ai) > DMINFLOAT) && (fabs(nx) > DMINFLOAT))
1820 nb_elem_effective += 1.;
1821 const double d = (xf - xp(e1, dir)) * nx;
1822 switch(phase_pilote)
1832 xx = - un_sur_rho_1 * mpoint[e1] * nx;
1833 xx_aux = - un_sur_rho_0 * mpoint[e1] * nx;
1837 const double un_sur_rho = (d > 0.) ? un_sur_rho_0 : un_sur_rho_1;
1838 xx = - un_sur_rho * mpoint[e1] * nx;
1849 xx = (un_sur_rho_1 - un_sur_rho_0)* mpoint[e1] * nx;
1854 const double p = (d > 0.) ? 0. : (un_sur_rho_1 - un_sur_rho_0);
1855 xx = p * mpoint[e1] * nx;
1867 xx_aux = (un_sur_rho_0 - un_sur_rho_1)* mpoint[e1] * nx;
1871 const double p = (d > 0.) ? (un_sur_rho_0 - un_sur_rho_1) : 0.;
1872 xx = p * mpoint[e1] * nx;
1878 Cerr <<
"Error for the method Navier_Stokes_FT_Disc::calculer_delta_u_interface phase_pilote" << finl;
1884 if (e2 >= 0 && e1< nb_elem_reel)
1886 const double nx = -normale_elements(e2, dir);
1888 const double ai = interfacial_area(e2);
1889 if ((fabs(ai) > DMINFLOAT) && (fabs(nx) > DMINFLOAT))
1891 nb_elem_effective += 1.;
1893 const double d = (xf - xp(e2, dir)) * nx;
1894 switch(phase_pilote)
1904 xx += -un_sur_rho_1 * mpoint[e2] * nx;
1905 xx_aux += -un_sur_rho_0 * mpoint[e2] * nx;
1909 const double un_sur_rho = (d > 0.) ? un_sur_rho_0 : un_sur_rho_1;
1910 xx += -un_sur_rho * mpoint[e2] * nx;
1921 xx += (un_sur_rho_1 - un_sur_rho_0) * mpoint[e2] * nx;
1926 const double p = (d > 0.) ? 0. : (un_sur_rho_1 - un_sur_rho_0);
1927 xx += p * mpoint[e2] * nx;
1939 xx_aux += (un_sur_rho_0 - un_sur_rho_1) * mpoint[e2] * nx;
1943 const double p = (d > 0.) ? (un_sur_rho_0 - un_sur_rho_1) : 0.;
1944 xx += p * mpoint[e2] * nx;
1950 Cerr <<
"Error for the method Navier_Stokes_FT_Disc::calculer_delta_u_interface phase_pilote" << finl;
1956 xx = est_egal(nb_elem_effective, 0.) ? 0. : xx/ nb_elem_effective;
1957 xx_aux = est_egal(nb_elem_effective, 0.) ? 0. : xx_aux/ nb_elem_effective;
1959 u_aux(face) = xx_aux;
1971 const ArrOfInt& index_facette = intersections.
index_facette();
1974 const int nb_faces_per_elem = elem_faces.
line_size();
1975 for (
int facette = 0; facette < mesh.
nb_facettes(); facette++)
1977 int index = index_facette[facette];
1984 for (
int idx_face_de_lelem = 0; idx_face_de_lelem < nb_faces_per_elem; idx_face_de_lelem++)
1986 const int face_of_elem = elem_faces(elem, idx_face_de_lelem);
1988 const int e1 = face_voisins(face_of_elem, 0) + face_voisins(face_of_elem, 1) - elem;
1989 if ((e1 >= 0) && (fabs(interfacial_area(e1)) < DMINFLOAT))
1993 const int num_face_den_face = get_num_face_den_face(face_of_elem, e1, elem_faces);
1994 if (fabs(u0(num_face_den_face)) < DMINFLOAT)
2000 u0(num_face_den_face) = est_egal(indicatrice(e1), 0.) ? u_aux(face_of_elem) : u0(face_of_elem);
2002 u0(num_face_den_face) = u0(face_of_elem);
2017 assert(future_or_past ==
false);
2022 for (
int i = 0; i < n; i++)
2028 const double div_n = phi(i);
2031 const double mp = mpoint[i];
2040 p = d * (1. - 0.5 * div_n * d) * mp;
2044 p = d * (1. - 0.5 * div_n * d + div_n * div_n * d * d / 6.) * mp;
2047 Cerr <<
"Error for the method Navier_Stokes_FT_Disc::calculer_delta_u_interface ordre" << finl;
2050 switch(phase_pilote)
2066 p *= (un_sur_rho_0 - un_sur_rho_1);
2072 p *= (un_sur_rho_1 - un_sur_rho_0);
2077 Cerr <<
"Error for the method Navier_Stokes_FT_Disc::calculer_delta_u_interface phase_pilote" << finl;
2094 Cerr <<
"Error for the method Navier_Stokes_FT_Disc::calculer_delta_u_interface\n" <<
" Non code pour " << champ_u0.
que_suis_je() << finl;
2102 const IntTab& face_voisins = domaine_vf.
face_voisins();
2103 const int nb_faces = domaine_vf.
nb_faces();
2105 for (
int i = 0; i < nb_faces; i++)
2107 for (
int j = 0; j < 2; j++)
2109 const int elem = face_voisins(i, j);
2110 if (elem >= 0 && dist(elem) < -1e20)
2119 solveur_masse->appliquer(u0);
2125 DoubleTab secmem2_loc(secmem2);
2126 DoubleTab secmem2_tmp(secmem2);
2145 DoubleTab nb_voisions_vap(secmem2);
2146 nb_voisions_vap = 0.;
2151 const IntTab& face_voisins = domaine_vf.
face_voisins();
2152 const IntTab& elem_faces = domaine_vf.
elem_faces();
2155 const int nb_elem = elem_faces.
dimension(0);
2157 ArrOfInt list_bc_elems;
2158 ArrOfInt list_bc_faces;
2159 for (
int i=0; i< nb_elem; i++)
2161 if (!est_egal(indicatrice[i],0) && !est_egal(indicatrice[i],1))
2163 secmem2_loc[i] = secmem2[i];
2164 const int nb_voisins = elem_faces.
dimension(1);
2165 for (
int iv=0; iv < nb_voisins; iv++)
2167 const int num_face2 = elem_faces(i,iv);
2168 int elem_voisin = face_voisins(num_face2, 0) + face_voisins(num_face2, 1) - i;
2176 if ( est_egal(indicatrice[elem_voisin],0) )
2178 nb_voisions_vap[i] += 1;
2188 ArrOfInt list_bc_elems_nv;
2191 for (
int iv=0; iv < list_bc_elems.
size_array(); iv++)
2193 const int elem_loc = list_bc_elems[iv];
2194 if (est_egal(nb_voisions_vap[elem_loc],0))
2196 const int face_loc = list_bc_faces[iv];
2197 const int dir = orientation[face_loc];
2198 const double nx = normale_elements(elem_loc, 1-dir);
2204 int num_face_next = elem_faces(elem_loc,iface);
2205 int elem = elem_loc;
2207 bool found_elem = 0;
2209 for (
int count = 0; count<5; count++)
2211 elem = face_voisins(num_face_next, 0) + face_voisins(num_face_next, 1) - elem;
2216 if (!est_egal(nb_voisions_vap[elem],0))
2218 secmem2_loc[elem] += secmem2_loc[elem_loc];
2219 secmem2_loc[elem_loc] = 0.;
2233 for (
int iv=0; iv < list_bc_elems_nv.
size_array(); iv++)
2235 const int elem_loc = list_bc_elems_nv[iv];
2236 nb_voisions_vap[elem_loc] += 1;
2247 double sum_loc = 0.;
2248 double sum_orig = 0.;
2252 for (
int i=0; i< nb_elem; i++)
2254 sum_loc += secmem2_loc[i];
2255 sum_orig += secmem2[i];
2261 if (abs(sum_loc-sum_orig) > 0.01*abs(sum_orig) )
2263 Cerr<<
"Balance of seconde memeber 2: "<<finl;
2264 Cerr<<
" sum been pre-restributed-0: "<< sum_loc <<
" origianl sum: "<<sum_orig<<finl;
2265 Process::exit(
"[Navier_Stokes_FT_Disc::shift_secmem2]: !!! shift second member failed");
2271 for (
int i=nb_reel; i<nb_tot; i++)
2272 secmem2_loc[i] = 0.;
2276 for (
int i=0; i< nb_elem; i++)
2278 if (!est_egal(indicatrice[i],0) && !est_egal(indicatrice[i],1))
2280 if ( est_egal(nb_voisions_vap[i],0) && !est_egal(secmem2_loc[i],0))
2282 int nb_voisin_mix_usefuel = 0;
2283 ArrOfInt list_useful_elems;
2284 const int nb_voisins = elem_faces.
dimension(1);
2285 for (
int iv=0; iv < nb_voisins; iv++)
2287 const int num_face2 = elem_faces(i,iv);
2288 int elem_voisin = face_voisins(num_face2, 0) + face_voisins(num_face2, 1) - i;
2292 if (!est_egal(nb_voisions_vap[elem_voisin],0) )
2294 nb_voisin_mix_usefuel += 1;
2300 if (est_egal(nb_voisin_mix_usefuel,0))
2302 Process::exit(
"[Navier_Stokes_FT_Disc::shift_secmem2]: !!! ALL neigher of one elem has no vap neighers" );
2305 for (
int iv=0; iv < list_useful_elems.
size_array(); iv++)
2307 const int elem_loc = list_useful_elems[iv];
2308 secmem2_loc[elem_loc] += secmem2_loc[i]/nb_voisin_mix_usefuel;
2322 for (
int i=0; i< nb_elem; i++)
2325 sum_loc += secmem2_loc[i];
2326 if ( (!est_egal(secmem2_loc[i],0)) && est_egal(nb_voisions_vap[i],0))
2328 Cerr<<
" secmem2_loc non nulle: "<< secmem2_loc[i] <<
" nb_voisions_vap "<<nb_voisions_vap[i]<<finl;
2329 Process::exit(
"[Navier_Stokes_FT_Disc::shift_secmem2]: !!! shift second member failed");
2335 if (abs(sum_loc-sum_orig) > 0.01*abs(sum_orig) )
2337 Cerr<<
"Balance of seconde memeber 2: "<<finl;
2338 Cerr<<
" sum been pre-restributed-1: "<< sum_loc <<
" origianl sum: "<<sum_orig<<finl;
2339 Process::exit(
"[Navier_Stokes_FT_Disc::shift_secmem2]: !!! shift second member failed");
2358 for (
int i=0; i< nb_elem; i++)
2360 if (!est_egal(indicatrice[i],0) && !est_egal(indicatrice[i],1))
2362 if ( !est_egal(nb_voisions_vap[i],0) )
2364 const int nb_voisins = elem_faces.
dimension(1);
2365 for (
int iv=0; iv < nb_voisins; iv++)
2367 const int num_face2 = elem_faces(i,iv);
2368 int elem_voisin = face_voisins(num_face2, 0) + face_voisins(num_face2, 1) - i;
2371 if (est_egal(indicatrice[elem_voisin],0) )
2373 secmem2_tmp[elem_voisin] += secmem2_loc[i]/nb_voisions_vap[i];
2381 for (
int iv=0; iv < list_bc_elems_nv.
size_array(); iv++)
2383 const int elem_loc = list_bc_elems_nv[iv];
2384 secmem2_tmp[elem_loc] += secmem2_loc[elem_loc]/nb_voisions_vap[elem_loc];
2390 double sum_tmp = 0.;
2394 for (
int i=0; i< nb_elem; i++)
2396 sum_tmp += secmem2_tmp[i];
2402 if (abs(sum_tmp-sum_orig) > 0.01*abs(sum_orig) )
2404 Cerr<<
"Balance of seconde memeber 2: "<<finl;
2405 Cerr<<
" sum been restributed: "<< sum_tmp <<
" origianl sum: "<<sum_orig<<finl;
2406 Process::exit(
"[Navier_Stokes_FT_Disc::shift_secmem2]: !!! shift second member failed");
2409 secmem2 = secmem2_tmp;
2413double calculer_indicatrice_face_privilegie_pure(
const DoubleTab& indicatrice,
const IntTab& face_voisins,
const int num_face)
2415 const int elem0 = face_voisins(num_face, 0);
2416 const int elem1 = face_voisins(num_face, 1);
2417 double indic_0 = (elem0 >= 0) ? indicatrice[elem0] : indicatrice[elem1];
2418 double indic_1 = (elem1 >= 0) ? indicatrice[elem1] : indicatrice[elem0];
2421 if (indic_0 == 0. || indic_0 == 1.)
2423 if (indic_1 == 0. || indic_1 == 1.)
2425 const double indic_face = (indic_0 + indic_1) * 0.5;
2429double calculer_indicatrice_face_based_on_ai(
const DoubleTab& indicatrice,
const DoubleTab& indicatrice_faces,
const IntTab& face_voisins,
const Domaine_VF& domaine_vf,
2430 const DoubleTab& interfacial_area,
const DoubleTab& normale_elements,
const int face,
const int dim)
2432 double indic_face = 0.;
2434 for (v = 0; v < 2; v++)
2436 const int elem = face_voisins(face, v);
2440 const double indic = indicatrice[elem];
2442 if (indic <= 5e-3 || indic >= 1. - 5e-3)
2444 indic_face = 1 - indic;
2451 const double ai = interfacial_area(elem);
2452 if (fabs(ai) > DMINFLOAT)
2457 for (
int j = 0; j < dim; j++)
2460 const double nx = normale_elements(elem, j);
2465 indic_face += 1 - x;
2467 Cerr <<
"Never tested. To be verified. It should depend on a scalar product with the vect (xp-xv)" << finl;
2476 const int dir = orientation[face];
2477 const double nx = normale_elements(elem, dir);
2481 x = ai / surface * nx;
2484 indic_face += 1 - x;
2492 indic_face += (1. - indicatrice_faces[face]);
2498 Cerr <<
" WTF, c'est impossible" << finl;
2506 const int elem_voisin = face_voisins(face, 1 - v);
2507 const double indic = indicatrice[elem_voisin];
2508 indic_face = 1 - indic;
2520 if (indic_face > 1.)
2525void 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,
2529 const int n0 = face_voisins(num_face, 0);
2530 const int n1 = face_voisins(num_face, 1);
2531 if ((n0 == -1) or (n1 == -1))
2534 const int outward_normal = (n0 == -1) ? -1 : 1;
2535 const int elem = n0 + n1 + 1;
2536 const double indic_ghost = compute_indic_ghost(elem, num_face, indicatrice(elem), outward_normal, zvf, maillage);
2537 indic_face = indic_ghost;
2538 if ((privilegie_pure) && (est_egal(indicatrice(elem), 1.) || est_egal(indicatrice(elem), 0.)))
2540 indic_face = indicatrice(elem);
2556 const double delta_rho = rho_0 - rho_1;
2558 double rho_0_sur_delta_rho = 0.;
2560 rho_0_sur_delta_rho = rho_0 / delta_rho;
2571 DoubleTab tmp(tab_vitesse);
2572 const int dim = tab_vitesse.
line_size();
2577 resu.
copy(variables_internes().second_membre_projection->valeurs(), RESIZE_OPTIONS::NOCOPY_NOINIT);
2594 if (variables_internes().ref_equation_mpoint_ || variables_internes().ref_equation_mpoint_vap_)
2599 tmp += variables_internes().vitesse_jump0_->valeurs();
2608 if (variables_internes().ref_equation_mpoint_ || variables_internes().ref_equation_mpoint_vap_)
2613 tmp -= variables_internes().delta_u_interface->valeurs();
2622 resu[i] *= indicatrice[i];
2632 tmp += variables_internes().vitesse_jump1_->valeurs();
2637 switch(variables_internes_.type_interpol_indic_pour_dI_dt_)
2642 for (
int i = 0; i < n; i++)
2644 double indic_face = calculer_indicatrice_face_privilegie_pure(indicatrice, face_voisins, i);
2645 if (ghost_correction)
2646 correct_indicatrice_face_bord(i, maillage, domVF, face_voisins, indicatrice,
true , indic_face);
2647 const double x = rho_0_sur_delta_rho - indic_face;
2648 for (
int j = 0; j < dim; j++)
2655 for (
int i = 0; i < n; i++)
2657 double indic_face = calculer_indicatrice_face_privilegie_pure(indicatrice, face_voisins, i);
2658 if (ghost_correction)
2659 correct_indicatrice_face_bord(i, maillage, domVF, face_voisins, indicatrice,
true , indic_face);
2660 const double x = -indic_face;
2661 for (
int j = 0; j < dim; j++)
2669 refeq_transport->update_indicatrice_faces();
2670 const DoubleTab& indicatrice_faces = refeq_transport->get_indicatrice_faces().valeurs();
2671 for (
int i = 0; i < n; i++)
2673 double indic_face = indicatrice_faces(i);
2674 if (ghost_correction)
2675 correct_indicatrice_face_bord(i, maillage, domVF, face_voisins, indicatrice,
false, indic_face);
2676 const double x = rho_0_sur_delta_rho - indic_face;
2677 for (
int j = 0; j < dim; j++)
2684 refeq_transport->update_indicatrice_faces();
2685 const DoubleTab& indicatrice_faces = refeq_transport->get_indicatrice_faces().valeurs();
2686 for (
int i = 0; i < n; i++)
2688 double indic_face = indicatrice_faces(i);
2689 if (ghost_correction)
2690 correct_indicatrice_face_bord(i, maillage, domVF, face_voisins, indicatrice,
false, indic_face);
2691 const double x = -indic_face;
2692 for (
int j = 0; j < dim; j++)
2701 refeq_transport->update_indicatrice_faces();
2702 const DoubleTab& indicatrice_faces = refeq_transport->get_indicatrice_faces().valeurs();
2705 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;
2708 const DoubleTab& interfacial_area = variables_internes().ai->valeurs();
2711 const DoubleTab& xp = domaine_vf.
xp();
2712 const DoubleTab& xv = domaine_vf.
xv();
2716 for (
int face = 0; face < n; face++)
2718 double indic_face = calculer_indicatrice_face_based_on_ai(indicatrice, indicatrice_faces, face_voisins, domaine_vf, interfacial_area, normale_elements, face, dim);
2719 if (ghost_correction)
2720 correct_indicatrice_face_bord(face, maillage, domVF, face_voisins, indicatrice,
false, indic_face);
2723 const double val = 1.-indicatrice_faces[face];
2724 if (fabs(indic_face-val)>DMINFLOAT)
2726 const int elem0 = face_voisins(face, 0);
2727 const int elem1 = face_voisins(face, 1);
2728 double indic_0 = (elem0 >= 0) ? indicatrice[elem0] : indicatrice[elem1];
2729 double indic_1 = (elem1 >= 0) ? indicatrice[elem1] : indicatrice[elem0];
2731 Cerr <<
"xp0["<< elem0<<
"]: " << xp(elem0, 0) <<
" " << xp(elem0, 1) <<
" " << finl;
2733 Cerr <<
"xp0: bord!" <<finl;
2735 Cerr <<
"xp1["<< elem1<<
"]: " << xp(elem1, 0) <<
" " << xp(elem1, 1) <<
" " << finl;
2737 Cerr <<
"xp1: bord!" <<finl;
2739 Cerr <<
"xv: " << xv(face, 0) <<
" " << xv(face, 1) <<
" " << finl;
2740 Cerr <<
"voisins (ou ghost): " << indic_0 <<
" " << indic_1 << finl;
2741 Cerr <<
"GB whats up?face="<< face <<
" indic / val / diff " << indic_face <<
" " << val <<
" " << indic_face-val << finl;
2745 for (
int j = 0; j < dim; j++)
2746 tmp(face, j) *= indic_face;
2751 Cerr <<
" Navier_Stokes_FT_Disc::calculer_dI_dt \n" <<
" unknown case?" << finl;
2782 switch(variables_internes_.OutletCorrection_pour_dI_dt_)
2798 for (
int n_bord = 0; n_bord < zvdf.
nb_front_Cl(); n_bord++)
2814 for (
int num_face = ndeb; num_face < nfin; num_face++)
2816 const int n0 = face_voisins(num_face, 0);
2817 const int n1 = face_voisins(num_face, 1);
2818 const int elem = n0 + n1 + 1;
2819 const double indic = indicatrice(elem);
2820 if (indic * (1 - indic) > 1e-6)
2822 const double coef = face_surfaces(num_face);
2827 for (
int j = 0; j < dim; j++)
2829 const int outward_normal = (n0 == -1) ? -1 : 1;
2830 double flux_bord_calcule_par_operateur_div = 0.;
2831 flux_bord_calcule_par_operateur_div = outward_normal * coef * tmp(num_face, j);
2832 resu(elem) -= flux_bord_calcule_par_operateur_div;
2848 Cerr <<
"unexpected" << finl;
2854 assert(nb_elem == dI_dt.
size());
2867 Cerr <<
"[BEFORE-PCH] Locally, the maximum of dI_dt is : " << dI_dt.
mp_max_abs_vect() << finl;
2870 for (
int i=0; i< nb_elem; i++)
2872 Cerr <<
"[BEFORE-PCH] " << temps <<
" The sum is : " << sum <<
" [not valid in //]" << finl;
2876 switch(variables_internes_.type_interpol_indic_pour_dI_dt_)
2889 Cerr <<
"Checking if secmem2 is correctly filled in that case. Check it if you need it..." <<finl;
2891 DoubleTab& secmem2 = variables_internes().second_membre_projection_jump_.valeurs();
2903 const double rho_phase_0 = tab_rho_phase_0(0,0);
2904 const double rho_phase_1 = tab_rho_phase_1(0,0);
2905 const double jump_inv_rho = 1./rho_phase_1 - 1./rho_phase_0;
2907 const DoubleTab& interfacial_area = variables_internes().ai->valeurs();
2910 DoubleTab mpoint = variables_internes().ref_equation_mpoint_->get_mpoint();
2911 if (variables_internes().ref_equation_mpoint_vap_)
2914 const DoubleTab& mpointv = variables_internes().ref_equation_mpoint_vap_->get_mpoint();
2915 for (
int elem = 0; elem < nb_elem; elem++)
2916 mpoint[elem] += mpointv[elem];
2918 for (
int elem = 0; elem < nb_elem; elem++)
2920 double diff = (secmem2[elem] - jump_inv_rho*interfacial_area[elem]*mpoint[elem]);
2921 if (fabs(diff)>DMINFLOAT)
2923 Cerr <<
"Problem, secmem2 is not filled properly in that case? "
2924 <<
"elem= " << elem <<
" diff=" << diff <<finl;
2930 if ((
bool(variables_internes().ref_equation_mpoint_)) && !variables_internes().mpoint_inactif)
2934 const double un_sur_rho_0 = 1. / rho_0;
2938 const DoubleTab& interfacial_area = variables_internes().ai->valeurs();
2941 DoubleTab mpoint = variables_internes().ref_equation_mpoint_->get_mpoint();
2942 if (variables_internes().ref_equation_mpoint_vap_)
2946 const DoubleTab& mpointv = variables_internes().ref_equation_mpoint_vap_->get_mpoint();
2947 for (
int elem = 0; elem < nb_elem; elem++)
2948 mpoint[elem] += mpointv[elem];
2964 Cerr <<
"[TCL] Contact line model activated in volume correction" << finl;
2968 for (
int elem = 0; elem < nb_elem; elem++)
2975 const double x = mpoint[elem] * interfacial_area[elem] * un_sur_rho_0;
2987 const double un_sur_rho_0 = 1. / rho_0;
2988 const DoubleTab& interfacial_area = variables_internes().ai->valeurs();
2989 Cerr <<
"[TCL] Contact line model activated in volume correction" << finl;
2993 for (
int idx = 0; idx < tcl_elems.
size_array(); idx++)
2995 const int elem = tcl_elems[idx];
3001 const double x = tcl_mp[idx] * interfacial_area[elem] * un_sur_rho_0;
3013 Cerr <<
"[AFTER-PCH] Locally, the maximum of dI_dt is : " << dI_dt.
mp_max_abs_vect() << finl;
3016 for (
int i=0; i< nb_elem; i++)
3018 Cerr <<
"[AFTER-PCH] " << temps <<
" The sum is : " << sum <<
" [not valid in //]" << finl;
3024 const double un_sur_rho_1 = 1. / rho_1;
3025 const DoubleTab& interfacial_area = variables_internes().ai->valeurs();
3026 DoubleTab mpoint(interfacial_area);
3028 if (variables_internes().ref_equation_mpoint_)
3030 const DoubleTab& mp = variables_internes().ref_equation_mpoint_->get_mpoint();
3032 if (!variables_internes().mpoint_inactif)
3035 if (variables_internes().ref_equation_mpoint_vap_)
3037 const DoubleTab& mpv = variables_internes().ref_equation_mpoint_vap_->get_mpoint();
3039 if (!variables_internes().mpointv_inactif)
3042 for (
int i = 0; i < nb_elem; i++)
3043 dI_dt[i] += mpoint[i]*un_sur_rho_1*interfacial_area[i];
3053void compute_normale_barycenter_area_in_cell(
const int elem,
const Maillage_FT_Disc& mesh,
Vecteur3& normale,
Vecteur3& bary_facettes_dans_elem,
double& surface_tot)
3056 const IntTab& facettes = mesh.
facettes();
3057 const DoubleTab& sommets = mesh.
sommets();
3063 bary_facettes_dans_elem = 0.;
3066 int index = intersections.
index_elem()[elem];
3077 const double surface_facette = surface_facettes[fa7];
3083 Vecteur3 coord_barycentre_fraction(0., 0., 0.);
3084 for (
int dir = 0; dir < 3; dir++)
3086 const double nx = normale_facettes(fa7, dir);
3087 normale[dir] += nx * surf;
3089 for (
int isom = 0; isom < 3; isom++)
3091 const int num_som = facettes(fa7, isom);
3093 for (
int dir = 0; dir < 3; dir++)
3094 coord_barycentre_fraction[dir] += bary_som * sommets(num_som, dir);
3097 coord_barycentre_fraction *= surf;
3098 surface_tot += surf;
3099 bary_facettes_dans_elem += coord_barycentre_fraction;
3104 if (surface_tot > 0.)
3106 normale *= 1. / surface_tot;
3107 bary_facettes_dans_elem *= 1. / surface_tot;
3112 Cerr <<
" Error in compute_normale_barycenter_area_in_cell (Navier_Stokes_FT_Disc.cpp)." << finl;
3113 Cerr <<
"The element " << elem <<
" only contains facettes of surface=0, so that surface_totale is zero!" << finl;
3114 Cerr <<
"What a mess for the barycentre? ..." << finl;
3117 bary_facettes_dans_elem = 0.;
3120 const double norm = normale[0]*normale[0] + normale[1]*normale[1] + normale[2]*normale[2];
3123 Cerr <<
" In Navier_Stokes_FT_Disc.cpp compute_normale_barycenter_area_in_cell." << finl;
3124 Cerr <<
"Small normal : " << count <<
" facettes dans l'element " << elem
3125 <<
". surface_tot = "<< surface_tot <<
"Norm**2 = " << norm << finl;
3132 const DoubleVect& volumes_entrelaces,
const IntVect& orientation,
const DoubleTab& indicatrice,
const ArrOfDouble& g,
3133 DoubleTab& gravite_face)
const
3138 const DoubleTab& tab_beta_th_phase_eq = fluide_phase_eq.
beta_t().
valeurs();
3139 const double beta_th_phase_eq = tab_beta_th_phase_eq(0, 0);
3141 for (
int face = 0; face < gravite_face.
dimension(0); face++)
3143 const int elem0 = face_voisins(face, 0);
3144 const int elem1 = face_voisins(face, 1);
3155 double chi = (2 * phase_eq - 1) * indicatrice[elem0] + 1 - phase_eq;
3156 double T_eq = temperature_eq[elem0];
3161 double chi = (2 * phase_eq - 1) * indicatrice[elem1] + 1 - phase_eq;
3162 double T_eq = temperature_eq[elem1];
3165 if (elem0 >= 0 && elem1 >= 0)
3167 gravite_face(face) -= volumes_entrelaces(face) * g(orientation[face]) * coef * beta_th_phase_eq;
3191 terme_diffusif.calculer(la_vitesse->valeurs(), variables_internes().terme_diffusion->valeurs());
3192 if (correction_diffusion_pch_)
3194 DoubleTab& diffusion = variables_internes().terme_diffusion->valeurs();
3195 DoubleTab diffusion_liq(diffusion);
3196 DoubleTab diffusion_vap(diffusion);
3198 variables_internes().ref_eq_interf_proprietes_fluide;
3199 if (refeq_transport)
3204 if (variables_internes().ref_equation_mpoint_)
3211 if (variables_internes().ref_equation_mpoint_vap_)
3219 if ((phase_liq == 1) && (phase_vap == 0))
3225 Cerr <<
"error bad weighting below" << finl;
3228 refeq_transport->update_indicatrice_faces();
3229 const DoubleTab& indicatrice_faces = refeq_transport->get_indicatrice_faces().valeurs();
3230 const DoubleTab& dist_faces = refeq_transport.valeur().get_update_distance_interface_faces().valeurs();
3231 for (
int i = 0; i < diffusion.dimension(0) ; i++)
3233 const double indic_f = indicatrice_faces(i);
3235 if (std::fabs(dist_faces(i))< 3.*1.414e-6)
3237 diffusion(i) = (indic_f)* diffusion_liq(i) + (1-indic_f)* diffusion_vap(i) ;
3242 solveur_masse->appliquer(variables_internes().terme_diffusion->valeurs());
3255 if (refeq_transport)
3257 const Champ_base& indicatrice = refeq_transport->get_indicatrice();
3258 Champ_base& gradient_i = variables_internes().gradient_indicatrice.valeur();
3267 calculer_champ_forces_superficielles(maillage, gradient_i, variables_internes().potentiel_elements, variables_internes().potentiel_faces, variables_internes().terme_source_interfaces);
3273 variables_internes().terme_source_interfaces->valeurs() = 0.;
3276 solveur_masse->appliquer(variables_internes().terme_source_interfaces->valeurs());
3277 if (
is_solid_particle_) solveur_masse->appliquer(variables_internes().contact_force_source_term->valeurs());
3285 variables_internes().terme_source->valeurs() = 0.;
3286 les_sources.ajouter(variables_internes().terme_source->valeurs());
3287 solveur_masse->appliquer(variables_internes().terme_source->valeurs());
3295 DoubleTab& terme_convection_valeurs = variables_internes().terme_convection->valeurs();
3296 bool calcul_explicite =
false;
3302 if (
schema_temps().diffusion_implicite() && !calcul_explicite)
3304 terme_convection_valeurs = 0;
3309 terme_convectif.calculer(la_vitesse->valeurs(), terme_convection_valeurs);
3311 solveur_masse->appliquer(variables_internes().terme_convection->valeurs());
3314 const DoubleTab& tab_rho_faces = champ_rho_faces_->valeurs();
3316 const DoubleTab& tab_diffusion = variables_internes().terme_diffusion->valeurs();
3317 const DoubleTab& termes_sources_interf = variables_internes().terme_source_interfaces->valeurs();
3318 const DoubleTab& termes_sources = variables_internes().terme_source->valeurs();
3319 const DoubleTab& tab_convection = variables_internes().terme_convection->valeurs();
3320 const DoubleTab& contact_force_source_term = variables_internes().contact_force_source_term->valeurs();
3322 const int nbdim1 = (vpoint.
line_size() == 1);
3325 DoubleTab gravite_face(
inconnue().valeurs());
3326 if (
milieu().a_gravite())
3333 Cerr <<
"Error for calculer_champ_forces_superficielles\n";
3334 Cerr <<
" gravite.line_size() != Objet_U::dimension" << finl;
3338 g[j] = gravite(0, j);
3344 const IntTab& face_voisins = le_dom_dis->face_voisins();
3348 for (
int face = 0; face < n; face++)
3349 gravite_face(face, 0) = volumes_entrelaces(face) * g[orientation[face]];
3356 if (variables_internes().is_boussinesq_)
3359 if (!refeq_transport)
3361 Cerr <<
"Trying to use Boussinesq approximation on a 2phase flow when the transport equation is not specified" << finl;
3364 const DoubleTab& indicatrice = refeq_transport->get_indicatrice().valeurs();
3366 if (variables_internes().ref_equation_mpoint_)
3373 if (variables_internes().ref_equation_mpoint_vap_)
3385 if (variables_internes().is_boussinesq_)
3387 Cerr <<
"Trying to use Boussinesq approximation on a 2phase flow in VEF? Not yet available. Ask TRUST support." << finl;
3392 for (
int face = 0; face < n; face++)
3393 for (
int dim = 0; dim < m; dim++)
3394 gravite_face(face, dim) = volumes_entrelaces(face) * g[dim];
3401 solveur_masse->appliquer(gravite_face);
3409 IntTab flag_gradP(n);
3413 DoubleTab& gradP = variables_internes().gradient_pression->valeurs();
3418 solveur_masse->appliquer(gradP);
3420 if (variables_internes().is_penalized)
3427 if (!variables_internes().is_explicite && !calcul_explicite)
3438 bool interf_vitesse_imposee_ok =
false;
3439 int nb_eqs = variables_internes().ref_eq_interf_vitesse_imposee.
size();
3440 int nb_eq_non_nul = 0;
3441 for (
int k = 0; k < nb_eqs; k++)
3445 if (refeq_transport)
3448 DoubleTab terme_mul;
3449 if (nb_eq_non_nul == nb_eqs && nb_eqs != 0)
3451 interf_vitesse_imposee_ok =
true;
3452 terme_mul.
copy(champ_rho_faces_->valeurs(), RESIZE_OPTIONS::COPY_INIT);
3457 if (refeq_transport_2pha && interf_vitesse_imposee_ok && variables_internes().is_penalized)
3461 const IntTab& face_voisins = domaine_vf.
face_voisins();
3462 const IntTab& elem_faces = domaine_vf.
elem_faces();
3463 const IntVect& orientation = domaine_vdf.
orientation();
3464 const int nb_faces_elem = elem_faces.
line_size();
3465 for (
int k = 0; k < nb_eqs; k++)
3468 const DoubleTab& indicatrice_faces = refeq_transport->get_indicatrice_faces().valeurs();
3469 for (
int i = 0; i < face_voisins.
dimension(0); i++)
3471 if (indicatrice_faces(i) > 0.)
3475 const int ori = orientation(i);
3476 const int voisin0 = face_voisins(i, 0);
3479 int face_visavi = elem_faces(voisin0, ori) + elem_faces(voisin0, ori +
Objet_U::dimension) - i;
3480 for (
int i_face = 0; i_face < nb_faces_elem; i_face++)
3482 const int face = elem_faces(voisin0, i_face);
3483 if (indicatrice_faces(face) == 0. && face == face_visavi)
3485 flag_gradP(face) = 0;
3490 const int voisin1 = face_voisins(i, 1);
3493 int face_visavi = elem_faces(voisin1, ori) + elem_faces(voisin1, ori +
Objet_U::dimension) - i;
3494 for (
int i_face = 0; i_face < nb_faces_elem; i_face++)
3496 const int face = elem_faces(voisin1, i_face);
3497 if (indicatrice_faces(face) == 0. && face == face_visavi)
3499 flag_gradP(face) = 0;
3510 for (
int i = 0; i < n; i++)
3512 const double rho_face = tab_rho_faces(i);
3514 for (
int j = 0; j < m; j++)
3515 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))
3516 / rho_face + tab_convection(i, j) + termes_sources(i, j) + gravite_face(i, j);
3521 if (
schema_temps().diffusion_implicite() && !calcul_explicite && variables_internes().is_explicite)
3523 DoubleTab derivee(la_vitesse->valeurs());
3525 solveur_masse->set_name_of_coefficient_temporel(champ_rho_faces_->le_nom());
3527 DoubleTrav tt(vpoint);
3532 solveur_masse->set_name_of_coefficient_temporel(
"no_coeff");
3536 for (
int i = 0; i < n; i++)
3537 for (
int j = 0; j < m; j++)
3538 vpoint(i, j) += gradP(i, j) / tab_rho_faces(i);
3543 if (interf_vitesse_imposee_ok)
3545 int compteur_vimp_regul = 0;
3546 DoubleTrav vpoint0(vpoint);
3550 DoubleTrav forces_tot(vpoint);
3551 int nb_eqs_bis = variables_internes().ref_eq_interf_vitesse_imposee.size();
3552 for (
int k = 0; k < nb_eqs_bis; k++)
3559 const DoubleTab& rho_faces = champ_rho_faces_->valeurs();
3560 DoubleTab& source_val = variables_internes().terme_source->valeurs();
3566 eq_transport.
modifier_vpoint_pour_imposer_vit(inco_val, vpoint0, vpoint, rho_faces, source_val, temps, dt, variables_internes().is_explicite, variables_internes().eta);
3568 forces_tot += source_val;
3573 compteur_vimp_regul++;
3575 if (!variables_internes().is_explicite)
3577 const DoubleTab& indicatrice_faces = refeq_transport->get_indicatrice_faces().valeurs();
3578 for (
int i = 0; i < nfaces; i++)
3580 if ((eq_transport.
get_vimp_regul() == 0 && indicatrice_faces(i) > 0.) || (eq_transport.
get_vimp_regul() == 1 && indicatrice_faces(i) == 1.))
3581 terme_mul(i) += 1. / variables_internes().eta;
3586 Debog::verifier(
"Navier_Stokes_FT_Disc::derivee_en_temps_inco terme_mul:", terme_mul);
3592 if (!variables_internes().is_explicite && !calcul_explicite)
3594 const DoubleTab& rho_faces = champ_rho_faces_->valeurs();
3595 const DoubleTab& diffusion = variables_internes().terme_diffusion->valeurs();
3597 for (
int i = 0; i < vpoint.
dimension(0); i++)
3598 for (
int j = 0; j < vpoint.
line_size(); j++)
3599 vpoint(i, j) -= diffusion(i, j) / rho_faces(i);
3602 DoubleTab derivee(la_vitesse->valeurs());
3605 solveur_masse->set_name_of_coefficient_temporel(champ_rho_faces_->le_nom());
3607 DoubleTrav tt(vpoint);
3611 solveur_masse->set_name_of_coefficient_temporel(
"no_coeff");
3618 for (
int i = 0; i < nbis; i++)
3619 for (
int j = 0; j < mbis; j++)
3620 vpoint(i, j) += (flag_gradP(i) * gradP(i, j)) / rho_faces(i);
3628 if (!variables_internes().is_explicite)
3632 for (
int i = 0; i < nfaces; i++)
3633 for (
int j = 0; j < mbis; j++)
3634 vpoint(i, j) /= terme_mul(i);
3640 Debog::verifier(
"Navier_Stokes_FT_Disc::derivee_en_temps_inco vpoint:", vpoint);
3645 if (!variables_internes().is_explicite && compteur_vimp_regul)
3649 DoubleTrav forces_totbis(vpoint);
3650 for (
int k = 0; k < nb_eqs_bis; k++)
3657 const DoubleTab& rho_faces = champ_rho_faces_->valeurs();
3658 DoubleTab& source_val = variables_internes().terme_source->valeurs();
3666 forces_totbis += source_val;
3675 const DoubleTab& tab_rho_facesbis = champ_rho_faces_->valeurs();
3676 for (
int k = 0; k < nb_eqs_bis; k++)
3690 if (!interf_vitesse_imposee_ok)
3692 if (!variables_internes().matrice_pression_invariante)
3694 assembleur_pression()->assembler_rho_variable(
matrice_pression_, champ_rho_faces_.valeur());
3715 DoubleTab& secmem = variables_internes().second_membre_projection->valeurs();
3716 DoubleTab& secmem2 = variables_internes().second_membre_projection_jump_->valeurs();
3717 const int nb_elem = secmem2.
dimension(0);
3727 double int_sec_mem = 0;
3728 for (
int elem = 0; elem < secmem.
dimension(0); elem++)
3729 int_sec_mem +=secmem(elem);
3730 Cerr <<
"Secmem before tcl= " << int_sec_mem << finl;
3735 const Noms& noms_eq = variables_internes().equations_concentration_source_fluide_;
3736 for (
int i_eq = 0; i_eq < noms_eq.size(); i_eq++)
3739 for (
int i_source = 0; i_source < eq.
sources().size(); i_source++)
3752 if (variables_internes().ref_equation_mpoint_ || variables_internes().ref_equation_mpoint_vap_)
3763 if (variables_internes().ref_equation_mpoint_)
3764 variables_internes().ref_equation_mpoint_->calculer_mpoint(variables_internes().mpoint.valeur());
3765 if (variables_internes().ref_equation_mpoint_vap_)
3766 variables_internes().ref_equation_mpoint_vap_->calculer_mpoint(variables_internes().mpoint_vap.valeur());
3769 DoubleTab mpoint = variables_internes().ref_equation_mpoint_->get_mpoint();
3770 if (variables_internes().ref_equation_mpoint_vap_)
3772 const DoubleTab& mpointv = variables_internes().ref_equation_mpoint_vap_->get_mpoint();
3773 for (
int elem = 0; elem < nb_elem; elem++)
3774 mpoint[elem] += mpointv[elem];
3788 const double rho_phase_0 = tab_rho_phase_0(0, 0);
3789 const double rho_phase_1 = tab_rho_phase_1(0, 0);
3790 const double jump_inv_rho = 1. / rho_phase_1 - 1. / rho_phase_0;
3791 if (variables_internes().new_mass_source_)
3794 const DoubleTab& interfacial_area = variables_internes().ai->valeurs();
3795 for (
int elem = 0; elem < nb_elem; elem++)
3796 secmem2[elem] = jump_inv_rho * interfacial_area[elem] * mpoint[elem];
3801 const IntTab& face_voisins = domaine_vf.
face_voisins();
3802 const IntTab& elem_faces = domaine_vf.
elem_faces();
3803 const int nb_faces_elem = elem_faces.
line_size();
3811 divergence.calculer(variables_internes().delta_u_interface->valeurs(), secmem2);
3813 for (
int elem = 0; elem < nb_elem; elem++)
3815 const double dist = distance(elem);
3820 i_face = nb_faces_elem;
3825 for (i_face = 0; i_face < nb_faces_elem; i_face++)
3827 const int face = elem_faces(elem, i_face);
3828 const int voisin = face_voisins(face, 0) + face_voisins(face, 1) - elem;
3831 const double d = distance(voisin);
3832 if (d > -1e20 && d * dist < 0.)
3835 Cerr <<
"Compa "<< secmem2[elem] <<
" " << jump_inv_rho*interfacial_area[elem]*mpoint[elem] << finl;
3842 if (i_face == nb_faces_elem)
3847 if(interfacial_area[elem]>DMINFLOAT)
3849 Cerr <<
"[WARNING] secmem2 is set to zero in element whereas phase is not pure (indic= "
3850 << indicatrice[elem] <<
"). This is because the choice is based on the signs of distance." << finl;
3880 Cerr <<
"[TCL] Contact line model is activated" << finl;
3884 const ArrOfInt& elems_with_CL_contrib = tcl.
elems();
3886 const ArrOfDouble& Q_from_CL = tcl.
Q();
3908 const double coef = jump_inv_rho / Lvap;
3910 if (!variables_internes().mpoint_inactif)
3913 const int check_consistency = 1;
3914 if (check_consistency)
3916 Cerr <<
"Verifying Contact line model consistency" << finl;
3918 const int nb_contact_line_contribution = elems_with_CL_contrib.
size_array();
3919 for (
int idx = 0; idx < nb_contact_line_contribution; idx++)
3921 const int elem = elems_with_CL_contrib[idx];
3922 const double sec = secmem2(elem);
3925 for (
int idx2 = 0; idx2 < nb_contact_line_contribution; idx2++)
3927 if (elem == elems_with_CL_contrib[idx2])
3929 Q += Q_from_CL[idx2];
3932 const double value = coef * Q;
3935 error += fabs(sec - value);
3936 if (fabs(sec - value) > 1.e-12)
3938 Cerr <<
"local difference sec-value=" << sec <<
" - " << value <<
" = " << (sec - value) << finl;
3944 Cerr <<
"Final error : " << error <<
" is fatal!" << finl;
3953 if (variables_internes().shift_secmem2_)
3960 double int_sec_mem2 = 0;
3961 double int_sec_mem = 0;
3962 for (
int elem = 0; elem < nb_elem; elem++)
3964 int_sec_mem2 +=secmem2(elem);
3965 int_sec_mem +=secmem(elem);
3967 Cerr <<
"Integral of secmem2 after TCL and /DT : " << int_sec_mem2 << finl;
3968 Cerr <<
"Integral of secmem after TCL and /DT : " << int_sec_mem << finl;
3973 DoubleTab& rho_faces_modifie = champ_rho_faces_modifie->valeurs();
3975 if (interf_vitesse_imposee_ok)
3979 int compteur_vimp_regul = 0;
3980 int nb_eqs_bis = variables_internes().ref_eq_interf_vitesse_imposee.size();
3981 for (
int k = 0; k < nb_eqs_bis; k++)
3987 compteur_vimp_regul++;
3996 int modif_rho_true = 0;
3997 if (variables_internes().is_penalized && (compteur_vimp_regul == 0 || refeq_transport_2pha))
3999 for (
int i = 0; i < nfaces; i++)
4001 if (compteur_vimp_regul != 0)
4003 for (
int k = 0; k < nb_eqs; k++)
4008 if (eq_transport.
get_vimp_regul() == 1 && indicatrice_faces(i) > 0.0 && indicatrice_faces(i) != 1.)
4009 terme_mul(i) += 1.0 / variables_internes().eta;
4012 rho_faces_modifie(i) *= terme_mul(i);
4017 Debog::verifier(
"Navier_Stokes_FT_Disc::derivee_en_temps_inco rho_faces_modifie:", rho_faces_modifie);
4022 assembleur_pression()->assembler_rho_variable(
matrice_pression_, champ_rho_faces_modifie.valeur());
4025 if (modif_rho_true == 1 && variables_internes().p_ref_pena != -1.e40)
4035 const IntTab& elem_faces = domaine_vf.
elem_faces();
4036 const int nb_faces_elem = elem_faces.
line_size();
4038 int numero_global_som, ligne_mat;
4039 int point_fluide_dirichlet = -1;
4040 if (variables_internes().is_pfl_flottant)
4044 point_fluide_dirichlet = mon_dom.
chercher_elements(variables_internes().x_pfl_imp, variables_internes().y_pfl_imp, variables_internes().z_pfl_imp);
4048 point_fluide_dirichlet = mon_dom.
chercher_elements(variables_internes().x_pfl_imp, variables_internes().y_pfl_imp);
4050 if (
mp_max(point_fluide_dirichlet) == -1)
4052 Cerr <<
"Point de reference pression fluide situe en dehors du domaine !" << finl;
4056 for (
int e = 0; e < nb_elem; e++)
4060 for (
int f = 0; f < nb_faces_elem; f++)
4062 int fglob = elem_faces(e, f);
4067 for (
int k = 0; k < nb_eqs_bis && dejafait == 0; k++)
4070 const DoubleTab& indicatrice_faces = refeq_transport->get_indicatrice_faces().valeurs();
4071 if (indicatrice_faces(fglob) > 0.0)
4079 if (nbfpena == nbfglob && nbfpena != 0)
4081 matrice_valeurs(e, e) += 1.0 / variables_internes().eta;
4082 secmem(e) += variables_internes().p_ref_pena / variables_internes().eta;
4083 pressu(e) = variables_internes().p_ref_pena;
4086 for (
int somloc = 0; somloc < nb_sommet; somloc++)
4088 numero_global_som = mon_dom.
sommet_elem(e, somloc);
4089 ligne_mat = nb_elem + numero_global_som;
4091 pressu(ligne_mat) = 0.0;
4095 if (point_fluide_dirichlet == e)
4097 if (nbfpena != nbfglob && nbfpena != 0)
4100 secmem(e) += matrice_valeurs(e, e) * variables_internes().p_ref_pena / (float(nbfglob - nbfpena));
4101 matrice_valeurs(e, e) *= float(nbfglob - nbfpena + 1) / (float(nbfglob - nbfpena));
4105 Cerr <<
"Point de reference pression fluide non situe dans une cellule fluide voisin d'une IBC !" << finl;
4106 Cerr <<
"Nb faces IBC = " << nbfpena << finl;
4120 assembleur_pression_->modifier_secmem(secmem);
4123 statistics().begin_count(STD_COUNTERS::system_solver,statistics().get_last_opened_counter_level()+1);
4125 statistics().end_count(STD_COUNTERS::system_solver);
4127 assembleur_pression_->modifier_solution(
la_pression->valeurs());
4130 solveur_masse->appliquer(gradP);
4137 for (
int i = 0; i < nbis; i++)
4138 for (
int j = 0; j < mbis; j++)
4139 vpoint(i, j) -= gradP(i, j) / rho_faces_modifie(i);
4145 if (interf_vitesse_imposee_ok &&
limpr())
4147 const DoubleTab& rho = champ_rho_faces_->valeurs();
4149 DoubleTrav forces_tot_2(vpoint);
4150 DoubleTrav pressure_part(vpoint);
4151 DoubleTrav diffusion_part(vpoint);
4152 DoubleTrav diffusion_part2(vpoint);
4155 DoubleTab vv(vpoint);
4160 terme_diffusif.calculer(vv, variables_internes().terme_diffusion->valeurs());
4161 variables_internes().terme_diffusion->valeurs().echange_espace_virtuel();
4162 solveur_masse->appliquer(variables_internes().terme_diffusion->valeurs());
4163 const DoubleTab& diffusion = variables_internes().terme_diffusion->valeurs();
4165 DoubleTrav trav(variables_internes().terme_convection->valeurs());
4167 variables_internes().terme_convection->valeurs() = trav;
4168 solveur_masse->appliquer(variables_internes().terme_convection->valeurs());
4169 const DoubleTab& convection = variables_internes().terme_convection->valeurs();
4173 for (
int i = 0; i < nbis; i++)
4174 for (
int j = 0; j < mbis; j++)
4176 pressure_part(i, j) = gradP(i, j);
4177 diffusion_part(i, j) = -rho(i) * convection(i, j) - diffusion(i, j);
4178 diffusion_part2(i, j) = - diffusion(i, j);
4179 forces_tot_2(i, j) = pressure_part(i, j) + diffusion_part(i, j);
4182 int nb_eqs_bis = variables_internes().ref_eq_interf_vitesse_imposee.size();
4183 for (
int k = 0; k < nb_eqs_bis; k++)
4197 return probleme_ft_.valeur();
4202 return probleme_ft_.valeur();
4215 return variables_internes_;
4219 return variables_internes_;
4231 if (variables_internes().ref_equation_mpoint_ ||
4232 variables_internes().ref_equation_mpoint_vap_)
4233 return &(variables_internes().delta_u_interface.valeur());
4246 DoubleTab& phi = variables_internes().laplacien_d->valeurs();
4247 DoubleTab u0(
inconnue().valeurs());
4252 for (
int i = 0; i < n; i++)
4260 solveur_masse->appliquer(u0);
4266 for (
int i = 0; i < n; i++)
4268 const double p = phi(i);
4271 const double v = volumes[i];
4276 return variables_internes().laplacien_d.valeur();
4281 return champ_rho_faces_;
4308 const int nb_elem=domaine_vf.
nb_elem();
4310 ref_eq_interf_proprietes_fluide;
4311 const DoubleTab& volumic_phase_indicator_function = refeq_transport->\
4312 get_indicatrice().valeurs();
4315 for (
int elem = 0; elem < nb_elem; elem++)
4317 if (collision_model_ptr &&
4320 == id_fluid_phase) ? -1 : 1;
4323 != 1 - id_fluid_phase ) ? -1 : 1;
4326 const IntTab& elem_faces = domaine_vf.
elem_faces();
4328 const int nb_local_connex_components = search_connex_components_local(elem_faces,
4338 const int nb_particles_tot=gravity_center_elem.
size_array();
4347 IntVect particle_lagrangian_id_number(nb_particles_tot);
4348 particle_lagrangian_id_number=0;
4349 for (
int id_number=0; id_number<nb_particles_tot; id_number++)
4351 int elem=gravity_center_elem(id_number);
4353 if (elem>-1 && elem < nb_elem_tot)
4360 for (
int elem = 0; elem < nb_elem; elem++)
4374 Cerr <<
"Navier_Stokes_FT_Disc::compute_eulerian_field_contact_forces" << finl;
4376 statistics().create_custom_counter(
"compute_eulerian_field_contact_forces",3,
"FrontTracking");
4377 statistics().begin_count(
"compute_eulerian_field_contact_forces",statistics().get_last_opened_counter_level()+1);
4379 auto& eq_transport=variables_internes().ref_eq_interf_proprietes_fluide.valeur();
4380 const auto& eq_transport_const=variables_internes().ref_eq_interf_proprietes_fluide.valeur();
4384 const DoubleTab& particles_position=eq_transport.get_particles_position();
4385 const DoubleTab& particles_velocity=eq_transport.get_particles_velocity();
4396 if (nb_dt_Verlet >= nb_dt_compute_Verlet_ || nb_dt == 0)
4422 const DoubleTab& volumic_phase_indicator_function_face =
4423 eq_transport.get_indicatrice_faces().valeurs();
4424 DoubleTab& contact_force = variables_internes().contact_force_source_term->valeurs();
4427 volumic_phase_indicator_function_face,
4432 statistics().end_count(
"compute_eulerian_field_contact_forces");
int set_resoudre_en_u(int flag)
Sets the value of the resoudre_en_u__ flag.
virtual void associer_domaine_dis_base(const Domaine_dis_base &)=0
int set_resoudre_increment_pression(int flag)
Sets the value of the resoudre_increment_pression_ flag.
class Champ_Don_base base class of Given Fields (not calculated)
void mettre_a_jour(double temps) override
Time update.
DoubleTab & valeurs() override
Overrides Champ_base::valeurs() Returns the array of values.
class Champ_Fonc_base Base class of fields that are functions of a calculated quantity
void mettre_a_jour(double temps) override
Time update of the field.
DoubleTab & valeurs() override
Returns the array of field values at the current time.
virtual DoubleTab & futur(int i=1)
virtual DoubleTab & valeurs()=0
class Champ_base This class is the base of the fields hierarchy.
virtual DoubleTab & valeur_aux_elems(const DoubleTab &positions, const IntVect &les_polys, DoubleTab &valeurs) const
Causes an error! Must be overridden by derived classes.
: 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()
class Cond_lim Generic class used to represent any class
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 This class is the base class of the hierarchy of homogeneous Dirichlet-type...
Dirichlet This class is the base class of the hierarchy of Dirichlet-type boundary conditions.
class Discretisation_base This class represents a spatial discretization scheme, which
void discretiser_champ(const Motcle &directive, const Domaine_dis_base &z, const Nom &nom, const Nom &unite, int nb_comp, int nb_pas_dt, double temps, OWN_PTR(Champ_Inc_base)&champ, const Nom &sous_type=NOM_VIDE) const
int nb_som_elem() const
Returns the number of vertices of the geometric elements that make up the domain.
int_t nb_elem_tot() const
SmallArrOfTID_t & chercher_elements(const DoubleTab &pos, SmallArrOfTID_t &elem, int reel=0) const
Searches for the elements containing the points whose coordinates are specified.
virtual void creer_tableau_elements(Array_base &, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT) const
Creates a parallel array of values at elements.
int_t sommet_elem(int_t i, int j) const
Returns the (global) number of the j-th vertex of the i-th element.
class Domaine_Cl_dis_base Domaine_Cl_dis_base objects represent discretized boundary conditions
const Cond_lim & les_conditions_limites(int) const
Returns the i-th boundary condition.
int orientation(int) const override
inline DoubleVect& Domaine_VDF::porosite_face() {
virtual const DoubleVect & face_surfaces() const
int nb_faces() const
Returns the total number of 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
Returns the index of the i-th face of element num_elem; the face numbering convention is.
double xp(int num_elem, int k) const
int face_voisins(int num_face, int i) const
Returns the neighbouring element of num_face in direction i.
const Nom & le_nom() const override
Returns the name of the Objet_U. Virtual method to override: returns "neant" in this implementation.
class Domaine_dis_base This class is the base of the hierarchy of discretized domains.
virtual IntTab & face_voisins()
const Domaine & domaine() const
Class defining operators and methods for all reading operation in an input flow (file,...
class Equation_base The role of an equation is the calculation of one or more fields....
const Nom & le_nom() const override
Returns the name of the 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()
Returns the source terms associated with the equation.
const Discretisation_base & discretisation() const
Returns the discretization associated with the equation.
LIST(RefObjU) liste_modeles_
virtual int preparer_calcul()
Everything that does not depend on other possible problems.
virtual Domaine_Cl_dis_base & domaine_Cl_dis()
Returns the discretized boundary condition domain associated with the equation.
Probleme_base & probleme()
Returns the problem associated with the equation.
int limpr() const
Ask the time scheme if an output is needed.
Schema_Temps_base & schema_temps()
Returns the time scheme associated with the equation.
void Gradient_conjugue_diff_impl(DoubleTrav &secmem, DoubleTab &solution)
virtual void discretiser()
Discretizes the equation.
Champs_compris champs_compris_
Domaine_dis_base & domaine_dis()
Returns the discretized domain associated with the equation.
double chaleur_latente() const
const Fluide_Incompressible & fluide_phase(int la_phase) const
const int & get_id_fluid_phase() const
Represents an incompressible fluid and its properties:
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,
Matrice_Morse_Sym class - Represents a sparse symmetric matrix M stored in Morse format.
Milieu_base This class is the base of the (physical) medium hierarchy.
virtual const Champ_Don_base & beta_t() const
Returns beta_t of the medium (const version).
virtual const Champ_base & masse_volumique() const
Returns the mass density of the medium (const version).
virtual const Champ_Don_base & gravite() const
Returns the gravity of the medium if it has been associated, raises an error otherwise (const version...
void associer_eqn(const Equation_base &)
Associates an equation with the object.
A character string (Nom) in uppercase.
An array of Motcle objects.
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
The value of the unknown at the time step has been calculated.
int preparer_calcul() override
methode appelee par Probleme_base::preparer_calcul()
void associer_pb_base(const Probleme_base &probleme) override
Associates with the Problem passed as parameter.
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
We resume the unknown from an input stream.
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
We save the unknown, then the source terms to an output stream.
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
Reads non-simple-type parameters of an Objet_U from an input stream.
Navier-Stokes equation for a viscous incompressible fluid (div U = 0) with turbulence modelling.
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
Performs a time update of the equation.
int sauvegarder(Sortie &) const override
Saves the equation (and its turbulence model) to an output stream.
int reprendre(Entree &) override
Restores the equation and its turbulence model from an input stream.
void set_param(Param &titi) const override
int lire_motcle_non_standard(const Motcle &, Entree &) override
Reads non-simple-type parameters of an Objet_U from an input stream.
Entree & lire_op_diff_turbulent(Entree &is)
Operateur_Diff terme_diffusif
Operateur_Conv terme_convectif
const Champ_Inc_base & inconnue() const override
Returns the velocity (unknown field of the equation) (const version).
const Fluide_base & fluide() const
Returns the incompressible fluid (physical medium of the equation) associated with the equation.
Matrice matrice_pression_
void associer_pb_base(const Probleme_base &) override
Associates with the problem: calls Equation_base::associer_pb_base(const Probleme_base&).
virtual int projection_a_faire()
SolveurSys & solveur_pression()
Returns the pressure solver (const version).
SolveurSys solveur_pression_
Neumann_sortie_libre This class represents an open boundary without imposed velocity.
class Nom: a character string for naming TRUST objects.
An array of character strings (VECT(Nom)).
const Nom & que_suis_je() const
Returns the string identifying the class.
virtual Entree & readOn(Entree &)
Reads an Objet_U from an input stream. Virtual method to override.
static double precision_geom
virtual Sortie & printOn(Sortie &) const
Writes the object to an output stream. Virtual method to override.
Operateur_Div Generic class of the hierarchy of operators computing the divergence.
Operateur_base & l_op_base() override
Returns the underlying object upcast to Operateur_base.
void typer() override
Types the operator: types as "Op_div_"+discretisation()+.
DoubleTab & calculer(const DoubleTab &, DoubleTab &) const override
Initializes the array passed as parameter with the contribution of the operator.
DoubleTab & ajouter(const DoubleTab &, DoubleTab &) const override
Adds the contribution of the operator to the array passed as parameter.
void associer_eqn(const Equation_base &)
Associates an equation with the operator.
virtual void completer()
Updates the references of the objects associated with the operator.
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.
class Parametre_implicite A Parametre_implicite object groups together the various
bool & calcul_explicite()
class Periodique This class represents a periodic boundary condition.
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): Virtual method added for problems having several equations of the same type (Probleme_FT_D...
const Triple_Line_Model_FT_Disc & tcl() const
class Probleme_base It is a Probleme_U that is not a coupling.
const Domaine & domaine() const
Returns the domain associated with the problem.
virtual const Equation_base & get_equation_by_name(const Nom &) const
(B. Math): Virtual method added for problems having several equations of the same type (Probleme_FT_D...
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)
Computes the sum of x over all processors in the current group.
static void barrier()
Synchronizes all processors in the current group (waits until all processors have reached the barrier...
static void exit(int exit_code=-1)
Exit routine for TRUST within a Kokkos region.
static int je_suis_maitre()
Returns 1 if on the master processor of the current group (i.e. me() == 0), 0 otherwise.
double temps_courant() const
Returns the current time.
double pas_de_temps() const
Returns the current time step (delta_t).
int nb_pas_dt() const
Returns the number of time steps performed.
class SolveurSys A SolveurSys represents any class
Base class for output streams.
Symetrie On symmetry faces, the following properties hold:
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