TrioCFD 1.9.8
TrioCFD documentation
Loading...
Searching...
No Matches
Probleme_FTD_IJK_tools.cpp
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#include <Probleme_FTD_IJK_tools.h>
17#include <Probleme_FTD_IJK_base.h>
18
19void copy_field_values(IJK_Field_double& field, const IJK_Field_double& field_to_copy)
20{
21 const int ni = field.ni(), nj = field.nj(), nk = field.nk();
22
23 const int ni_to_copy = field_to_copy.ni(), nj_to_copy = field_to_copy.nj(), nk_to_copy = field_to_copy.nk();
24
25 const bool bool_dim = (ni == ni_to_copy && nj == nj_to_copy && nk == nk_to_copy);
26
27 if (!bool_dim)
29
30 for (int k = 0; k < nk; k++)
31 for (int j = 0; j < nj; j++)
32 for (int i = 0; i < ni; i++)
33 field(i,j,k) = field_to_copy(i,j,k);
34
35 field.echange_espace_virtuel(field.ghost());
36}
37
38// PRODUITS DE CHAMPS
39IJK_Field_double scalar_product(const Probleme_FTD_IJK_base& pb, const IJK_Field_vector3_double& V1, const IJK_Field_vector3_double& V2)
40{
41 /*
42 * * ATTENTION : valide pour un maillage cartesien, de maille cubiques uniquement !
43 */
44 IJK_Field_double resu;
46
47 const int nk = V1[0].nk();
48 if (nk != V2[0].nk())
49 Cerr << "scalar product of fields with different dimensions (nk)" << finl;
50
51 const int nj = V1[0].nj();
52 if (nj != V2[0].nj())
53 Cerr << "scalar product of fields with different dimensions (nj)" << finl;
54
55 const int ni = V1[0].ni();
56 if (ni != V2[0].ni())
57 Cerr << "scalar product of fields with different dimensions (ni)" << finl;
58
59 for (int k = 0; k < nk; ++k)
60 for (int j = 0; j < nj; ++j)
61 for (int i = 0; i < ni; ++i)
62 {
63 resu(i, j, k) = 0.25 * ((V1[0](i, j, k) + V1[0](i + 1, j, k)) * (V2[0](i, j, k) + V2[0](i + 1, j, k)) +
64 (V1[1](i, j, k) + V1[1](i, j + 1, k)) * (V2[1](i, j, k) + V2[1](i, j + 1, k))
65 + (V1[2](i, j, k) + V1[2](i, j, k + 1)) * (V2[2](i, j, k) + V2[2](i, j, k + 1)));
66 }
67 // Communication avec tous les process ?
68 return resu;
69}
70
71IJK_Field_vector3_double scalar_times_vector(const Probleme_FTD_IJK_base& pb, const IJK_Field_double& Sca, const IJK_Field_vector3_double& Vec)
72{
73 /*
74 * Produit d'un champ scalaire (Sca) par un champ de vecteur (Vec).
75 * Le champ scalaire est aux centre des elements, le champ de vecteur est aux faces
76 * Le resultat reste localise au meme endroit que le champ de vecteur passe en entree.
77 * ATTENTION : valide pour un maillage cartesien, de maille cubiques uniquement !
78 */
79
80 IJK_Field_vector3_double resu;
81 allocate_velocity(resu, pb.domaine_ijk(), 3); // j'ai besoin de mettre des cellules ghost ? non, je ne pense pas
82
83 const int nk = Vec[0].nk();
84 if (nk != Sca.nk())
85 Cerr << "scalar fields has different dimension from vector field (nk)" << finl;
86
87 const int nj = Vec[0].nj();
88 if (nj != Sca.nj())
89 Cerr << "scalar fields has different dimension from vector field (nj)" << finl;
90
91 const int ni = Vec[0].ni();
92 if (ni != Sca.ni())
93 Cerr << "scalar fields has different dimension from vector field (ni)" << finl;
94
95 for (int k = 0; k < nk; ++k)
96 for (int j = 0; j < nj; ++j)
97 for (int i = 0; i < ni; ++i)
98 {
99 resu[0](i, j, k) = 0.5 * (Sca(i - 1, j, k) + Sca(i, j, k)) * Vec[0](i, j, k);
100 resu[1](i, j, k) = 0.5 * (Sca(i, j - 1, k) + Sca(i, j, k)) * Vec[1](i, j, k);
101 resu[2](i, j, k) = 0.5 * (Sca(i, j, k - 1) + Sca(i, j, k)) * Vec[2](i, j, k);
102 }
103 // Communication avec tous les process ?
104 return resu;
105}
106
107IJK_Field_double scalar_fields_product(const Probleme_FTD_IJK_base& pb, const IJK_Field_double& S1, const IJK_Field_double& S2, int dir)
108{
109 /*
110 * Produit d'un champ scalaire aux centres (S1) par une des composantes d'un champ de vecteur (S2).
111 * Le resultat est localise au meme endroit que le champ de vecteur dont est issu S2.
112 * ATTENTION : valide pour un maillage cartesien, de maille cubiques uniquement !
113 */
114 IJK_Field_double resu;
116
117 const int nk = S1.nk();
118 if (nk != S2.nk())
119 Cerr << "scalar fields have different dimensions for the product (nk)" << finl;
120
121 const int nj = S1.nj();
122 if (nj != S2.nj())
123 Cerr << "scalar fields have different dimensions for the product (nj)" << finl;
124
125 const int ni = S1.ni();
126 if (ni != S2.ni())
127 Cerr << "scalar fields have different dimensions for the product (ni)" << finl;
128
129 for (int k = 0; k < nk; ++k)
130 for (int j = 0; j < nj; ++j)
131 for (int i = 0; i < ni; ++i)
132 {
133 if (dir == 0)
134 resu(i, j, k) = 0.5 * (S1(i - 1, j, k) + S1(i, j, k)) * S2(i, j, k);
135
136 if (dir == 1)
137 resu(i, j, k) = 0.5 * (S1(i, j - 1, k) + S1(i, j, k)) * S2(i, j, k);
138
139 if (dir == 2)
140 resu(i, j, k) = 0.5 * (S1(i, j, k - 1) + S1(i, j, k)) * S2(i, j, k);
141 }
142 // Communication avec tous les process ?
143 return resu;
144}
145
146void ecrire_donnees(const Probleme_FTD_IJK_base& pb, const IJK_Field_vector3_double& f3compo, SFichier& le_fichier, const int compo, bool binary)
147{
148 const IJK_Field_double& f = f3compo[compo];
149
150 ArrOfDouble coord_i, coord_j, coord_k;
151 build_local_coords(f, coord_i, coord_j, coord_k);
152
153 const int ni = f.ni();
154 const int nj = f.nj();
155 const int nk = f.nk();
156
157 int cnt = 0;
158 for (int k = 0; k < nk; k++)
159 for (int j = 0; j < nj; j++)
160 for (int i = 0; i < ni; i++)
161 {
162 // le_fichier << coord_i[i] << Separateur::SPACE << coord_j[j] << Separateur::SPACE << coord_k[k] << f(i,j,k) << Separateur::SPACE;
163 le_fichier << coord_i[i] << coord_j[j] << coord_k[k] << f(i,j,k);
164 cnt++;
165 }
166
167 const Domaine_IJK& geom = pb.get_domaine();
168 const int idx_min = f.get_domaine().get_offset_local(compo);
169 if ((idx_min == 0) && (geom.get_periodic_flag(compo)))
170 {
171 double l = geom.get_domain_length(compo) + geom.get_origin(compo);
172 if (compo == 0)
173 {
174 Cerr << "compo 0: " << l << " " << coord_i[0] << finl;
175 for (int k = 0; k < nk; k++)
176 for (int j = 0; j < nj; j++)
177 {
178 le_fichier << l << coord_j[j] << coord_k[k] << f(0,j,k);
179 cnt++;
180 }
181 }
182 if (compo == 1)
183 {
184 Cerr << "compo 1: " << l << " " << coord_j[0] << finl;
185 for (int k = 0; k < nk; k++)
186 for (int i = 0; i < ni; i++)
187 {
188 le_fichier << coord_i[i] << l << coord_k[k] << f(i,0,k);
189 cnt++;
190 }
191 }
192 if (compo == 2)
193 {
194 for (int j = 0; j < nj; j++)
195 for (int i = 0; i < ni; i++)
196 {
197 le_fichier << coord_i[i] << coord_j[j] << l << f(i,j,0);
198 cnt++;
199 }
200 }
201 }
202 le_fichier.flush();
203 Cerr << "Written " << cnt << " items with (ni, nj, nk)." << ni << " " << nj << " " << nk << finl;
204}
205
206// Initialize field with specified string expression (must be understood by Parser class)
207void dumpxyz_vector(const Probleme_FTD_IJK_base& pb, const IJK_Field_vector3_double& f3compo, const char * filename, bool binary)
208{
209 int np = Process::nproc();
210 int rank = Process::me();
211
213 int token = 1;
215 {
216 // Write and send token to rank+1
217 SFichier le_fichier;
218 le_fichier.set_bin(1);
219 le_fichier.ouvrir(filename);
220 for (unsigned compo=0; compo<3; compo++)
221 ecrire_donnees(pb, f3compo, le_fichier, compo, binary);
222 if (np > 1)
223 envoyer(token, rank, rank+1, 2345);
224 }
225 else
226 {
227 int rcv;
228 recevoir(rcv, rank-1, rank, 2345);
229
230 SFichier le_fichier;
231 le_fichier.set_bin(1);
232 le_fichier.ouvrir(filename, ios::app); // in append mode!
233 for (unsigned compo=0; compo<3; compo++)
234 ecrire_donnees(pb, f3compo, le_fichier, compo, binary);
235
236 if (rank != np-1)
237 envoyer(token, rank, rank+1, 2345);
238 }
239
241 Cerr << "Fin de l ecriture dans le fichier XYZ: " << filename << finl;
242}
This class encapsulates all the information related to the eulerian mesh for TrioIJK.
Definition Domaine_IJK.h:47
int get_offset_local(int direction) const
Returns the local offset in requested direction.
bool get_periodic_flag(int direction) const
Method returns true if periodic in this direction.
double get_domain_length(int direction) const
Returns the length of the entire domain in requested direction.
double get_origin(int direction) const
Returns the coordinate of the first node (global) of the mesh in the requested direction.
void allocate(const Domaine_IJK &d, Domaine_IJK::Localisation l, int ghost_size, int additional_k_layers=0, int nb_compo=1, const Nom &name=Nom(), bool external_storage=false, int monofluide=0, double rov=0., double rol=0., int use_inv_rho_in_pressure_solver=0)
void echange_espace_virtuel(int ghost)
Exchange data over "ghost" number of cells.
const Domaine_IJK & get_domaine() const
const Domaine_IJK & domaine_ijk() const
const Domaine_IJK & get_domaine() const
static int nproc()
renvoie le nombre de processeurs dans le groupe courant Voir Comm_Group::nproc() et PE_Groups::curren...
Definition Process.cpp:104
static void barrier()
Synchronise tous les processeurs du groupe courant (attend que tous les processeurs soient arrives a ...
Definition Process.cpp:136
static int me()
renvoie mon rang dans le groupe de communication courant.
Definition Process.cpp:125
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
Definition Process.cpp:455
static int je_suis_maitre()
renvoie 1 si on est sur le processeur maitre du groupe courant (c'est a dire me() == 0),...
Definition Process.cpp:86
Cette classe est a la classe C++ ofstream ce que la classe Sortie est a la classe C++ ostream Elle re...
Definition SFichier.h:27
virtual int ouvrir(const char *name, IOS_OPEN_MODE mode=ios::out)
Sortie & flush() override
Force l'ecriture sur disque des donnees dans le tampon Utilise l'implementation de la classe ofstream...
void set_bin(bool bin) override
Change le mode d'ecriture du fichier.
Definition Sortie.cpp:255