TrioCFD 1.9.9_beta
TrioCFD documentation
Loading...
Searching...
No Matches
Terme_Source_Acceleration_VEF_Face.cpp
1/****************************************************************************
2* Copyright (c) 2026, 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 <Terme_Source_Acceleration_VEF_Face.h>
17#include <Domaine_VEF.h>
18#include <Domaine_Cl_VEF.h>
19#include <Periodique.h>
20#include <Navier_Stokes_std.h>
21#include <Champ_Fonc_P0_VEF.h>
22#include <Milieu_base.h>
23
24Implemente_instanciable(Terme_Source_Acceleration_VEF_Face,"Acceleration_VEF_P1NC",Terme_Source_Acceleration);
25
27{
28 return s << que_suis_je() ;
29}
30
31/*! @brief Call Terme_Source_Acceleration::lire_data.
32 *
33 */
35{
36 lire_data(s);
37 return s;
38}
39
40/*! @brief Method called by Source_base::completer() after associer_domaines. Fills the references to the domains and domain_cl.
41 *
42 */
44 const Domaine_Cl_dis_base& domaine_Cl_dis)
45{
46 if (je_suis_maitre())
47 Cerr << "Terme_Source_Acceleration_VEF_Face::associer_domaines" << finl;
48 le_dom_VEF_ = ref_cast(Domaine_VEF, domaine_dis);
49 le_dom_Cl_VEF_ = ref_cast(Domaine_Cl_VEF, domaine_Cl_dis);
50}
51
52/*! @brief Helper function for Terme_Source_Acceleration_VEF_Face::ajouter. Adds contributions from a contiguous list of faces of the translation source term:
53 *
54 * s_face = source_term * rho
55 * resu += integral (s_face) over the velocity control volume.
56 * Handles the following cases:
57 * rho = null reference (=> rho = 1.) otherwise rho != null
58 * boundary faces => free outlet
59 * periodicity
60 * symmetry because in VEF the velocity on a boundary face may not be zero (V_tangential)
61 * internal faces
62 *
63 */
64static void TSAVEF_ajouter_liste_faces(const int premiere_face, const int derniere_face,
65 const DoubleVect& volumes_entrelaces,
66 const DoubleVect& volumes_elements,
67 const DoubleVect& porosite_surf,
68 const IntTab& face_voisins,
69 const OBS_PTR(Champ_base) & ref_rho,
70 const DoubleTab& terme_source,
71 DoubleTab& s_face,
72 DoubleTab& resu)
73{
74 int num_face;
75 // Constant pointer to a constant array.
76 // Null pointer if ref_rho_ is a null reference.
77 const DoubleTab * const rho_elem =
78 (bool(ref_rho)) ? &(ref_rho->valeurs()) : 0;
79 const int dim = Objet_U::dimension;
80
81 for (num_face=premiere_face; num_face<derniere_face; num_face++)
82 {
83 const double vol = volumes_entrelaces(num_face)*porosite_surf(num_face);
84 double src[3] = {0., 0., 0.};
85 int j;
86
87 for (j = 0; j < dim; j++)
88 src[j] = terme_source(num_face, j);
89
90 double rho = 1.;
91
92 // Compute a mean rho over the velocity control volume
93 if (rho_elem)
94 {
95 const int elem0 = face_voisins(num_face,0);
96 const int elem1 = face_voisins(num_face,1);
97 double rho0 = 0, rho1 = 0, vol0 = 0, vol1 = 0;
98 if (elem0 >= 0)
99 {
100 rho0 = (*rho_elem)(elem0);
101 vol0 = volumes_elements(elem0);
102 }
103 if (elem1 >= 0)
104 {
105 rho1 = (*rho_elem)(elem1);
106 vol1 = volumes_elements(elem1);
107 }
108 rho = (rho0 * vol0 + rho1 * vol1) / (vol0 + vol1);
109 }
110
111 for (j = 0; j < dim; j++)
112 {
113 double a = src[j] * rho;
114 s_face(num_face, j) = a;
115 // Integral over the control volume:
116 resu(num_face, j) += a * vol;
117 }
118 }
119}
120
121/*! @brief Adds the term (la_source_ * rho * volume_entrelace) to the resu field.
122 *
123 * Assumes that resu is discretized like the velocity.
124 * The virtual space of "resu" is NOT updated!
125 *
126 * Note on the scheme: the acceleration d/dt(v) is computed at elements,
127 * then multiplied by "rho" at elements, then evaluated at faces via an
128 * average over the neighbouring elements of the face. This is a first attempt,
129 * not necessarily the best approach. Since the acceleration depends on the velocity
130 * which is at faces, two successive interpolations are used.
131 * Side effect:
132 * (la_source_ * rho) is stored in terme_source_post_
133 *
134 */
135DoubleTab& Terme_Source_Acceleration_VEF_Face::ajouter(DoubleTab& resu) const
136{
137 const Domaine_VF& domaine = le_dom_VEF_.valeur();
138 const Domaine_Cl_dis_base& domaine_Cl = le_dom_Cl_VEF_.valeur();
139 const IntTab& face_voisins = domaine.face_voisins();
140 const DoubleVect& porosite_surf = equation().milieu().porosite_face();
141 const DoubleVect& volumes_entrelaces = domaine.volumes_entrelaces();
142
143 DoubleTab& s_face = get_set_terme_source_post().valeurs();
144 s_face = 0.;
145
146 // Compute la_source_ from the acceleration fields and the fluid velocity.
147 const int dim = Objet_U::dimension;
148 const int nb_faces = resu.dimension(0);
149 DoubleTab acceleration_aux_faces(nb_faces, dim);
150 calculer_la_source(acceleration_aux_faces);
151
152 // Loop over the boundary conditions to process the boundary faces
153
154 for (int n_bord = 0; n_bord < domaine.nb_front_Cl(); n_bord++)
155 {
156 // for each boundary condition check its type
157 // If Dirichlet face do nothing
158 // If Neumann, Periodic or Symmetry face compute the contribution to the source term
159 const Cond_lim& la_cl = domaine_Cl.les_conditions_limites(n_bord);
160 const Front_VF& le_bord = ref_cast(Front_VF,la_cl->frontiere_dis());
161 const int ndeb = le_bord.num_premiere_face();
162 const int nfin = ndeb + le_bord.nb_faces();
163
164 TSAVEF_ajouter_liste_faces(ndeb, nfin,
165 volumes_entrelaces,
166 domaine.volumes(),
167 porosite_surf,
168 face_voisins,
169 ref_rho_,
170 acceleration_aux_faces,
171 s_face,
172 resu);
173
174 }
175 // Loop over internal faces
176 {
177 const int ndeb = domaine.premiere_face_int();
178 const int nfin = domaine.nb_faces();
179 TSAVEF_ajouter_liste_faces(ndeb, nfin,
180 volumes_entrelaces,
181 domaine.volumes(),
182 porosite_surf,
183 face_voisins,
184 ref_rho_,
185 acceleration_aux_faces,
186 s_face,
187 resu);
188 }
189
190 {
191 // Enforce periodicity
192 int nb_comp=resu.line_size();
193 for (int n_bord=0; n_bord<domaine.nb_front_Cl(); n_bord++)
194 {
195 const Cond_lim& la_cl = domaine_Cl.les_conditions_limites(n_bord);
196 if (sub_type(Periodique,la_cl.valeur()))
197 {
198 const Periodique& la_cl_perio = ref_cast(Periodique,la_cl.valeur());
199 const Front_VF& le_bord = ref_cast(Front_VF,la_cl->frontiere_dis());
200 int nb_faces_bord=le_bord.nb_faces();
201 ArrOfInt fait(nb_faces_bord);
202 fait = 0;
203 for (int ind_face=0; ind_face<nb_faces_bord; ind_face++)
204 {
205 if (fait[ind_face] == 0)
206 {
207 int ind_face_associee = la_cl_perio.face_associee(ind_face);
208 fait[ind_face] = 1;
209 fait[ind_face_associee] = 1;
210 int face = le_bord.num_face(ind_face);
211 int face_associee = le_bord.num_face(ind_face_associee);
212 for (int comp=0; comp<nb_comp; comp++)
213 {
214 double val = 0.5*(resu(face_associee, comp)+resu(face, comp));
215 resu(face, comp)=resu(face_associee, comp) = val;
216 }
217 }// if fait
218 }// for face
219 }// sub_type Perio
220 }
221 }
222 return resu;
223}
224
225/*! @brief Computes the three-component velocity field at faces from the velocity field at faces of eq_hydraulique_.
226 *
227 * inconnue().
228 * In VEF: nothing to do. The provided storage is not used; N.S.inconnue() is returned directly.
229 *
230 * @param v_faces_stockage array to store the result if computations are needed. Not used in VEF.
231 * @return reference to the velocity values.
232 */
233const DoubleTab& Terme_Source_Acceleration_VEF_Face::calculer_vitesse_faces(DoubleTab& v_faces_stockage) const
234{
236}
237
238/*! @brief Associates the density field. The computed source term will then be homogeneous to d/dt(integral(rho*v)).
239 *
240 * @param champ_rho a field of type Champ_Fonc_P0_VEF that will be used in calls to "ajouter()" to evaluate the density.
241 */
242
244{
245 // The field must be discretized at elements: possibility
246 // to allow other types if needed (Champ_Don, Champ_Inc, etc.)
247 // as long as they are P0 fields.
248 if (!sub_type(Champ_Fonc_P0_VEF, champ_rho))
249 {
250 Cerr << "Error in Terme_Source_Acceleration_VEF_Face::associer_champ_rho" << finl;
251 Cerr << " The density field must be of type Champ_Fonc_P0_VEF" << finl;
252 Cerr << " Type of the associated field: " << champ_rho.que_suis_je() << finl;
253 Cerr << " Name of the associated field: " << champ_rho.le_nom() << finl;
254 assert(0);
255 exit();
256 }
257 ref_rho_ = champ_rho;
258}
259
DoubleTab & valeurs() override
Overrides Champ_base::valeurs() Returns the array of values.
class Champ_Fonc_P0_VEF
DoubleTab & valeurs() override
Returns the array of field values at the current time.
virtual DoubleTab & valeurs()=0
class Champ_base This class is the base of the fields hierarchy.
Definition Champ_base.h:43
class Cond_lim Generic class used to represent any class
Definition Cond_lim.h:31
class Domaine_Cl_dis_base Domaine_Cl_dis_base objects represent discretized boundary conditions
const Cond_lim & les_conditions_limites(int) const
Returns the i-th boundary condition.
class Domaine_VEF
Definition Domaine_VEF.h:53
class Domaine_VF
Definition Domaine_VF.h:44
class Domaine_dis_base This class is the base of the hierarchy of discretized domains.
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
virtual const Milieu_base & milieu() const =0
const Nom & le_nom() const override
Returns the name of the field.
class Front_VF
Definition Front_VF.h:36
int nb_faces() const
Definition Front_VF.h:53
int num_premiere_face() const
Definition Front_VF.h:63
int num_face(const int) const
Definition Front_VF.h:68
DoubleVect & porosite_face()
Definition Milieu_base.h:62
const Equation_base & equation() const
Returns the reference to the equation pointed to by MorEqn::mon_equation.
Definition MorEqn.h:62
const Champ_Inc_base & inconnue() const override
Returns the velocity (unknown field of the equation) (const version).
static int dimension
Definition Objet_U.h:94
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
class Periodique This class represents a periodic boundary condition.
Definition Periodique.h:31
int face_associee(int i) const
Definition Periodique.h:35
static void exit(int exit_code=-1)
Exit routine for TRUST within a Kokkos region.
Definition Process.cpp:466
static int je_suis_maitre()
Returns 1 if on the master processor of the current group (i.e. me() == 0), 0 otherwise.
Definition Process.cpp:82
Base class for output streams.
Definition Sortie.h:52
_SIZE_ dimension(int d) const
Definition TRUSTTab.tpp:133
int line_size() const
Definition TRUSTVect.tpp:67
Acceleration source term specialized for the VEF discretization.
const DoubleTab & calculer_vitesse_faces(DoubleTab &v_faces_stockage) const override
Computes the three-component velocity field at faces from the velocity field at faces of eq_hydrauliq...
void associer_domaines(const Domaine_dis_base &, const Domaine_Cl_dis_base &) override
Method called by Source_base::completer() after associer_domaines. Fills the references to the domain...
void associer_champ_rho(const Champ_base &champ_rho) override
Associates the density field. The computed source term will then be homogeneous to d/dt(integral(rho*...
DoubleTab & ajouter(DoubleTab &) const override
Adds the term (la_source_ * rho * volume_entrelace) to the resu field.
virtual const Navier_Stokes_std & get_eq_hydraulique() const
Returns eq_hydraulique_ !
const DoubleTab & calculer_la_source(DoubleTab &src_faces) const
Computes the value of the la_source field at faces based on - calculer_vitesse_faces().
virtual Champ_Fonc_base & get_set_terme_source_post() const
virtual void lire_data(Entree &s)
Method called by readOn of derived classes Terme_Source_Acceleration_VDF_Face, .