TrioCFD 1.9.8
TrioCFD documentation
Loading...
Searching...
No Matches
MD_Vector_composite.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 <MD_Vector_composite.h>
17#include <MD_Vector_seq.h>
18#include <Array_tools.h>
19#include <Param.h>
20
21Implemente_instanciable(MD_Vector_composite,"MD_Vector_composite",MD_Vector_base);
22
23/*! @brief method used to dump/restore a descriptor in a file Each process writes a different descriptor.
24 *
25 * See MD_Vector_tools::restore_vector_with_md()
26 */
28{
30
31 int np;
32 is >> np ;
33 for (int p=0; p<np; p++)
34 {
35 OWN_PTR(MD_Vector_base) md_ptr;
36 Nom md_type;
37 is >> md_type;
38 md_ptr.typer(md_type);
39 is >> md_ptr.valeur();
40 if (1)
41 {
42 // Creation du MD_Vector attache au tableau
43 data_.add(MD_Vector());
44 MD_Vector& mdV =data_[p];
45 mdV.copy(md_ptr.valeur());
46 }
47 }
48 Param p(que_suis_je());
49 p.ajouter("is_seq", &is_seq_);
50 p.ajouter_non_std("global_md", this);
51 p.ajouter("parts_offsets", &parts_offsets_);
52 p.ajouter("shapes", &shapes_);
53 p.ajouter("names", &names_);
54 p.lire_avec_accolades(is);
55 return is;
56}
57
59{
60 if (mot == "global_md")
61 {
62 assert(is_seq_ != -1);
63 is_seq_ ? instanciate_seq() : instanciate_std();
64 is >> *global_md_;
65 return 1;
66 }
67 return -1;
68}
69
70/*! @brief method used to dump/restore a descriptor in a file Each process writes a different descriptor.
71 *
72 * See MD_Vector_tools::dump_vector_with_md()
73 */
75{
77 int np=data_.size();
78 os << np<<finl;
79 for (int p=0; p<np; p++)
80 {
81 const MD_Vector_base& md = get_desc_part(p).valeur();
82 os << md.que_suis_je() << finl;
83 os << md << finl;
84 }
85
86 os << "{" << finl;
87 os << "is_seq" << tspace << is_seq_ << finl;
88 os << "global_md" << finl << *global_md_ << finl;
89 os << "parts_offsets" << tspace << parts_offsets_ << finl;
90 os << "shapes" << tspace << shapes_ << finl;
91 os << "names" << tspace << names_ << finl;
92 os << "}" << finl;
93 return os;
94}
95
96// [ABN] TODO the 2 methods below could be made more OO by using Objet_U::duplique() or sth like that ... can't be bothered ...
97void MD_Vector_composite::instanciate_std()
98{
99 if(!global_md_)
100 {
101 global_md_ = std::make_shared<MD_Vector_std>();
102 is_seq_ = 0;
103 }
104}
105
106void MD_Vector_composite::instanciate_seq()
107{
108 if(!global_md_)
109 {
110 // important: initialize with a number of 0 items - will be incremented by add_part() below:
111 global_md_ = std::make_shared<MD_Vector_seq>(0);
112 is_seq_ = 1;
113 }
114}
115
116
117/*! @brief Append the "part" descriptor to the composite vector.
118 *
119 * By default, shape=0 says that for each item in "part", one item will
120 * be appended to the composite descriptor.
121 * If shape=n, each items in "part" will be duplicated n times in the
122 * composite descriptor.
123 * The difference between 0 and 1 is when we create parts with DoubleTab_parts
124 * (see class DoubleTab_parts)
125 * Exemples:
126 * 1) P1Bubble pressure fields have one, two or three parts with shape=1.
127 * (see Domaine_VEF::discretiser_suite())
128 * 2) One can create a composite field containing
129 * - velocity degrees of freedom at the faces
130 * - pressure d.o.f. at the elements
131 * - one multiscalar d.o.f at nodes
132 * MD_Vector_composite mdc;
133 * mdc.add_part(domainevf.md_vector_faces(), dimension);
134 * mdc.add_part(domaine.md_vector_elements(), 0 // scalar //);
135 * mdc.add_part(domaine.md_vector_sommets(), 1 // multiscalar with 1 component //);
136 * MD_Vector md;
137 * md.copy(mdc);
138 * I will create a DoubleVect of this form by attaching this descriptor:
139 * DoubleVect v;
140 * MD_Vector_tools::creer_tableau_distribue(md, v);
141 * DoubleTab_Parts parts(v);
142 * // parts[0] has nb_dim()==2, dimensions are [ domainevf.nb_faces_tot, 3 ]
143 * // parts[1] has nb_dim()==1, dimension [ domaine.nb_elem_tot ] // speciel case shape==0 //
144 * // parts[2] has nb_dim()==2, dimension [ domaine.nb_som_tot, 1 ]
145 * I can duplicate items in the descriptor by creating DoubleTab objects:
146 * The following code will create an array containing 12 d.o.f for each face
147 * followed by 4 d.o.f for each element and 4 d.o.f for each node:
148 * DoubleTab tab(0, 4);
149 * MD_Vector_tools::creer_tableau_distribue(md, tab);
150 * DoubleTab_Parts parts(tab);
151 * // parts[0] has nb_dim()==3, dimensions are [ domainevf.nb_faces_tot, 3, 4 ]
152 * // parts[1] has nb_dim()==2, dimension [ domaine.nb_elem_tot, 4 ] // speciel case shape==0 //
153 * // parts[2] has nb_dim()==3, dimension [ domaine.nb_som_tot, 1, 4 ]
154 *
155 */
156void MD_Vector_composite::add_part(const MD_Vector& part, int shape, Nom name)
157{
158 assert(part);
159 assert(shape >= 0);
160
161 if (data_.size() == 0)
162 {
163 nb_items_tot_ = 0;
166 }
167 const int multiplier = (shape == 0) ? 1 : shape;
168 data_.add(part);
169 const int offset = nb_items_tot_;
170
171 parts_offsets_.append_array(offset);
172
173 shapes_.append_array(shape);
174 names_.add(name);
175
176 nb_items_tot_ += part->get_nb_items_tot() * multiplier;
177 if (data_.size() > 1 || part->get_nb_items_reels() < 0)
178 nb_items_reels_ = -1; // size() will be invalid for arrays with this descriptor
179 else
180 nb_items_reels_ = part->get_nb_items_reels() * multiplier;
181 nb_items_seq_tot_ += part->nb_items_seq_tot() * multiplier;
182 nb_items_seq_local_ += part->nb_items_seq_local() * multiplier;
183
184 // Double dynamic dispatch here:
185 // - global_md_ can be either MD_Vector_std or MD_Vector_seq
186 // - and part.valeur() can be any child of MD_Vector_base
187 // First dispatch is made with C++ polymorphism ... and for the second, no choice, we must sub_type:
188 if (sub_type(MD_Vector_std, part.valeur()))
189 {
190 assert(Process::is_parallel());
191 instanciate_std();
192 global_md_->append_from_other_std(ref_cast(MD_Vector_std, part.valeur()), offset, multiplier);
193 }
194 else if (sub_type(MD_Vector_seq, part.valeur()))
195 {
196 assert(Process::is_sequential());
197 instanciate_seq();
198 global_md_->append_from_other_seq(ref_cast(MD_Vector_seq, part.valeur()), offset, multiplier);
199 }
200 else if (sub_type(MD_Vector_composite, part.valeur()))
201 {
202 const MD_Vector_mono& oth = * ( ref_cast(MD_Vector_composite, part.valeur()).global_md_ );
203 if (sub_type(MD_Vector_std, oth))
204 {
205 instanciate_std();
206 global_md_->append_from_other_std(ref_cast(MD_Vector_std, oth), offset, multiplier);
207 }
208 else if (sub_type(MD_Vector_seq, oth))
209 {
210 instanciate_seq();
211 global_md_->append_from_other_seq(ref_cast(MD_Vector_seq, oth), offset, multiplier);
212 }
213 else
214 Process::exit("Internal error in MD_Vector_composite::add_part: should not happen. ");
215 }
216 else
217 {
218 Cerr << "Internal error in MD_Vector_composite::add_part: unknown part type " << part->que_suis_je() << finl;
220 }
221
222 // Update the block information - in sequential (MD_Vector_seq) nothing will be changed (since underlying arrays
223 // remain empty), but this is OK because all algorithsm using this data (determine_blocks() in TRUSTVect_tools for
224 // example, or get_sequential_items_flags()) are overriden for sequential cases.
225 append_blocs(global_md_->blocs_items_to_sum_, part->get_blocs_items_to_sum(), offset, multiplier);
226 append_blocs(global_md_->blocs_items_to_compute_, part->get_blocs_items_to_compute(), offset, multiplier);
227}
228
229void MD_Vector_composite::fill_md_vect_renum(const IntVect& renum, MD_Vector& md_vect) const
230{
231 global_md_->fill_md_vect_renum(renum, md_vect);
232}
233
234/*! Override, to avoid using the standard implementation of the method that scans the blocks 'bloc_items_to_sum_'
235 * in case of a sequential situation.
236 */
237int MD_Vector_composite::get_seq_flags_impl(ArrOfBit& flags, int line_size) const
238{
239 assert(data_.size() > 0);
240 assert(is_seq_ != -1);
241 if (is_seq_)
242 {
243 assert(dynamic_cast<MD_Vector_seq *>(global_md_.get()) != nullptr);
244 return global_md_->get_seq_flags_impl(flags, line_size);
245 }
246 else // bloc_* members are up-to-date, we can use the base implementation:
247 {
248 assert(dynamic_cast<MD_Vector_std *>(global_md_.get()) != nullptr);
249 return MD_Vector_base::get_seq_flags_impl(flags, line_size);
250 }
251}
252
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
Base class for distributed vectors parallel descriptors.
virtual const ArrOfInt & get_blocs_items_to_sum() const =0
friend class MD_Vector
static void append_blocs(ArrOfInt &dest, const ArrOfInt &src, int offset=0, int multiplier=1)
trustIdType nb_items_seq_tot_
virtual int get_seq_flags_impl(ArrOfBit &flags, int line_size) const
virtual int nb_items_seq_local() const
virtual int get_nb_items_tot() const
virtual trustIdType nb_items_seq_tot() const
virtual int get_nb_items_reels() const
virtual const ArrOfInt & get_blocs_items_to_compute() const =0
Metadata for a distributed composite vector.
int lire_motcle_non_standard(const Motcle &mot, Entree &is) override
Lecture des parametres de type non simple d'un objet_U a partir d'un flot d'entree.
void fill_md_vect_renum(const IntVect &renum, MD_Vector &md_vect) const override
int get_seq_flags_impl(ArrOfBit &flags, int line_size) const override
void add_part(const MD_Vector &part, int shape=0, Nom name="")
Append the "part" descriptor to the composite vector.
const MD_Vector & get_desc_part(int i) const
std::shared_ptr< MD_Vector_mono > global_md_
Generic class for all mono-block MD_Vectors (i.e. non compoosite).
Dummy parallel descriptor used for sequential computations.
C'est le plus simple des descripteurs, utilise pour les tableaux de valeurs aux sommets,...
void copy(const MD_Vector_base &)
construction d'un objet MD_Vector par copie d'un objet existant.
Definition MD_Vector.cpp:26
const MD_Vector_base & valeur() const
Definition MD_Vector.h:77
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
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
static bool is_parallel()
Definition Process.cpp:110
static void exit(int exit_code=-1)
Routine de sortie de TRUST dans une region Kokkos.
Definition Process.cpp:455
static bool is_sequential()
Definition Process.cpp:115
Classe de base des flux de sortie.
Definition Sortie.h:52