TrioCFD 1.9.8
TrioCFD documentation
Loading...
Searching...
No Matches
Iterateur_Source_VEF_Face.h
1/****************************************************************************
2* Copyright (c) 2025, 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#ifndef Iterateur_Source_VEF_Face_included
17#define Iterateur_Source_VEF_Face_included
18
19#include <Evaluateur_Source_VEF_Face.h>
20#include <Iterateur_Source_base.h>
21#include <Champ_Uniforme.h>
22#include <TRUSTSingle.h>
23#include <Milieu_base.h>
24#include <Domaine_Cl_VEF.h>
25#include <Dirichlet.h>
26#include <Domaine_VEF.h>
27
28template<typename _TYPE_>
30{
31 inline unsigned taille_memoire() const override { throw; }
32
33 inline int duplique() const override
34 {
36 if(!xxx) Process::exit("Not enough memory !");
37 return xxx->numero();
38 }
39
40public:
41 Iterateur_Source_VEF_Face() : nb_faces_(-1), nb_faces_elem_(-1), premiere_face_std_(-1) { }
42 Iterateur_Source_VEF_Face(const Iterateur_Source_VEF_Face<_TYPE_>& iter) : Iterateur_Source_base(iter), evaluateur_source_face_(iter.evaluateur_source_face_),
43 nb_faces_(iter.nb_faces_), nb_faces_elem_(iter.nb_faces_elem_), premiere_face_std_(iter.premiere_face_std_) { }
44
45 DoubleTab& ajouter(DoubleTab&) const override;
46
47 void completer_() override
48 {
49 nb_faces_ = ref_cast(Domaine_VEF,le_dom.valeur()).nb_faces();
50 nb_faces_elem_ = le_dom->domaine().nb_faces_elem();
51 premiere_face_std_ = ref_cast(Domaine_VEF,le_dom.valeur()).premiere_face_std();
52 }
53
54 inline Evaluateur_Source_VEF_Face& evaluateur() override { return static_cast<Evaluateur_Source_VEF_Face&> (evaluateur_source_face_); }
55 inline const Evaluateur_Source_VEF_Face& evaluateur() const { return static_cast<const Evaluateur_Source_VEF_Face&> (evaluateur_source_face_); }
56
57protected:
58 int initialiser(double tps) override;
60
61 inline const int& faces_doubles(int num_face) const { return ref_cast(Domaine_VEF,le_dom.valeur()).faces_doubles()[num_face]; }
62 inline double volumes_entrelaces_Cl(int& num_face) const { return volumes_cl_dirichlet_[num_face]; }
63 inline double volumes_entrelaces(int& num_face) const { return ref_cast(Domaine_VEF,le_dom.valeur()).volumes_entrelaces()[num_face]; }
64 inline int face_voisins(int num_face, int dir) const { return ref_cast(Domaine_VEF,le_dom.valeur()).face_voisins(num_face, dir); }
65 inline int elem_faces(int num_elem, int i) const { return ref_cast(Domaine_VEF,le_dom.valeur()).elem_faces(num_elem, i); }
66
67private:
68 _TYPE_ evaluateur_source_face_;
69 int nb_faces_, nb_faces_elem_, premiere_face_std_;
70 mutable DoubleTab tab_coef_;
71 DoubleVect volumes_cl_dirichlet_;
72
73 public_for_cuda
74 template <typename Type_Double> DoubleTab& ajouter_faces_standard(const int, DoubleTab& ) const;
75 template <typename Type_Double> DoubleTab& ajouter_faces_non_standard(const int, DoubleTab& ) const;
76};
77
78template<typename _TYPE_>
80{
82 evaluateur().changer_volumes_entrelaces_Cl(volumes_cl_dirichlet_);
83 return 1;
84}
85
86template<typename _TYPE_>
87DoubleTab& Iterateur_Source_VEF_Face<_TYPE_>::ajouter(DoubleTab& resu) const
88{
89 ((_TYPE_&) (evaluateur_source_face_)).mettre_a_jour();
90
91 assert(resu.nb_dim() < 3);
92 int ncomp = resu.line_size();
93 int nb_faces_tot = ref_cast(Domaine_VEF,le_dom.valeur()).nb_faces_tot();
94 DoubleVect& bilan = so_base->bilan();
95 if (bilan.size_array()!=ncomp) bilan.resize(ncomp);
96 bilan = 0;
97 if (tab_coef_.size_array()!=nb_faces_tot) tab_coef_.resize(nb_faces_tot, RESIZE_OPTIONS::NOCOPY_NOINIT);
98 tab_coef_ = 1;
100 {
101 const Milieu_base& milieu = la_zcl->equation().milieu();
102 const Champ_base& rho = milieu.masse_volumique();
103 if (sub_type(Champ_Uniforme, rho))
104 tab_coef_ = rho.valeurs()(0, 0);
105 else
106 {
107 const DoubleTab& val_rho = rho.valeurs();
108 const IntTab& face_vois = le_dom->face_voisins();
109 const DoubleVect& volumes = ref_cast(Domaine_VEF,le_dom.valeur()).volumes();
110 tab_coef_ = 0.;
111 ToDo_Kokkos("critical");
112 for (int fac = 0; fac < nb_faces_tot; fac++)
113 {
114 int elem1 = face_vois(fac, 0);
115 int elem2 = face_vois(fac, 1);
116 double vol = 0;
117 if (elem1 != -1)
118 {
119 tab_coef_(fac) += val_rho(elem1) * volumes(elem1);
120 vol += volumes(elem1);
121 }
122 if (elem2 != -1)
123 {
124 tab_coef_(fac) += val_rho(elem2) * volumes(elem2);
125 vol += volumes(elem2);
126 }
127 tab_coef_(fac) /= vol;
128 }
129 }
130 }
131 if (ncomp == 1)
132 {
133 ajouter_faces_non_standard<SingleDouble>(ncomp,resu);
134 ajouter_faces_standard<SingleDouble>(ncomp,resu);
135 }
136 else
137 {
138 ajouter_faces_non_standard<ArrOfDouble>(ncomp,resu);
139 ajouter_faces_standard<ArrOfDouble>(ncomp,resu);
140 }
141 return resu;
142}
143
144template<typename _TYPE_>
146{
147 Domaine_VEF& zvef = ref_cast(Domaine_VEF,le_dom.valeur());
148 Domaine_Cl_VEF& zclvef = ref_cast(Domaine_Cl_VEF,la_zcl.valeur());
149 zvef.creer_tableau_faces(volumes_cl_dirichlet_);
150 DoubleVect& marq = volumes_cl_dirichlet_;
151 for (int f = 0; f < zvef.premiere_face_std(); f++)
152 marq[f] = zclvef.volumes_entrelaces_Cl()[f];
153 for (int f = zvef.premiere_face_std(); f < zvef.nb_faces(); f++)
154 marq[f] = volumes_entrelaces(f);
155 for (int num_cl = 0; num_cl < zvef.nb_front_Cl() * 0; num_cl++)
156 {
157 const Cond_lim& la_cl = zclvef.les_conditions_limites(num_cl);
158 const Front_VF& le_bord = ref_cast(Front_VF, la_cl->frontiere_dis());
159 int nf = le_bord.nb_faces();
160 if (sub_type(Dirichlet, la_cl.valeur()))
161 for (int ind_face = 0; ind_face < nf; ind_face++)
162 {
163 int num_face = le_bord.num_face(ind_face);
164 if (volumes_entrelaces_Cl(num_face) == 0)
165 marq[num_face] = 1;
166 }
167 }
169}
170
171template<typename _TYPE_> template<typename Type_Double>
172DoubleTab& Iterateur_Source_VEF_Face<_TYPE_>::ajouter_faces_non_standard(const int ncomp, DoubleTab& tab_resu) const
173{
174 DoubleVect& tab_bilan = so_base->bilan();
175 for (int num_cl = 0; num_cl < le_dom->nb_front_Cl(); num_cl++)
176 {
177 const Cond_lim& la_cl = la_zcl->les_conditions_limites(num_cl);
178 const Front_VF& le_bord = ref_cast(Front_VF, la_cl->frontiere_dis());
179 int nf = le_bord.nb_faces_tot();
180 bool Dirichlet = sub_type(Dirichlet, la_cl.valeur());
181 if (evaluateur().has_view())
182 {
183 const int nb_faces = nb_faces_, nb_faces_elem = nb_faces_elem_; // Remember *never* use an attribute in Kernel else crash !
184 _TYPE_ evaluateur_source_face;
185 evaluateur_source_face.set(evaluateur_source_face_);
186 CIntArrView faces_doubles = ref_cast(Domaine_VEF,le_dom.valeur()).faces_doubles().view_ro();
187 CIntTabView elem_faces = ref_cast(Domaine_VEF,le_dom.valeur()).elem_faces().view_ro();
188 CIntTabView face_voisins = ref_cast(Domaine_VEF,le_dom.valeur()).face_voisins().view_ro();
189 CDoubleArrView volumes_entrelaces_Cl = volumes_cl_dirichlet_.view_ro();
190 CIntArrView le_bord_num_face = le_bord.num_face().view_ro();
191 CDoubleArrView coef = static_cast<const ArrOfDouble&>(tab_coef_).view_ro();
192 DoubleArrView bilan = tab_bilan.view_rw();
193 DoubleTabView resu = tab_resu.view_rw();
194 Kokkos::View<double**, DoubleTabView::array_layout> source_view("source", nf, ncomp);
195 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), range_1D(0, nf), KOKKOS_LAMBDA(const int ind_face)
196 {
197 int num_face = le_bord_num_face(ind_face);
198 auto source = Kokkos::subview(source_view, ind_face, Kokkos::ALL());
199 evaluateur_source_face.calculer_terme_source_non_standard_view(num_face, source);
200 if (volumes_entrelaces_Cl(num_face) == 0)
201 {
202 int faces_dirichlet = 0;
203 for (int i = 0; i < nb_faces_elem; i++)
204 {
205 int face_voisine = elem_faces(face_voisins(num_face, 0), i);
206 if (volumes_entrelaces_Cl(face_voisine) == 0)
207 faces_dirichlet += 1;
208 }
209 for (int i = 0; i < nb_faces_elem; i++)
210 {
211 int face_voisine = elem_faces(face_voisins(num_face, 0), i);
212 if (volumes_entrelaces_Cl(face_voisine) != 0)
213 for (int k = 0; k < ncomp; k++)
214 {
215 Kokkos::atomic_add(&resu(face_voisine, k), + source(k) / (nb_faces_elem - faces_dirichlet));
216 if (face_voisine < nb_faces)
217 {
218 double contribution = (faces_doubles(face_voisine) == 1) ? 0.5 : 1;
219 Kokkos::atomic_add(&bilan(k), + contribution * coef(face_voisine) * source(k) /
220 (nb_faces_elem - faces_dirichlet));
221 }
222 }
223 }
224 }
225 else
226 {
227 for (int k = 0; k < ncomp; k++)
228 {
229 resu(num_face, k) += source(k);
230 if (num_face < nb_faces && !Dirichlet)
231 {
232 double contribution = (faces_doubles(num_face) == 1) ? 0.5 : 1;
233 Kokkos::atomic_add(&bilan(k), + contribution * coef(num_face) * source(k));
234 }
235 }
236 }
237 });
238 end_gpu_timer(__KERNEL_NAME__);
239 }
240 else
241 {
242 Type_Double source(ncomp);
243 ToDo_Kokkos("critical");
244 for (int ind_face = 0; ind_face < nf; ind_face++)
245 {
246 int num_face = le_bord.num_face(ind_face);
247 evaluateur_source_face_.calculer_terme_source_non_standard(num_face, source);
248 if (volumes_entrelaces_Cl(num_face) == 0)
249 {
250 int faces_dirichlet = 0;
251 for (int i = 0; i < nb_faces_elem_; i++)
252 {
253 int face_voisine = elem_faces(face_voisins(num_face, 0), i);
254 if (volumes_entrelaces_Cl(face_voisine) == 0)
255 faces_dirichlet += 1;
256 }
257 for (int i = 0; i < nb_faces_elem_; i++)
258 {
259 int face_voisine = elem_faces(face_voisins(num_face, 0), i);
260 if (volumes_entrelaces_Cl(face_voisine) != 0)
261 for (int k = 0; k < ncomp; k++)
262 {
263 tab_resu(face_voisine, k) += source(k) / (nb_faces_elem_ - faces_dirichlet);
264 if (face_voisine < nb_faces_)
265 {
266 double contribution = (faces_doubles(face_voisine) == 1) ? 0.5 : 1;
267 tab_bilan(k) += contribution * tab_coef_(face_voisine) * source(k) /
268 (nb_faces_elem_ - faces_dirichlet);
269 }
270 }
271 }
272 }
273 else
274 {
275 for (int k = 0; k < ncomp; k++)
276 {
277 tab_resu(num_face, k) += source(k);
278 if (num_face < nb_faces_ && !Dirichlet)
279 {
280 double contribution = (faces_doubles(num_face) == 1) ? 0.5 : 1;
281 tab_bilan(k) += contribution * tab_coef_(num_face) * source(k);
282 }
283 }
284 }
285 }
286 }
287 }
288 if (evaluateur().has_view())
289 {
290 const int premiere_face_std = premiere_face_std_; // Remember *never* use an attribute in Kernel else crash !
291 const int premiere_face_int = ref_cast(Domaine_VEF, le_dom.valeur()).premiere_face_int();
292 _TYPE_ evaluateur_source_face;
293 evaluateur_source_face.set(evaluateur_source_face_);
294 CIntArrView faces_doubles = ref_cast(Domaine_VEF,le_dom.valeur()).faces_doubles().view_ro();
295 CDoubleArrView coef = static_cast<const ArrOfDouble&>(tab_coef_).view_ro();
296 DoubleArrView bilan = tab_bilan.view_rw();
297 DoubleTabView resu = tab_resu.view_rw();
298 Kokkos::View<double**, DoubleTabView::array_layout> source_view("source", premiere_face_std-premiere_face_int, ncomp);
299 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), range_1D(premiere_face_int, premiere_face_std), KOKKOS_LAMBDA(const int num_face)
300 {
301 auto source = Kokkos::subview(source_view, num_face-premiere_face_int, Kokkos::ALL());
302 evaluateur_source_face.calculer_terme_source_non_standard_view(num_face, source);
303 for (int k = 0; k < ncomp; k++)
304 {
305 resu(num_face, k) += source(k);
306 double contribution = (faces_doubles(num_face) == 1) ? 0.5 : 1;
307 Kokkos::atomic_add(&bilan(k), contribution * coef(num_face) * source(k));
308 }
309 });
310 end_gpu_timer(__KERNEL_NAME__);
311 }
312 else
313 {
314 ToDo_Kokkos("critical");
315 Type_Double source(ncomp);
316 const int premiere_face_int = ref_cast(Domaine_VEF, le_dom.valeur()).premiere_face_int();
317 for (int num_face = premiere_face_int; num_face < premiere_face_std_; num_face++)
318 {
319 evaluateur_source_face_.calculer_terme_source_non_standard(num_face, source);
320 for (int k = 0; k < ncomp; k++)
321 {
322 tab_resu(num_face, k) += source(k);
323 double contribution = (faces_doubles(num_face) == 1) ? 0.5 : 1;
324 tab_bilan(k) += contribution * tab_coef_(num_face) * source(k);
325 }
326 }
327 }
328 return tab_resu;
329}
330
331template<typename _TYPE_> template<typename Type_Double>
332DoubleTab& Iterateur_Source_VEF_Face<_TYPE_>::ajouter_faces_standard(const int ncomp, DoubleTab& tab_resu) const
333{
334 DoubleVect& tab_bilan = so_base->bilan();
335 if (evaluateur().has_view())
336 {
337 const int nb_faces = nb_faces_, premiere_face_std = premiere_face_std_; // Remember *never* use an attribute in Kernel else crash !
338 _TYPE_ evaluateur_source_face;
339 evaluateur_source_face.set(evaluateur_source_face_);
340 CIntArrView faces_doubles = ref_cast(Domaine_VEF,le_dom.valeur()).faces_doubles().view_ro();
341 CDoubleArrView coef = static_cast<const ArrOfDouble&>(tab_coef_).view_ro();
342 DoubleArrView bilan = tab_bilan.view_rw();
343 DoubleTabView resu = tab_resu.view_rw();
344 Kokkos::View<double**, DoubleTabView::array_layout> source_view("source", nb_faces-premiere_face_std, ncomp);
345 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), range_1D(premiere_face_std, nb_faces), KOKKOS_LAMBDA(const int num_face)
346 {
347 auto source = Kokkos::subview(source_view, num_face-premiere_face_std, Kokkos::ALL());
348 evaluateur_source_face.calculer_terme_source_standard_view(num_face, source);
349 for (int k = 0; k < ncomp; k++)
350 {
351 resu(num_face, k) += source(k);
352 double contribution = (faces_doubles(num_face) == 1) ? 0.5 : 1;
353 Kokkos::atomic_add(&bilan(k), contribution * coef(num_face) * source(k));
354 }
355 });
356 end_gpu_timer(__KERNEL_NAME__);
357 }
358 else
359 {
360 ToDo_Kokkos("critical");
361 Type_Double source(ncomp);
362 for (int num_face = premiere_face_std_; num_face < nb_faces_; num_face++)
363 {
364 evaluateur_source_face_.calculer_terme_source_standard(num_face, source);
365 for (int k = 0; k < ncomp; k++)
366 {
367 tab_resu(num_face, k) += source(k);
368 double contribution = (faces_doubles(num_face) == 1) ? 0.5 : 1;
369 tab_bilan(k) += contribution * tab_coef_(num_face) * source(k);
370 }
371 }
372 }
373 return tab_resu;
374}
375
376#endif /* Iterateur_Source_VEF_Face_included */
virtual DoubleTab & valeurs()=0
classe Champ_Uniforme Represente un champ constant dans l'espace et dans le temps.
classe Champ_base Cette classe est la base de la hierarchie des champs.
Definition Champ_base.h:43
classe Cond_lim Classe generique servant a representer n'importe quelle classe
Definition Cond_lim.h:31
classe Dirichlet Cette classe est la classe de base de la hierarchie des conditions aux limites de ty...
Definition Dirichlet.h:31
DoubleVect & volumes_entrelaces_Cl()
const Cond_lim & les_conditions_limites(int) const
Renvoie la i-ieme condition aux limites.
class Domaine_VEF
Definition Domaine_VEF.h:54
int premiere_face_std() const
Definition Domaine_VEF.h:80
int nb_faces() const
renvoie le nombre global de faces.
Definition Domaine_VF.h:471
void creer_tableau_faces(Array_base &, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT) const
int nb_front_Cl() const
virtual const Milieu_base & milieu() const =0
class Front_VF
Definition Front_VF.h:36
int nb_faces() const
Definition Front_VF.h:53
int nb_faces_tot() const
Definition Front_VF.h:58
int num_face(const int) const
Definition Front_VF.h:68
const Evaluateur_Source_VEF_Face & evaluateur() const
double volumes_entrelaces(int &num_face) const
Evaluateur_Source_VEF_Face & evaluateur() override
int face_voisins(int num_face, int dir) const
int elem_faces(int num_elem, int i) const
const int & faces_doubles(int num_face) const
DoubleTab & ajouter(DoubleTab &) const override
Iterateur_Source_VEF_Face(const Iterateur_Source_VEF_Face< _TYPE_ > &iter)
double volumes_entrelaces_Cl(int &num_face) const
int initialiser(double tps) override
classe Milieu_base Cette classe est la base de la hierarchie des milieux (physiques)
Definition Milieu_base.h:50
virtual const Equation_base & equation(const std::string &nom_inc) const
virtual const Champ_base & masse_volumique() const
Renvoie la masse volumique du milieu.
virtual int duplique() const =0
virtual unsigned taille_memoire() const =0
int numero() const
Renvoie l'indice de l'objet dans Memoire::data.
Definition Objet_U.cpp:268
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
Definition Process.cpp:455
_SIZE_ size_array() const
int nb_dim() const
Definition TRUSTTab.h:199
std::enable_if_t< is_default_exec_space< EXEC_SPACE >, View< _TYPE_, _SHAPE_ > > view_rw()
Definition TRUSTTab.h:291
int line_size() const
Definition TRUSTVect.tpp:67
void resize(_SIZE_, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
Definition TRUSTVect.tpp:91
virtual void echange_espace_virtuel(IsExchangeBlocking exchange_type=IsExchangeBlocking::DefaultBlocking, const std::string kernel_name="noname")