TrioCFD 1.9.9_beta
TrioCFD documentation
Loading...
Searching...
No Matches
Terme_Source_Coriolis_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_Coriolis_VDF_Face.h>
17#include <Domaine_VDF.h>
18#include <Domaine_Cl_VDF.h>
19#include <Neumann_sortie_libre.h>
20#include <Dirichlet.h>
21#include <Dirichlet_homogene.h>
22#include <Symetrie.h>
23#include <Periodique.h>
24#include <Pb_Fluide_base.h>
25#include <Navier_Stokes_std.h>
26#include <Fluide_Dilatable_base.h>
27
28// Added for compatibility with Quasi-Compressible
29Implemente_instanciable(Terme_Source_Coriolis_QC_VDF_Face,"Coriolis_QC_VDF_Face",Terme_Source_Coriolis_VDF_Face);
30//// printOn
31//
33{
34 return s << que_suis_je() ;
35}
36//// readOn
37//
39{
41}
42
43
44
45
46Implemente_instanciable(Terme_Source_Coriolis_VDF_Face,"Coriolis_VDF_Face",Terme_Source_Coriolis_base);
47
48//// printOn
49//
50
52{
53 return s << que_suis_je() ;
54}
55
56
57//// readOn
58//
59
61{
63}
64
66{
67 if (sub_type(Pb_Fluide_base,pb))
68 {
69 const Navier_Stokes_std& eqn_th = ref_cast(Navier_Stokes_std,pb.equation(0));
71 }
72 else
73 {
74 Cerr << "Error for the method Terme_Source_Coriolis_VDF_Face::associer_pb" << finl;
75 Cerr << "The source term "<<que_suis_je()<<" cannot be activated for the problem "<<pb.que_suis_je()<< finl;
76 exit();
77 }
78
79 la_source.resize(0,dimension);
80 le_dom_VDF->domaine().creer_tableau_elements(la_source);
81}
82
83
85 const Domaine_Cl_dis_base& domaine_Cl_dis)
86{
87 le_dom_VDF = ref_cast(Domaine_VDF, domaine_dis);
88 le_dom_Cl_VDF = ref_cast(Domaine_Cl_VDF, domaine_Cl_dis);
89
90}
91
92
93void Terme_Source_Coriolis_VDF_Face::ajouter_blocs(matrices_t matrices, DoubleTab& secmem, const tabs_t& semi_impl) const
94{
95 const Domaine_VDF& domaine_VDF = le_dom_VDF.valeur();
96 const Domaine_Cl_VDF& domaine_Cl_VDF = le_dom_Cl_VDF.valeur();
97 const IntTab& face_voisins = domaine_VDF.face_voisins();
98 const IntVect& orientation = domaine_VDF.orientation();
99 const DoubleVect& porosite_surf = equation().milieu().porosite_face();
100 const DoubleVect& volumes_entrelaces = domaine_VDF.volumes_entrelaces();
101
102
103 int ndeb,nfin,ncomp,num_face,num_elem;
104 double vol;
105
107
108 // Loop over boundary conditions to process boundary faces
109
110 for (int n_bord=0; n_bord<domaine_VDF.nb_front_Cl(); n_bord++)
111 {
112
113 // for each boundary condition, check its type
114 // If Dirichlet or Symmetry face, do nothing
115 // If Neumann face, compute the contribution to the source term
116
117 const Cond_lim& la_cl = domaine_Cl_VDF.les_conditions_limites(n_bord);
118
119 if (sub_type(Neumann_sortie_libre,la_cl.valeur()))
120 {
121
122 // const Neumann_sortie_libre& la_cl_neumann = ref_cast(Neumann_sortie_libre,la_cl.valeur());
123 const Front_VF& le_bord = ref_cast(Front_VF,la_cl->frontiere_dis());
124 ndeb = le_bord.num_premiere_face();
125 nfin = ndeb + le_bord.nb_faces();
126
127 for (num_face=ndeb; num_face<nfin; num_face++)
128 {
129 vol = volumes_entrelaces(num_face)*porosite_surf(num_face);
130 ncomp = orientation(num_face);
131
132 num_elem = face_voisins(num_face,0);
133 if (num_elem == -1)
134 num_elem = face_voisins(num_face,1);
135
136 secmem(num_face)+= la_source(num_elem,ncomp)*vol;
137 }
138 }
139
140 else if (sub_type(Symetrie,la_cl.valeur()))
141 { /* Do nothing */}
142 else if ( (sub_type(Dirichlet,la_cl.valeur()))
143 ||
144 (sub_type(Dirichlet_homogene,la_cl.valeur()))
145 )
146 { /* Do nothing */}
147 else if (sub_type(Periodique,la_cl.valeur()))
148 {
149 const Front_VF& le_bord = ref_cast(Front_VF,la_cl->frontiere_dis());
150 ndeb = le_bord.num_premiere_face();
151 nfin = ndeb + le_bord.nb_faces();
152
153 for (num_face=ndeb; num_face<nfin; num_face++)
154 {
155 vol = volumes_entrelaces(num_face)*porosite_surf(num_face);
156 ncomp = orientation(num_face);
157
158 secmem(num_face)+= 0.5*(la_source(face_voisins(num_face,0),ncomp)
159 +la_source(face_voisins(num_face,1),ncomp))*vol;
160 }
161 }
162 }
163
164 // Loop over internal faces
165
166 ndeb = domaine_VDF.premiere_face_int();
167 for (num_face =domaine_VDF.premiere_face_int(); num_face<domaine_VDF.nb_faces(); num_face++)
168 {
169 vol = volumes_entrelaces(num_face)*porosite_surf(num_face);
170 ncomp = orientation(num_face);
171 secmem(num_face)+= 0.5*(la_source(face_voisins(num_face,0),ncomp)+
172 la_source(face_voisins(num_face,1),ncomp))*vol;
173 }
174}
175
176DoubleTab& Terme_Source_Coriolis_VDF_Face::calculer(DoubleTab& resu) const
177{
178 resu = 0;
179 return ajouter(resu);
180}
181
183{
184 // Compute the Coriolis force per element (staggered mesh!)
185 // Will be projected to faces in ajouter
186 const Domaine_VDF& domaine_VDF = le_dom_VDF.valeur();
187 const DoubleTab& vitesse = eq_hydraulique().inconnue().valeurs();
188 // int nb_faces = domaine_VDF.nb_faces();
189 const int nb_elems = eq_hydraulique().domaine_dis().domaine().nb_elem();
190 const IntTab& elem_faces = domaine_VDF.elem_faces();
191 // const IntTab& face_voisins = domaine_VDF.face_voisins();
192 DoubleVect om = omega();
193
194 int num_elem,i;
195 DoubleVect vit(dimension);
196
197 DoubleTab& la_source_ = ref_cast_non_const(DoubleTab, la_source);
198
199 switch(dimension)
200 {
201 case 2:
202 {
203 for (num_elem=0; num_elem <nb_elems; num_elem++)
204 {
205 for (i=0; i<dimension; i++)
206 vit[i] = 0.5*(vitesse(elem_faces(num_elem,i))+vitesse(elem_faces(num_elem,i+dimension)));
207
208 la_source_(num_elem,0)= 2.*om(0)*vit[1];
209 la_source_(num_elem,1)=-2.*om(0)*vit[0];
210 }
211 break;
212 }
213 case 3:
214 {
215 for (num_elem=0; num_elem <nb_elems; num_elem++)
216 {
217 for (i=0; i<dimension; i++)
218 vit[i] = 0.5*(vitesse(elem_faces(num_elem,i))+vitesse(elem_faces(num_elem,i+dimension)));
219
220 la_source_(num_elem,0)=-2.*(om(1)*vit[2]-om(2)*vit[1]);
221 la_source_(num_elem,1)=-2.*(om(2)*vit[0]-om(0)*vit[2]);
222 la_source_(num_elem,2)=-2.*(om(0)*vit[1]-om(1)*vit[0]);
223 }
224 break;
225 }
226 default:
227 {
228 Cerr << "To use the Coriolis force, the simulation must be 2D or 3D" << finl;
229 exit();
230 }
231 }
232
233 if (eq_hydraulique().milieu().que_suis_je()=="Fluide_Weakly_Compressible")
234 {
235 Cerr << "Terme_Source_Coriolis_VDF_Face is not yet tested for a Weakly Compressible fluid !" << finl;
236 Cerr << "Contact the TRUST support if you want to use this source term." << finl;
238 }
239
240 // In Quasi-Compressible mode, the source term must be
241 // multiplied by the density since the NS equation is written in this form.
242 const Probleme_base& pb = eq_hydraulique().probleme();
243 if(pb.is_dilatable())
244 {
245 const Fluide_Dilatable_base& le_fluide = ref_cast(Fluide_Dilatable_base,eq_hydraulique().milieu());
246 const DoubleTab& tab_rho_elem = le_fluide.masse_volumique().valeurs();
247 double rhoelem;
248 for (num_elem=0; num_elem <nb_elems; num_elem++)
249 {
250 rhoelem=tab_rho_elem[num_elem];
251 for (i=0; i<dimension; i++)
252 la_source_(num_elem,i)*=rhoelem;
253 }
254 }
255
256 la_source_.echange_espace_virtuel();
257}
DoubleTab & valeurs() override
Returns the array of field values at the current time.
virtual DoubleTab & valeurs()=0
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
int_t nb_elem() const
Definition Domaine.h:131
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
int elem_faces(int i, int j) const
Returns the index of the i-th face of element num_elem; the face numbering convention is.
Definition Domaine_VF.h:542
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
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
Probleme_base & probleme()
Returns the problem associated with the equation.
Domaine_dis_base & domaine_dis()
Returns the discretized domain associated with the equation.
Base class for a dilatable fluid, inheriting from Fluide_base.
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
Navier_Stokes_std This class carries the terms of the momentum equation.
const Champ_Inc_base & inconnue() const override
Returns the velocity (unknown field of the equation) (const version).
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
Pb_Fluide_base This class provides a base class for.
class Periodique This class represents a periodic boundary condition.
Definition Periodique.h:31
class Probleme_base It is a Probleme_U that is not a coupling.
bool is_dilatable() const
virtual const Equation_base & equation(int) const =0
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
virtual DoubleTab & ajouter(DoubleTab &) const
Symetrie On symmetry faces, the following properties hold:
Definition Symetrie.h:37
virtual void echange_espace_virtuel(IsExchangeBlocking exchange_type=IsExchangeBlocking::DefaultBlocking, const std::string kernel_name="noname")
class Terme_Source_Coriolis_VDF_Face This class computes the Coriolis force in VDF.
DoubleTab & calculer(DoubleTab &) const override
void associer_domaines(const Domaine_dis_base &, const Domaine_Cl_dis_base &) override
void associer_pb(const Probleme_base &) override
void ajouter_blocs(matrices_t matrices, DoubleTab &secmem, const tabs_t &semi_impl) const override
void associer_eqn(const Navier_Stokes_std &eq_hyd)
const Navier_Stokes_std & eq_hydraulique() const