TrioCFD 1.9.8
TrioCFD documentation
Loading...
Searching...
No Matches
Champ_Fonc_Interp.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 <Discretisation_tools.h>
17#include <Champ_Generique_base.h>
18#include <Option_Interpolation.h>
19#include <Champ_Fonc_Interp.h>
20#include <TRUSTTab_parts.h>
21#include <Comm_Group_MPI.h>
22#include <Param.h>
23#include <MEDLoader.hxx>
24#ifdef MPI_
25#include <ParaFIELD.hxx>
26#endif
27
28Implemente_instanciable(Champ_Fonc_Interp, "Champ_Fonc_Interp", Champ_Fonc_P0_base);
29// XD Champ_Fonc_Interp champ_don_base Champ_Fonc_Interp BRACE Field that is interpolated from a distant domain via
30// XD_CONT MEDCoupling (remapper).
31
33
35{
36#ifdef MEDCOUPLING_
37 using namespace MEDCoupling;
38
39 Param param(que_suis_je());
40 Nom nom_pb_loc, nom_pb_dist, nom_dom_loc, nom_dom_dist, nat;
41 param.ajouter("nom_champ", &nom_, Param::REQUIRED); // XD_ADD_P chaine
42 // XD_CONT Name of the field (for example: temperature).
43 param.ajouter("pb_loc", &nom_pb_loc, Param::REQUIRED); // XD_ADD_P chaine
44 // XD_CONT Name of the local problem.
45 param.ajouter("pb_dist", &nom_pb_dist, Param::REQUIRED); // XD_ADD_P chaine
46 // XD_CONT Name of the distant problem.
47 param.ajouter("dom_loc", &nom_dom_loc); // XD_ADD_P chaine
48 // XD_CONT Name of the local domain.
49 param.ajouter("dom_dist", &nom_dom_dist); // XD_ADD_P chaine
50 // XD_CONT Name of the distant domain.
51 param.ajouter("default_value", &default_value_); // XD_ADD_P chaine
52 // XD_CONT Name of the distant domain.
53 param.ajouter("nature", &nat, Param::REQUIRED); // XD_ADD_P chaine
54 // XD_CONT Nature of the field (knowledge from MEDCoupling is required; IntensiveMaximum, IntensiveConservation, ...).
55 param.ajouter("use_overlapdec", &use_dec_); // XD_ADD_P chaine
56 // XD_CONT Nature of the field (knowledge from MEDCoupling is required; IntensiveMaximum, IntensiveConservation, ...).
57 param.lire_avec_accolades_depuis(is);
58
59 pb_loc_ = ref_cast(Probleme_base, Interprete::objet(nom_pb_loc));
60 pb_dist_ = ref_cast(Probleme_base, Interprete::objet(nom_pb_dist));
61 if (nom_dom_loc == "??") dom_loc_ = pb_loc_->domaine();
62 else dom_loc_ = ref_cast(Domaine, Interprete::objet(nom_dom_loc));
63 if (nom_dom_dist == "??") dom_dist_ = pb_dist_->domaine();
64 else dom_dist_ = ref_cast(Domaine, Interprete::objet(nom_dom_dist));
65
66 is_elem_trgt_ = (pb_loc_->domaine_dis().que_suis_je() != "Domaine_VEF");
67
68 if (nat == "IntensiveMaximum") nature_ = IntensiveMaximum;
69 else if (nat == "IntensiveConservation") nature_ = IntensiveConservation;
70 else if (nat == "ExtensiveMaximum") nature_ = ExtensiveMaximum;
71 else if (nat == "ExtensiveConservation") nature_ = ExtensiveConservation;
72 else
73 {
74 Cerr << "Champ_Front_Interp : wrong NatureOfField read : " << nat << finl;
76 }
77
78 if (use_dec_ != -123)
80 else
82
83 return is;
84#else
85 Cerr << "Champ_Fonc_Interp::readOn should not be called since it requires a TRUST version compiled with MEDCoupling !" << finl;
86 throw;
87#endif
88}
89
91{
92 const int ok = Champ_Fonc_P0_base::initialiser(temps);
93 const Champ_base& ch = pb_dist_->has_champ(le_nom()) ? pb_dist_->get_champ(le_nom()) : pb_dist_->get_champ_post(le_nom()).get_champ(espace_stockage_);
94
96
97 if (is_elem_trgt_)
98 {
99 valeurs_.resize(0, nb_compo_);
100 dom_loc_->creer_tableau_elements(valeurs_);
101 }
102 else
103 {
104 Domaine_VF& dvf = ref_cast(Domaine_VF, pb_loc_->domaine_dis());
105 valeurs_.resize(dvf.nb_faces(), nb_compo_);
107 valeurs_elem_.resize(0, nb_compo_);
108 dom_loc_->creer_tableau_elements(valeurs_elem_);
109 }
110
111 is_initialized_ = true;
112 return ok;
113}
114
116{
117#ifdef MEDCOUPLING_
118 using namespace MEDCoupling;
119
120 local_field_ = MEDCouplingFieldDouble::New(ON_CELLS, ONE_TIME);
121 local_field_->setName(le_nom().getString());
122 local_array_ = DataArrayDouble::New();
123 // XXX Pb with MEDCoupling : OvelapDEC seems to modify the meshes ...
124 if (Process::nproc() > 1 && use_dec_)
125 {
126 MCAuto<MEDCouplingUMesh> msh_cpy = dom_loc_->get_mc_mesh()->deepCopy();
127 local_field_->setMesh(msh_cpy);
128 }
129 else
130 local_field_->setMesh(dom_loc_->get_mc_mesh());
131 local_field_->setNature(nature_);
132
133 distant_field_ = MEDCouplingFieldDouble::New(ON_CELLS, ONE_TIME);
134 distant_array_ = DataArrayDouble::New();
135 distant_field_->setName(le_nom().getString());
136 // XXX Pb with MEDCoupling : OvelapDEC seems to modify the meshes ...
137 if (Process::nproc() > 1 && use_dec_)
138 {
139 MCAuto<MEDCouplingUMesh> msh_cpy = dom_dist_->get_mc_mesh()->deepCopy();
140 distant_field_->setMesh(msh_cpy);
141 }
142 else
143 distant_field_->setMesh(dom_dist_->get_mc_mesh());
144 distant_field_->setNature(nature_);
145#endif
146}
147
149{
150#ifdef MEDCOUPLING_
151 using namespace MEDCoupling;
152
153 const Champ_base& ch = pb_dist_->has_champ(le_nom()) ? pb_dist_->get_champ(le_nom()) : pb_dist_->get_champ_post(le_nom()).get_champ(espace_stockage_);
154
155 const DoubleTab& distant_values = ch.valeurs();
156 ConstDoubleTab_parts local_parts(valeurs()), distant_parts(distant_values);
157
158 if (local_field_ == nullptr) init_fields();
159
160 // Target Stuff
161 if (is_elem_trgt_)
162 local_array_->useExternalArrayWithRWAccess(valeurs().addr(), local_parts[0].dimension(0), nb_compo_);
163 else
164 local_array_->useExternalArrayWithRWAccess(valeurs_elem_.addr(), valeurs_elem_.dimension(0), nb_compo_);
165
166 local_field_->setArray(local_array_);
167
168 // Source Stuff
169 if (pb_dist_->domaine_dis().que_suis_je() == "Domaine_VEF"
170 && pb_dist_->domaine_dis().nb_elem() > 0
171 && distant_values.dimension_tot(0) == ref_cast(Domaine_VF, pb_dist_->domaine_dis()).nb_faces_tot())
172 {
173 Cerr << finl << "ERROR in Champ_Fonc_Interp : in problem " << pb_loc_->le_nom() << ", the distant field is located at faces!" << finl;
174 Cerr << "Use a postprocessing field located at elements instead of " << le_nom() << finl;
175 Cerr << "In your case, try : " << le_nom() << "_elem_" << pb_dist_->domaine().le_nom() << finl;
177 }
178
179 distant_array_->useArray(distant_values.addr(), false, MEDCoupling::DeallocType::CPP_DEALLOC, distant_parts[0].dimension(0), nb_compo_);
180 distant_field_->setArray(distant_array_);
181#endif
182}
183
185{
186#ifdef MEDCOUPLING_
187 using MEDCoupling::WriteField;
189 if (!is_initialized_) return;
190
191 if (Process::nproc() > 1 && use_dec_)
192 {
193#ifdef MPI_
194 if (dom_loc_->get_mc_mesh() == nullptr) dom_loc_->build_mc_mesh();
195 if (dom_dist_->get_mc_mesh() == nullptr) dom_dist_->build_mc_mesh();
196
198 OverlapDEC *dec = dom_loc_->get_dec(dom_dist_.valeur(), distant_field_, local_field_);
199 /* the fields given to OverlapDEC can not be changed without calling synchronize... but we can change where they point to! */
200 dec->setDefaultValue(default_value_);
201 dec->getSourceLocalField()->getField()->setArray(distant_array_);
202 dec->getTargetLocalField()->getField()->setArray(local_array_);
203 dec->sendRecvData(true);
204#endif
205 }
206 else
207 {
208 MEDCouplingRemapper *rmp = dom_loc_->get_remapper(dom_dist_.valeur());
210 rmp->transfer(distant_field_, local_field_, default_value_);
211
212 if (verbose_)
213 {
214 WriteField("/tmp/source" + le_nom().getString() + Nom(Process::me()).getString() + ".med", distant_field_, true);
215 WriteField("/tmp/target" + le_nom().getString() + Nom(Process::me()).getString() + ".med", local_field_, true);
216 }
217 }
218
219 // Put values on faces !
220 if (!is_elem_trgt_)
221 {
222 valeurs_elem_.echange_espace_virtuel();
223 const Domaine_VF& dvf = ref_cast(Domaine_VF, pb_loc_->domaine_dis());
225 }
226#endif
227}
virtual int initialiser(const double temps)
NE FAIT RIEN.
DoubleTab & valeurs() override
Surcharge Champ_base::valeurs() Renvoie le tableau des valeurs.
DoubleTab valeurs_
void mettre_a_jour(double) override
Mise a jour en temps du champ.
int initialiser(double) override
NE FAIT RIEN.
void mettre_a_jour(double) override
Mise a jour en temps du champ.
virtual DoubleTab & valeurs()=0
classe Champ_base Cette classe est la base de la hierarchie des champs.
Definition Champ_base.h:43
static void cells_to_faces(const Champ_base &He, Champ_base &Hf)
class Domaine_VF
Definition Domaine_VF.h:44
int nb_faces() const
renvoie le nombre global de faces.
Definition Domaine_VF.h:471
void creer_tableau_faces(Array_base &, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT) const
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
const Nom & le_nom() const override
Renvoie le nom du champ.
int nb_compo_
Definition Field_base.h:95
Nature_du_champ nature_
Definition Field_base.h:96
static Objet_U & objet(const Nom &)
Voir Interprete_bloc::objet_global() BM: la classe Interprete n'est pas le meilleur endroit pour cett...
class Nom Une chaine de caractere pour nommer les objets de TRUST
Definition Nom.h:31
static int dimension
Definition Objet_U.h:99
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
@ REQUIRED
Definition Param.h:115
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 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
Classe de base des flux de sortie.
Definition Sortie.h:52
_TYPE_ * addr()
_SIZE_ dimension_tot(int) const override
Definition TRUSTTab.tpp:160
int line_size() const
Definition TRUSTVect.tpp:67