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
Overrides Champ_base::valeurs() Returns the array of values.
DoubleTab & valeurs() override
Returns the array of field values at the current time.
const Champ_Inc_base & inconnue() const override
Returns the unknown field of the equation: the 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
Returns the physical medium of the equation.
const Champ_Fonc_base & get_mutilde_() const
DoubleTab & set_mutilde_demi()
int nb_faces() const
Returns the total number of faces.
double volumes(int i) const
int premiere_face_int() const
A face is internal if and only if it separates two elements.
int face_voisins(int num_face, int i) const
Returns the neighbouring element of num_face in direction i.
An input stream whose source is a character string.
Class defining operators and methods for all reading operation in an input flow (file,...
class Equation_base The role of an equation is the calculation of one or more fields....
Sources & sources()
Returns the source terms associated with the equation.
Solveur_Masse_base & solv_masse()
Returns the mass solver associated with the equation.
virtual Domaine_Cl_dis_base & domaine_Cl_dis()
Returns the discretized boundary condition domain associated with the equation.
Schema_Temps_base & schema_temps()
Returns the time scheme associated with the equation.
int get_kappa_ind() const
double call_kappa_func_c(const double d) const
void nommer(const Nom &) override
Gives a name to the field.
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
Returns the reference to the equation pointed to by MorEqn::mon_equation.
classe Navier_Stokes_phase_field Cette classe porte les termes de l'equation de la dynamique
Navier_Stokes_std This class carries the terms of the momentum equation.
const Champ_Inc_base & inconnue() const override
Returns the velocity (unknown field of the equation) (const version).
Operateur_Div & operateur_divergence()
Returns the divergence operator associated with the equation.
Operateur_Grad & operateur_gradient()
Returns the gradient operator associated with the equation.
const Nom & que_suis_je() const
Returns the string identifying the class.
virtual Entree & readOn(Entree &)
Reads an Objet_U from an input stream. Virtual method to override.
virtual Sortie & printOn(Sortie &) const
Writes the object to an output stream. Virtual method to override.
Operateur_Div Generic class of the hierarchy of operators computing the divergence.
DoubleTab & calculer(const DoubleTab &, DoubleTab &) const override
Initializes the array passed as parameter with the contribution of the operator.
Classe Operateur_Grad Generic class of the hierarchy of operators computing the gradient.
DoubleTab & calculer(const DoubleTab &, DoubleTab &) const override
Initializes the array passed as parameter with the contribution of the operator.
static double mp_sum(double)
Computes the sum of x over all processors in the current group.
static int me()
Returns the rank of the local processor in the current communication group. See Comm_Group::rank() an...
static void exit(int exit_code=-1)
Exit routine for TRUST within a Kokkos region.
SFichier is to the C++ ofstream class what Sortie is to the C++ ostream class.
double temps_courant() const
Returns the current time.
double pas_de_temps() const
Returns the current time step (delta_t).
virtual DoubleTab & appliquer(DoubleTab &) const
Returns appliquer_impl(x/temporal_coefficient) if a temporal coefficient is set, otherwise returns ap...
Base class for output streams.
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")