TRUST 1.9.8
HPC thermohydraulic platform
Loading...
Searching...
No Matches
Masse_VDF_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 <Dirichlet_homogene.h>
17#include <Masse_ajoutee_base.h>
18#include <Champ_Face_base.h>
19#include <Masse_VDF_Face.h>
20#include <Pb_Multiphase.h>
21#include <Equation_base.h>
22#include <Milieu_base.h>
23#include <Domaine_Cl_VDF.h>
24#include <TRUSTTrav.h>
25#include <Dirichlet.h>
26#include <Domaine_VDF.h>
27#include <Symetrie.h>
28#include <Matrix_tools.h>
29
30Implemente_instanciable(Masse_VDF_Face,"Masse_VDF_Face",Masse_VDF_base);
31
32Sortie& Masse_VDF_Face::printOn(Sortie& s) const { return s << que_suis_je() << " " << le_nom(); }
33
34Entree& Masse_VDF_Face::readOn(Entree& s) { return s ; }
35
40
41DoubleTab& Masse_VDF_Face::appliquer_impl(DoubleTab& sm) const
42{
43 if (sub_type(Pb_Multiphase, equation().probleme())) return Solveur_Masse_Face_proto::appliquer_impl_proto(sm);
44 else
45 {
46
47 assert(le_dom_VDF);
48 assert(le_dom_Cl_VDF);
49 const Domaine_VDF& domaine_VDF = le_dom_VDF.valeur();
50 const DoubleVect& porosite_face = equation().milieu().porosite_face();
51 const DoubleVect& volumes_entrelaces = domaine_VDF.volumes_entrelaces();
52 const int nb_faces = domaine_VDF.nb_faces(), N = sm.line_size();
53
54 if (sm.dimension(0) != nb_faces)
55 {
56 Cerr << "Masse_VDF_Face::appliquer : erreur dans la taille de sm" << finl;
58 }
59
60 // Boucle sur les faces joint
61
62 // Boucle sur les bords
63 // Sur les faces qui portent des conditions aux limites de Dirichlet ou de Symetrie
64 // la vitesse normale reste egale a sa valeur initiale.
65 // Donc sur ces faces vpoint doit rester a 0.
66
67 for (int n_bord = 0; n_bord < domaine_VDF.nb_front_Cl(); n_bord++)
68 {
69
70 // pour chaque Condition Limite on regarde son type
71 const Cond_lim& la_cl = le_dom_Cl_VDF->les_conditions_limites(n_bord);
72 const Front_VF& la_front_dis = ref_cast(Front_VF, la_cl->frontiere_dis());
73 const int ndeb = la_front_dis.num_premiere_face();
74 const int nfin = ndeb + la_front_dis.nb_faces();
75
76 if ( sub_type(Dirichlet,la_cl.valeur()) || sub_type(Dirichlet_homogene, la_cl.valeur()))
77 // Pour les faces de Dirichlet on met sm a 0
78 for (int f = ndeb; f < nfin; f++)
79 for (int n = 0; n < N; n++)
80 sm(f, n) = 0;
81 else if (sub_type(Symetrie, la_cl.valeur()))
82 // Pour les faces de Symetrie on met vpoint a 0
83 for (int f = ndeb; f < nfin; f++)
84 for (int n = 0; n < N; n++)
85 sm(f, n) = 0;
86 else
87 for (int f = ndeb; f < nfin; f++)
88 for (int n = 0; n < N; n++)
89 sm(f, n) /= (volumes_entrelaces(f) * porosite_face(f));
90
91 }
92
93 // Boucle sur les faces internes
94 const int ndeb = domaine_VDF.premiere_face_int();
95 for (int f = ndeb; f < nb_faces; f++)
96 for (int n = 0; n < N; n++)
97 sm(f, n) /= (volumes_entrelaces(f) * porosite_face(f));
98 //sm.echange_espace_virtuel();
99 //Debog::verifier("Masse_VDF_Face::appliquer sm",sm);
100 return sm;
101 }
102}
103
104void Masse_VDF_Face::dimensionner_blocs(matrices_t matrices, const tabs_t& semi_impl) const
105{
106 if (sub_type(Pb_Multiphase, equation().probleme()))
107 {
108 Stencil sten(0, 2);
109
110 Solveur_Masse_Face_proto::dimensionner_blocs_proto(matrices, semi_impl, true /* allocate too */, sten);
111 }
112 else
113 Masse_VDF_base::dimensionner_blocs(matrices, semi_impl);
114}
115
116void Masse_VDF_Face::ajouter_blocs(matrices_t matrices, DoubleTab& secmem, double dt, const tabs_t& semi_impl, int resoudre_en_increments) const
117{
118 if (sub_type(Pb_Multiphase, equation().probleme()))
119 {
120 const DoubleTab& inco = equation().inconnue().valeurs(), &passe = equation().inconnue().passe();
121 Matrice_Morse *mat = matrices[equation().inconnue().le_nom().getString()]; //facultatif
122 const Domaine_VF& domaine = ref_cast(Domaine_VF, equation().domaine_dis());
123 const Conds_lim& cls = ref_cast(Domaine_Cl_dis_base, equation().domaine_Cl_dis()).les_conditions_limites();
124 const IntTab& f_e = domaine.face_voisins(), &fcl = ref_cast(Champ_Face_base, equation().inconnue()).fcl();
125 const DoubleVect& pf = equation().milieu().porosite_face(), &vf = domaine.volumes_entrelaces(), &fs = domaine.face_surfaces();
126 const Pb_Multiphase *pbm = sub_type(Pb_Multiphase, equation().probleme()) ? &ref_cast(Pb_Multiphase, equation().probleme()) : nullptr;
127 const DoubleTab& rho = equation().milieu().masse_volumique().passe(),
128 *alpha = pbm ? &pbm->equation_masse().inconnue().passe() : nullptr,
129 *a_r = pbm ? &pbm->equation_masse().champ_conserve().passe() : nullptr,
130 &vfd = domaine.volumes_entrelaces_dir();
131 const Masse_ajoutee_base *corr = pbm && pbm->has_correlation("masse_ajoutee") ? &ref_cast(Masse_ajoutee_base, pbm->get_correlation("masse_ajoutee")) : nullptr;
132 int i, e, f, m, n, N = inco.line_size(), d, D = dimension, cR = rho.dimension_tot(0) == 1;
133
134 /* faces : si CLs, pas de produit par alpha * rho en multiphase */
135 DoubleTrav masse(N, N), masse_e(N, N); //masse alpha * rho, contribution
136 for (f = 0; f < domaine.nb_faces(); f++) //faces reelles
137 {
138 if (!pbm || fcl(f, 0) >= 2)
139 for (masse = 0, n = 0; n < N; n++) masse(n, n) = 1; //pas Pb_Multiphase ou CL -> pas de alpha * rho
140 else for (masse = 0, i = 0; i < 2; i++)
141 if ((e = f_e(f, i)) >= 0)
142 {
143 for (masse_e = 0, n = 0; n < N; n++) masse_e(n, n) = (*a_r)(e, n); //partie diagonale
144 if (corr) corr->ajouter(&(*alpha)(e, 0), &rho(!cR * e, 0), masse_e); //partie masse ajoutee
145 for (n = 0; n < N; n++)
146 for (m = 0; m < N; m++) masse(n, m) += vfd(f, i) / vf(f) * masse_e(n, m); //contribution au alpha * rho de la face
147 }
148 for (n = 0; n < N; n++)
149 {
150 double fac = pf(f) * vf(f) / dt;
151 for (m = 0; m < N; m++) secmem(f, n) -= fac * resoudre_en_increments * masse(n, m) * inco(f, m);
152 if (fcl(f, 0) < 2)
153 for (m = 0; m < N; m++) secmem(f, n) += fac * masse(n, m) * passe(f, m);
154 else if (fcl(f, 0) == 3)
155 for (d = 0; d < D; d++)
156 secmem(f, n) += fac * masse(n, n) * ref_cast(Dirichlet, cls[fcl(f, 1)].valeur()).val_imp(fcl(f, 2), N * d + n) * domaine.face_normales(f, d) / fs(f);
157 if (mat)
158 for (m = 0; m < N; m++)
159 if (masse(n, m)) (*mat)(N * f + n, N * f + m) += fac * masse(n, m);
160 }
161 }
162 i++;
163 }
164 else
165 Masse_VDF_base::ajouter_blocs(matrices, secmem, dt, semi_impl, resoudre_en_increments);
166}
167
168DoubleTab& Masse_VDF_Face::corriger_solution(DoubleTab& x, const DoubleTab& y, int incr) const
169{
170 if (!sub_type(Pb_Multiphase, equation().probleme())) return Masse_VDF_base::corriger_solution(x,y,incr);
171
172 const Domaine_VDF& domaine = ref_cast(Domaine_VDF, equation().domaine_dis());
173 const Conds_lim& cls = ref_cast(Domaine_Cl_dis_base, equation().domaine_Cl_dis()).les_conditions_limites();
174 const IntTab& fcl = ref_cast(Champ_Face_base, equation().inconnue()).fcl();
175 const DoubleTab& vit = equation().inconnue().valeurs();
176 const DoubleVect& fs = domaine.face_surfaces();
177 int f, n, N = x.line_size(), d, D = dimension;
178
179 for (f = 0; f < domaine.nb_faces_tot(); f++)
180 if (fcl(f, 0) == 2 || fcl(f, 0) == 4)
181 for (n = 0; n < N; n++) x(f, n) = incr ? -vit(f, n) : 0; //Dirichlet homogene / Symetrie: on revient a 0
182 else if (fcl(f, 0) == 3)
183 for (n = 0; n < N; n++)
184 for (x(f, n) = incr ? -vit(f, n) : 0, d = 0; d < D; d++) //Dirichlet : valeur de la CL
185 x(f, n) += domaine.face_normales(f, d) / fs(f) * ref_cast(Dirichlet, cls[fcl(f, 1)].valeur()).val_imp(fcl(f, 2), N * d + n);
186
187 return x;
188}
DoubleTab & passe(int i=1) override
Renvoie les valeurs du champs a l'instant t-i.
DoubleTab & valeurs() override
Renvoie le tableau des valeurs du champ au temps courant.
virtual DoubleTab & passe(int i=1)
Definition Champ_Proto.h:50
classe Cond_lim Classe generique servant a representer n'importe quelle classe
Definition Cond_lim.h:31
classe Conds_lim Cette classe represente un vecteur de conditions aux limites.
Definition Conds_lim.h:32
Classe Dirichlet_homogene Cette classe est la classe de base de la hierarchie des conditions aux limi...
classe Dirichlet Cette classe est la classe de base de la hierarchie des conditions aux limites de ty...
Definition Dirichlet.h:31
classe Domaine_Cl_dis_base Les objets Domaine_Cl_dis_base representent les conditions aux limites
class Domaine_VDF
Definition Domaine_VDF.h:64
class Domaine_VF
Definition Domaine_VF.h:44
int nb_faces() const
renvoie le nombre global de faces.
Definition Domaine_VF.h:471
DoubleVect & volumes_entrelaces()
Definition Domaine_VF.h:99
int premiere_face_int() const
une face est interne ssi elle separe deux elements.
Definition Domaine_VF.h:463
int nb_front_Cl() const
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
Champ_Inc_base & champ_conserve() const
virtual const Champ_Inc_base & inconnue() 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
DoubleTab & corriger_solution(DoubleTab &x, const DoubleTab &y, int incr) const override
DoubleTab & appliquer_impl(DoubleTab &) const override
void dimensionner_blocs(matrices_t matrices, const tabs_t &semi_impl) const override
void completer() override
void ajouter_blocs(matrices_t matrices, DoubleTab &secmem, double dt, const tabs_t &semi_impl, int resoudre_en_increments) const override
void ajouter_blocs(matrices_t matrices, DoubleTab &secmem, double dt, const tabs_t &semi_impl, int resoudre_en_increments) const override
void dimensionner_blocs(matrices_t matrices, const tabs_t &semi_impl) const override
classe Masse_ajoutee_base masse ajoutee de la forme
virtual void ajouter(const double *alpha, const double *rho, DoubleTab &a_r) const =0
Classe Matrice_Morse Represente une matrice M (creuse), non necessairement carree.
virtual const Champ_base & masse_volumique() const
Renvoie la masse volumique du milieu.
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 std::string & getString() const
Definition Nom.h:92
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 const Nom & le_nom() const
Donne le nom de l'Objet_U Methode a surcharger : renvoie "neant" dans cette implementation.
Definition Objet_U.cpp:319
virtual Sortie & printOn(Sortie &) const
Ecriture de l'objet sur un flot de sortie Methode a surcharger.
Definition Objet_U.cpp:282
classe Pb_Multiphase Cette classe represente un probleme de thermohydraulique multiphase de type "3*N...
virtual Equation_base & equation_masse()
int has_correlation(std::string nom_correlation) const
const Correlation_base & get_correlation(std::string nom_correlation) const
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
Definition Process.cpp:455
void associer_masse_proto(const Solveur_Masse_base &, const Domaine_VF &)
void dimensionner_blocs_proto(matrices_t matrices, const tabs_t &semi_impl, const bool allocate, Stencil &) const
DoubleTab & appliquer_impl_proto(DoubleTab &) const
virtual DoubleTab & corriger_solution(DoubleTab &x, const DoubleTab &y, int incr=0) const
Classe de base des flux de sortie.
Definition Sortie.h:52
classe Symetrie Sur les faces de symetrie on a les proprietes suivantes:
Definition Symetrie.h:37
_SIZE_ dimension_tot(int) const override
Definition TRUSTTab.tpp:160
_SIZE_ dimension(int d) const
Definition TRUSTTab.tpp:133
int line_size() const
Definition TRUSTVect.tpp:67