TrioCFD 1.9.9_beta
TrioCFD documentation
Loading...
Searching...
No Matches
Terme_Source_Qdm_VDF_Face.cpp
1/****************************************************************************
2* Copyright (c) 2024, 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_Qdm_VDF_Face.h>
17#include <Neumann_sortie_libre.h>
18#include <Discretisation_base.h>
19#include <Dirichlet_homogene.h>
20#include <Champ_Uniforme.h>
21#include <Equation_base.h>
22#include <Pb_Multiphase.h>
23#include <Domaine_Cl_VDF.h>
24
25#include <Milieu_base.h>
26#include <Periodique.h>
27#include <Dirichlet.h>
28#include <Symetrie.h>
29#include <Domaine_VDF.h>
30
31Implemente_instanciable(Terme_Source_Qdm_VDF_Face, "Source_Qdm_VDF_Face", Source_base);
32
34
36{
37 s >> la_source;
38 if (la_source->nb_comp() != equation().inconnue().nb_comp())
39 {
40 Cerr << "Error reading the source term of type " << que_suis_je() << finl;
41 Cerr << "the source field must have " << equation().inconnue().nb_comp() << " components" << finl;
42 exit();
43 }
44 return s;
45}
46
48{
49 le_dom_VDF = ref_cast(Domaine_VDF, domaine_dis);
50 le_dom_Cl_VDF = ref_cast(Domaine_Cl_VDF, domaine_Cl_dis);
51}
52
53void Terme_Source_Qdm_VDF_Face::ajouter_blocs(matrices_t matrices, DoubleTab& resu, const tabs_t& semi_impl) const
54{
55 const Domaine_VDF& domaine_VDF = le_dom_VDF.valeur();
56 const Domaine_Cl_VDF& domaine_Cl_VDF = le_dom_Cl_VDF.valeur();
57 const IntTab& face_voisins = domaine_VDF.face_voisins();
58 const IntVect& orientation = domaine_VDF.orientation();
59 const DoubleVect& porosite_surf = equation().milieu().porosite_face();
60 const DoubleVect& volumes_entrelaces = domaine_VDF.volumes_entrelaces();
61
62 // useful only if multiphase problem
63 const DoubleTab* alp = sub_type(Pb_Multiphase, equation().probleme()) ? &ref_cast(Pb_Multiphase, equation().probleme()).equation_masse().inconnue().passe() : nullptr;
64 const DoubleTab* rho = alp ? &equation().milieu().masse_volumique().passe() : nullptr;
65
66 const int cR = alp ? ((*rho).dimension_tot(0) == 1) : 0;
67 const int nb_comp = equation().inconnue().valeurs().line_size();
68
69 double vol;
70 int ndeb, nfin, ncomp, num_face, elem1, elem2;
71
72 if (sub_type(Champ_Uniforme, la_source.valeur()))
73 {
74 const DoubleVect& s = la_source->valeurs();
75
76 // Loop over boundary conditions to process boundary faces: for each boundary condition, check its type
77 // If Dirichlet or Symmetry face, do nothing
78 // If Neumann face, compute the contribution to the source term
79 for (int n_bord = 0; n_bord < domaine_VDF.nb_front_Cl(); n_bord++)
80 {
81 const Cond_lim& la_cl = domaine_Cl_VDF.les_conditions_limites(n_bord);
82
83 if (sub_type(Periodique, la_cl.valeur()))
84 {
85 if (alp) Process::exit("Terme_Source_Qdm_VDF_Face : periodic CL not yet available for Pb_Multiphase !");
86
87 const Front_VF& le_bord = ref_cast(Front_VF, la_cl->frontiere_dis());
88 ndeb = le_bord.num_premiere_face();
89 nfin = ndeb + le_bord.nb_faces();
90
91 for (int k = 0; k < nb_comp; k++)
92 for (num_face = ndeb; num_face < nfin; num_face++)
93 {
94 vol = volumes_entrelaces(num_face);
95 ncomp = orientation(num_face);
96 resu(num_face, k) += s(nb_comp * ncomp + k) * vol;
97 }
98 }
99 else if (sub_type(Neumann_sortie_libre, la_cl.valeur()))
100 {
101 const Front_VF& le_bord = ref_cast(Front_VF, la_cl->frontiere_dis());
102 ndeb = le_bord.num_premiere_face();
103 nfin = ndeb + le_bord.nb_faces();
104
105 for (int k = 0; k < nb_comp; k++)
106 for (num_face = ndeb; num_face < nfin; num_face++)
107 {
108 vol = volumes_entrelaces(num_face) * porosite_surf(num_face);
109 ncomp = orientation(num_face);
110 double alpha_rho = 1.0;
111 if (alp)
112 {
113 elem1 = face_voisins(num_face, 0), elem2 = face_voisins(num_face, 1);
114 const int e = ( elem1 > -1 ? elem1 : elem2);
115 double a = (*alp)(e, k), r = (*rho)(!cR * e, k);
116 alpha_rho = a * r;
117 }
118 resu(num_face, k) += s(nb_comp * ncomp + k) * vol * alpha_rho;
119 }
120
121 }
122 else if (sub_type(Symetrie, la_cl.valeur())) { /* Do nothing */}
123 else if ((sub_type(Dirichlet, la_cl.valeur())) || (sub_type(Dirichlet_homogene, la_cl.valeur()))) { /* Do nothing */}
124 }
125
126 // Loop over internal faces
127 ndeb = domaine_VDF.premiere_face_int();
128 for (int k = 0; k < nb_comp; k++)
129 for (num_face = domaine_VDF.premiere_face_int(); num_face < domaine_VDF.nb_faces(); num_face++)
130 {
131 vol = volumes_entrelaces(num_face) * porosite_surf(num_face);
132 ncomp = orientation(num_face);
133 double alpha_rho = 1.0;
134 if (alp)
135 {
136 elem1 = face_voisins(num_face, 0), elem2 = face_voisins(num_face, 1);
137 double a = 0.5 * ((*alp)(elem1, k) + (*alp)(elem2, k)), r = 0.5 * ((*rho)(!cR * elem1, k) + (*rho)(!cR * elem2, k));
138 alpha_rho = a * r;
139 }
140 resu(num_face, k) += s(nb_comp * ncomp + k) * vol * alpha_rho;
141 }
142 }
143 else // the source field is no longer uniform
144 {
145 const DoubleTab *s_tmp = nullptr;
146 DoubleTab eval;
147 if (la_source->que_suis_je().contient("_som_"))
148 {
149 // Need to interpolate
150 const int N = resu.dimension(1), D = dimension;
151 eval.resize(resu.dimension(0), N * D);
152 la_source->valeur_aux(domaine_VDF.xp(), eval);
153 s_tmp = &eval;
154 }
155 else
156 s_tmp = &(la_source->valeurs());
157 const DoubleTab& s = *s_tmp;
158
159 // Loop over boundary conditions to process boundary faces: for each boundary condition, check its type
160 // If Dirichlet or Symmetry face, do nothing
161 // If Neumann face, compute the contribution to the source term
162 for (int n_bord = 0; n_bord < domaine_VDF.nb_front_Cl(); n_bord++)
163 {
164 const Cond_lim& la_cl = domaine_Cl_VDF.les_conditions_limites(n_bord);
165
166 if (sub_type(Neumann_sortie_libre, la_cl.valeur()))
167 {
168 const Front_VF& le_bord = ref_cast(Front_VF, la_cl->frontiere_dis());
169 ndeb = le_bord.num_premiere_face();
170 nfin = ndeb + le_bord.nb_faces();
171
172 for (int k = 0; k < nb_comp; k++)
173 for (num_face = ndeb; num_face < nfin; num_face++)
174 {
175 vol = volumes_entrelaces(num_face) * porosite_surf(num_face);
176 ncomp = orientation(num_face);
177 elem1 = face_voisins(num_face, 0), elem2 = face_voisins(num_face, 1);
178 const int e = (elem1 > -1 ? elem1 : elem2);
179 double alpha_rho = 1.0;
180 if (alp)
181 {
182 double a = (*alp)(e, k), r = (*rho)(!cR * e, k);
183 alpha_rho = a * r;
184 }
185 resu(num_face, k) += s(e, nb_comp * ncomp + k) * vol * alpha_rho;
186 }
187 }
188 else if (sub_type(Symetrie, la_cl.valeur())) { /* Do nothing */}
189 else if ((sub_type(Dirichlet, la_cl.valeur())) || (sub_type(Dirichlet_homogene, la_cl.valeur()))) { /* Do nothing */}
190 else if (sub_type(Periodique, la_cl.valeur()))
191 {
192 if (alp) Process::exit("Terme_Source_Qdm_VDF_Face : periodic CL not yet available for Pb_Multiphase !");
193
194 const Front_VF& le_bord = ref_cast(Front_VF, la_cl->frontiere_dis());
195 ndeb = le_bord.num_premiere_face();
196 nfin = ndeb + le_bord.nb_faces();
197
198 for (int k = 0; k < nb_comp; k++)
199 for (num_face = ndeb; num_face < nfin; num_face++)
200 {
201 vol = volumes_entrelaces(num_face) * porosite_surf(num_face);
202 ncomp = orientation(num_face);
203 double s_face = 0.5 * (s(face_voisins(num_face, 0), nb_comp * ncomp + k) + s(face_voisins(num_face, 1), nb_comp * ncomp + k));
204 resu(num_face, k) += s_face * vol;
205 }
206 }
207 }
208
209 // Loop over internal faces
210 ndeb = domaine_VDF.premiere_face_int();
211
212 for (int k = 0; k < nb_comp; k++)
213 for (num_face = domaine_VDF.premiere_face_int(); num_face < domaine_VDF.nb_faces(); num_face++)
214 {
215 vol = volumes_entrelaces(num_face) * porosite_surf(num_face);
216 ncomp = orientation(num_face);
217 elem1 = face_voisins(num_face, 0), elem2 = face_voisins(num_face, 1);
218 double alpha_rho = 1.0;
219 if (alp)
220 {
221 double a = 0.5 * ((*alp)(elem1, k) + (*alp)(elem2, k)), r = 0.5 * ((*rho)(!cR * elem1, k) + (*rho)(!cR * elem2, k));
222 alpha_rho = a * r;
223 }
224 double s_face = 0.5 * (s(elem1, nb_comp * ncomp + k) + s(elem2, nb_comp * ncomp + k));
225 resu(num_face,k ) += s_face * vol * alpha_rho;
226 }
227 }
228}
229
231{
232 la_source->mettre_a_jour(temps);
233}
234
236{
237 equation().discretisation().nommer_completer_champ_physique(equation().domaine_dis(), "source_qdm", "", la_source.valeur(), equation().probleme());
238 la_source->initialiser(temps);
239 return Source_base::initialiser(temps);
240}
DoubleTab & valeurs() override
Returns the array of field values at the current time.
virtual DoubleTab & passe(int i=1)
Definition Champ_Proto.h:50
Champ_Uniforme Represents a field that is constant in space and time.
class Cond_lim Generic class used to represent any class
Definition Cond_lim.h:31
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
void nommer_completer_champ_physique(const Domaine_dis_base &domaine_vdf, const Nom &nom_champ, const Nom &unite, Champ_base &champ, const Probleme_base &pbi) const
class Domaine_Cl_VDF
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_VDF
Definition Domaine_VDF.h:61
int orientation(int) const override
inline DoubleVect& Domaine_VDF::porosite_face() {
int nb_faces() const
Returns the total number of faces.
Definition Domaine_VF.h:471
DoubleVect & volumes_entrelaces()
Definition Domaine_VF.h:99
double xp(int num_elem, int k) const
Definition Domaine_VF.h:77
int premiere_face_int() const
A face is internal if and only if it separates two elements.
Definition Domaine_VF.h:463
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 Domaine_dis_base This class is the base of the hierarchy of discretized domains.
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
const Discretisation_base & discretisation() const
Returns the discretization associated with the equation.
virtual const Champ_Inc_base & inconnue() const =0
virtual int nb_comp() const
Definition Field_base.h:56
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
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
Neumann_sortie_libre This class represents an open boundary without imposed velocity.
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
Multiphase thermohydraulics problem of type "3*N equations":
class Periodique This class represents a periodic boundary condition.
Definition Periodique.h:31
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
Source_base A Source_base object is a term appearing on the right-hand side of an.
Definition Source_base.h:42
virtual int initialiser(double temps)
Unlike the mettre_a_jour methods, the initializer methods of sources cannot depend on the outside.
Symetrie On symmetry faces, the following properties hold:
Definition Symetrie.h:37
void resize(_SIZE_ n, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
Definition TRUSTTab.tpp:469
_SIZE_ dimension(int d) const
Definition TRUSTTab.tpp:133
int line_size() const
Definition TRUSTVect.tpp:67
class Terme_Source_Qdm_VDF_Face
void associer_domaines(const Domaine_dis_base &, const Domaine_Cl_dis_base &) override
void ajouter_blocs(matrices_t matrices, DoubleTab &secmem, const tabs_t &semi_impl) const override
void mettre_a_jour(double) override
DOES NOTHING - to override in derived classes.
int initialiser(double temps) override
Unlike the mettre_a_jour methods, the initializer methods of sources cannot depend on the outside.