TrioCFD 1.9.9_beta
TrioCFD documentation
Loading...
Searching...
No Matches
Partitionneur_Partition.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#include <Cast.h>
16#include <Interprete.h>
17#include <Partitionneur_Partition.h>
18#include <Domaine.h>
19#include <Reordonner_faces_periodiques.h>
20#include <EFichier.h>
21#include <Param.h>
22
23Implemente_instanciable(Partitionneur_Partition,"Partitionneur_Partition",Partitionneur_base);
24// XD partitionneur_partition partitionneur_deriv PARTITION INHERITS_BRACE This algorithm re-use the partition of the
25// XD_CONT domain named DOMAINE_NAME. It is useful to partition for example a post processing domain. The partition
26// XD_CONT should match with the calculation domain.
27// XD attr domaine ref_domaine domaine REQ domain name
28
29
30
32{
33 Cerr << "Partitionneur_Partition::printOn invalid\n" << finl;
34 exit();
35 return os;
36}
37
38/*! @brief The syntax is { Domaine NOM_DOM }
39 *
40 */
42{
43 if (!ref_domaine_interpol_)
44 {
45 Cerr << " Error: the domain has not been associated" << finl;
47 }
48 param.ajouter("domaine",&dom_calcul_,Param::REQUIRED);
49}
50
52{
53 Cerr << que_suis_je() << "::validate_params" << finl;
54 Cerr << " Reference domain : " << dom_calcul_ << finl;
55
56 if (Interprete::objet_existant(dom_calcul_) == 0)
57 {
58 Cerr << "ERROR: provided name '" << dom_calcul_ <<"' does not name an existing object."<< finl;
60 }
61
62 if (not sub_type(Domaine, Interprete::objet(dom_calcul_)))
63 {
64 Cerr << "ERROR: provided name '" << dom_calcul_ <<"' is not a domain."<< finl;
66 }
67}
68
69/*! @brief First initialisation step of the partitioner: associate a domain.
70 *
71 */
73{
74 ref_domaine_interpol_ = domaine;
75}
76
77/*! @brief Second initialisation step: define the number of slices.
78 *
79 * (readOn can be used instead).
80 *
81 * WARNING: the message above is copy-pasted from Partitionneur_Tranche and is incorrect;
82 * please correct this if you know better.
83 */
85{
86
87 assert(ref_domaine_interpol_);
88}
89
90void Partitionneur_Partition::construire_partition(IntVect& elem_part, int& nb_parts_tot) const
91{
92
93
94 OBS_PTR(Domaine) ref_domaine_calcul_ = ref_cast(Domaine, Interprete::objet(dom_calcul_));
95 assert(ref_domaine_interpol_);
96 assert(ref_domaine_calcul_);
97
98 // Domaine dom_interpol
99 const Domaine& dom_interpol = ref_domaine_interpol_.valeur();
100 if(dom_interpol.nb_som()==0)
101 {
102 Cerr << "The domain \"" << dom_interpol.le_nom() << "\" to be split is empty !" << finl;
103 exit();
104 }
105 const int nb_elem_interpol = dom_interpol.nb_elem_tot();
106 const int dim_interpol = dom_interpol.dimension;
107
108 // Domaine dom_calcul
109 const Domaine dom_calcul = ref_domaine_calcul_.valeur();
110 if(dom_calcul.nb_som()==0)
111 {
112 Cerr << "The reference domain \"" << dom_calcul.le_nom() << "\" is empty !" << finl;
113 exit();
114 }
115 const int nb_elem_calcul = dom_calcul.nb_elem();
116 const int dim_calcul = dom_calcul.dimension;
117
118 IntVect elem_part_calcul;
119 int nb_parts_tot_calcul;
120 EFichier file;
121 Nom nom_fichier;
122 nom_fichier=nom_du_cas()+"_"+dom_calcul.le_nom()+".dec";
123 file.ouvrir(nom_fichier);
124 if (!file.good())
125 {
126 Cerr << "Error in Partitionneur_Partition::construire_partition\n";
127 Cerr << " Failed to open file " << nom_fichier << finl;
128 Cerr << "To use the partitioner Partition, you must check" << finl;
129 Cerr << "that you use the option:" << finl;
130 Cerr << "Ecrire_decoupage " << nom_fichier << finl;
131 Cerr << "In the splitting block of the computational domain " << dom_calcul.le_nom() << finl;
132 exit();
133 }
134 file >> elem_part_calcul;
135 file >> nb_parts_tot_calcul;
136 file.close();
137
138 const int sz = elem_part_calcul.size_array();
139 if (nb_elem_calcul != sz)
140 {
141 Cerr << "Error in Partitionneur_Partition::construire_partition\n";
142 Cerr << " The file " << nom_fichier << " contains an array of " << sz << " values.\n";
143 Cerr << " The area contains " << nb_elem_calcul << " elements" << finl;
144 exit();
145 }
146
147 // Centre of gravity of the elements of dom_interpol
148 DoubleTab coord_g_interpol;
149 // Compute the centres of gravity of the elements of dom_interpol
150 dom_interpol.calculer_centres_gravite(coord_g_interpol);
151 assert(coord_g_interpol.dimension(0) == nb_elem_interpol);
152 assert(coord_g_interpol.dimension(1) == dim_interpol);
153
154 // Centre of gravity of the elements of dom_calcul
155 DoubleTab coord_g_calcul;
156 // Compute the centres of gravity of the elements of dom_calcul
157 dom_calcul.calculer_centres_gravite(coord_g_calcul);
158 assert(coord_g_calcul.dimension(0) == nb_elem_calcul);
159 assert(coord_g_calcul.dimension(1) == dim_calcul);
160
161 elem_part.resize(nb_elem_interpol);
162 elem_part = 0;
163 // Find the nearest centres of gravity
164 {
165 int i,j;
166 double distance_min,distance;
167 for (i = 0; i < nb_elem_interpol; i++)
168 {
169 distance_min=1e+9;
170 double x_interpol = coord_g_interpol(i,0);
171 double y_interpol = coord_g_interpol(i,1);
172 double z_interpol = (dim_interpol == 3) ? coord_g_interpol(i,2) : 0.;
173 for (j = 0; j < nb_elem_calcul; j++)
174 {
175 double x_calcul = coord_g_calcul(j,0);
176 double y_calcul = coord_g_calcul(j,1);
177 double z_calcul = (dim_calcul == 3) ? coord_g_calcul(j,2) : 0.;
178 distance=sqrt((x_calcul-x_interpol)*(x_calcul-x_interpol)+(y_calcul-y_interpol)*(y_calcul-y_interpol)+(z_calcul-z_interpol)*(z_calcul-z_interpol));
179 if (distance < distance_min)
180 {
181 distance_min=distance;
182 elem_part[i]=elem_part_calcul[j];
183 }
184 }
185 }
186 }
187
188 int nb_parties_interpol, nb_parties_calcul;
189 nb_parties_interpol=0;
190 nb_parties_calcul=0;
191 // Number of procs in elem_part
192 if (elem_part.size_array() > 0)
193 nb_parties_interpol = max_array(elem_part) + 1;
194 // Number of procs in elem_part_calcul
195 if (elem_part_calcul.size_array() > 0)
196 nb_parties_calcul = max_array(elem_part_calcul) + 1;
197 // If empty parts, take them into account
198 if (nb_parties_calcul < nb_parts_tot_calcul)
199 nb_parties_calcul = nb_parts_tot_calcul;
200 else
201 nb_parts_tot_calcul = nb_parties_calcul;
202
203 // Total number of parts to generate
204 if ((nb_parties_interpol < nb_parties_calcul) && nb_parts_tot==-1)
205 nb_parts_tot=nb_parties_calcul;
206 if (nb_parts_tot_calcul < nb_parts_tot)
207 nb_parts_tot=nb_parts_tot_calcul;
208}
int_t nb_elem_tot() const
Definition Domaine.h:132
void calculer_centres_gravite(DoubleTab_t &xp) const
Calculates the centers of gravity of the domain elements.
Definition Domaine.h:503
int_t nb_elem() const
Definition Domaine.h:131
int_t nb_som() const
Returns the number of vertices of the domain.
Definition Domaine.h:121
const Nom & le_nom() const override
Returns the name of the Objet_U. Virtual method to override: returns "neant" in this implementation.
File for reading. This class is to the C++ ifstream class what the Entree class is to the.
Definition EFichier.h:29
virtual int ouvrir(const char *name, IOS_OPEN_MODE mode=ios::in)
static Objet_U & objet(const Nom &)
See Interprete_bloc::objet_global(). BM: the Interprete class is not the best place for this.
static int objet_existant(const Nom &)
Returns 1 if the object exists, 0 otherwise. See Interprete_bloc::objet_global_existant().
class Nom: a character string for naming TRUST objects.
Definition Nom.h:31
virtual void set_param(Param &) const
Definition Objet_U.h:130
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
static const Nom & nom_du_cas()
Returns a constant reference to the case name. This method is static.
Definition Objet_U.cpp:145
virtual Sortie & printOn(Sortie &) const
Writes the object to an output stream. Virtual method to override.
Definition Objet_U.cpp:278
Helper class to factorize the readOn method of Objet_U classes.
Definition Param.h:112
void ajouter(const char *keyword, const int *value, Param::Nature nat=Param::OPTIONAL)
Register an integer parameter.
Definition Param.cpp:364
@ REQUIRED
Definition Param.h:115
Domain partitioner based on the partitioning of another domain.
void associer_domaine(const Domaine &domaine) override
First initialisation step of the partitioner: associate a domain.
void validate_params() const override
Called in the readOn of Objet_U_With_Params, after reading the params.
void construire_partition(IntVect &elem_part, int &nb_parts_tot) const override
void initialiser()
Second initialisation step: define the number of slices.
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
_SIZE_ size_array() const
_SIZE_ dimension(int d) const
Definition TRUSTTab.tpp:133
void resize(_SIZE_, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
Definition TRUSTVect.tpp:91