16#include <Convection_Diffusion_Phase_field.h>
17#include <Source_Con_Phase_field_Binaire_Compact.h>
18#include <Source_Qdm_VDF_Phase_field.h>
19#include <Navier_Stokes_phase_field.h>
20#include <Source_Con_Phase_field.h>
21#include <Check_espace_virtuel.h>
22#include <MD_Vector_composite.h>
23#include <Milieu_Phase_field.h>
24#include <Champ_Fonc_Tabule.h>
25#include <Domaine_Cl_VDF.h>
26#include <TRUSTTab_parts.h>
27#include <Champ_Uniforme.h>
28#include <Equation_base.h>
29#include <Probleme_base.h>
30#include <Matrix_tools.h>
31#include <Domaine_VDF.h>
32#include <Milieu_base.h>
33#include <SolveurSys.h>
41#include <Perf_counters.h>
57 Cerr <<
"Source_Con_Phase_field_Binaire_Compact::readOn" << finl;
61 SFichier fichier_residu(
"residu.txt");
62 fichier_residu <<
"# SAUVEGARDE DU RESIDU #" << finl;
63 fichier_residu <<
"# Time \t Time simu \t Residu" << finl;
65 SFichier fichier_eval(
"eval.txt");
66 fichier_eval <<
"# Time simu \t Number eval FormFunction" << finl;
82 DoubleTab& prov_face = ref_cast_non_const(DoubleTab,
prov_face_);
83 if (prov_face.
size() == 0)
107 const Domaine_VDF& domaine_VDF = le_dom_VDF_.valeur();
108 const IntTab& face_voisins = domaine_VDF.
face_voisins();
109 const DoubleVect& volumes = domaine_VDF.
volumes();
111 DoubleTab& prov_face = ref_cast_non_const(DoubleTab,
prov_face_);
112 if (prov_face.
size() == 0)
122 int nbfaces = domaine_VDF.
nb_faces();
124 double kappa_face, vol0, vol1;
126 for (
int fac = ndeb; fac < nbfaces; fac++)
128 el0 = face_voisins(fac, 0);
129 el1 = face_voisins(fac, 1);
132 kappa_face = (vol0 * kappa_var(el0) + vol1 * kappa_var(el1)) / (vol0 + vol1);
135 prov_face(fac) = kappa_face * prov_face(fac);
161 DoubleTab& prov_face = ref_cast_non_const(DoubleTab,
prov_face_);
162 if (prov_face.
size() == 0)
169 prov_face *= fermeture.get_alpha();
172 opdiv.
calculer(prov_face, div_alpha_gradC);
191 const Domaine_VDF& domaine_VDF = le_dom_VDF_.valeur();
192 const IntTab& face_voisins = domaine_VDF.
face_voisins();
193 const DoubleVect& volumes = domaine_VDF.
volumes();
195 const int nbfaces = domaine_VDF.
nb_faces();
199 DoubleTab& prov_face = ref_cast_non_const(DoubleTab,
prov_face_);
200 if (prov_face.
size() == 0)
212 prov_face *= fermeture.get_alpha() *
rho0_;
215 for (
int fac = ndeb; fac < nbfaces; fac++)
217 el0 = face_voisins(fac, 0);
218 el1 = face_voisins(fac, 1);
222 rho_face = (vol0 * rhoPF(el0) + vol1 * rhoPF(el1)) / (vol0 + vol1);
223 prov_face(fac) *= fermeture.get_alpha() * rho_face;
228 opdiv.
calculer(prov_face, div_alpha_rho_gradC);
238 const Domaine_VDF& domaine_VDF = le_dom_VDF_.valeur();
321 const double theta = 0.6;
324 for (
int n_elem = 0; n_elem < nb_elem; n_elem++)
330 c_demi(n_elem) -= (1 - theta) * c(n_elem);
331 c_demi(n_elem) /= theta;
343 mutilde_demi(n_elem) -= (1 - theta) * mutilde(n_elem);
344 mutilde_demi(n_elem) /= theta;
364 mutilde = mutilde_demi;
381 if (prov_elem.
size() == 0)
386 DoubleTab kappa_var(prov_elem);
388 for (
int ikappa = 0; ikappa < nb_elem; ikappa++)
414 Cerr <<
"Type de schema errone !!" << finl;
430 ch_kappa_ou_alpha_->
nommer(
"ch_kappa_ou_alpha");
458 ch_kappa_ou_alpha_->
nommer(
"ch_kappa_ou_alpha");
468 ch_kappa_ou_alpha_->valeurs() = -fermeture.get_alpha();
473 const DoubleVect& vol = le_dom_VDF_->volumes();
474 tab_divide_any_shape(ch_kappa_ou_alpha_->valeurs(), vol);
488 Cout <<
"Vecteur de conditions limites = " << eq_c.
domaine_Cl_dis();
489 Cout <<
"Vecteur de conditions limites vec_cl = " <<
vec_cl_;
499 const int nb_elem = le_dom_VDF_->nb_elem_tot();
501 if (fermeture.get_kappa_ind() == 0)
505 for (
int elem = 0; elem < nb_elem; elem++)
506 kappa_tab_(elem) = fermeture.call_kappa_func_c(donne(elem));
521 const double theta = 0.6;
524 ch_kappa_ou_alpha_->valeurs() *= (theta * dt);
525 const DoubleVect& vol = le_dom_VDF_->volumes();
526 tab_divide_any_shape(ch_kappa_ou_alpha_->valeurs(), vol);
542 const int nb_elem = le_dom_VDF_->nb_elem_tot();
544 DoubleVect term_cin(nb_elem);
547 DoubleVect second_membre(nb_elem);
548 DoubleTab B_c_demi(nb_elem);
549 DoubleTab A_B_c_demi_sec_membre(nb_elem);
551 for (
int n_elem = 0; n_elem < nb_elem; n_elem++)
553 term_cin(n_elem) = 0.;
557 second_membre(n_elem) = term_cin(n_elem) + fermeture.get_beta() * fermeture.call_dWdc(c_demi(n_elem));
566 for (
int n_elem = 0; n_elem < nb_elem; n_elem++)
568 second_membre(n_elem) = second_membre(n_elem) - B_c_demi(n_elem);
573 for (
int n_elem = 0; n_elem < nb_elem; n_elem++)
575 v0(n_elem) = c_demi(n_elem) - c(n_elem) + A_B_c_demi_sec_membre(n_elem);
585 const double delta = 1.e-5;
607void tabToVecBis(
const DoubleTab& tab, Vec& f)
609 PetscScalar *f_array;
611 VecGetArray(f, &f_array);
612 VecGetSize(f, &size);
616 VecRestoreArray(f, &f_array);
620void vecToTabBis(
const Vec& v, DoubleTab& result)
623 const PetscScalar *array;
624 VecGetSize(v, &size);
625 VecGetArrayRead(v, &array);
627 for (PetscInt i = 0; i < size; ++i)
628 result((
int)i) = array[i];
629 VecRestoreArrayRead(v, &array);
636PetscErrorCode FormFunctionCompactOld(SNES snes, Vec x, Vec f,
void* ctx)
644 DoubleTab c_demi(nb_elem);
646 vecToTabBis(x,c_demi);
652 DoubleTrav second_membre(c_demi);
654 for (
int n_elem = 0; n_elem < nb_elem; n_elem++)
656 second_membre(n_elem) = fermeture.get_beta() * fermeture.call_dWdc(c_demi(n_elem));
659 DoubleTrav B_c_demi(nb_elem);
660 DoubleTrav A_B_c_demi_sec_membre(nb_elem);
668 for (
int n_elem = 0; n_elem < nb_elem; n_elem++)
670 second_membre(n_elem) = second_membre(n_elem) - B_c_demi(n_elem);
675 for (
int n_elem = 0; n_elem < nb_elem; n_elem++)
677 second_membre(n_elem) = c_demi(n_elem) - C(n_elem) + A_B_c_demi_sec_membre(n_elem);
680 tabToVecBis(second_membre, f);
685PetscErrorCode MySNESMonitorBis(SNES snes, PetscInt its, PetscReal norm,
void* ctx)
689 double temps_exec = statistics().get_time_since_last_open(STD_COUNTERS::total_execution_time);
691 Cout <<
"[SNES] Iteration " << its <<
" : ||F(x)|| = " << norm << finl;
695 SFichier fichier_residu(
"residu.txt", ios::app);
714PetscErrorCode LuisKSPMonitorBis(KSP ksp, PetscInt its, PetscReal rnorm,
void* ctx)
716 Cout <<
" [KSP] Iteration " << its <<
" : residu = " << rnorm << finl;
730 Cout <<
"Size total = " << c.
size_totale() << finl;
741 VecCreate(PETSC_COMM_WORLD, &x);
742 VecSetSizes(x, PETSC_DECIDE, nb_elem_tot);
743 VecSetFromOptions(x);
751 PetscInt x_size, r_size;
752 VecGetSize(x, &x_size);
753 VecGetSize(r, &r_size);
754 assert(x_size == nb_elem_tot);
755 assert(r_size == nb_elem_tot);
759 FormFunctionCompactOld(
nullptr, x, r, &
equation());
763 VecNorm(r, NORM_2, &norm);
764 PetscPrintf(PETSC_COMM_WORLD,
"Résidu F(x) = %g\n", (
double)norm);
767 SNESCreate(PETSC_COMM_WORLD, &snes);
769 SNESSetType(snes, SNESNEWTONLS);
772 SNESSetFunction(snes, r, FormFunctionCompactOld, &
equation());
775 SNESLineSearch linesearch;
776 SNESGetLineSearch(snes, &linesearch);
778 SNESLineSearchSetType(linesearch, SNESLINESEARCHNONE);
782 SNESLineSearchGetType(linesearch, &ls_type);
783 PetscPrintf(PETSC_COMM_WORLD,
"Type of Line Search used: %s\n", ls_type);
788 MatCreateSNESMF(snes, &J);
792 MatMFFDSetFunctionError(J,
erel_);
793 MatMFFDSetType(J,
"ds");
794 MatMFFDDSSetUmin(J,
umin_);
796 SNESSetJacobian(snes, J, J, MatMFFDComputeJacobian,
nullptr);
799 MatView(J, PETSC_VIEWER_STDOUT_WORLD);
811 SNESSetForceIteration(snes, PETSC_TRUE);
812 SNESSetMaxLinearSolveFailures(snes, 200);
816 SNESGetForceIteration(snes, &force_it);
817 PetscPrintf(PETSC_COMM_WORLD,
"Force iteration: %s\n", force_it ?
"ON" :
"OFF");
820 SNESGetKSP(snes, &ksp);
821 KSPSetType(ksp, KSPGMRES);
822 KSPGMRESSetRestart(ksp,
nkr_);
830 PCSetType(pc, PCNONE);
834 KSPMonitorSet(ksp, LuisKSPMonitorBis,
nullptr,
nullptr);
835 SNESMonitorSet(snes, MySNESMonitorBis, &
equation(),
nullptr);
846 PetscOptionsView(
nullptr, PETSC_VIEWER_STDOUT_WORLD);
847 PetscOptionsLeft(
nullptr);
850 SNESSetOptionsPrefix(snes,
"mysolver_");
852 SNESSetFromOptions(snes);
854 SNESView(snes, PETSC_VIEWER_STDOUT_WORLD);
857 SNESSolve(snes,
nullptr, x);
861 SNESGetNumberFunctionEvals(snes, &nfunc);
865 SFichier fichier_eval(
"eval.txt", ios::app);
870 const char *reasonstr;
871 SNESGetConvergedReasonString(snes, &reasonstr);
872 Cout <<
"SNES converged for this reason: " << reasonstr << finl;
874 DoubleTrav solution(nb_elem_tot);
876 vecToTabBis(x,solution);
878 for (
int n_elem = 0; n_elem < nb_elem_tot; n_elem++)
880 c_demi(n_elem) = solution(n_elem);
883 DoubleTrav mu_temp(nb_elem_tot);
884 DoubleTrav B_c_demi(nb_elem_tot);
885 const Milieu_Phase_field& mil = ref_cast(Milieu_Phase_field,
equation().milieu());
888 for (
int n_elem = 0; n_elem < nb_elem_tot; n_elem++)
890 mu_temp(n_elem) = fermeture.get_beta() * fermeture.call_dWdc(c_demi(n_elem));
898 for (
int n_elem = 0; n_elem < nb_elem_tot; n_elem++)
900 mutilde_demi(n_elem) = mu_temp(n_elem) - B_c_demi(n_elem);
925 return petsc_snes(c, mutilde, c_demi, mutilde_demi);
928 int i, j, nk, i0, im, it, ii;
929 double tem = 1., res, ccos, ssin;
931 double temps_exec = 0.;
937 DoubleTrav x1(nb_elem_tot);
939 for (
int n_elem = 0; n_elem < nb_elem_tot; n_elem++)
941 x1(n_elem) = c(n_elem);
944 DoubleTab v(nb_elem_tot,
nkr_);
946 DoubleVect r(
nkr_ + 1);
964 for (ii = 0; ii < c.
size(); ii++)
965 res += v0(ii) * v0(ii);
967 res += v0(ii) * v0(ii);
973 Cout <<
"Norme du premier résidu = " << res << finl;
995 for (j = 0; j <
nkr_; j++)
997 for (ii = 0; ii < nb_elem_tot; ii++)
1007 for (i = 0; i <= j; i++)
1009 for (ii = 0; ii < c.
size(); ii++)
1010 h(i, j) += v0(ii) * v(ii, i);
1012 h(i, j) += v0(ii) * v(ii, i);
1013 h(i, j) =
mp_sum(h(i, j));
1015 for (ii = 0; ii < nb_elem_tot; ii++)
1016 v0(ii) -= h(i, j) * v(ii, i);
1022 for (ii = 0; ii < c.
size(); ii++)
1023 tem += v0(ii) * v0(ii);
1025 tem += v0(ii) * v0(ii);
1040 for (i = 0; i < nk; i++)
1043 tem = 1. / sqrt(h(i, i) * h(i, i) + h(im, i) * h(im, i));
1044 ccos = h(i, i) * tem;
1045 ssin = -h(im, i) * tem;
1046 for (j = i; j < nk; j++)
1049 h(i, j) = ccos * tem - ssin * h(im, j);
1050 h(im, j) = ssin * tem + ccos * h(im, j);
1052 r[im] = ssin * r[i];
1057 for (i = nk - 1; i >= 0; i--)
1060 for (i0 = i - 1; i0 >= 0; i0--)
1061 r[i0] -= h(i0, i) * r[i];
1063 for (i = 0; i < nk; i++)
1064 for (ii = 0; ii < nb_elem_tot; ii++)
1065 x1(ii) += r[i] * v(ii, i);
1079 for (ii = 0; ii < c.
size(); ii++)
1080 res += v0(ii) * v0(ii);
1082 res += v0(ii) * v0(ii);
1087 Cout <<
" - At it = " << it <<
", residu scalar = " << res << finl;
1089 temps_exec = statistics().get_time_since_last_open(STD_COUNTERS::total_execution_time);
1093 SFichier fichier_residu(
"residu.txt", ios::app);
1101 for (
int n_elem = 0; n_elem < nb_elem_tot; n_elem++)
1103 c_demi(n_elem) = x1(n_elem);
1106 DoubleTrav mu_temp(nb_elem_tot);
1107 DoubleTrav B_c_demi(nb_elem_tot);
1111 for (
int n_elem = 0; n_elem < nb_elem_tot; n_elem++)
1113 mu_temp(n_elem) = fermeture.get_beta() * fermeture.call_dWdc(c_demi(n_elem));
1121 for (
int n_elem = 0; n_elem < nb_elem_tot; n_elem++)
1123 mutilde_demi(n_elem) = mu_temp(n_elem) - B_c_demi(n_elem);
1130 Cout <<
"Number of iterations to reach convergence : " << it + 1 << finl;
1137 Cout <<
"Stopped before convergence" << finl;
1143 SFichier fichier_eval(
"eval.txt", ios::app);
1149 Cerr <<
"Error: Phase_field - Bad input for choosing between resolution with PETSc or not." << finl;
1171 mutilde = div_alpha_gradC;
1176 const int taille = mutilde.
size();
1177 for (
int i = 0; i < taille; i++)
1179 mutilde(i) += fermeture.get_beta() * fermeture.call_dWdc(c(i));
1185 assert_invalide_items_non_calcules(mutilde);
1200 DoubleTab& prov_face = ref_cast_non_const(DoubleTab,
prov_face_);
1201 if (prov_face.
size() == 0)
1206 opgrad.
calculer(c_demi, prov_face);
1208 prov_face *= fermeture.get_alpha();
1211 opdiv.
calculer(prov_face, mutilde_demi);
1215 mutilde_demi *= -1.;
1217 const int taille = mutilde_demi.
size();
1218 for (
int i = 0; i < taille; i++)
1220 mutilde_demi(i) += fermeture.get_beta() * fermeture.call_dWdc(c_demi(i));
1228 assert_invalide_items_non_calcules(mutilde_demi);
DoubleTab & valeurs() override
Surcharge Champ_base::valeurs() Renvoie le tableau des valeurs.
DoubleTab & valeurs() override
Renvoie le tableau des valeurs du champ au temps courant.
const Champ_Inc_base & inconnue() const override
Renvoie le champ inconnue de l'equation: la concentration.
classe Convection_Diffusion_Phase_field Cas particulier de Convection_Diffusion_Concentration
const DoubleTab & get_div_alpha_gradC() const
DoubleTab & set_div_alpha_gradC()
Champ_Fonc_base & set_mutilde_()
const Milieu_base & milieu() const override
Renvoie le milieu physique de l'equation.
const Champ_Fonc_base & get_mutilde_() const
DoubleTab & set_mutilde_demi()
int nb_faces() const
renvoie le nombre global de faces.
double volumes(int i) const
int premiere_face_int() const
une face est interne ssi elle separe deux elements.
int face_voisins(int num_face, int i) const
renvoie l'element voisin de numface dans la direction i.
Une entree dont la source est une chaine de caracteres.
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....
Sources & sources()
Renvoie les termes sources asssocies a l'equation.
Solveur_Masse_base & solv_masse()
Renvoie le solveur de masse associe a l'equation.
virtual Domaine_Cl_dis_base & domaine_Cl_dis()
Renvoie le domaine des conditions aux limite discretisee associee a l'equation.
Schema_Temps_base & schema_temps()
Renvoie le schema en temps associe a l'equation.
int get_kappa_ind() const
double call_kappa_func_c(const double d) const
void nommer(const Nom &) override
Donne un nom au champ.
virtual DoubleVect & multvect_(const DoubleVect &, DoubleVect &) const
const Champ_Don_base & rho() const
const Fermeture_Phase_field_base & get_fermeture() const
const Equation_base & equation() const
Renvoie la reference sur l'equation pointe par MorEqn::mon_equation.
classe Navier_Stokes_phase_field Cette classe porte les termes de l'equation de la dynamique
classe Navier_Stokes_std Cette classe porte les termes de l'equation de la dynamique
const Champ_Inc_base & inconnue() const override
Renvoie la vitesse (champ inconnue de l'equation) (version const).
Operateur_Div & operateur_divergence()
Renvoie l'operateur de calcul de la divergence associe a l'equation.
Operateur_Grad & operateur_gradient()
Renvoie l'operateur de calcul du gradient associe a l'equation.
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.
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
DoubleTab & calculer(const DoubleTab &, DoubleTab &) const override
Initialise le tableau passe en parametre avec la contribution de l'operateur.
Classe Operateur_Grad Classe generique de la hierarchie des operateurs calculant le gradient.
DoubleTab & calculer(const DoubleTab &, DoubleTab &) const override
Initialise le tableau passe en parametre avec la contribution de l'operateur.
static double mp_sum(double)
Calcule la somme de x sur tous les processeurs du groupe courant.
static int me()
renvoie mon rang dans le groupe de communication courant.
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
Cette classe est a la classe C++ ofstream ce que la classe Sortie est a la classe C++ ostream Elle re...
double temps_courant() const
Renvoie le temps courant.
double pas_de_temps() const
Renvoie le pas de temps (delta_t) courant.
virtual DoubleTab & appliquer(DoubleTab &) const
renvoie appliquer_impl(x/coeffient_temporelle) si on a un coefficient temporel sinon renvoie applique...
Classe de base des flux de sortie.
void calculer_div_alpha_rho_grad(const DoubleTab &, DoubleTab &) const
Calcul de Div(alpha*rho*Grad((C)) au centre des elements.
void calculer_mutilde(DoubleTab &) const
Calcul de mutilde au centre des elements.
bool is_matrix_kappa_initialised_
Matrice_Morse & get_matrice_kappa()
bool is_matrix_alpha_initialised_
void initialiser_matrice_kappa()
void initialiser_matrice_alpha()
void calculer_div_alpha_grad(const DoubleTab &, DoubleTab &) const
Calcul de Div(alpha*rho*Grad((C)) au centre des elements.
int petsc_snes(const DoubleTab &, const DoubleTab &, DoubleTab &, DoubleTab &)
void premier_demi_dt() override
Calcule le premier demi pas de temps dans le cas implicite Calcule le pas de temps dans le cas explic...
Operateur_Diff terme_diffusif_vdf_
DoubleTab & div_kappa_grad(const DoubleTab &, const DoubleTab &, DoubleTab &) const
DoubleTab & laplacien(const DoubleTab &, DoubleTab &) const
void jacobian_vect(const DoubleTab &, const DoubleTab &, const DoubleTab &, DoubleTab &)
Construire la jacobienne multipliée par un vecteur Y.
int resolution_jfnk(const DoubleTab &, const DoubleTab &, DoubleTab &, DoubleTab &)
Algorithme JFNK (ancienne version de D. Jamet et nouvelle version de PETSc).
Matrice_Morse & get_matrice_alpha()
void calculer_residu_jfnk(const DoubleTab &, DoubleTab &, const DoubleTab &)
Construire le residu du JFNK.
void update_tab_kappa(const DoubleTab &)
Matrice_Morse matrice_kappa_
Matrice_Morse matrice_alpha_
void calculer_mutilde_demi(DoubleTab &, DoubleTab &) const
void update_matrice_kappa(const DoubleTab &)
virtual void calculer_u2_elem(DoubleVect &)
double drhodc(const int n_elem) const
_SIZE_ dimension_tot(int) const override
_SIZE_ size_totale() const
virtual void echange_espace_virtuel(IsExchangeBlocking exchange_type=IsExchangeBlocking::DefaultBlocking, const std::string kernel_name="noname")