TrioCFD 1.9.9_beta
TrioCFD documentation
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: error in the size of sm" << finl;
58 }
59
60 // Loop over joint faces
61
62 // Loop over boundaries
63 // On faces carrying Dirichlet or Symmetry boundary conditions,
64 // the normal velocity remains equal to its initial value.
65 // Therefore vpoint must remain 0 on these faces.
66
67 for (int n_bord = 0; n_bord < domaine_VDF.nb_front_Cl(); n_bord++)
68 {
69
70 // for each boundary condition, check its 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 // For Dirichlet faces, set sm to 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 // For Symmetry faces, set vpoint to 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 // Loop over internal faces
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: if BCs, no multiplication by alpha * rho in multiphase */
135 DoubleTrav masse(N, N), masse_e(N, N); //masse alpha * rho, contribution
136 for (f = 0; f < domaine.nb_faces(); f++) //real faces
137 {
138 if (!pbm || fcl(f, 0) >= 2)
139 for (masse = 0, n = 0; n < N; n++) masse(n, n) = 1; //not Pb_Multiphase or BC -> no 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); //diagonal part
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 to alpha * rho on the 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; //homogeneous Dirichlet / Symmetry: reset to 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: boundary condition value
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
Returns field values at instant t-i.
DoubleTab & valeurs() override
Returns the array of field values at the current time.
virtual DoubleTab & passe(int i=1)
Definition Champ_Proto.h:50
class Cond_lim Generic class used to represent any class
Definition Cond_lim.h:31
class Conds_lim This class represents a vector of boundary conditions.
Definition Conds_lim.h:32
Classe Dirichlet_homogene This class is the base class of the hierarchy of homogeneous Dirichlet-type...
Dirichlet This class is the base class of the hierarchy of Dirichlet-type boundary conditions.
Definition Dirichlet.h:31
class Domaine_Cl_dis_base Domaine_Cl_dis_base objects represent discretized boundary conditions
class Domaine_VDF
Definition Domaine_VDF.h:61
class Domaine_VF
Definition Domaine_VF.h:44
int nb_faces() const
Returns the total number of faces.
Definition Domaine_VF.h:471
DoubleVect & volumes_entrelaces()
Definition Domaine_VF.h:99
int premiere_face_int() const
A face is internal if and only if it separates two 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
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
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
Added-mass correlation of the form: alpha_k rho_k Dv_k / Dt -> alpha_k rho_k Dv_k / Dt + sum_l ma(k,...
virtual void ajouter(const double *alpha, const double *rho, DoubleTab &a_r) const =0
Matrice_Morse class - Represents a (sparse) matrix M, not necessarily square,.
virtual const Champ_base & masse_volumique() const
Returns the mass density of the medium (const version).
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 std::string & getString() const
Definition Nom.h:92
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 const Nom & le_nom() const
Returns the name of the Objet_U. Virtual method to override: returns "neant" in this implementation.
Definition Objet_U.cpp:317
virtual Sortie & printOn(Sortie &) const
Writes the object to an output stream. Virtual method to override.
Definition Objet_U.cpp:278
Multiphase thermohydraulics problem of type "3*N equations":
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)
Exit routine for TRUST within a Kokkos region.
Definition Process.cpp:466
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
Base class for output streams.
Definition Sortie.h:52
Symetrie On symmetry faces, the following properties hold:
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