TrioCFD 1.9.8
TrioCFD documentation
Loading...
Searching...
No Matches
Terme_Boussinesq_VEFPreP1B_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_Boussinesq_VEFPreP1B_Face.h>
17#include <Fluide_Incompressible.h>
18#include <Champ_Uniforme.h>
19#include <Periodique.h>
20#include <Domaine_VEF.h>
21#include <Domaine_Cl_VEF.h>
22#include <Domaine_VEF.h>
23#include <Synonyme_info.h>
24
25
26extern double calculer_coef_som(int elem, int dimension, int& nb_face_diri, int* indice_diri);
27
28Implemente_instanciable(Terme_Boussinesq_VEFPreP1B_Face,"Boussinesq_VEFPreP1B_P1NC",Terme_Boussinesq_VEF_Face);
29Add_synonym(Terme_Boussinesq_VEFPreP1B_Face,"Boussinesq_temperature_VEFPreP1B_P1NC");
30Add_synonym(Terme_Boussinesq_VEFPreP1B_Face,"Boussinesq_concentration_VEFPreP1B_P1NC");
31
32//// printOn
34{
36}
37
38//// readOn
40{
42}
43
44DoubleTab& Terme_Boussinesq_VEFPreP1B_Face::ajouter(DoubleTab& tab_resu) const
45{
46 const Domaine_VEF& domaine_VEF = ref_cast(Domaine_VEF, le_dom_VEF.valeur());
47 // Si seulement support P0 on appelle en VEF
48 if (domaine_VEF.get_alphaE() && !domaine_VEF.get_alphaS() && !domaine_VEF.get_alphaA())
50
51 // Verifie la validite de T0:
52 check();
53
54 int nbpts=-1; // nombre de points d'integration
55 // static variable can't be used on kernel devices:
56 int dim = Objet_U::dimension;
57 assert(dim==2 || dim==3);
58 if(dim==2)
59 {
60 nbpts=3; // ordre 2
61 }
62 else if(dim==3)
63 {
64 nbpts=4; // ordre 2
65 }
66
67 // On remplit les Poids et les coord_bary :
68 double Poids = 1./(dim+1);
69 if (tab_coord_bary_.dimension(0)!=nbpts)
70 {
71 tab_coord_bary_.resize(nbpts, dim + 1); // lambda_i des points
72 if (dim == 2)
73 {
74 tab_coord_bary_(0, 0) = 0.5;
75 tab_coord_bary_(0, 1) = 0.;
76 tab_coord_bary_(0, 2) = 0.5;
77
78 tab_coord_bary_(1, 0) = 0.;
79 tab_coord_bary_(1, 1) = 0.5;
80 tab_coord_bary_(1, 2) = 0.5;
81
82 tab_coord_bary_(2, 0) = 0.5;
83 tab_coord_bary_(2, 1) = 0.5;
84 tab_coord_bary_(2, 2) = 0.;
85 }
86 else if (dim == 3)
87 {
88 double a = 0.5854101966249685;
89 double b = 0.1381966011250105;
90
91 tab_coord_bary_(0, 0) = a;
92 tab_coord_bary_(0, 1) = b;
93 tab_coord_bary_(0, 2) = b;
94 tab_coord_bary_(0, 3) = b;
95
96 tab_coord_bary_(1, 0) = b;
97 tab_coord_bary_(1, 1) = a;
98 tab_coord_bary_(1, 2) = b;
99 tab_coord_bary_(1, 3) = b;
100
101 tab_coord_bary_(2, 1) = b;
102 tab_coord_bary_(2, 0) = b;
103 tab_coord_bary_(2, 2) = a;
104 tab_coord_bary_(2, 3) = b;
105
106 tab_coord_bary_(3, 2) = b;
107 tab_coord_bary_(3, 0) = b;
108 tab_coord_bary_(3, 1) = b;
109 tab_coord_bary_(3, 3) = a;
110 }
111 }
112
113 const Champ_Inc_base& le_scalaire = equation_scalaire().inconnue();
114 int nb_comp = le_scalaire.nb_comp(); // Vaut 1 si temperature, nb_constituents si concentration
115 int nb_elem_tot = domaine_VEF.nb_elem_tot();
116 // XXXTrav to not reallocate on the host/device each time:
117 IntTrav tab_les_polygones(nb_elem_tot * nbpts);
118 DoubleTrav tab_les_positions(nb_elem_tot * nbpts, dim);
119
120 CDoubleTabView coord_bary = tab_coord_bary_.view_ro();
121 CIntTabView elem_sommets = domaine_VEF.domaine().les_elems().view_ro();
122 CDoubleTabView coord_sommets = domaine_VEF.domaine().les_sommets().view_ro();
123 IntArrView les_polygones = static_cast<ArrOfInt&>(tab_les_polygones).view_wo();
124 DoubleTabView les_positions = tab_les_positions.view_wo();
125 // Remplissage des tableaux de travail:
126 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__),
127 Kokkos::RangePolicy<>(0, nb_elem_tot), KOKKOS_LAMBDA(
128 const int elem)
129 {
130 for (int pt = 0; pt < nbpts; pt++)
131 les_polygones(elem * nbpts + pt) = elem;
132
133 //On remplit la matrice de changement d'element :
134 double a0[3], a0a1[3], a0a2[3], a0a3[3];
135 const int som_glob = elem_sommets(elem,0);
136 for (int d=0; d<dim; d++)
137 a0[d]=coord_sommets(som_glob,d);
138
139 const int som_glob1 = elem_sommets(elem,1);
140 for (int d=0; d<dim; d++)
141 a0a1[d]=coord_sommets(som_glob1,d)-a0[d];
142
143 const int som_glob2 = elem_sommets(elem,2);
144 for (int d=0; d<dim; d++)
145 a0a2[d]=coord_sommets(som_glob2,d)-a0[d];
146
147 if(dim == 3)
148 {
149 const int som_glob3 = elem_sommets(elem,3);
150 for (int d=0; d<dim; d++)
151 a0a3[d]=coord_sommets(som_glob3,d)-a0[d];
152 }
153
154 //On remplit les_positions :
155 for (int pt = 0; pt < nbpts; pt++)
156 {
157 int point = elem * nbpts + pt;
158 for (int d=0; d<dim; d++)
159 if (dim == 2)
160 les_positions(point, d) = a0[d]
161 + coord_bary(pt, 1) * a0a1[d]
162 + coord_bary(pt, 2) * a0a2[d];
163 else if (dim == 3)
164 les_positions(point, d) = a0[d]
165 + coord_bary(pt, 1) * a0a1[d]
166 + coord_bary(pt, 2) * a0a2[d]
167 + coord_bary(pt, 3) * a0a3[d];
168 }
169 });
170 end_gpu_timer(__KERNEL_NAME__);
171
172 // XXXTrav to not reallocate on the host/device each time:
173 DoubleTrav tab_valeurs_scalaire(nb_elem_tot * nbpts, nb_comp);
174 DoubleTrav tab_valeurs_beta(nb_elem_tot * nbpts, nb_comp);
175
176 // Calcul du terme source aux points d'integration :
177 le_scalaire.valeur_aux_elems(tab_les_positions, tab_les_polygones, tab_valeurs_scalaire);
178 beta().valeur_aux_elems(tab_les_positions, tab_les_polygones, tab_valeurs_beta);
179
180 // Extension possible des volumes de controle:
181 //int modif_traitement_diri=( sub_type(Domaine_VEF,domaine_VEF) ? ref_cast(Domaine_VEF,domaine_VEF).get_modif_div_face_dirichlet() : 0);
182 //modif_traitement_diri = 0; // Forcee a 0 car ne marche pas d'apres essais Ulrich&Thomas
183
184 const Domaine_Cl_VEF& domaine_Cl_VEF = le_dom_Cl_VEF.valeur();
185
186 //CIntArrView rang_elem_non_std = domaine_VEF.rang_elem_non_std().view_ro();
187 //CIntArrView type_elem_Cl = domaine_Cl_VEF.type_elem_Cl().view_ro();
188 CDoubleArrView g = static_cast<const DoubleVect&>(gravite().valeurs()).view_ro();
189 CDoubleArrView porosite_surf = equation().milieu().porosite_face().view_ro();
190 CIntTabView elem_faces = domaine_VEF.elem_faces().view_ro();
191 CDoubleArrView volumes = domaine_VEF.volumes().view_ro();
192 CDoubleTabView valeurs_scalaire = tab_valeurs_scalaire.view_ro();
193 CDoubleTabView valeurs_beta = tab_valeurs_beta.view_ro();
194 CDoubleArrView Scalaire0 = getScalaire0().view_ro();
195 // indice_diri
196 DoubleTabView resu = tab_resu.view_rw();
197 // Boucle sur les elements:
198 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__),
199 Kokkos::RangePolicy<>(0, nb_elem_tot), KOKKOS_LAMBDA(
200 const int elem)
201 {
202 /*
203 int nb_face_diri = 0;
204 int indice_diri[4];
205 if (modif_traitement_diri)
206 {
207 int rang_elem = (int) rang_elem_non_std(elem);
208 int type_elem = rang_elem < 0 ? 0 : (int) type_elem_Cl(rang_elem);
209 calculer_coef_som(type_elem, dim, nb_face_diri, indice_diri);
210 } */
211
212 double volume=volumes(elem);
213
214 // Boucle sur les faces de l'element:
215 for(int face=0; face<=dim; face++)
216 {
217 int num_face=elem_faces(elem, face);
218 double valeurs_Psi[4];
219 // Integration sur les nbpts points:
220 for (int pt=0; pt<nbpts; pt++)
221 {
222 int point = elem * nbpts + pt;
223
224 valeurs_Psi[pt]=(1-dim*coord_bary(pt,face))*porosite_surf(num_face);
225
226 for (int d=0; d<dim; d++)
227 {
228 double contrib=0;
229 for (int comp=0; comp<nb_comp; comp++)
230 contrib+=Poids*volume*(Scalaire0(comp)-valeurs_scalaire(point,comp))*valeurs_beta(point,comp)*g(d)*valeurs_Psi[pt];
231 Kokkos::atomic_add(&resu(num_face,d), contrib);
232 /*
233 if (modif_traitement_diri)
234 {
235 for (int fdiri=0; fdiri<nb_face_diri; fdiri++)
236 {
237 int indice=indice_diri[fdiri];
238 int facel = elem_faces(elem,indice);
239 if (num_face==facel)
240 {
241 Kokkos::atomic_sub(&resu(facel,d), contrib);
242 double contrib2=contrib/(dim+1-nb_face_diri);
243 for (int f2=0; f2<dim+1; f2++)
244 {
245 int face2=elem_faces(elem,f2);
246 Kokkos::atomic_add(&resu(face2,d), contrib2);
247 }
248 }
249 }
250 }
251 */
252 }
253 }
254 }
255 });
256 end_gpu_timer(__KERNEL_NAME__);
257
258 // modif pour periodique
259 for (int n_bord=0; n_bord<domaine_VEF.nb_front_Cl(); n_bord++)
260 {
261 const Cond_lim& la_cl = domaine_Cl_VEF.les_conditions_limites(n_bord);
262 if (sub_type(Periodique,la_cl.valeur()))
263 {
264 const Periodique& la_cl_perio = ref_cast(Periodique,la_cl.valeur());
265 const Front_VF& le_bord = ref_cast(Front_VF,la_cl->frontiere_dis());
266 int nb_faces_bord=le_bord.nb_faces();
267 CIntArrView le_bord_num_face = le_bord.num_face().view_ro();
268 CIntArrView la_cl_perio_face_associee = la_cl_perio.face_associee().view_ro();
269 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__),
270 Kokkos::RangePolicy<>(0, nb_faces_bord/2), KOKKOS_LAMBDA(
271 const int ind_face)
272 {
273 int face = le_bord_num_face(ind_face);
274 int face_associee = le_bord_num_face(la_cl_perio_face_associee(ind_face));
275 for (int d=0; d<dim; d++)
276 {
277 resu(face_associee, d) += resu(face, d);
278 resu(face, d) = resu(face_associee, d);
279 }
280 });// for face
281 end_gpu_timer(__KERNEL_NAME__);
282 }// sub_type Perio
283 }
284 return tab_resu;
285}
DoubleTab & valeurs() override
Surcharge Champ_base::valeurs() Renvoie le tableau des valeurs.
Classe Champ_Inc_base.
virtual DoubleTab & valeur_aux_elems(const DoubleTab &positions, const IntVect &les_polys, DoubleTab &valeurs) const
provoque une erreur ! doit etre surchargee par les classes derivees
classe Cond_lim Classe generique servant a representer n'importe quelle classe
Definition Cond_lim.h:31
const Champ_Inc_base & inconnue() const override=0
DoubleTab_t & les_sommets()
Definition Domaine.h:113
IntTab_t & les_elems()
Definition Domaine.h:129
const Cond_lim & les_conditions_limites(int) const
Renvoie la i-ieme condition aux limites.
class Domaine_VEF
Definition Domaine_VEF.h:54
int get_alphaA() const
Definition Domaine_VEF.h:94
int get_alphaS() const
Definition Domaine_VEF.h:93
int get_alphaE() const
Definition Domaine_VEF.h:92
double volumes(int i) const
Definition Domaine_VF.h:113
int elem_faces(int i, int j) const
renvoie le numero de le ieme face de la maille num_elem la facon dont ces faces sont numerotees est
Definition Domaine_VF.h:543
int nb_elem_tot() const
int nb_front_Cl() const
const Domaine & domaine() 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
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_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
static int dimension
Definition Objet_U.h:99
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
Classe de base des flux de sortie.
Definition Sortie.h:52
std::enable_if_t< is_default_exec_space< EXEC_SPACE >, View< _TYPE_, _SHAPE_ > > view_wo()
Definition TRUSTTab.h:276
std::enable_if_t< is_default_exec_space< EXEC_SPACE >, ConstView< _TYPE_, _SHAPE_ > > view_ro() const
Definition TRUSTTab.h:261
std::enable_if_t< is_default_exec_space< EXEC_SPACE >, View< _TYPE_, _SHAPE_ > > view_rw()
Definition TRUSTTab.h:291
class Terme_Boussinesq_scalaire_VEFPreP1B_Face Terme Source de Boussinesq pour une dicretisation VEFP...
DoubleTab & ajouter(DoubleTab &) const override
Terme Source de Boussinesq pour une dicretisation VEF.
DoubleTab & ajouter(DoubleTab &) const override
double Scalaire0(int i) const
const Convection_Diffusion_std & equation_scalaire() const
const Champ_Don_base & gravite() const
const ArrOfDouble & getScalaire0() const
const Champ_Don_base & beta() const