TrioCFD 1.9.9_beta
TrioCFD documentation
Loading...
Searching...
No Matches
Partitionneur_Sous_Domaines.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 <Partitionneur_Sous_Domaines.h>
17#include <Synonyme_info.h>
18#include <Domaine.h>
19#include <Sous_Domaines.h>
20#include <Param.h>
21#include <Interprete.h>
22
23Implemente_instanciable_sans_constructeur(Partitionneur_Sous_Domaines,"Partitionneur_Sous_Domaines",Partitionneur_base);
24// XD partitionneur_sous_domaines partitionneur_deriv partitionneur_sous_domaines INHERITS_BRACE This algorithm will
25// XD_CONT create one part for each specified subdomaine/domain. All elements contained in the first subdomaine/domain
26// XD_CONT are put in the first part, all remaining elements contained in the second subdomaine/domain in the second
27// XD_CONT part, etc... NL2 If all elements of the current domain are contained in the specified subdomaines/domain,
28// XD_CONT then N parts are created, otherwise, a supplemental part is created with the remaining elements. NL2 If no
29// XD_CONT subdomaine is specified, all subdomaines defined in the domain are used to split the mesh.
30Add_synonym(Partitionneur_Sous_Domaines, "Partitionneur_Sous_Zones");
31
32Partitionneur_Sous_Domaines::Partitionneur_Sous_Domaines()
33{
34}
35
36
38{
39 Cerr << "Partitionneur_Sous_Domaines::printOn invalid\n" << finl;
40 exit();
41 return os;
42}
43
44/*! @brief Reading format: (the sub-domain/domain list is optional, N is the number of entities read)
45 *
46 * {
47 * [ Sous_domaines N nom_sous_domaine1 nom_sous_domaine2 nom_sous_domaine3 ... ]
48 * [ Domaines N nom_domaine1 nom_domaine2 ... ]
49 * }
50 *
51 */
53{
54 if (!ref_domaine_)
55 {
56 Cerr << " Error: the domain has not been associated" << finl;
58 }
59 param.ajouter("sous_zones",&noms_sous_domaines_); // XD attr sous_zones listchaine sous_zones OPT N SUBZONE_NAME_1
60 // XD_CONT SUBZONE_NAME_2 ...
61 param.ajouter("domaines",&noms_domaines_); // XD attr domaines listchaine domaines OPT N DOMAIN_NAME_1
62 // XD_CONT DOMAIN_NAME_2 ...
63}
64
65/*! @brief First initialisation step of the partitioner: associate a domain.
66 *
67 */
69{
70 ref_domaine_ = domaine;
71}
72
73/*! @brief Second initialisation step: define the sub-domains to use.
74 *
75 * (readOn can be used instead).
76 *
77 */
78void Partitionneur_Sous_Domaines::initialiser(const Noms& noms_sous_domaines)
79{
80 assert(ref_domaine_);
81 noms_sous_domaines_ = noms_sous_domaines;
82}
83
84/*! @brief Each sub-domain in noms_sous_domaines_ defines the elements assigned to a processor.
85 *
86 * Processors are assigned in the order of appearance of the
87 * sub-domains/domains within the domain (not in the order they appear in
88 * the sub-domain list).
89 * First sub-domain/domain in the list => proc 0
90 * Elements of the second sub-domain => proc 1
91 * ...
92 * Remaining elements not in any sub-domain => assigned to a new pe.
93 * If an element belongs to several sub-domains, the first sub-domain wins.
94 *
95 */
96void Partitionneur_Sous_Domaines::construire_partition(IntVect& elem_part, int& nb_parts_tot) const
97{
98 assert(ref_domaine_);
99 const Domaine& dom = ref_domaine_.valeur();
100 const int nb_elem = dom.nb_elem_tot();
101 elem_part.resize(nb_elem);
102 elem_part = -1;
103 if (noms_domaines_.size()!=0 && noms_sous_domaines_.size())
104 {
105 Cerr << "Can't mix sous_domaines and domaines yet in sous_domaines partitionner." << finl;
107 }
108 // Current processor number being assigned:
109 int pe = 0;
110 int count = 0;
111 if (noms_domaines_.size()!=0)
112 {
113 for (int i=0; i<noms_domaines_.size(); i++)
114 {
115 const Nom& nom_domaine = noms_domaines_[i];
116 if (!interprete().objet_existant(nom_domaine) || !sub_type(Domaine, interprete().objet(nom_domaine)))
117 {
118 // Unlike sub-domains, the domain must exist for now
119 Cerr << "Domain " << nom_domaine << " is not existing." << finl;
121 // ToDo: eventually a list of domains from files e.g.: DOM_0000.Zones, DOM_0001.Zones
122 }
123 const Domaine& domaine = ref_cast(Domaine, interprete().objet(nom_domaine));
124 DoubleTab domaine_xp;
125 domaine.calculer_centres_gravite(domaine_xp);
126 IntVect dom_cells_containing_domaine_cells;
127 dom.chercher_elements(domaine_xp, dom_cells_containing_domaine_cells);
128 Cerr << " Allocation of elements of the domain " << domaine.le_nom() << " to the processor " << pe << finl;
129 for (int cell = 0; cell < dom_cells_containing_domaine_cells.size(); cell++)
130 {
131 int elem = dom_cells_containing_domaine_cells[cell];
132 if (elem_part[elem] < 0)
133 {
134 count++;
135 elem_part[elem] = pe;
136 }
137 }
138 Cerr << " Number of elements attributed to the processor " << pe << " : " << count << finl;
139 pe++;
140 }
141 }
142 else
143 {
144 Noms noms_sous_domaines(noms_sous_domaines_);
145 // If the name of the only Sous_Domaine is a list of Sous_Domaine, retrieve all of them:
146 if (noms_sous_domaines_.size()==1 && sub_type(Sous_Domaines, Interprete::objet(noms_sous_domaines_[0])))
147 {
148 const Sous_Domaines& liste = ref_cast(Sous_Domaines, Interprete::objet(noms_sous_domaines_[0]));
149 noms_sous_domaines.dimensionner_force(liste.size());
150 for (int i=0; i<liste.size(); i++) noms_sous_domaines[i]=liste[i].le_nom();
151 }
152 const int nb_sous_domaines = dom.nb_ss_domaines();
153 const int toutes_sous_domaines = (noms_sous_domaines.size() == 0);
154 if (toutes_sous_domaines)
155 Cerr << " No subarea specified, we use all existing subareas." << finl;
156 for (int i_sous_domaine = 0; i_sous_domaine < nb_sous_domaines; i_sous_domaine++)
157 {
158 const Sous_Domaine& sous_domaine = dom.ss_domaine(i_sous_domaine);
159 const Nom& nom = sous_domaine.le_nom();
160 bool sous_domaine_trouvee = noms_sous_domaines.contient_(nom);
161 if (!toutes_sous_domaines && !sous_domaine_trouvee)
162 continue;
163
164 count = 0;
165 const int nb_elem_ssz = sous_domaine.nb_elem_tot();
166 for (int i = 0; i < nb_elem_ssz; i++)
167 {
168 const int elem = sous_domaine[i];
169 if (elem_part[elem] < 0)
170 {
171 count++;
172 elem_part[elem] = pe;
173 }
174 }
175 Cerr << " Allocation of " << count << " elements from the subarea " << nom << " to the processor " << pe << finl;
176 pe++;
177 }
178 }
179 count = 0;
180 for (int elem = 0; elem < nb_elem; elem++)
181 {
182 if (elem_part[elem] < 0)
183 {
184 count++;
185 elem_part[elem] = pe;
186 }
187 }
188 if (count>0) Cerr << " Allocation of the remaining " << count << " elements to the processor " << pe << finl;
189 /*
190 if (count==0)
191 {
192 Cerr << "Error! The last domaine will be empty with 0 elements. It is surely not what you want." << finl;
193 Cerr << "Check, your partition strategy." << finl;
194 Process::exit();
195 } */
196 if (ref_domaine_->bords_perio().size() > 0)
197 corriger_bords_avec_liste(dom, 0, elem_part);
198
199 // Do not correct elem0 on proc0 (test case CouplageFluide_Pb1Pb2_VEF_CN)
200}
const Sous_Domaine_t & ss_domaine(int i) const
Definition Domaine.h:290
int_t nb_elem_tot() const
Definition Domaine.h:132
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
int nb_ss_domaines() const
Definition Domaine.h:289
static Objet_U & objet(const Nom &)
See Interprete_bloc::objet_global(). BM: the Interprete class is not the best place for this.
class Nom: a character string for naming TRUST objects.
Definition Nom.h:31
An array of character strings (VECT(Nom)).
Definition Noms.h:26
int contient_(const char *const ch) const
Definition Noms.cpp:60
virtual void set_param(Param &) const
Definition Objet_U.h:130
const Interprete & interprete() const
Definition Objet_U.cpp:211
virtual const Nom & le_nom() const
Returns the name of the Objet_U. Virtual method to override: returns "neant" in this implementation.
Definition Objet_U.cpp:317
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
Domain partitioner based on sub-domains of the domain. See construire_partition().
void associer_domaine(const Domaine &domaine) override
First initialisation step of the partitioner: associate a domain.
void initialiser(const Noms &noms_sous_domaines)
Second initialisation step: define the sub-domains to use.
void construire_partition(IntVect &elem_part, int &nb_parts_tot) const override
Each sub-domain in noms_sous_domaines_ defines the elements assigned to a processor.
static void corriger_bords_avec_liste(const Domaine_t &dom, const int_t my_offset, BigIntVect_ &elem_part)
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
const Nom & le_nom() const override
Returns the name of the Objet_U. Virtual method to override: returns "neant" in this implementation.
int_t nb_elem_tot() const
A vector of Sous_Domaine (VECT(Sous_Domaine)).
_SIZE_ size() const
Definition TRUSTVect.tpp:45
void resize(_SIZE_, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
Definition TRUSTVect.tpp:91