TrioCFD 1.9.8
TrioCFD documentation
Loading...
Searching...
No Matches
Decouper_multi.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 <Decouper_multi.h>
16#include <Domaine.h>
17#include <Param.h>
18#include <Connectivite_som_elem.h>
19#include <Static_Int_Lists.h>
20
21#include <medcoupling++.h>
22#ifdef MEDCOUPLING_
23#include <MEDCouplingMemArray.hxx>
24
25using namespace MEDCoupling;
26#endif
27
28Implemente_instanciable(Decouper_multi,"Decouper_multi|Partition_multi",Interprete);
29// XD partition_multi interprete decouper_multi NO_BRACE allows to partition multiple domains in contact with each other
30// XD_CONT in parallel: necessary for resolution monolithique in implicit schemes and for all coupled problems using
31// XD_CONT PolyMAC_HFV. By default, this keyword is commented in the reference test cases.
32// XD attr aco chaine(into=["{"]) aco REQ Opening curly bracket.
33// XD attr domaine1 chaine(into=["domaine"]) domaine1 REQ not set.
34// XD attr dom ref_domaine dom REQ Name of the first domain to be cut.
35// XD attr blocdecoupdom1 bloc_decouper blocdecoupdom1 REQ Partition bloc for the first domain.
36// XD attr domaine2 chaine(into=["domaine"]) domaine2 REQ not set.
37// XD attr dom2 ref_domaine dom2 REQ Name of the second domain to be cut.
38// XD attr blocdecoupdom2 bloc_decouper blocdecoupdom2 REQ Partition bloc for the second domain.
39// XD attr acof chaine(into=["}"]) acof REQ Closing curly bracket.
40
41
43{
44 exit();
45 return os;
46}
47
49{
50 exit();
51 return is;
52}
53
55{
56 if (mot=="domaine") //parametres de decoupage d'un domaine
57 {
58 Decouper decoup;
59 decoup.lire(is);
60 const Nom& nom = decoup.domaine().le_nom();
61 if (doms_lus.count(nom.getString())) //decoupeur deja lu
62 Process::exit(Nom("Decouper_multi: domain ") + nom + "already read!");
63 else decoupeurs.push_back(decoup), doms_lus.insert(nom.getString()); //sinon, on l'ajoute
64 }
65 else return -1;
66 return 0;
67}
68
69
71{
72 //lecture des domaines et des raccords
73 Param param(que_suis_je());
74 param.ajouter_non_std("domaine",(this),Param::REQUIRED);
75 param.ajouter("tolerance", &tolerance);
77
78 /* partition des domaines */
79 std::vector<Decouper*> v_dec; //decoupeurs
80 std::vector<const Domaine*> v_dom; //domaines
81 std::vector<Static_Int_Lists> v_se; //connectivites
82 std::vector<MCAuto<DataArrayDouble>> v_da; //DataArrayDouble de coordonnes
83 std::vector<const DataArrayDouble*> v_pda; //et des pointeurs (ppur Aggregate)
84 std::vector<int> off = { 0 }; //offset des sommets de chaque domaine dans le tableau aggrege
85 for (auto &&dec : decoupeurs)
86 {
87 const Domaine& dom = dec.domaine();
88 const DoubleTab& coord = dom.coord_sommets();
89 v_dec.push_back(&dec);
90 v_dom.push_back(&dom);
91 v_se.push_back(Static_Int_Lists());
92 v_da.push_back(DataArrayDouble::New());
93 v_da.back()->useExternalArrayWithRWAccess((double *) coord.addr(), coord.dimension(0), coord.dimension(1));
94 v_pda.push_back(v_da.back());
95 off.push_back(off.back() + coord.dimension(0));
96
97 Partitionneur_base& partitionneur = dec.deriv_partitionneur_.valeur();
98 partitionneur.construire_partition(dec.elem_part_, dec.nb_parts_tot_);
99 if (dec.nom_fichier_med_ != "?")
100 dec.postraiter_decoupage(dec.nom_fichier_med_);
101
102 construire_connectivite_som_elem(dom.nb_som(), dom.les_elems(), v_se.back(), 1);
103 }
104
105#ifdef MEDCOUPLING_
106 /* concatenation des coordonnees et recherche de sommets coincidents */
107 Cerr << "Decouper_multi: searching for coinciding vertices ... ";
108 MCAuto<DataArrayDouble> da(DataArrayDouble::Aggregate(v_pda)); //tous les sommets!
109 DataArrayIdType* S_i = nullptr, *S = nullptr; //groupes de sommets coincidants : S([S_i(i), S_i(i + 1)[)
110 da->findCommonTuples(tolerance, -1, S, S_i); // * heavy lifting *
111
112 /* pour chaque groupe de sommets, recherche de tous les procs les touchant et ajout a chaque sommet des procs qui ne le possedent pas encore */
113 std::vector<std::map<int, std::set<int>>> v_sp(v_dec.size()); //v_sp[d][s] = { processeurs supplementaires ayant besoin du sommet s du domaine d }
114 std::vector<std::set<int>> procs; //processeurs possedant chaque sommet du groupe...
115 std::set<int> u_procs; //et leur union
116 std::vector<std::array<int, 2>> v_ds; //liste (domaine, num sommet local)
117 int ns, l, d, count = 0;
118 mcIdType j, s;
119 for (mcIdType i = 0; i + 1 < S_i->getNumberOfTuples(); i++)
120 if ((ns = static_cast<int>(S_i->getIJ(i + 1, 0) - S_i->getIJ(i, 0))) > 1) //pas besoin de traiter les sommets seuls
121 {
122 count++;
123 procs.resize(ns);
124 v_ds.resize(ns);
125 int k = 0;
126 for (j = S_i->getIJ(i, 0); j < S_i->getIJ(i + 1, 0); j++, k++)
127 {
128 // Retrouve le numero de dom dans lequel le sommet doublon est localise:
129 for (s = S->getIJ(j, 0), d = 0; s >= off[d + 1]; )
130 d++; //d : indice du domaine contenant s
131 const IntVect& elem_part = v_dec[d]->elem_part_;
132 mcIdType som_loc0 = s - off[d]; // son numero local
133 assert(som_loc0 < std::numeric_limits<int>::max());
134 int som_loc = static_cast<int>(som_loc0);
135 v_ds[k] = {{ d, som_loc }}; //stockage du couple (d, s)
136 procs[k].clear();
137 for (l = 0; l < v_se[d].get_list_size(som_loc); l++)
138 procs[k].insert(elem_part(v_se[d](som_loc, l))); //processeurs connectes
139 }
140 for (u_procs.clear(), k = 0; k < ns; k++)
141 for (auto &&pr : procs[k])
142 u_procs.insert(pr); //union
143 for (k = 0; k < ns; k++) /* on ajoute a chaque sommet les procs auxquels il n'est pas deja connecte */
144 if (procs[k].size() < u_procs.size())
145 {
146 std::set<int>& dest = v_sp[v_ds[k][0]][v_ds[k][1]]; //ou on doit inserer
147 std::set_difference(u_procs.begin(), u_procs.end(), procs[k].begin(), procs[k].end(), std::inserter(dest, dest.end()));
148 }
149 }
150 S_i->decrRef(), S->decrRef();
151 Cerr << count << " sommets trouves!" << finl;
152
153#else
154 Process::exit("Decouper_multi requires MEDCoupling!");
155#endif
156
157 /* ecriture des domaines avec les sommets raccord qu'on a trouves */
158 for (d = 0; d < (int) v_dec.size(); d++)
159 {
160 Static_Int_Lists som_raccord;
161 ArrOfInt sizes(v_dom[d]->nb_som()); //tailles des listes par sommet
162 sizes = 0;
163 for (auto && s_p : v_sp[d]) sizes[s_p.first] = (int)s_p.second.size();
164 som_raccord.set_list_sizes(sizes);
165 for (auto && s_p : v_sp[d])
166 {
167 int i = 0;
168 for (auto &&p : s_p.second)
169 {
170 som_raccord.set_value(s_p.first, i, p);
171 i++;
172 }
173 }
174 v_dec[d]->ecrire(&som_raccord); // * heavier lifting *
175 }
176 return is;
177}
Entree & lire(Entree &is)
Definition Decouper.cpp:277
Interprete Decouper_multi.
int lire_motcle_non_standard(const Motcle &, Entree &) override
Lecture des parametres de type non simple d'un objet_U a partir d'un flot d'entree.
Entree & interpreter(Entree &is) override
IntTab_t & les_elems()
Definition Domaine.h:129
const DoubleTab_t & coord_sommets() const
Definition Domaine.h:112
int_t nb_som() const
Renvoie le nombre de sommets du domaine.
Definition Domaine.h:121
const Nom & le_nom() const override
Donne le nom de l'Objet_U Methode a surcharger : renvoie "neant" dans cette implementation.
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
Classe de base des objets "interprete".
Definition Interprete.h:38
Une chaine de caractere (Nom) en majuscules.
Definition Motcle.h:26
class Nom Une chaine de caractere pour nommer les objets de TRUST
Definition Nom.h:31
const std::string & getString() const
Definition Nom.h:92
friend class Entree
Definition Objet_U.h:76
const Nom & que_suis_je() const
renvoie la chaine identifiant la classe.
Definition Objet_U.cpp:104
virtual Entree & readOn(Entree &)
Lecture d'un Objet_U sur un flot d'entree Methode a surcharger.
Definition Objet_U.cpp:293
virtual Sortie & printOn(Sortie &) const
Ecriture de l'objet sur un flot de sortie Methode a surcharger.
Definition Objet_U.cpp:282
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
void ajouter_non_std(const char *keyword, const Objet_U *value, Param::Nature nat=Param::OPTIONAL)
Register a keyword handled by Objet_U::lire_motcle_non_standard.
Definition Param.cpp:489
int lire_avec_accolades_depuis(Entree &is)
Parse the parameter block { ... } from is.
Definition Param.cpp:32
virtual void construire_partition(BigIntVect_ &elem_part, int &nb_parts_tot) const =0
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
Definition Process.cpp:455
Classe de base des flux de sortie.
Definition Sortie.h:52
void set_value(int_t i_liste, int_t i_element, int_t valeur)
affecte la "valeur" au j-ieme element de la i-ieme liste avec 0 <= i < get_nb_lists() et 0 <= j < get...
void set_list_sizes(const ArrOfInt_t &sizes)
detruit les listes existantes et en cree de nouvelles.
_TYPE_ * addr()
_SIZE_ dimension(int d) const
Definition TRUSTTab.tpp:133