16#include <Cahn_Hilliard.h>
17#include <Schema_Cahn_Hilliard.h>
18#include <Discretisation_base.h>
19#include <Domaine_VDF.h>
20#include <Discret_Thyd.h>
21#include <Probleme_base.h>
22#include <Cond_lim_base.h>
24#include <Champ_front_uniforme.h>
25#include <CL_Types_include.h>
26#include <Courant_impose.h>
30#include <TRUST_2_PDI.h>
31#include <Milieu_Incompressible_Phase_Field.h>
37 os << le_dom_Cl_dis_mutilde_ << finl;
40 os <<
" -- mobilite explicite = TRUE " << finl;
42 os <<
" -- mobilite explicite = FALSE " << finl;
56 Cerr <<
"EQUATION CAHN HILLIARD : Setting multiscalar boolean to TRUE." << finl;
74 if (mot==
"conditions_limites_potentiel|boundary_conditions_potential")
94 Cerr <<
"Reading of boundaries conditions on chemical potential \n";
95 if(!le_dom_Cl_dis_mutilde_)
97 Cerr <<
"Error while reading boundaries conditions : " <<
99 Cerr <<
"The Domaine_Cl_dis_base corresponding to mutilde is empty ..." << finl;
102 is >> le_dom_Cl_dis_mutilde_.valeur();
135 Cerr <<
"Error for Cahn_Hilliard::operateur(int i)" << finl;
137 Cerr <<
"and you are trying to access the " << i <<
" th one."<< finl;
157 Cerr <<
"Error for Cahn_Hilliard::operateur(int i)" << finl;
159 Cerr <<
"and you are trying to access the " << i <<
" th one."<< finl;
172 static Motcle domaine =
"Cahn_Hilliard";
182 return concentration_.valeur();
191 return concentration_.valeur();
214 milieu_ = un_fluide_ch;
219 Cerr <<
"Error of medium type for the method Cahn_Hilliard::associer_milieu_base." << finl;
220 Cerr <<
"You have to implement a new compatible kind of Milieu_base." << finl;
233 Cerr <<
"You forgot to associate a phase-field medium to the problem named " <<
probleme().
le_nom() << finl;
236 return milieu_.valeur();
247 Cerr <<
"You forgot to associate a phase-field medium to the problem named " <<
probleme().
le_nom() << finl;
250 return milieu_.valeur();
258 Cerr <<
"!! WARNING !! : for now, equation discretization (Cahn_Hilliard::discretiser) is only for hydraulic problems." << finl;
280 Cerr <<
"Discretizing of the boundary conditions of mutilde... ";
281 le_dom_Cl_dis_mutilde_.typer(
discretisation().domaine_cl_dis_type());
283 Cerr <<
" OK " << finl;
285 le_dom_Cl_dis_mutilde_->associer_eqn(*
this);
286 le_dom_Cl_dis_mutilde_->associer_inconnue(
mutilde_);
296 Cerr <<
"Concentration discretization... " << finl;
299 concentration_->nommer(
"concentration");
300 concentration_->fixer_nature_du_champ(multi_scalaire);
307 Cerr <<
"Mutilde discretization... " << finl;
311 mutilde_->nommer(
"potentiel_chimique_generalise");
312 mutilde_->fixer_nature_du_champ(multi_scalaire);
319 Cerr <<
"Kappa discretization... " << finl;
322 kappa_->nommer(
"capillarite");
323 kappa_->fixer_nature_du_champ(multi_scalaire);
331 Cerr <<
"Mobility discretization... " << finl;
333 mobilite_->nommer(
"mobilite");
334 mobilite_->fixer_nature_du_champ(multi_scalaire);
346 kappa_->valeurs().echange_espace_virtuel();
356 mobilite_->valeurs()(x,j) = result_mob(x,j);
367 Cerr <<
"[COMPLETER()] Typing of the diffusion operator of mobility... " << finl;
385 Cerr <<
"[COMPLETER()] Typing of the diffusion operator of capillarity... " << finl;
390 terme_kappa_.associer_champ(concentration_,
"concentration");
399 Cerr <<
"####### CAHN_HILLIARD::COMPLETER() ########" << finl;
406 le_dom_Cl_dis->completer();
409 mutilde_->completer(le_dom_Cl_dis_mutilde_.valeur());
412 if (le_dom_Cl_dis_mutilde_)
413 le_dom_Cl_dis_mutilde_->completer();
417 Cerr <<
"[COMPLETER()] The unknown field c is associated to boundary conditions." << finl;
420 mutilde_->associer_domaine_cl_dis(le_dom_Cl_dis_mutilde_);
421 Cerr <<
"[COMPLETER()] The potential field mutilde is associated to boundary conditions." << finl;
423 if (mon_probleme->is_coupled())
425 Cerr <<
"Cahn_Hilliard :: Coupled problem not coded..." << finl;
431 if (liste_modeles_.size()==0)
432 liste_modeles_.add(mod);
435 Debog::verifier(
"Cahn_Hilliard::completer() avant concentration ", concentration_->valeurs());
436 Debog::verifier(
"Cahn_Hilliard::completer() avant mobilite ", mobilite_->valeurs());
439 Cerr <<
"Mobility field is built..." << finl;
441 Cerr <<
"Mobility field well computed !" << finl;
442 Cerr <<
"Kappa field is built..." << finl;
444 Cerr <<
"Kappa field well computed !" << finl;
449 Debog::verifier(
"Cahn_Hilliard::completer() apres concentration ", concentration_->valeurs());
450 Debog::verifier(
"Cahn_Hilliard::completer() apres mobilite ", mobilite_->valeurs());
458 Cerr <<
"Number of operators = " << nb_op << finl;
459 Nom msg=
"Equation_base::completer(), nb_op = " ;
461 for(
int i=0; i<nb_op; i++)
490 le_dom_Cl_dis_mutilde_->initialiser(temps);
495 le_dom_Cl_dis->mettre_a_jour(temps);
496 le_dom_Cl_dis_mutilde_->mettre_a_jour(temps);
528 if (i <=
mutilde().nb_valeurs_temporelles())
575 std::vector<YAML_data> mutilde_sauv =
mutilde_->data_a_sauvegarder();
576 data.insert(data.end(), mutilde_sauv.begin(), mutilde_sauv.end());
609 ident_mutilde +=
mutilde_->que_suis_je();
611 ident_mutilde +=
Nom(temps,
probleme().reprise_format_temps());
612 avancer_fichier(is, ident_mutilde);
627 le_schema_en_temps=un_schema_en_temps;
632 <<
" cannot support other time scheme than Schema_Cahn_Hilliard." << finl;
666 return le_schema_en_temps->pas_temps_max();
679 DoubleTrav secmem(derivee);
694 solveur_masse->appliquer(secmem);
717 Cerr <<
"[Cahn_Hilliard] Warning: Be careful with implicit part in derivative computation." << finl;
722 Cerr <<
"Error in Cahn_Hilliard::derivee_en_temps_inco" << finl;
723 Cerr <<
"implicite_ = " <<
implicite_ <<
" has not been initialized!" << finl;
724 Cerr <<
"May be " <<
que_suis_je() <<
"::completer() method doesn't call Cahn_Hilliard::completer()" << finl;
736 Debog::verifier(
"Cahn_Hilliard::compute_mutilde() avant concentration_ ", concentration_->valeurs());
738 DoubleTrav terme_non_lin(concentration_->valeurs());
740 const int nb_elem = terme_non_lin.
dimension(0);
741 const int nb_param = terme_non_lin.
line_size();
755 for (
int elem = 0; elem < nb_elem; elem++)
756 for (
int p = 0; p < nb_param; p++)
759 mutilde_->valeurs()(elem,p) = terme_non_lin(elem,p) -
mutilde_->valeurs()(elem,p);
764 DoubleTrav second_terme(concentration_->valeurs());
769 mat_kappa_.multvect_(concentration_->valeurs(), second_terme);
771 for (
int elem = 0; elem < nb_elem; elem++)
772 for (
int p = 0; p < nb_param; p++)
780 mutilde_->valeurs().echange_espace_virtuel();
782 Debog::verifier(
"Cahn_Hilliard::compute_mutilde() apres concentration_ ", concentration_->valeurs());
792 DoubleTrav terme_non_lin(concentration_->valeurs());
794 const int nb_elem = terme_non_lin.
dimension(0);
795 const int nb_param = terme_non_lin.
line_size();
797 DoubleTrav muti(concentration_->valeurs());
811 for (
int elem = 0; elem < nb_elem; elem++)
812 for (
int p = 0; p < nb_param; p++)
815 muti(elem,p) = terme_non_lin(elem,p) - muti(elem,p);
820 DoubleTrav second_terme(concentration_->valeurs()) ;
827 for (
int elem = 0; elem < nb_elem; elem++)
828 for (
int p = 0; p < nb_param; p++)
861 DoubleTrav mutilde_theta(concentration_->valeurs());
862 DoubleTrav residu(concentration_->valeurs());
880 for (
int i=0; i<le_dom_Cl_dis_mutilde_->nb_cond_lim(); i++)
882 Cond_lim& la_cl=le_dom_Cl_dis_mutilde_->les_conditions_limites(i);
886 ref_cast(
Courant_impose, la_cl.valeur()).mettre_a_jour_courant(c, mutilde_theta);
898 terme_mobilite_->ajouter_blocs( { }, residu, { {
"potentiel_chimique_generalise", mutilde_theta } });
902 for (
int elem = 0; elem < nb_elem; elem++)
903 for (
int p = 0; p < nb_param; p++)
904 residu(elem, p) = c(elem, p) - c_n(elem, p) - theta * dt * residu(elem, p);
910 for (
int elem = 0; elem < nb_elem; elem++)
911 for (
int p = 0; p < nb_param; p++)
921 Debog::verifier(
"Cahn_Hilliard::fonction_residu() apres residu ", residu);
931 DoubleTrav temp(inco), temp2(inco);
935 Cerr <<
"[Cahn_Hilliard] You cannot add a BC contribution without calling the initialisation of matrices before." << finl;
952 DoubleTrav temp(inco), temp2(inco);
956 Cerr <<
"[Cahn_Hilliard] You cannot add a BC contribution without calling the initialisation of matrices before." << finl;
961 terme_mobilite_.valeur().ajouter_blocs({}, temp, {{
"potentiel_chimique_generalise",temp2 }} );
962 solveur_masse->appliquer(temp);
971 const DoubleVect& vol = zvf.
volumes();
978 DoubleTrav temp(concentration_->valeurs());
979 temp = concentration_->valeurs();
981 Cerr <<
" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ." << finl;
982 Cerr <<
". . . . . . . . . . . INITIALIZATION: Mobility matrix & Kappa matrix . . . . . . . . . ." << finl;
983 Cerr <<
" . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . ." << finl;
988 Cerr <<
"Dimensions of matrix K = " <<
mat_kappa_.nb_lignes() <<
" x " <<
mat_kappa_.nb_colonnes() << finl;
1042 const DoubleVect& vol = zvf.
volumes();
1048 DoubleTrav temp(
mutilde_->valeurs());
1069 le_dom_Cl_dis_mutilde_->les_conditions_limites().compatible_avec_eqn(*
this);
1078 Cerr <<
"** Checking compatibility between boundary conditions on concentration and potential... **" << finl;
1083 const Cond_lim& cl_c=le_dom_Cl_dis->les_conditions_limites(n_cl);
1085 const Cond_lim& cl_mutilde=le_dom_Cl_dis_mutilde_->les_conditions_limites(n_cl);
1090 Cerr <<
"---------↧ " << finl;
1091 Cerr <<
" [" << nom_frontiere <<
"] Boundary conditions on c and mutilde are compatible: both are PERIODIC." << finl;
1092 Cerr <<
" ↪" << finl;
1097 Cerr <<
"---------↧ " << finl;
1099 Cerr <<
" [" << nom_frontiere <<
"] Boundary conditions on c and mutilde are compatible: both are NEUMANN." << finl;
1101 Cerr <<
" [" << nom_frontiere <<
"] Boundary conditions on c and mutilde are compatible: NEUMANN on c / DIRICHLET on mutilde." << finl;
1104 Cerr <<
" [" << nom_frontiere <<
"] Problem of compatibility between boundary conditions." << finl;
1105 Cerr <<
" Please check your dataset and the physics behind Cahn-Hilliard equation." << finl;
1106 Cerr <<
" Stop..." << finl;
1109 Cerr <<
" ↪" << finl;
1114 Cerr <<
" [" << nom_frontiere <<
"] Impossible to impose a current on the concentration." << finl;
1115 Cerr <<
" Please check your dataset and the physics behind Cahn-Hilliard equation." << finl;
1116 Cerr <<
" Stop..." << finl;
1122 Cerr <<
"---------↧ " << finl;
1125 Cerr <<
" [" << nom_frontiere <<
"] Boundary conditions are DIRICHLET on c / DIRICHLET on mutilde." << finl;
1126 Cerr <<
" To keep consistance of the Cahn-Hilliard equation, BC on mutilde are computed again "
1127 "depending on BC on c." << finl;
1129 Cerr <<
" CANNOT CHANGE VALUES THAT ARE NOT UNIFORM. Stop..." << finl;
1134 Cerr <<
" [" << nom_frontiere <<
"] Boundary conditions on c and mutilde are compatible: DIRICHLET on c / NEUMANN on mutilde." << finl;
1137 Cerr <<
" [" << nom_frontiere <<
"] Problem of compatibility between boundary conditions." << finl;
1138 Cerr <<
" Please check your dataset and the physics behind Cahn-Hilliard equation." << finl;
1139 Cerr <<
" Stop..." << finl;
1142 Cerr <<
" ↪" << finl;
1146 Cerr <<
"---------↧ " << finl;
1147 Cerr <<
" [" << nom_frontiere <<
"] Problem of compatibility between boundary conditions." << finl;
1148 Cerr <<
" Please check your dataset and the physics behind Cahn-Hilliard equation." << finl;
1149 Cerr <<
" Stop..." << finl;
int nb_parametres_d_ordre()
bool passer_par_ajouter_mobilite_
int preparer_calcul() override
cf Equation_base::preparer_calcul()
void discretiser_mobilite()
DoubleTab contribution_CL_concentration_
void calculer_contribution_CL_concentration(const DoubleTab &)
Renvoie la contribution des conditions limites sur la concentration sous forme d'un vecteur (multi-co...
DoubleTab contribution_CL_mutilde_
virtual DoubleTab fonction_residu(const DoubleTab &)
Construit la fonction résidu pour un algorithme de Newton :
void discretiser() override
Dicretise l'equation.
void completer() override
Complete l'equation base, associe le potentiel chimique généralisé a l'equation, initialise le vecteu...
void associer_sch_tps_base(const Schema_Temps_base &) override
S'associe au schema_en_temps : peut seulement être Schema_CH_Semi_Implicite pour l'instant.
void mettre_a_jour(double temps) override
Effectue une mise a jour en temps de l'equation.
int lire_motcle_non_standard(const Motcle &, Entree &) override
Reads non-simple-type parameters of an Objet_U from an input stream.
const Milieu_base & milieu() const override
Renvoie le milieu physique de l'equation.
int verif_Cl_mutilde() const
Méthode pour vérifier la compatibilité entre les CL de la concentration et les CL du potentiel.
int sauvegarder(Sortie &) const override
Appelle Equation_base::sauvegarder(Sortie&) et sauvegarde le potentiel chimique sur un flot de sortie...
const Fermeture_Thermo_base & fermeture() const
void associer_milieu_base(const Milieu_base &) override
Associe un mileu physique a l'equation en construisant dynamiquement (cast) un objet de type Milieu_I...
void resetTime(double time) override
Reset current time of the equation. Used from ICoCo. See documentation of Problem_base::resetTime().
void compute_mutilde()
Calcul de mutilde = beta*dW/dc - ∇. kappa ∇c.
std::vector< YAML_data > data_a_sauvegarder() const override
for PDI IO: retrieve name, type and dimensions of the fields to save/restore
int nb_parametres_d_ordre_
bool passer_par_ajouter_kappa_
bool updateGivenFields() override
cf Equation_base::updateGivenFields()
void set_param(Param &) const override
void abortTimeStep() override
Reinitialize what must be.
void construire_mobilite(const DoubleTab &)
Operateur_Diff terme_mobilite_
Operateur_Diff terme_kappa_
Entree & lire_cl_potentiel(Entree &)
Lecture des conditions limites sur un flot d'entree.
int nombre_d_operateurs_tot() const override
bool initTimeStep(double dt) override
Allocation and initialization of the unknown and boundary conditions until present+dt.
void initialiser_matrices()
const Operateur & operateur(int) const override
Renvoie le i-eme operateur de l'equation:
void discretiser_mutilde()
void associer_pb_base(const Probleme_base &) override
S'associe au probleme: apelle Equation_base::associer_pb_base(const Probleme_base&) les deux termes d...
void calculer_contribution_CL_mutilde(const DoubleTab &)
Renvoie la contribution des conditions limites sur le potentiel chimique sous forme d'un vecteur (mul...
bool matrices_initialisees_
int reprendre(Entree &) override
Effectue une reprise a partir d'un flot d'entree.
void lire_terme_mobilite()
const Champ_Inc_base & mutilde() const
Matrice_Morse mat_mobilite_
const Motcle & domaine_application() const override
Renvoie le nom du domaine d'application: "Cahn_Hilliard".
int nombre_d_operateurs() const override
Renvoie le nombre d'operateurs de l'equation: Pour Cahn-Hilliard c'est 2.
DoubleTab & derivee_en_temps_inco(DoubleTab &) override
Returns the time derivative of the unknown I of the equation: dI/dt = M-1*(sum(operators(I) + sources...
Domaine_Cl_dis_base & domaine_Cl_dis_mutilde()
void update_terme_mobilite(const DoubleTab &)
double calculer_pas_de_temps() const override
Calcul du prochain pas de temps.
void discretiser_concentration()
Matrice_Morse & matrice_mobilite()
const Champ_Inc_base & inconnue() const override
Renvoie la concentration (champ inconnue de l'equation) (version const).
DoubleTab & futur(int i=1) override
Returns field values at instant t+i.
virtual void associer_domaine_cl_dis(const Domaine_Cl_dis_base &)
DoubleTab & passe(int i=1) override
Returns field values at instant t-i.
void resetTime(double time) override
double changer_temps(const double temps) override
Sets the time of the field.
DoubleTab & valeurs() override
Returns the array of field values at the current time.
virtual void associer_eqn(const Equation_base &)
Associates the field with the equation of which it represents an unknown.
virtual void verifie_valeurs_cl()
double changer_temps_futur(double, int i=1)
Sets the time of the i-th future field.
virtual void completer(const Domaine_Cl_dis_base &zcl)
virtual void abortTimeStep()
class Cond_lim Generic class used to represent any class
Classe Courant_impose Cette condition limite correspond a un courant imposé. Utile uniquement dans le...
static void verifier(const char *const msg, double)
class Discret_Thyd This class is the base class representing a discretization
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
void calculer_derivee_en_temps(double t1, double t2)
Computes the growth rate of unsteady BCs between t1 and t2.
virtual void imposer_cond_lim(Champ_Inc_base &, double)=0
void resetTime(double time)
void set_temps_defaut(double temps)
Changes the i-th future time of all BCs.
virtual void mettre_a_jour(double temps)
Performs a time update of all boundary conditions.
int avancer(double temps)
Rotates the wheel of all BCs up to the given time.
void changer_temps_futur(double temps, int i)
Changes the i-th future time of all BCs.
double volumes(int i) const
const Nom & le_nom() const override
Returns the name of the Objet_U. Virtual method to override: returns "neant" in this implementation.
const Domaine & domaine() const
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....
virtual void set_param(Param &titi) const override
int reprendre(Entree &) override
We resume the unknown from an input stream.
virtual std::vector< YAML_data > data_a_sauvegarder() const
for PDI IO: retrieve name, type and dimensions of the data to save/restore. This has to be overrode f...
virtual void associer_pb_base(const Probleme_base &)
Associates with the Problem passed as parameter.
Sources & sources()
Returns the source terms associated with the equation.
const Discretisation_base & discretisation() const
Returns the discretization associated with the equation.
Solveur_Masse_base & solv_masse()
Returns the mass solver associated with the equation.
void set_diffusion_multi_scalaire(bool flg=true)
virtual void mettre_a_jour(double temps)
The value of the unknown at the time step has been calculated.
virtual void abortTimeStep()
Reinitialize what must be.
virtual int preparer_calcul()
Everything that does not depend on other possible problems.
virtual bool updateGivenFields()
void initialise_residu(int=0)
int sauvegarder(Sortie &) const override
We save the unknown, then the source terms to an output stream.
Probleme_base & probleme()
Returns the problem associated with the equation.
int lire_motcle_non_standard(const Motcle &, Entree &) override
Reads non-simple-type parameters of an Objet_U from an input stream.
Schema_Temps_base & schema_temps()
Returns the time scheme associated with the equation.
virtual bool initTimeStep(double dt)
Allocation and initialization of the unknown and boundary conditions until present+dt.
virtual void discretiser()
Discretizes the equation.
virtual void resetTime(double time)
Reset current time of the equation. Used from ICoCo. See documentation of Problem_base::resetTime().
Champs_compris champs_compris_
Domaine_dis_base & domaine_dis()
Returns the discretized domain associated with the equation.
Potentiel_Chimique_base & potentiel_chimique()
int nb_parametres_d_ordre() const
DoubleTab mobilite(const DoubleTab &d) const
const Nom & le_nom() const override
Returns the name of the Objet_U. Virtual method to override: returns "neant" in this implementation.
virtual DoubleVect & multvect_(const DoubleVect &, DoubleVect &) const
const Fermeture_Thermo_base & fermeture() const
Milieu_base This class is the base of the (physical) medium hierarchy.
A character string (Nom) in uppercase.
Classe Neumann_paroi This boundary condition corresponds to an imposed flux for the.
class Nom: a character string for naming TRUST objects.
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.
class Operateur Generic class of the operator hierarchy.
virtual DoubleTab & calculer(const DoubleTab &, DoubleTab &) const =0
virtual void completer()
Updates the references of the objects associated with the operator.
Helper class to factorize the readOn method of Objet_U classes.
void ajouter_flag(const char *keyword, const bool *value)
Register a boolean flag whose mere presence switches it to true.
void ajouter_non_std(const char *keyword, const Objet_U *value, Param::Nature nat=Param::OPTIONAL)
Register a keyword handled by Objet_U::lire_motcle_non_standard.
class Periodique This class represents a periodic boundary condition.
virtual DoubleTab dWdc(const DoubleTab &)
const Nom & le_nom() const override
Returns the name of the Objet_U. Virtual method to override: returns "neant" in this implementation.
class Probleme_base It is a Probleme_U that is not a coupling.
const Domaine & domaine() const
Returns the domain associated with the problem.
static void exit(int exit_code=-1)
Exit routine for TRUST within a Kokkos region.
Scalaire_impose_paroi Imposes a scalar at the wall in a Convection-Diffusion equation for a scalar.
class Schema_Cahn_Hilliard. Il herite de schema Euler semi implicite et ne s'applique qu'à Cahn-Hilli...
double temps_courant() const
Returns the current time.
virtual double temps_futur(int i) const =0
double pas_de_temps() const
Returns the current time step (delta_t).
virtual int nb_valeurs_futures() const =0
virtual double temps_defaut() const =0
virtual void completer()=0
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 mettre_a_jour(double temps)
Time update of all sources in the list.
_SIZE_ dimension(int d) const
_SIZE_ size_totale() const
virtual void echange_espace_virtuel(IsExchangeBlocking exchange_type=IsExchangeBlocking::DefaultBlocking, const std::string kernel_name="noname")
static int is_PDI_restart()