TrioCFD 1.9.9_beta
TrioCFD documentation
Loading...
Searching...
No Matches
Interpolation_IBM_mean_gradient_proto.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 <Interpolation_IBM_mean_gradient_proto.h>
17#include <TRUSTTrav.h>
18#include <Domaine.h>
19
21 const Champ_Don_base& solid_points,
22 const Champ_Don_base& corresp_elems,
23 bool has_corres)
24{
25 int nb_som = le_dom_.nb_som();
26 int nb_som_tot = le_dom_.nb_som_tot();
27 int nb_elem = le_dom_.nb_elem();
28 int nb_elem_tot = le_dom_.nb_elem_tot();
29 int nb_som_elem = le_dom_.domaine().nb_som_elem();
30 DoubleTab& elems_solid_ref = solid_elems_->valeurs();
31 const IntTab& elems = le_dom_.domaine().les_elems();
32 const DoubleTab& coordsDom = le_dom_.domaine().coord_sommets();
33 const DoubleTab& solidPointsCoords = solid_points.valeurs();
34
35 //Cerr << "nb_som_elem = " << nb_som_elem << finl;
36
37 DoubleTab& is_dirichlet = my_is_dirichlet_->valeurs();
38
39 // Create a nodal indicator identifying whether a node belongs to one or more elements
40 // that are totally fluid (without immersed Dirichlet boundary nodes)
41 DoubleTrav is_elem_fluide(nb_elem_tot);
42 DoubleTrav is_node_voisin_elem_fluide(is_dirichlet);
43 is_node_voisin_elem_fluide = 0.;
44 for (int num_elem_tf = 0; num_elem_tf < nb_elem_tot; num_elem_tf++)
45 {
46 is_elem_fluide(num_elem_tf) = 1.;
47 // Is this correct?
48 for (int j_tf = 0; j_tf < nb_som_elem; j_tf++)
49 {
50 int num_som_tf = elems(num_elem_tf,j_tf);
51 if ((num_som_tf < nb_som) && (is_dirichlet(num_som_tf) > 0.0)) is_elem_fluide(num_elem_tf) = 0.;
52 }
53 if (is_elem_fluide(num_elem_tf) == 1.)
54 {
55 for (int j_tf = 0; j_tf < nb_som_elem; j_tf++)
56 {
57 int num_som_tf = elems(num_elem_tf,j_tf);
58 is_node_voisin_elem_fluide(num_som_tf) = 1.;
59 }
60 }
61 }
62
63 // Element numbering may have changed between the pre_pro step and
64 // the calculation step (case of Salome pre_pro)
65 // Use a label field for solid_elems_ (e.g. the Salome element number)
66 // and an element field using these labels
67 if (has_corres)
68 {
69 const DoubleTab& corresp_elemsref = corresp_elems.valeurs();
70 int nb_tag_max = -1;
71 for (int i = 0 ; i < nb_elem_tot ; i++)
72 {
73 int int_cor_elem = (int)lrint(corresp_elemsref(i));
74 if (int_cor_elem > nb_tag_max) nb_tag_max = int_cor_elem;
75 }
76 int dimtag = nb_tag_max+1;
77 DoubleTrav elems_solid_trust(dimtag);
78 elems_solid_trust = -0.1*DMAXFLOAT;
79 for (int i = 0 ; i < nb_elem_tot ; i++)
80 {
81 int indextag = (int)lrint(corresp_elemsref(i)) ;
82 if (indextag < dimtag && indextag >= 0)
83 {
84 elems_solid_trust(indextag) = i*1.0;
85 }
86 else
87 {
88 Cerr<<"error in computeSommetsVoisins : elem corresp_elemsref(elem) = "<<i<<" "<<corresp_elemsref(i)<<" ; indextag = "<<indextag<<" < 0 or >= "<<dimtag<<finl;
90 }
91 }
92 for (int i = 0 ; i < nb_som_tot ; i++)
93 {
94 if (elems_solid_ref(i) >= 0.0)
95 {
96 int indexr = (int)lrint(elems_solid_ref(i));
97 if (indexr < dimtag && indexr >= 0)
98 {
99 if (elems_solid_trust(indexr) >= 0.) elems_solid_ref(i) = elems_solid_trust(indexr);
100 }
101 }
102 }
103 }
104
105 sommets_voisins_ = IntLists(nb_som);
106 int nb_nodes_in_list = 0;
107
108 for (int num_elem = 0; num_elem < nb_elem_tot; num_elem++)
109 {
110 for (int j = 0; j < nb_som_elem; j++)
111 {
112 int num_som = elems(num_elem,j);
113 double x1 = coordsDom(num_som,0);
114 double x2 = coordsDom(num_som,1);
115 double x3 = coordsDom(num_som,2);
116 double xp1 = solidPointsCoords(num_som,0);
117 double xp2 = solidPointsCoords(num_som,1);
118 double xp3 = solidPointsCoords(num_som,2);
119
120 if ((num_som < nb_som) && (is_dirichlet(num_som) > 0.0))
121 {
122 for (int k = 0; k < nb_som_elem; k++)
123 {
124 if (k != j)
125 {
126 int num_som_2 = elems(num_elem,k);
127 double xf1 = coordsDom(num_som_2,0);
128 double xf2 = coordsDom(num_som_2,1);
129 double xf3 = coordsDom(num_som_2,2);
130 double xpf1 = solidPointsCoords(num_som_2,0);
131 double xpf2 = solidPointsCoords(num_som_2,1);
132 double xpf3 = solidPointsCoords(num_som_2,2);
133
134 double d = (x1-xp1)*(xf1-xpf1)+(x2-xp2)*(xf2-xpf2)+(x3-xp3)*(xf3-xpf3);
135 double d1 = (xf1-xpf1)*(xf1-xpf1)+(xf2-xpf2)*(xf2-xpf2)+(xf3-xpf3)*(xf3-xpf3);
136 double d2 = (x1-xp1)*(x1-xp1)+(x2-xp2)*(x2-xp2)+(x3-xp3)*(x3-xp3);
137
138 // Requirements:
139 // *) the neighboring point must be of fluid type (not Dirichlet)
140 // *) the projection of the neighboring fluid point must be on the same side of the
141 // immersed boundary as the considered Dirichlet point
142 // *) the fluid point projection must be in an element traversed by the
143 // boundary (we use the immersed boundary velocity at this point)
144 // *) the projection of the neighboring fluid point must be at a squared distance d1 from
145 // the immersed boundary greater than d2 of the considered Dirichlet point
146 // (we interpolate; we do not extrapolate; distance criterion:
147 // d1 = 2.0^2 times d2)
148 // *) the neighboring fluid point must belong to at least one fully fluid element
149 if (is_dirichlet(num_som_2) < 0.0 && d > 0.0 && (3.0*d2) < d1 && is_node_voisin_elem_fluide(num_som_2) == 1.0)
150 {
151 // Element containing the fluid point projection
152 int elems_xpf = (int)lrint(elems_solid_ref(num_som_2));
153 bool flag_xpf = true;
154 //bool flag_prt_nodes = false;
155 int elem_found = le_dom_.domaine().chercher_elements(xpf1,xpf2,xpf3);
156 if (elems_xpf >= 0)
157 {
158 // test de verification prepro Salome/Trust :
159 if ((elems_xpf != elem_found) && (elem_found != -1))
160 {
161 Cerr << __FILE__ << (int)__LINE__ << "Interpolation_IBM_mean_gradient_proto::computeSommetsVoisins : WARNING : elem solid prepro " << elems_xpf << " != elem solid Trust " << elem_found << finl;
162 flag_xpf = true;
163 //flag_prt_nodes = true;
164 }
165 }
166 else
167 {
168 if (elems_xpf == -1.e+50)
169 {
170 flag_xpf = false;
171 }
172 else if (elem_found != -1)
173 {
174 Cerr<<"node_fluide = "<<num_som_2<<" we use chercher_elements(xpf,ypf,zpf) = "<<elem_found<<" to replace values from SALOME = "<<elems_xpf<<finl;
175 Cerr<<"coords_point(node_fluide) : xf yf zf = "<<xf1<<" "<<xf2<<" "<<xf3<<finl;
176 Cerr<<"solid_points(node_fluide) : xpf ypf zpf = "<<xpf1<<" "<<xpf2<<" "<<xpf3<<finl;
177 elems_xpf = elem_found ;
178 }
179 }
180 if (!flag_xpf)
181 {
182 // Error handling
183 Cerr << __FILE__ << (int)__LINE__ << "Interpolation_IBM_mean_gradient_proto::computeSommetsVoisins : ERROR : joint width too low?" << finl;
184 Cerr<<"Nb elem; Nb elem tot = "<<nb_elem<<" "<<nb_elem_tot<<finl;
185 Cerr<<"Nb som; Nb som tot = "<<nb_som<<" "<<nb_som_tot<<finl;
186 Cerr<<"element; node_Dirichlet = "<<num_elem<<" "<<num_som<<finl;
187 Cerr<<"coords_point(node_Dirichlet) : x y z = "<<x1<<" "<<x2<<" "<<x3<<finl;
188 Cerr<<"solid_points(node_Dirichlet) : xp yp zp = "<<xp1<<" "<<xp2<<" "<<xp3<<finl;
189 Cerr<<"node_fluide elems_solid_ref(node_fluide) elems_xpf = "<<num_som_2<<" "<<elems_solid_ref(num_som_2)<<" "<<elems_xpf<<finl;
190 Cerr<<"coords_point(node_fluide) : xf yf zf = "<<xf1<<" "<<xf2<<" "<<xf3<<finl;
191 Cerr<<"solid_points(node_fluide) : xpf ypf zpf = "<<xpf1<<" "<<xpf2<<" "<<xpf3<<finl;
192 Cerr<<"chercher_elements(xpf,ypf,zpf) = "<<elem_found<<finl;
193 /*if (flag_prt_nodes)
194 {
195 double x1kf = 0.0;
196 double x2kf = 0.0;
197 double x3kf = 0.0;
198 double x1kf2 = 0.0;
199 double x2kf2 = 0.0;
200 double x3kf2 = 0.0;
201 for (int kf = 0; kf < nb_som_elem; kf++)
202 {
203 int num_som_kf = elems(elems_xpf,kf);
204 int num_som_kf2 = elems(elem_found,kf);
205 x1kf += coordsDom(num_som_kf,0)/nb_som_elem;
206 x2kf += coordsDom(num_som_kf,1)/nb_som_elem;
207 x3kf += coordsDom(num_som_kf,2)/nb_som_elem;
208 x1kf2 += coordsDom(num_som_kf2,0)/nb_som_elem;
209 x2kf2 += coordsDom(num_som_kf2,1)/nb_som_elem;
210 x3kf2 += coordsDom(num_som_kf2,2)/nb_som_elem;
211 Cerr<<"x elems_solid_ref = "<<coordsDom(num_som_kf,0)<<" "<<coordsDom(num_som_kf,1)<<" "<<coordsDom(num_som_kf,2)<<finl;
212 Cerr<<"x chercher_elements = "<<coordsDom(num_som_kf2,0)<<" "<<coordsDom(num_som_kf2,1)<<" "<<coordsDom(num_som_kf2,2)<<finl;
213 }
214 Cerr<<"bary elems_solid_ref = "<<x1kf<<" "<<x2kf<<" "<<x3kf<<finl;
215 Cerr<<"bary chercher_elements = "<<x1kf2<<" "<<x2kf2<<" "<<x3kf2<<finl;
216 }*/
218 }
219 // Require that the fluid point projection be in an element
220 // traversed by the boundary or bordered by elements traversed by the boundary
221 if (elems_xpf >= 0)
222 {
223 for (int kxpf = 0; kxpf < nb_som_elem; kxpf++)
224 {
225 int num_som_2xpf = elems(elems_xpf,kxpf);
226 if (is_dirichlet(num_som_2xpf) < 0.0) flag_xpf = false;
227 }
228 if (flag_xpf)
229 {
230 sommets_voisins_[num_som].add_if_not(num_som_2);
231 nb_nodes_in_list += 1;
232 }
233 }
234 }
235 }
236 }
237 }
238 }
239 }
240 Cerr << __FILE__ << (int)__LINE__ << "Interpolation_IBM_mean_gradient_proto::computeSommetsVoisins : nb nodes for interpolation = " <<nb_nodes_in_list<<finl;
241}
class Champ_Don_base base class of Given Fields (not calculated)
DoubleTab & valeurs() override
Overrides Champ_base::valeurs() Returns the array of values.
int nb_som_elem() const
Returns the number of vertices of the geometric elements that make up the domain.
Definition Domaine.h:474
SmallArrOfTID_t & chercher_elements(const DoubleTab &pos, SmallArrOfTID_t &elem, int reel=0) const
Searches for the elements containing the points whose coordinates are specified.
Definition Domaine.cpp:404
IntTab_t & les_elems()
Definition Domaine.h:129
const DoubleTab_t & coord_sommets() const
Definition Domaine.h:112
class Domaine_dis_base This class is the base of the hierarchy of discretized domains.
int nb_elem_tot() const
const Domaine & domaine() const
int nb_som_tot() const
void computeSommetsVoisins(Domaine_dis_base &le_dom_, const Champ_Don_base &solid_points, const Champ_Don_base &corresp_elems, bool has_corres)
static void exit(int exit_code=-1)
Exit routine for TRUST within a Kokkos region.
Definition Process.cpp:466