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)
Definit la valeur du drapeau resoudre_en_u__.
virtual void associer_domaine_dis_base(const Domaine_dis_base &)=0
int set_resoudre_increment_pression(int flag)
Definit la valeur du drapeau resoudre_increment_pression_.
classe Champ_Don_base classe de base des Champs donnes (non calcules)
void mettre_a_jour(double temps) override
Mise a jour en temps.
DoubleTab & valeurs() override
Surcharge Champ_base::valeurs() Renvoie le tableau des valeurs.
classe Champ_Fonc_base Classe de base des champs qui sont fonction d'une grandeur calculee
void mettre_a_jour(double temps) override
Mise a jour en temps du champ.
DoubleTab & valeurs() override
Renvoie le tableau des valeurs du champ au temps courant.
virtual DoubleTab & futur(int i=1)
virtual DoubleTab & valeurs()=0
classe Champ_base Cette classe est la base de la hierarchie des champs.
virtual DoubleTab & valeur_aux_elems(const DoubleTab &positions, const IntVect &les_polys, DoubleTab &valeurs) const
provoque une erreur ! doit etre surchargee par les classes derivees
: class Collision_Model_FT
int & get_set_nb_dt_Verlet()
const int & get_nb_dt_compute_Verlet() const
virtual void discretize_contact_forces_eulerian_field(const DoubleTab &volumic_phase_indicator_function, const Domaine_VF &domain_vf, const IntTab &particles_eulerian_id_number, DoubleTab &contact_force_source_term)=0
void research_collision_pairs_Verlet(const Navier_Stokes_FT_Disc &eq_ns, const Transport_Interfaces_FT_Disc &eq_transport)
virtual void compute_lagrangian_contact_forces(const Fluide_Diphasique &two_phase_fluid, const DoubleTab &particles_position, const DoubleTab &particles_velocity, const double &deltat_simu)=0
const int & get_is_force_on_two_phase_elem() const
bool is_Verlet_activated()
classe Cond_lim Classe generique servant a representer n'importe quelle classe
const Champ_base & vitesse_pour_transport() const override
const Champ_Inc_base & inconnue() const override
static void verifier(const char *const msg, double)
Classe Dirichlet_homogene Cette classe est la classe de base de la hierarchie des conditions aux limi...
classe Dirichlet Cette classe est la classe de base de la hierarchie des conditions aux limites de ty...
classe Discretisation_base Cette classe represente un schema de discretisation en espace,...
void discretiser_champ(const Motcle &directive, const Domaine_dis_base &z, const Nom &nom, const Nom &unite, int nb_comp, int nb_pas_dt, double temps, OWN_PTR(Champ_Inc_base)&champ, const Nom &sous_type=NOM_VIDE) const
int nb_som_elem() const
Renvoie le nombre de sommets des elements geometriques constituants le domaine.
int_t nb_elem_tot() const
SmallArrOfTID_t & chercher_elements(const DoubleTab &pos, SmallArrOfTID_t &elem, int reel=0) const
Recherche des elements contenant les points dont les coordonnees sont specifiees.
virtual void creer_tableau_elements(Array_base &, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT) const
creation d'un tableau parallele de valeurs aux elements.
int_t sommet_elem(int_t i, int j) const
Renvoie le numero (global) du j-ieme sommet du i-ieme element.
classe Domaine_Cl_dis_base Les objets Domaine_Cl_dis_base representent les conditions aux limites
const Cond_lim & les_conditions_limites(int) const
Renvoie la i-ieme condition aux limites.
int orientation(int) const override
inline DoubleVect& Domaine_VDF::porosite_face() {
virtual const DoubleVect & face_surfaces() const
int nb_faces() const
renvoie le nombre global de faces.
virtual double face_normales(int face, int comp) const
double xv(int num_face, int k) const
double volumes(int i) const
virtual const IntVect & orientation() const
int elem_faces(int i, int j) const
renvoie le numero de le ieme face de la maille num_elem la facon dont ces faces sont numerotees est
double xp(int num_elem, int k) const
int face_voisins(int num_face, int i) const
renvoie l'element voisin de numface dans la direction i.
const Nom & le_nom() const override
Donne le nom de l'Objet_U Methode a surcharger : renvoie "neant" dans cette implementation.
classe Domaine_dis_base Cette classe est la base de la hierarchie des domaines discretisees.
virtual IntTab & face_voisins()
const Domaine & domaine() const
Class defining operators and methods for all reading operation in an input flow (file,...
classe Equation_base Le role d'une equation est le calcul d'un ou plusieurs champs....
const Nom & le_nom() const override
Renvoie le nom de l'equation.
virtual void associer_milieu_base(const Milieu_base &)=0
virtual const Milieu_base & milieu() const =0
DoubleTab & derivee_en_temps_conv(DoubleTab &, const DoubleTab &)
Add convection term In: solution is the unknown I.
Sources & sources()
Renvoie les termes sources asssocies a l'equation.
const Discretisation_base & discretisation() const
Renvoie la discretisation associee a l'equation.
LIST(RefObjU) liste_modeles_
virtual int preparer_calcul()
Tout ce qui ne depend pas des autres problemes eventuels.
virtual Domaine_Cl_dis_base & domaine_Cl_dis()
Renvoie le domaine des conditions aux limite discretisee associee a l'equation.
Probleme_base & probleme()
Renvoie le probleme associe a l'equation.
int limpr() const
Demande au schema en temps si il faut effectuer une impression.
Schema_Temps_base & schema_temps()
Renvoie le schema en temps associe a l'equation.
void Gradient_conjugue_diff_impl(DoubleTrav &secmem, DoubleTab &solution)
virtual void discretiser()
Discretise l'equation.
Champs_compris champs_compris_
Domaine_dis_base & domaine_dis()
Renvoie le domaine discretise associe a l'equation.
double chaleur_latente() const
const Fluide_Incompressible & fluide_phase(int la_phase) const
const int & get_id_fluid_phase() const
classe Fluide_Incompressible Cette classe represente un d'un fluide incompressible ainsi que
const Champ_Don_base & viscosite_dynamique() const
const Champ_Don_base & viscosite_cinematique() const
int num_premiere_face() const
int index_element_suivant_
double fraction_surface_intersection_
int index_facette_suivante_
: class Intersections_Elem_Facettes
const ArrOfInt & index_elem() const
Renvoie un tableau de taille domaine.
const ArrOfInt & index_facette() const
Renvoie un tableau de taille "nombre de facettes de l'interface" pour un element 0 <= facette < nb_fa...
const Intersections_Elem_Facettes_Data & data_intersection(int index) const
Renvoie les donnees de l'intersection stockee a l'indice "index" dans le tableau "data" ( 0 <= index ...
: class Maillage_FT_Disc Cette classe decrit un maillage:
int nb_sommets() const
renvoie le nombre de sommets (reels et virtuels) (egal a sommets().
const DoubleTab & sommets() const
renvoie le tableau des sommets (reels et virtuels) dimension(0) = nombre de sommets,
int nb_facettes() const
renvoie le nombre de facettes (reelles et virtuelles) (egal a facettes().
virtual const DoubleTab & get_update_normale_facettes() const
Calcule la grandeur demandee, stocke le resultat dans un tableau interne a la classe et renvoie le re...
virtual double compute_normale_element(const int elem, const bool normalize, ArrOfDouble &normale) const
const Intersections_Elem_Facettes & intersections_elem_facettes() const
virtual const ArrOfDouble & get_update_surface_facettes() const
Calcule la grandeur demandee, stocke le resultat dans un tableau interne a la classe et renvoie le re...
virtual const ArrOfDouble & get_update_courbure_sommets() const
Calcule la grandeur demandee, stocke le resultat dans un tableau interne a la classe et renvoie le re...
const IntTab & facettes() const
renvoie le tableau des facettes (reelles et virtuelles) dimension(0) = nombre de facettes,
Classe Matrice_Morse_Sym Represente une matrice M (creuse) symetrique stockee au format Morse.
classe Milieu_base Cette classe est la base de la hierarchie des milieux (physiques)
virtual const Champ_Don_base & beta_t() const
Renvoie beta_t du milieu.
virtual const Champ_base & masse_volumique() const
Renvoie la masse volumique du milieu.
virtual const Champ_Don_base & gravite() const
Renvoie la gravite du milieu si elle a ete associe provoque une erreur sinon.
void associer_eqn(const Equation_base &)
Associe une equation a l'objet.
Une chaine de caractere (Nom) en majuscules.
Un tableau d'objets de la classe Motcle.
int search(const Motcle &t) const
@ ZERO_OUT_FLUX_ON_MIXED_CELLS
@ ZERO_NET_FLUX_ON_MIXED_CELLS
const DoubleTab & get_mpoint() const
void associer_milieu_base(const Milieu_base &fluide) override
virtual void calculer_gradient_indicatrice(const Champ_base &indicatrice, const DoubleTab &distance_interface_sommets, Champ_base &gradient_i)
Calcul du gradient de l'indicatrice.
DoubleTab & derivee_en_temps_inco(DoubleTab &vpoint) override
Calcul de la derivee en temps de la vitesse.
void projeter() override
methode appelee par Navier_Stokes_std::preparer_calcul.
const SolveurSys & get_solveur_pression() const
virtual const Champ_base * get_delta_vitesse_interface() const
Si le champ de vitesse est discontinu (calcul avec changement de phase), renvoie un pointeur vers le ...
void discretiser_assembleur_pression() override
Methode surchargee de Navier_Stokes_std, appelee par Navier_Stokes_std::discretiser().
void set_id_fluid_phase(const int &id_fluid_phase)
void calculer_delta_u_interface(Champ_base &u0, int phase_pilote, int ordre, const bool future_or_past=false)
Calcul du saut de vitesse a l'interface du au changement de phase.
virtual void calculer_champ_forces_superficielles(const Maillage_FT_Disc &maillage, const Champ_base &gradient_indicatrice, Champ_base &potentiel_elements, Champ_base &potentiel_faces, Champ_base &champ)
Calcul des forces de tension superficielles (F_sigma) et de la partie a rotationnel non nul de la gra...
void compute_particles_eulerian_id_number(const OWN_PTR(Collision_Model_FT_base)&collision_model_ptr)
const DoubleTab & get_interfacial_area() const
void mettre_a_jour(double temps) override
La valeur de l'inconnue sur le pas de temps a ete calculee.
int preparer_calcul() override
methode appelee par Probleme_base::preparer_calcul()
void associer_pb_base(const Probleme_base &probleme) override
S'associe au Probleme passe en parametre.
const int & get_is_penalized() const
void compute_boussinesq_additional_gravity(const Convection_Diffusion_Temperature_FT_Disc &eq, const Fluide_Diphasique &fluide_diphasique, const IntTab &face_voisins, const DoubleVect &volumes_entrelaces, const IntVect &orientation, const DoubleTab &indicatrice, const ArrOfDouble &g, DoubleTab &gravite_face) const
OWN_PTR(Champ_Fonc_base) champ_rho_elem_
const Milieu_base & milieu() const override
OBS_PTR(Probleme_FT_Disc_gen) probleme_ft_
virtual const Probleme_FT_Disc_gen & probleme_ft() const
bool get_new_mass_source() const
bool get_is_solid_particle() const
IntTab particles_eulerian_id_number_
int is_terme_gravite_rhog() const
void shift_secmem2(DoubleTab &shift_secmem2)
void compute_eulerian_field_contact_forces(const Maillage_FT_Disc &mesh, const Champ_base &field_volumic_phase_indicator_function)
int reprendre(Entree &) override
On reprend l'inconnue a partir d'un flot d'entree.
void set_param(Param &titi) const override
virtual void calculer_dI_dt(DoubleVect &dI_dt, const DoubleTab &tab_vitesse)
virtual const Fluide_Diphasique & fluide_diphasique() const
int sauvegarder(Sortie &) const override
On sauvegarde l'inconnue, puis les sources sur un flot de sortie.
const Champ_Don_base & diffusivite_pour_transport() const override
void set_is_solid_particle(const bool &is_solid_particle)
void calculer_la_pression_en_pa() override
In Front Tracking, pression is in Pa and so pression_pa field <=> pression field.
void discretiser() override
Discretisation des champs utilises dans cette equation.
virtual const Champ_base & calculer_div_normale_interface()
void correct_at_exit_bad_gradient(DoubleTab &u0) const
bool is_shift_secmem2_activated() const
friend class Post_Processing_Hydrodynamic_Forces
std::vector< YAML_data > data_a_sauvegarder() const override
for PDI IO: retrieve name, type and dimensions of the fields to save/restore
void mettre_a_jour_physical_properties(double temps)
void swap_particles_eulerian_id_number(const ArrOfInt &gravity_center_elem)
const Champ_Fonc_base & champ_rho_faces() const
DoubleTab & get_set_interfacial_area()
DoubleTab & get_set_mpoint()
int lire_motcle_non_standard(const Motcle &, Entree &) override
Lecture des parametres de type non simple d'un objet_U a partir d'un flot d'entree.
classe Navier_Stokes_Turbulent Cette classe represente l'equation de la dynamique pour un fluide
std::vector< YAML_data > data_a_sauvegarder() const override
for PDI IO: retrieve name, type and dimensions of the fields to save/restore
void mettre_a_jour(double) override
Effecttue une mise a jour en temps de l'equation.
int sauvegarder(Sortie &) const override
Sauvegarde l'equation (et son modele de turbulence) sur un flot de sortie.
int reprendre(Entree &) override
Reprise de l'equation et de son modele de turbulence a partir d'un flot d'entree.
void set_param(Param &titi) const override
int lire_motcle_non_standard(const Motcle &, Entree &) override
Lecture des parametres de type non simple d'un objet_U a partir d'un flot d'entree.
Entree & lire_op_diff_turbulent(Entree &is)
Operateur_Diff terme_diffusif
Operateur_Conv terme_convectif
const Champ_Inc_base & inconnue() const override
Renvoie la vitesse (champ inconnue de l'equation) (version const).
const Fluide_base & fluide() const
Renvoie le fluide incompressible (milieu physique de l'equation) associe a l'equation.
Matrice matrice_pression_
void associer_pb_base(const Probleme_base &) override
S'associe au probleme: apelle Equation_base::associer_pb_base(const Probleme_base&).
virtual int projection_a_faire()
SolveurSys & solveur_pression()
Renvoie le solveur en pression (version const).
SolveurSys solveur_pression_
classe Neumann_sortie_libre Cette classe represente une frontiere ouverte sans vitesse imposee
class Nom Une chaine de caractere pour nommer les objets de TRUST
Un tableau de chaine de caracteres (VECT(Nom)).
const Nom & que_suis_je() const
renvoie la chaine identifiant la classe.
virtual Entree & readOn(Entree &)
Lecture d'un Objet_U sur un flot d'entree Methode a surcharger.
static double precision_geom
virtual Sortie & printOn(Sortie &) const
Ecriture de l'objet sur un flot de sortie Methode a surcharger.
classe Operateur_Div Classe generique de la hierarchie des operateurs calculant la divergence
Operateur_base & l_op_base() override
Renvoie l'objet sous-jacent upcaste en Operateur_base.
void typer() override
Type l'operateur: se type "Op_div_"+discretisation()+.
DoubleTab & calculer(const DoubleTab &, DoubleTab &) const override
Initialise le tableau passe en parametre avec la contribution de l'operateur.
DoubleTab & ajouter(const DoubleTab &, DoubleTab &) const override
Ajoute la contribution de l'operateur au tableau passe en parametre.
void associer_eqn(const Equation_base &)
Associe une equation a l'operateur.
virtual void completer()
Met a jour les references des objets associes a l'operateur.
Helper class to factorize the readOn method of Objet_U classes.
void ajouter_flag(const char *keyword, const bool *value)
Register a boolean flag whose mere presence switches it to true.
void ajouter(const char *keyword, const int *value, Param::Nature nat=Param::OPTIONAL)
Register an integer parameter.
void ajouter_non_std(const char *keyword, const Objet_U *value, Param::Nature nat=Param::OPTIONAL)
Register a keyword handled by Objet_U::lire_motcle_non_standard.
classe Parametre_implicite Un objet Parametre_implicite est un objet regroupant les differentes
bool & calcul_explicite()
classe Periodique Cette classe represente une condition aux limites periodique.
bool get_is_compute_forces_Stokes_th() const
virtual const Transport_Interfaces_FT_Disc & equation_interfaces(const Motcle &nom) const
const Equation_base & get_equation_by_name(const Nom &le_nom) const override
(B. Math): Methode virtuelle ajoutee pour les problemes ayant plusieurs equations de meme type (Probl...
const Triple_Line_Model_FT_Disc & tcl() const
classe Probleme_base C'est un Probleme_U qui n'est pas un couplage.
const Domaine & domaine() const
Renvoie le domaine associe au probleme.
virtual const Equation_base & get_equation_by_name(const Nom &) const
(B. Math): Methode virtuelle ajoutee pour les problemes ayant plusieurs equations de meme type (Probl...
static void mp_max_for_each_item(TRUSTArray< _TYPE_ > &x, int n=-1)
static int check_int_overflow(trustIdType)
static void mp_sum_for_each(T &arg1, T &arg2)
C++14 compatible mp_sum_for_each: combine multiple mp_sum calls into one collective operation Usage: ...
static double mp_max(double)
static double mp_sum(double)
Calcule la somme de x sur tous les processeurs du groupe courant.
static void barrier()
Synchronise tous les processeurs du groupe courant (attend que tous les processeurs soient arrives a ...
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
static int je_suis_maitre()
renvoie 1 si on est sur le processeur maitre du groupe courant (c'est a dire me() == 0),...
double temps_courant() const
Renvoie le temps courant.
double pas_de_temps() const
Renvoie le pas de temps (delta_t) courant.
int nb_pas_dt() const
Renvoie le nombre de pas de temps effectues.
class SolveurSys Un SolveurSys represente n'importe qu'elle classe
Classe de base des flux de sortie.
classe Symetrie Sur les faces de symetrie on a les proprietes suivantes:
void append_array(_TYPE_ valeur)
_SIZE_ size_array() const
TRUSTArray & inject_array(const TRUSTArray &source, _SIZE_ nb_elements=-1, _SIZE_ first_element_dest=0, _SIZE_ first_element_source=0)
void resize_array(_SIZE_ new_size, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
void resize(_SIZE_ n, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
_SIZE_ dimension_tot(int) const override
void copy(const TRUSTTab &, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
_SIZE_ dimension(int d) const
_SIZE_ size_totale() const
_TYPE_ mp_max_abs_vect(Mp_vect_options opt=VECT_REAL_ITEMS) const
_SIZE_ size_reelle() const
virtual void echange_espace_virtuel(IsExchangeBlocking exchange_type=IsExchangeBlocking::DefaultBlocking, const std::string kernel_name="noname")
void ajouter_terme_div_u(DoubleVect &secmem_pression, double dt) const
virtual const Champ_base & get_indicatrice_faces()
virtual const DoubleTab & get_update_distance_interface_sommets() const
Renvoi de la distance signee entre l'interface et les sommets du maillage eulerien.
void impr_effort_fluide_interface(DoubleTab &source_val, DoubleTab &pressure_part, DoubleTab &friction_part, DoubleTab &diff_part)
const Champ_Inc_base & inconnue() const override
virtual const Champ_base & get_normale_interface() const
const Maillage_FT_Disc & maillage_interface() const
void calcul_effort_fluide_interface(const DoubleTab &vpoint, const DoubleTab &rho_faces, DoubleTab &source_val, const int is_explicite, const double eta)
virtual const Champ_base & get_distance_interface() const
void modifier_vpoint_pour_imposer_vit(const DoubleTab &inco_val, DoubleTab &vpoint0, DoubleTab &vpoint, const DoubleTab &rho_faces, DoubleTab &terme_source, const double temps, const double dt, const int is_explicite, const double eta) override
const int & get_vimp_regul() const
void corriger_secmem(const double coef, DoubleTab &secmem2) const
void corriger_mpoint(DoubleTab &mpoint) const