TrioCFD 1.9.9_beta
TrioCFD documentation
Loading...
Searching...
No Matches
Courant_impose.cpp
1/****************************************************************************
2* Copyright (c) 2025, CEA
3* All rights reserved.
4*
5* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
9*
10* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
11* IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
12* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
13*
14*****************************************************************************/
15
16#include <Courant_impose.h>
17#include <Domaine_Cl_dis_base.h>
18#include <Equation_base.h>
19#include <Cahn_Hilliard.h>
20#include <Probleme_base.h>
21#include <Milieu_base.h>
22#include <Espece_intercalee.h>
23#include <EChaine.h>
24
25Implemente_instanciable(Courant_impose, "Courant_impose", Neumann_paroi);
26// XD Courant_impose condlim_base Courant_impose INHERITS_BRACE Neumann boundary condition for imposed courant
27// XD_CONT (multiphase problem)
28// XD attr ch front_field_base ch REQ Boundary field type.
29
30Sortie& Courant_impose::printOn(Sortie& s) const { return s << que_suis_je() << finl; }
31
33{
34 if (app_domains.size() == 0) app_domains = { Motcle("Cahn_Hilliard"), Motcle("indetermine") };
35 Cerr << "*** Boundary conditions : Imposed courant for Lithium-ion Batteries case (only Cahn-Hilliard has been added yet) ***" << finl;
36
37 if (supp_discs.size() == 0) supp_discs = { Nom("VDF") };
38
39 // Lecture de la valeur uniforme du champ de courant imposé
40 s >> Iimp_;
41
42// Cerr << "Après lecture : Iimp = " << Iimp_ << finl;
43
44 // Dimensionnement du champ de flux à la frontière et initialisation à 0
45 // Type : champ variable en espace et en temps
46 le_champ_front.typer("Champ_front_fonc");
47 le_champ_front->nommer("Courant_impose");
48// Cerr << "Après typer." << finl;
49
50// Cerr << "[Courant_impose] Sortie du readOn." << finl;
51 return s;
52}
53
55{
56 mon_dom_cl_dis = zcl;
57
58 Equation_base& eq = mon_dom_cl_dis->equation();
59 const int dim_champ = eq.inconnue().nb_comp();
60
61// Cerr << "dim_champ = " << dim_champ << finl;
62// Cerr << "Temps = " << eq.schema_temps().temps_courant() << finl;
63 // le_champ_front->set_temps_defaut(eq.schema_temps().temps_courant());
64 le_champ_front->fixer_nb_comp(dim_champ);
65// Cerr << "Après avoir fixé le nombre de composantes." << finl;
66
67 le_champ_front->verifier(*this);
68
69// Cerr << "PREMIER PRINT = " << le_champ_front << finl;
70}
71
73{
74 Cerr << "[Courant_impose::verifie_ch_init_nb_comp()] ..." << finl;
75
76 if (le_champ_front)
77 {
79 const int nb_comp = le_champ_front->nb_comp();
80 eq.verifie_ch_init_nb_comp_cl(eq.inconnue(), nb_comp, *this);
81 }
82}
83
85{
86 Equation_base& eq = mon_dom_cl_dis->equation();
87 const int dim_champ = eq.inconnue().nb_comp();
88
89 Cerr << "[Courant_impose::completer()] ..." << finl;
90
91 int i;
92 ndeb_ = ref_cast(Front_VF,frontiere_dis()).num_premiere_face();
93// Cerr << "ndeb_ = " << ndeb_ << finl;
94 nb_faces_ = ref_cast(Front_VF,frontiere_dis()).nb_faces();
95// Cerr << "nb_faces_ = " << nb_faces_ << finl;
96 le_champ_front->valeurs().resize(nb_faces_,dim_champ);
97// Cerr << "Dimension of le_champ_front = " << le_champ_front->valeurs().dimension(0) << " x "
98// << le_champ_front->valeurs().dimension(1) << finl;
99
100 le_champ_front->set_instationnaire(true);
101
102// Cerr << "Après set_instationnaire." << finl;
103 if (le_champ_front->instationnaire())
104 Cerr << "[Courant_impose] : Instationnary field OK." << finl;
105 else
106 {
107 Cerr << "[Courant_impose] : Stationnary field... Not normal." << finl;
108 exit();
109 }
110
111 surfaces_.resize(nb_faces_);
112
113 Domaine_VF& zvf = ref_cast(Domaine_VF, mon_dom_cl_dis->domaine_dis());
114 for (i = 0; i < nb_faces_; i++)
115 {
116 surfaces_(i) = zvf.face_surfaces(i + ndeb_);
117 }
118
120
121// Cerr << "SECOND PRINT = " << le_champ_front->valeurs() << finl;
122
123}
124
125/*! @brief Met a jour les conditions aux limites sur le courant (spécifique à cette classe)
126 *
127 */
128void Courant_impose::mettre_a_jour_courant(const DoubleTab& c, const DoubleTab& mutilde)
129{
130 // Potentiel de l'électrolyte
131 double mu_el(0.), numer(0.), denom(0.), numer_tot(0.), denom_tot(0.);
132
133 DoubleTab& courant(le_champ_front->valeurs());
134 int nb_couches = courant.line_size();
135
136 Espece_intercalee& mil = ref_cast(Espece_intercalee, mon_dom_cl_dis->equation().milieu());
137 double i0 = mil.i0();
138 double damkohler = mil.damkohler();
139 double T_sur_Tref = mil.T_sur_Tref();
140
141 double S(0.), S_tot(0.), ds(0.);
142
143// Cerr << "surfaces = " << surfaces_ << finl;
144
145 for (int j=0; j<nb_couches; j++)
146 for (int face = 0; face < nb_faces_; face++)
147 {
148 int facegl = face + ndeb_; // indice de face global
149 int elem = face_voisins_(facegl, 0);
150 if (elem == -1)
151 elem = face_voisins_(facegl, 1);
152 ds = surfaces_(face);
153// Cerr << "ds = " << ds << finl;
154 S += ds;
155 numer += c(elem,j)*(1.-c(elem,j))*mutilde(elem,j)*ds;
156 denom += c(elem,j)*(1.-c(elem,j))*ds;
157 }
158// Cerr << "S = " << S << finl;
159// Cerr << "numer = " << numer << finl;
160// Cerr << "denom = " << denom << finl;
161
162 S_tot = mp_sum(S); // N_couches * L_y (ou L_x)
163// Cerr << "S_tot = " << S_tot << finl;
164 numer_tot = mp_sum(numer);
165// Cerr << "numer_tot = " << numer_tot << finl;
166 numer_tot /= S_tot; // C'est une moyenne sur la surface d'entrée : N_couches * L_y (ou L_x)
167 denom_tot = mp_sum(denom);
168// Cerr << "denom_tot = " << denom_tot << finl;
169 denom_tot /= S_tot; // C'est aussi une moyenne sur la surface d'entrée
170// Cerr << "deuxieme terme du numerateur = " << (S_tot * (Iimp_)/i0) << finl;
171 // Multiplication par la surface totale (qui comprend aussi l'indice j des couches)
172// if (abs(denom_tot) < 1.E-12)
173// mu_el = 0.;
174// else
175 mu_el = ( ((Iimp_/i0) * T_sur_Tref) + numer_tot ) / denom_tot;
176
177// Cerr << "mu_el = " << mu_el << finl;
178
179 const double constante = damkohler/(T_sur_Tref);
180
181 // Boucle sur les couches
182 for (int j=0; j<nb_couches; j++)
183 for (int face = 0; face < nb_faces_; face++)
184 {
185 int facegl = face + ndeb_;
186 int elem = face_voisins_(facegl, 0);
187 if (elem == -1)
188 elem = face_voisins_(facegl, 1);
189 courant(face,j) = constante * c(elem,j)*(1.-c(elem,j))*(mu_el - mutilde(elem,j));
190 }
191
192// Cerr << "courant imposé = " << courant << finl;
193}
194
195/*! @brief Renvoie la valeur du flux impose sur la i-eme composante du champ representant le flux a la frontiere.
196 *
197 * Le champ a la frontiere est considere constant sur tous
198 * les elements de la frontiere.
199 * La valeur du flux impose a la frontiere est egale
200 * a la valeur du champ (considere constant) a la frontiere divise par d_rho.
201 *
202 * @param (int i) indice suivant la premiere dimension du champ
203 * @return (double) la valeur imposee sur la composante du champ specifiee
204 * @throws deuxieme dimension du champ de frontiere superieur a 1
205 */
207{
208 return Neumann::flux_impose(i);
209}
210
211/*! @brief Renvoie la valeur du flux impose sur la (i,j)-eme composante du champ representant le flux a la frontiere.
212 *
213 * Le champ a la frontiere n'est PAS constant sur tous les elements
214 * la frontiere.
215 *
216 * @param (int i) indice suivant la premiere dimension du champ
217 * @param (int j) indice suivant la deuxieme dimension du champ
218 * @return (double) la valeur imposee sur la composante du champ specifiee
219 */
220double Courant_impose::flux_impose(int i, int j) const
221{
222 return Neumann::flux_impose(i,j);
223}
224
std::vector< Nom > supp_discs
Domaine_Cl_dis_base & domaine_Cl_dis()
Returns the domain of discretized boundary conditions to which the object belongs.
std::vector< Motcle > app_domains
virtual Frontiere_dis_base & frontiere_dis()
Returns the discretized boundary to which the boundary conditions apply.
Classe Courant_impose Cette condition limite correspond a un courant imposé. Utile uniquement dans le...
void verifie_ch_init_nb_comp() const override
Calls the verification of the field read through the equation for which the boundary condition is con...
void mettre_a_jour_courant(const DoubleTab &, const DoubleTab &)
Met a jour les conditions aux limites sur le courant (spécifique à cette classe).
double flux_impose(int i) const override
Renvoie la valeur du flux impose sur la i-eme composante du champ representant le flux a la frontiere...
void completer() override
DOES NOTHING must be overridden in derived classes.
DoubleVect surfaces_
void associer_domaine_cl_dis_base(const Domaine_Cl_dis_base &) override
Associates the Domaine_Cl_dis_base (domain of discretized boundary conditions) with the object.
class Domaine_Cl_dis_base Domaine_Cl_dis_base objects represent discretized boundary conditions
class Domaine_VF
Definition Domaine_VF.h:44
virtual const DoubleVect & face_surfaces() const
Definition Domaine_VF.h:51
int face_voisins(int num_face, int i) const
Returns the neighbouring element of num_face in direction i.
Definition Domaine_VF.h:418
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
class Equation_base The role of an equation is the calculation of one or more fields....
virtual const Milieu_base & milieu() const =0
virtual const Champ_Inc_base & inconnue() const =0
virtual void verifie_ch_init_nb_comp_cl(const Champ_Inc_base &ch_ref, const int nb_comp, const Cond_lim_base &cl) const
virtual int nb_comp() const
Definition Field_base.h:56
class Front_VF
Definition Front_VF.h:36
virtual const Equation_base & equation(const std::string &nom_inc) const
const Equation_base & equation() const
Returns the reference to the equation pointed to by MorEqn::mon_equation.
Definition MorEqn.h:62
Classe Neumann_paroi This boundary condition corresponds to an imposed flux for the.
virtual double flux_impose(int i) const
Returns the value of the imposed flux on the i-th component of the field representing the flux at the...
Definition Neumann.cpp:35
const Nom & que_suis_je() const
Returns the string identifying the class.
Definition Objet_U.cpp:104
virtual Entree & readOn(Entree &)
Reads an Objet_U from an input stream. Virtual method to override.
Definition Objet_U.cpp:289
virtual Sortie & printOn(Sortie &) const
Writes the object to an output stream. Virtual method to override.
Definition Objet_U.cpp:278
static double mp_sum(double)
Computes the sum of x over all processors in the current group.
Definition Process.cpp:145
static void exit(int exit_code=-1)
Exit routine for TRUST within a Kokkos region.
Definition Process.cpp:466
Base class for output streams.
Definition Sortie.h:52
int line_size() const
Definition TRUSTVect.tpp:67