TrioCFD 1.9.9_beta
TrioCFD documentation
Loading...
Searching...
No Matches
Op_Curl_VEFP1B.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 <Op_Curl_VEFP1B.h>
17#include <Domaine_Cl_VEF.h>
18#include <Domaine_VEF.h>
19
20Implemente_instanciable(Op_Curl_VEFP1B, "Op_Curl_VEFPreP1B_P1NC", Operateur_base);
21
22Sortie& Op_Curl_VEFP1B::printOn(Sortie& s) const { return s << que_suis_je(); }
23Entree& Op_Curl_VEFP1B::readOn(Entree& is) { return is; }
24
25inline void add_curl_som(int nps, int sommet, int face, double flux, DoubleTab& curl, const Domaine& domaine)
26{
27 curl(nps + domaine.get_renum_som_perio(sommet)) += flux;
28}
29
30inline void traiter_flux(DoubleTab& curl, double flux, int element1, int element2, int npe)
31{
32 curl(npe + element1) += flux;
33 curl(npe + element2) -= flux;
34}
35
36void Op_Curl_VEFP1B::associer(const Domaine_dis_base& domaine_dis, const Domaine_Cl_dis_base& domaine_Cl_dis, const Champ_Inc_base& inco)
37{
38 le_dom_vef = ref_cast(Domaine_VEF, domaine_dis);
39 la_zcl_vef = ref_cast(Domaine_Cl_VEF, domaine_Cl_dis);
41}
42
43DoubleTab& Op_Curl_VEFP1B::calculer(const DoubleTab& vitesse, DoubleTab& curl) const
44{
45 curl = 0;
46 return ajouter(vitesse, curl);
47}
48
49DoubleTab& Op_Curl_VEFP1B::ajouter(const DoubleTab& vitesse, DoubleTab& curl) const
50{
51 const Domaine_VEF& domaine_VEF = le_dom_vef.valeur();
52 const Domaine& domaine = domaine_VEF.domaine();
53 //int prems=domaine_VEF.premiere_face_int();
54 if (dimension != 2)
55 {
56 Cerr << "Only 2D is supported at the moment. " << finl;
58 }
59
60 int face0 = 0, face1 = 0, face2 = 0;
61 int numero_triangle = 0;
62 int face_globale = 0, face_opp = 0;
63
64 DoubleTab vecteur_normal0(dimension);
65 DoubleTab vecteur_normal1(dimension);
66 DoubleTab vecteur_normal2(dimension);
67
68 // Process internal faces i.e. without boundary conditions
69 // NOTE: the vorticity basis consists of: the set of indicator
70 // functions of elements + the set of hat functions of P1
71 // minus the last of these shape functions
72
73 //P0 part of the vorticity
74 for (int numero_elem = 0; numero_elem < domaine.nb_elem(); numero_elem++)
75 {
76
77 //REM: this part can be generalized to 3D
78 //by using a loop with domaine.nb_faces_element()
79
80 //First we need the indices of the 3 faces
81 //belonging to element K
82 face0 = domaine_VEF.elem_faces(numero_elem, 0);
83 face1 = domaine_VEF.elem_faces(numero_elem, 1);
84 face2 = domaine_VEF.elem_faces(numero_elem, 2);
85
86 //Then we need the tangent vectors of
87 //these three faces.
88 vecteur_normal0 = vecteur_normal(face0, numero_elem);
89 vecteur_normal1 = vecteur_normal(face1, numero_elem);
90 vecteur_normal2 = vecteur_normal(face2, numero_elem);
91
92 int modulo;
93 for (int composante = 0; composante < dimension; composante++)
94 {
95 //The P0 part has been tested with functions (1,0);
96 //(0,1);(x,0) and (0,x).
97 //All results are correct
98
99 modulo = (composante + 1) % 2;
100 curl(numero_elem) += pow(-1., modulo)
101 * (vitesse(face0, composante) * vecteur_normal0(modulo) + vitesse(face1, composante) * vecteur_normal1(modulo) + vitesse(face2, composante) * vecteur_normal2(modulo));
102
103 }
104
105// Cerr << "Element curl(" << numero_elem << ") " << curl(numero_elem) << finl;
106 }
107
108 //P1 part of the vorticity
109
110 for (int numero_som = 0; numero_som < domaine.nb_som() - 1; numero_som++)
111 {
112 for (int num_loc_elem = 0; num_loc_elem < elem_som_size(numero_som); num_loc_elem++)
113
114 {
115 // for num_loc_elem
116
117 //Retrieve the global index of the triangle
118 numero_triangle = elements_pour_sommet(numero_som, num_loc_elem);
119
120 //Retrieve the global index of the face opposite to "numero_som"
121 //in triangle "numero_triangle"
122 face_opp = domaine_VEF.numero_sommet_local(numero_som, numero_triangle);
123 face_opp = domaine_VEF.elem_faces(numero_triangle, face_opp);
124
125 //Retrieve the normal vector of this opposite face.
126 vecteur_normal1 = vecteur_normal(face_opp, numero_triangle);
127
128 for (int num_loc_face = 0; num_loc_face < domaine.nb_faces_elem(); num_loc_face++)
129
130 {
131 // for num_loc_face
132
133 //Retrieve the global index of face "num_loc_face"
134 face_globale = domaine_VEF.elem_faces(numero_triangle, num_loc_face);
135
136 // //If "face_globale" is an internal edge, perform the correct
137 // //traitement
138 // if (face_globale >= domaine_VEF.premiere_face_int() )
139 {
140 //Compute the normal vectors associated with these faces.
141 vecteur_normal0 = vecteur_normal(face_globale, numero_triangle);
142
143 //Finally compute the curl contribution of each of
144 //these faces for each of the 2 triangles.
145 int modulo;
146 for (int composante = 0; composante < dimension; composante++)
147 {
148 //P1 part tested with functions (1,0);(0,1)
149 //(x,0) and (0,x).
150 //All tests are correct
151
152 modulo = (composante + 1) % 2;
153
154 //Partie (lambda_s,curl u)
155 curl(domaine.nb_elem() + numero_som) += -pow(-1., modulo) * 1. / (dimension + 1) * vitesse(face_globale, composante) * vecteur_normal0(modulo);
156
157 //Partie (rot lambda_s, u)
158 curl(domaine.nb_elem() + numero_som) += pow(-1., modulo) * 1. / (dimension * (dimension + 1)) * vitesse(face_globale, composante) * vecteur_normal1(modulo);
159 }
160
161 } // end if
162
163 } // end for num_loc_face
164
165 /* For now, we only work with H10 velocities */
166 /* This is the subject of the thesis */
167 /* Consequently, no need to treat boundary faces */
168
169 } // end for num_loc_elem
170
171 Cerr << "Vertex curl(" << numero_som << ") " << curl(domaine.nb_elem() + numero_som) << finl;
172
173 } // end for over vertices
174
175 Cerr << "exiting OpCurl" << finl;
176
177 return curl;
178}
179
180DoubleTab Op_Curl_VEFP1B::vecteur_normal(const int face, const int elem) const
181{
182 assert(dimension == 2);
183
184 const Domaine_VEF& domaine_VEF = le_dom_vef.valeur();
185 DoubleTab le_vecteur_normal(dimension);
186
187 for (int composante = 0; composante < dimension; composante++)
188
189 le_vecteur_normal(composante) = domaine_VEF.face_normales(face, composante) * domaine_VEF.oriente_normale(face, elem);
190
191 return le_vecteur_normal;
192}
193
194// Array that stores at position "i" all mesh elements containing the vertex with global index "i"
196{
197 const Domaine& domaine = le_dom_vef->domaine();
198 int numero_global_som;
199 elements_pour_sommet_.dimensionner(domaine.nb_som());
200
201 for (int numero_elem = 0; numero_elem < domaine.nb_elem(); numero_elem++)
202 for (int numero_som_loc = 0; numero_som_loc < domaine.nb_som_elem(); numero_som_loc++)
203 {
204 numero_global_som = domaine.sommet_elem(numero_elem, numero_som_loc);
205 elements_pour_sommet_[numero_global_som].add_if_not(numero_elem);
206 }
207
208 return 1;
209}
210
211// Function returning the global index of the element containing "sommet" located at position "indice" in the "elements_pour_sommet_" list
212int Op_Curl_VEFP1B::elements_pour_sommet(const int sommet, const int indice) const
213{
214 return elements_pour_sommet_[sommet][indice];
215}
216
217// Function returning the size of the list at position "sommet" in the "elements_pour_sommet_" array
218int Op_Curl_VEFP1B::elem_som_size(const int sommet) const
219{
220 return elements_pour_sommet_[sommet].size();
221}
Class Champ_Inc_base.
class Domaine_Cl_dis_base Domaine_Cl_dis_base objects represent discretized boundary conditions
class Domaine_VEF
Definition Domaine_VEF.h:53
virtual double face_normales(int face, int comp) const
Definition Domaine_VF.h:47
int numero_sommet_local(int som, int elem) const
Definition Domaine_VF.h:395
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 oriente_normale(int f, int e) const
Definition Domaine_VF.h:194
class Domaine_dis_base This class is the base of the hierarchy of discretized domains.
const Domaine & domaine() const
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
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
DoubleTab vecteur_normal(const int face, const int elem) const
DoubleTab & ajouter(const DoubleTab &, DoubleTab &) const override
void associer(const Domaine_dis_base &, const Domaine_Cl_dis_base &, const Champ_Inc_base &) override
int elem_som_size(const int sommet) const
IntLists elements_pour_sommet_
DoubleTab & calculer(const DoubleTab &, DoubleTab &) const override
class Operateur_base This class is the base of the hierarchy of objects representing an
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