TrioCFD 1.9.8
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 << "Erreur a la lecture du terme source de type " << que_suis_je() << finl;
41 Cerr << "le champ source doit avoir " << equation().inconnue().nb_comp() << " composantes" << 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 // Boucle sur les conditions limites pour traiter les faces de bord : pour chaque Condition Limite on regarde son type
77 // Si face de Dirichlet ou de Symetrie on ne fait rien
78 // Si face de Neumann on calcule la contribution au terme source
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 // Boucle sur les faces internes
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 // le champ source n'est plus uniforme
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 // Boucle sur les conditions limites pour traiter les faces de bord : pour chaque Condition Limite on regarde son type
160 // Si face de Dirichlet ou de Symetrie on ne fait rien
161 // Si face de Neumann on calcule la contribution au terme source
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 // Boucle sur les faces internes
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
Renvoie le tableau des valeurs du champ au temps courant.
virtual DoubleTab & passe(int i=1)
Definition Champ_Proto.h:50
classe Champ_Uniforme Represente un champ constant dans l'espace et dans le temps.
classe Cond_lim Classe generique servant a representer n'importe quelle classe
Definition Cond_lim.h:31
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
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
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_VDF
Definition Domaine_VDF.h:64
int orientation(int) const override
inline DoubleVect& Domaine_VDF::porosite_face() {
int nb_faces() const
renvoie le nombre global de 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
une face est interne ssi elle separe deux elements.
Definition Domaine_VF.h:463
int face_voisins(int num_face, int i) const
renvoie l'element voisin de numface dans la direction i.
Definition Domaine_VF.h:418
classe Domaine_dis_base Cette classe est la base de la hierarchie des domaines discretisees.
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
Renvoie la discretisation associee a l'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
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
classe Neumann_sortie_libre Cette classe represente une frontiere ouverte sans vitesse imposee
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 Pb_Multiphase Cette classe represente un probleme de thermohydraulique multiphase de type "3*N...
classe Periodique Cette classe represente une condition aux limites periodique.
Definition Periodique.h:31
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
Definition Process.cpp:455
Classe de base des flux de sortie.
Definition Sortie.h:52
classe Source_base Un objet Source_base est un terme apparaissant au second membre d'une
Definition Source_base.h:42
virtual int initialiser(double temps)
Contrairement aux methodes mettre_a_jour, les methodes initialiser des sources ne peuvent pas dependr...
classe Symetrie Sur les faces de symetrie on a les proprietes suivantes:
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
Contrairement aux methodes mettre_a_jour, les methodes initialiser des sources ne peuvent pas dependr...