TrioCFD 1.9.8
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 Appel a Terme_Source_Acceleration::lire_data
32 *
33 */
35{
36 lire_data(s);
37 return s;
38}
39
40/*! @brief Methode appelee par Source_base::completer() apres associer_domaines Remplit les ref.
41 *
42 * aux domaines et domaine_cl
43 *
44 */
46 const Domaine_Cl_dis_base& domaine_Cl_dis)
47{
48 if (je_suis_maitre())
49 Cerr << "Terme_Source_Acceleration_VEF_Face::associer_domaines" << finl;
50 le_dom_VEF_ = ref_cast(Domaine_VEF, domaine_dis);
51 le_dom_Cl_VEF_ = ref_cast(Domaine_Cl_VEF, domaine_Cl_dis);
52}
53
54/*! @brief Fonction outil pour Terme_Source_Acceleration_VEF_Face::ajouter Ajout des contributions d'une liste contigue de faces du terme source de translation:
55 *
56 * s_face = terme_source * rho
57 * resu += integrale (s_face) sur le volume de controle de la vitesse.
58 * On traite les cas suivants:
59 * rho = reference nulle (=> rho = 1.) sinon rho != nul
60 * faces de bord => sortie libre
61 * periodicite
62 * symetrie car en VEF la vitesse sur la face de bord peut ne pas etre nul (V_tangentielle)
63 * faces_internes
64 *
65 */
66static void TSAVEF_ajouter_liste_faces(const int premiere_face, const int derniere_face,
67 const DoubleVect& volumes_entrelaces,
68 const DoubleVect& volumes_elements,
69 const DoubleVect& porosite_surf,
70 const IntTab& face_voisins,
71 const OBS_PTR(Champ_base) & ref_rho,
72 const DoubleTab& terme_source,
73 DoubleTab& s_face,
74 DoubleTab& resu)
75{
76 int num_face;
77 // Pointeur constant sur tableau constant.
78 // Pointeur nul si ref_rho_ est une reference nulle.
79 const DoubleTab * const rho_elem =
80 (bool(ref_rho)) ? &(ref_rho->valeurs()) : 0;
81 const int dim = Objet_U::dimension;
82
83 for (num_face=premiere_face; num_face<derniere_face; num_face++)
84 {
85 const double vol = volumes_entrelaces(num_face)*porosite_surf(num_face);
86 double src[3] = {0., 0., 0.};
87 int j;
88
89 for (j = 0; j < dim; j++)
90 src[j] = terme_source(num_face, j);
91
92 double rho = 1.;
93
94 // Calcul d'un rho moyen sur le volume de controle de la vitesse
95 if (rho_elem)
96 {
97 const int elem0 = face_voisins(num_face,0);
98 const int elem1 = face_voisins(num_face,1);
99 double rho0 = 0, rho1 = 0, vol0 = 0, vol1 = 0;
100 if (elem0 >= 0)
101 {
102 rho0 = (*rho_elem)(elem0);
103 vol0 = volumes_elements(elem0);
104 }
105 if (elem1 >= 0)
106 {
107 rho1 = (*rho_elem)(elem1);
108 vol1 = volumes_elements(elem1);
109 }
110 rho = (rho0 * vol0 + rho1 * vol1) / (vol0 + vol1);
111 }
112
113 for (j = 0; j < dim; j++)
114 {
115 double a = src[j] * rho;
116 s_face(num_face, j) = a;
117 // Integrale sur le volume de controle :
118 resu(num_face, j) += a * vol;
119 }
120 }
121}
122
123/*! @brief Ajoute le terme (la_source_ * rho * volume_entrelace) au champ resu.
124 *
125 * On suppose que resu est discretise comme la vitesse.
126 * L'espace virtuel de "resu" n'est PAS mis a jour !
127 *
128 * Commentaire sur le schema: L'acceleration d/dt(v) est calculee aux elements,
129 * puis multipliee par "rho" aux elements, puis evaluee aux faces par une
130 * moyenne sur les elements voisins de la face. C'est un premier essai, pas
131 * forcement la meilleure idee. Comme l'acceleration depend de la vitesse qui
132 * est aux faces, on passe par deux interpolations successives.
133 * Effet de bord:
134 * On met (la_source_ * rho) dans terme_source_post_
135 *
136 */
137DoubleTab& Terme_Source_Acceleration_VEF_Face::ajouter(DoubleTab& resu) const
138{
139 const Domaine_VF& domaine = le_dom_VEF_.valeur();
140 const Domaine_Cl_dis_base& domaine_Cl = le_dom_Cl_VEF_.valeur();
141 const IntTab& face_voisins = domaine.face_voisins();
142 const DoubleVect& porosite_surf = equation().milieu().porosite_face();
143 const DoubleVect& volumes_entrelaces = domaine.volumes_entrelaces();
144
145 DoubleTab& s_face = get_set_terme_source_post().valeurs();
146 s_face = 0.;
147
148 // Calcul de la_source_ en fonction des champs d'acceleration et de la
149 // vitesse du fluide.
150 const int dim = Objet_U::dimension;
151 const int nb_faces = resu.dimension(0);
152 DoubleTab acceleration_aux_faces(nb_faces, dim);
153 calculer_la_source(acceleration_aux_faces);
154
155 // Boucle sur les conditions limites pour traiter les faces de bord
156
157 for (int n_bord = 0; n_bord < domaine.nb_front_Cl(); n_bord++)
158 {
159 // pour chaque Condition Limite on regarde son type
160 // Si face de Dirichlet on ne fait rien
161 // Si face de Neumann, Periodique ou de Symetrie on calcule la contribution au terme source
162 const Cond_lim& la_cl = domaine_Cl.les_conditions_limites(n_bord);
163 const Front_VF& le_bord = ref_cast(Front_VF,la_cl->frontiere_dis());
164 const int ndeb = le_bord.num_premiere_face();
165 const int nfin = ndeb + le_bord.nb_faces();
166
167 TSAVEF_ajouter_liste_faces(ndeb, nfin,
168 volumes_entrelaces,
169 domaine.volumes(),
170 porosite_surf,
171 face_voisins,
172 ref_rho_,
173 acceleration_aux_faces,
174 s_face,
175 resu);
176
177 }
178 // Boucle sur les faces internes
179 {
180 const int ndeb = domaine.premiere_face_int();
181 const int nfin = domaine.nb_faces();
182 TSAVEF_ajouter_liste_faces(ndeb, nfin,
183 volumes_entrelaces,
184 domaine.volumes(),
185 porosite_surf,
186 face_voisins,
187 ref_rho_,
188 acceleration_aux_faces,
189 s_face,
190 resu);
191 }
192
193 {
194 // Force la periodicite
195 int nb_comp=resu.line_size();
196 for (int n_bord=0; n_bord<domaine.nb_front_Cl(); n_bord++)
197 {
198 const Cond_lim& la_cl = domaine_Cl.les_conditions_limites(n_bord);
199 if (sub_type(Periodique,la_cl.valeur()))
200 {
201 const Periodique& la_cl_perio = ref_cast(Periodique,la_cl.valeur());
202 const Front_VF& le_bord = ref_cast(Front_VF,la_cl->frontiere_dis());
203 int nb_faces_bord=le_bord.nb_faces();
204 ArrOfInt fait(nb_faces_bord);
205 fait = 0;
206 for (int ind_face=0; ind_face<nb_faces_bord; ind_face++)
207 {
208 if (fait[ind_face] == 0)
209 {
210 int ind_face_associee = la_cl_perio.face_associee(ind_face);
211 fait[ind_face] = 1;
212 fait[ind_face_associee] = 1;
213 int face = le_bord.num_face(ind_face);
214 int face_associee = le_bord.num_face(ind_face_associee);
215 for (int comp=0; comp<nb_comp; comp++)
216 {
217 double val = 0.5*(resu(face_associee, comp)+resu(face, comp));
218 resu(face, comp)=resu(face_associee, comp) = val;
219 }
220 }// if fait
221 }// for face
222 }// sub_type Perio
223 }
224 }
225 return resu;
226}
227
228/*! @brief Calcul du champ de vitesse trois composantes aux faces a partir du champ de vitesse aux faces de eq_hydraulique_.
229 *
230 * inconnue().
231 * En VEF: rien a faire. On ne se sert pas du stockage fourni en
232 * parametre, on renvoie N.S.inconnue()
233 *
234 * @param (v_faces_stockage) tableau ou stocker le resultat s'il y a des calculs a faire. En vef, on ne s'en sert pas
235 */
236const DoubleTab& Terme_Source_Acceleration_VEF_Face::calculer_vitesse_faces(DoubleTab& v_faces_stockage) const
237{
239}
240
241/*! @brief Associe le champ de masse volumique=> Le terme source calcule sera alors homogene a d/dt(integrale(rho*v)).
242 *
243 * @param (champ_rho) un champ de type Champ_Fonc_P0_VEF qui sera utilise lors des appels a "ajouter()" pour evaluer la masse volumique.
244 */
245
247{
248 // Il faut que le champ soit discretise aux elements: possibilite
249 // d'autoriser d'autres types si besoin (Champ_Don, Champ_Inc, etc.)
250 // du moment que c'est des champs P0.
251 if (!sub_type(Champ_Fonc_P0_VEF, champ_rho))
252 {
253 Cerr << "Erreur dans Terme_Source_Acceleration_VEF_Face::associer_champ_rho" << finl;
254 Cerr << " Le champ de masse volumique doit etre de type Champ_Fonc_P0_VEF" << finl;
255 Cerr << " Type du champ associe : " << champ_rho.que_suis_je() << finl;
256 Cerr << " Nom du champ associe : " << champ_rho.le_nom() << finl;
257 assert(0);
258 exit();
259 }
260 ref_rho_ = champ_rho;
261}
262
DoubleTab & valeurs() override
Surcharge Champ_base::valeurs() Renvoie le tableau des valeurs.
classe Champ_Fonc_P0_VEF
DoubleTab & valeurs() override
Renvoie le tableau des valeurs du champ au temps courant.
virtual DoubleTab & valeurs()=0
classe Champ_base Cette classe est la base de la hierarchie des champs.
Definition Champ_base.h:43
classe Cond_lim Classe generique servant a representer n'importe quelle classe
Definition Cond_lim.h:31
classe Domaine_Cl_dis_base Les objets Domaine_Cl_dis_base representent les conditions aux limites
const Cond_lim & les_conditions_limites(int) const
Renvoie la i-ieme condition aux limites.
class Domaine_VEF
Definition Domaine_VEF.h:54
class Domaine_VF
Definition Domaine_VF.h:44
classe Domaine_dis_base Cette classe est la base de la hierarchie des domaines discretisees.
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
Renvoie le nom du champ.
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
Renvoie la reference sur l'equation pointe par MorEqn::mon_equation.
Definition MorEqn.h:62
const Champ_Inc_base & inconnue() const override
Renvoie la vitesse (champ inconnue de l'equation) (version const).
static int dimension
Definition Objet_U.h:99
const Nom & que_suis_je() const
renvoie la chaine identifiant la classe.
Definition Objet_U.cpp:104
virtual Entree & readOn(Entree &)
Lecture d'un Objet_U sur un flot d'entree Methode a surcharger.
Definition Objet_U.cpp:293
virtual Sortie & printOn(Sortie &) const
Ecriture de l'objet sur un flot de sortie Methode a surcharger.
Definition Objet_U.cpp:282
classe Periodique Cette classe represente une condition aux limites periodique.
Definition Periodique.h:31
int face_associee(int i) const
Definition Periodique.h:35
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
Definition Process.cpp:455
static int je_suis_maitre()
renvoie 1 si on est sur le processeur maitre du groupe courant (c'est a dire me() == 0),...
Definition Process.cpp:86
Classe de base des flux de sortie.
Definition Sortie.h:52
_SIZE_ dimension(int d) const
Definition TRUSTTab.tpp:133
int line_size() const
Definition TRUSTVect.tpp:67
Terme source d'acceleration specialise pour la discretisation VDF.
const DoubleTab & calculer_vitesse_faces(DoubleTab &v_faces_stockage) const override
Calcul du champ de vitesse trois composantes aux faces a partir du champ de vitesse aux faces de eq_h...
void associer_domaines(const Domaine_dis_base &, const Domaine_Cl_dis_base &) override
Methode appelee par Source_base::completer() apres associer_domaines Remplit les ref.
void associer_champ_rho(const Champ_base &champ_rho) override
Associe le champ de masse volumique=> Le terme source calcule sera alors homogene a d/dt(integrale(rh...
DoubleTab & ajouter(DoubleTab &) const override
Ajoute le terme (la_source_ * rho * volume_entrelace) au champ resu.
virtual const Navier_Stokes_std & get_eq_hydraulique() const
Renvoie eq_hydraulique_ !
const DoubleTab & calculer_la_source(DoubleTab &src_faces) const
Calcul de la valeur du champ la_source aux faces en fonction de - calculer_vitesse_faces().
virtual Champ_Fonc_base & get_set_terme_source_post() const
virtual void lire_data(Entree &s)
Methode appelee par readOn des classes derivees Terme_Source_Acceleration_VDF_Face,...