TrioCFD 1.9.8
TrioCFD documentation
Loading...
Searching...
No Matches
Champ_Generique_Transformation.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 <Champ_Generique_Transformation.h>
17#include <Probleme_base.h>
18#include <Domaine_VF.h>
19#include <TRUSTTabs.h>
20#include <ParserView.h>
21
22#include <Discretisation_base.h>
23#include <Interprete.h>
24#include <Equation_base.h>
25#include <Entree_complete.h>
26#include <Milieu_base.h>
27#include <Postraitement.h>
28#include <Synonyme_info.h>
29#include <Param.h>
30
31#include <Linear_algebra_tools_impl.h>
32#include <MD_Vector.h>
33#include <MD_Vector_composite.h>
34#include <Domaine_dis_base.h>
35
36Implemente_instanciable(Champ_Generique_Transformation,"Transformation",Champ_Gen_de_Champs_Gen);
37Add_synonym(Champ_Generique_Transformation,"Champ_Post_Transformation");
38
39// XD transformation champ_post_de_champs_post champ_post_transformation BRACE To create a field with a transformation
40// XD_CONT using source fields and x, y, z, t. If you use in your datafile source refChamp { Pb_champ pb pression }, the
41// XD_CONT field pression may be used in the expression with the name pression_natif_dom; this latter is the same as
42// XD_CONT pression. If you specify nom_source in refChamp bloc, you should use the alias given to pressure field. This
43// XD_CONT is avail for all equations unknowns in transformation.
44
46{
47 return s << que_suis_je() << " " << le_nom();
48}
49
51{
54 return s ;
55}
56
57//-methode : type de transformation a realiser
58// methodes possible :
59// formule : fonction de champs generiques sources, x, y, z et t
60// vecteur : construction d un vecteur a partir des donnees fournies
61// produit_scalaire : produit scalaire de deux vecteurs specifies
62// norme : norme d un vecteur specifie
63// composante : creation d un champ scalaire a partir d une composante d un champ vectoriel
64//-expression : expression de la transformation (cas des methodes formule et vecteur)
65//-numero : numero de la composante a extraire (uniquement pour le cas de la methode composante)
66//-localisation : localisation du champ de stockage
67//-unite : pour specifier l'unite d'un champ pour ameliorer la lisibilite des postraitements
69{
71 param.ajouter("methode",&methode_,Param::REQUIRED); // XD_ADD_P chaine(into=["produit_scalaire","norme","vecteur","formule","composante"])
72 // XD_CONT methode 0 methode norme : will calculate the norm of a vector given by a source field NL2 methode
73 // XD_CONT produit_scalaire : will calculate the dot product of two vectors given by two sources fields NL2 methode
74 // XD_CONT composante numero integer : will create a field by extracting the integer component of a field given by a
75 // XD_CONT source field NL2 methode formule expression 1 : will create a scalar field located to elements using
76 // XD_CONT expressions with x,y,z,t parameters and field names given by a source field or several sources fields. NL2
77 // XD_CONT methode vecteur expression N f1(x,y,z,t) fN(x,y,z,t) : will create a vector field located to elements by
78 // XD_CONT defining its N components with N expressions with x,y,z,t parameters and field names given by a source
79 // XD_CONT field or several sources fields.
80 param.ajouter("unite", &unite_); // XD_ADD_P chaine
81 // XD_CONT will specify the field unit
82 param.ajouter_non_std("expression",(this)); // XD_ADD_P listchaine
83 // XD_CONT expression 1 see methodes formule and vecteur
84 param.ajouter_non_std("numero",(this)); // XD_ADD_P entier
85 // XD_CONT numero 1 see methode composante
86 param.ajouter("localisation",&localisation_); // XD_ADD_P chaine
87 // XD_CONT localisation 1 type_loc indicate where is done the interpolation (elem for element or som for node). The
88 // XD_CONT optional keyword methode is limited to calculer_champ_post for the moment
89}
90
92{
93 if (mot=="expression")
94 {
95 int dim;
96 is >> dim;
97 les_fct.dimensionner(dim);
98 if ((Motcle(methode_) == "formule") && (dim!=1) )
99 {
100 Cerr << "The integer N of the expression with FORMULE method must be equal to 1." <<finl;
101 Cerr << "Use the VECTEUR expression method for N="<<dim<<finl;
102 exit();
103 }
104 for (int i=0; i<dim; i++)
105 is>>les_fct[i];
106 return 1;
107 }
108 else if (mot=="numero")
109 {
110 int num_compo;
111 is >> num_compo;
112 nb_comp_ = 1;
113 nature_ch = scalaire;
114 /* test numero composante : on ne peut pas se baser sur la dimension de l'espace dans le cas d'un champ multi_scalaire
115 Probleme : c'est nb_comp_ qui portera par la suite la dimension des composantes et il est ici initialise a 1 pour eviter bug
116 Le test est deplace dans Champ_Generique_Transformation::get_champ
117
118 if ((num_compo<0) || (num_compo>dimension-1))
119 {
120 // Cerr<<"Component number must be >=0 and < "<<dimension<<" for composante option."<<finl;
121 Cerr<<"Component number must be >=0 for composante option."<<finl;
122 exit();
123 } */
124 les_fct.dimensionner(num_compo+1);
125 return 1;
126 }
127 else
129}
130
132{
133 if ((Motcle(methode_) == "produit_scalaire") || (Motcle(methode_) == "norme"))
134 les_fct.dimensionner(1);
135 else if ((Motcle(methode_) == "formule") || (Motcle(methode_) == "vecteur"))
136 {
137 if (les_fct.size()<1)
138 {
139 Cerr<<"The expression must be read for the methods fonction and vecteur."<<finl;
140 exit();
141 }
142 }
143 else
144 {
145 Motcles methods(6);
146 methods[0] = "formule";
147 methods[1] = "vecteur";
148 methods[2] = "produit_scalaire";
149 methods[3] = "norme";
150 methods[4] = "composante";
151 methods[5] = "composante_normale";
152 if (methods.search(methode_) < 0)
153 {
154 Cerr<<"Error in "<<que_suis_je()<<finl;
155 Cerr<<"Read keyword : " << methode_ << "\n Allowed items are : "<<methods<<finl;
156 exit();
157 }
158 }
159
160 if ((Motcle(methode_) == "vecteur"))
161 {
162 // On essaie de fixer de suite le nombre de composantes avec vecteur
163 nb_comp_ = les_fct.size();
164
165 // la verification des sources est faite lors du completer pour les sources reference
166 }
167}
169{
170 //TODO DG temporary ?
171 const Domaine_dis_base& domaine_dis = get_source(0).get_ref_domaine_dis_base();
172 if (domaine_dis.que_suis_je()=="Domaine_DG")
173 {
174 if (!(localisation_=="elem"))
175 {
176 Cerr << "Error in Champ_Generique_Transformation::verifier_localisation" << finl;
177 Cerr << "with DG the only possible localisation for Transformation is \"elem\"" << finl;
178 exit();
179 }
180 }
181
182 Motcles localisations(4);
183 localisations[0] = "elem";
184 localisations[1] = "som";
185 localisations[2] = "faces";
186 localisations[3] = "elem_som";
187
188 if (localisations.search(localisation_) < 0)
189 {
190 Cerr << "Error in "<<que_suis_je()<<finl;
191 Cerr << "Read keyword : " << localisation_ << "\n Allowed items are " << localisations << finl;
192 exit();
193 }
194}
196{
197
198 bool sources_location_ok = true;
199 int nb_source_fictive=0;
200 int nb_sources = get_nb_sources();
201 if (nb_sources==0)
202 {
203 nb_source_fictive = 1;
204 OWN_PTR(Champ_Generique_base)& new_src = sources_.add(OWN_PTR(Champ_Generique_base)());
205 Nom nom_probleme = ref_cast(Postraitement,post).probleme().le_nom();
206 const Objet_U& ob = interprete().objet(nom_probleme);
207 const Probleme_base& pb = ref_cast(Probleme_base,ob);
208 const Nom& nom_champ = pb.equation(0).inconnue().le_nom();
209 Entree s_bidon;
210 Nom ajout("");
211 ajout += " Champ_Post_refChamp { Pb_champ ";
212 ajout += pb.le_nom();
213 ajout += " ";
214 ajout += nom_champ;
215 ajout += " }";
216 Entree_complete s_complete(ajout,s_bidon);
217 s_complete>>new_src;
218 nb_sources = get_nb_sources();
219 }
220
222
223 if (nb_source_fictive==1)
224 {
225 if (get_nb_sources()>1)
226 {
227 assert( sources_.size( ) == 1 );
228 // on a rajoute une source pour rien ...
229 sources_.vide();
230 nb_source_fictive = 0;
231 }
232 }
233
234 nb_sources = get_nb_sources();
235
236 //On determine le nombre de composantes qui sera attribue
237 //a l espace de stockage rendu par ce champ de postraitement en
238 //recherchant la source qui possede le plus grand nombre de composantes
239
240 nb_comp_ = 1;
241 nature_ch = scalaire;
242
243 if (nb_source_fictive==0)
244 {
245 for (int i=0; i<nb_sources; i++)
246 {
247 OWN_PTR(Champ_base) source_espace_stockage_tmp;
248 const Champ_base& source = get_source(i).get_champ_without_evaluation(source_espace_stockage_tmp);
249
250 if ((Motcle(methode_) == "vecteur"))
251 {
252
253 if (source.is_vectorial())
254 {
255 Cerr<<que_suis_je()<<" The source fields must be of scalar nature for option vecteur."<<finl;
256 exit();
257 }
258 }
259 int nb_comp = source.nb_vect_comp();
261
262 if (source.is_vectorial())
263 nature_ch = vectoriel;
264 else if (source.nature_du_champ()==multi_scalaire)
265 nature_ch = multi_scalaire;
266 }
267 }
268 //Si aucun champ source n a ete specifie on en ajoute une
269 //pour donner acces au domaine discretise ...
270
271 Noms sources_location;
272
273 if( nb_source_fictive > 0 )
274 {
275 //special treatment when we have fictives sources
276 //the user needs to provide a location
277 if( localisation_ == "??" )
278 {
279 // On prend la localisation de l'inconnue
280
281
282 Cerr << "Error in Champ_Generique_Transformation::completer "<<finl;
283 Cerr << "No sources were specified. So you need to specify at least the location."<<finl;
284 Cerr << "Aborting..."<<finl;
285 Cerr << "ToDo for developer: guess location by taking the pb.equation(0).inconnue() localization." << finl;
287 }
288 else
289 {
290 fictive_source_ = true;
291 }
292 }
293 else
294 {
295
296 //real sources
297 for( int i=0; i<nb_sources; i++)
298 {
299 //loop over sources to check that all sources have the same location
300 bool use_directive = false;
301 OWN_PTR(Champ_base) my_field;
302
303 const Champ_base& source_i = get_source( i ).get_champ_without_evaluation( my_field );
304 if( source_i.a_un_domaine_dis_base( ) )
305 {
306 const Domaine_dis_base& domaine_source_i = source_i.domaine_dis_base( );
307 if( ! sub_type( Domaine_VF , domaine_source_i ) )
308 {
309 Cerr << "Warning in Champ_Generique_Transformation::completer "<<finl;
310 Cerr << "The source number "<<i<<" has a domaine_dis_base but not of type Domaine_VF so use directive to determine the location"<<finl;
311 use_directive=true;
312 }
313 if( ! use_directive )
314 {
315 const DoubleTab& values_source_i = source_i.valeurs( );
316 const Domaine_VF& zvf_source_i = ref_cast( Domaine_VF, domaine_source_i );
317
318
319 MD_Vector md;
320 md = values_source_i.get_md_vector( );
321
322 //composite case, in particular Champ_{P0,Face}_PolyMAC_HFV...
323 if (get_source(i).get_discretisation().is_poly_family() && sub_type( MD_Vector_composite, md.valeur( )))
324 {
325 const MD_Vector& md0 = ref_cast(MD_Vector_composite, md.valeur()).get_desc_part(0);
326 if (md0 == zvf_source_i.domaine( ).les_elems().get_md_vector( ))
327 sources_location.add( "elem" );
328 else if (md0 == zvf_source_i.face_sommets( ).get_md_vector( ))
329 sources_location.add("faces");
330 }
331 else if( ( sub_type( MD_Vector_composite, md.valeur( ) ) ) && (localisation_=="??"))
332 {
333 Cerr << "Error in Champ_Generique_Transformation::completer "<<finl;
334 Cerr << "The source number "<<i<<" is composite and the location was not provided. It is forbidden to apply a 'transformation' on a composite source without providing a location. "<<finl;
335 Cerr << "You must perform an interpolation before or specify a location."<<finl;
336 Cerr << "Aborting..."<<finl;
338 // if we want to deal with composite case we can do something like...
339 // MD_Vector_composite md_comp = ref_cast( MD_Vector_composite, values_source_i.get_md_vector( ).valeur( ) );
340 // nb_parts = md_comp.nb_parts( ); //to perform loop over parts and then get the considered part :
341 // md = md_comp.get_desc_part( part );
342 // when dealing with pression_pa it leads to have elem and som locations
343 }
344 else if ( md == zvf_source_i.face_sommets( ).get_md_vector( ) )
345 {
346 sources_location.add( "faces" );
347 }
348 else if( md == zvf_source_i.domaine( ).les_elems( ).get_md_vector( ) )
349 {
350 sources_location.add( "elem" );
351 }
352 else if( md == zvf_source_i.domaine( ).les_sommets( ).get_md_vector( ) )
353 {
354 sources_location.add( "som" );
355 }
356 else if( md == zvf_source_i.xa( ).get_md_vector( ) )
357 {
358 sources_location.add( "xa" );
359 }
360 else
361 {
362 Cerr << "Warning in Champ_Generique_Transformation::completer "<<finl;
363 Cerr << "Impossible to determine the localisation of the source number "<<i<<" using md_vectors so try using directive"<<finl;
364 use_directive = true;
365 }
366 // Cout << "sources location "<<i<<" : "<<sources_location( i )<<finl;
367 }//end of not using directive case
368 }//end of has domaine dis
369 else
370 {
371 //in the case where there is no domaine dis base, we look at the directive
372 use_directive=true;
373 }
374
375 if( use_directive )
376 {
377 Motcle directive = get_source( i ).get_directive_pour_discr( );
378 if (directive=="champ_elem")
379 sources_location.add( "elem" );
380 else if (directive=="champ_sommets")
381 sources_location.add( "som" );
382 else if (directive=="champ_face")
383 sources_location.add( "faces" );
384 else if (directive=="pression")
385 {
386 if (localisation_=="??")
387 {
388 Cerr << "Error in Champ_Generique_Transformation::completer"<<finl;
389 Cerr << "The directive associated to the source number "<<i<<" is pressure and the location was not provided.";
390 Cerr <<" It is forbidden to apply a 'transformation' on a composite source without providing a location. "<<finl;
391 Cerr << "You must perform an interpolation before or specify a location." <<finl;
392 Cerr << "Aborting..."<<finl;
394 }
395 sources_location.add( "unknown" );
396 }
397 else if ( directive == "champ_uniforme" )
398 sources_location.add( "elem" );
399 else if ( directive == "champ_don" )
400 sources_location.add( "elem" );
401 else
402 {
403 Cerr<<"Error in Champ_Generique_Transformation::completer"<<finl;
404 Cerr<<"The discretization of the first source of the generic field "<<nom_post_<<finl;
405 Cerr<<"does not correspond to any TRUST field discretization."<<finl;
406 Cerr<<directive<<finl;
407 Cerr<<"Aborting..."<<finl;
409 }
410 }
411 }//loop over sources
412 const int nb_locations = sources_location.size( );
413 if( nb_sources != nb_locations )
414 {
415 Cerr << "Error in Champ_Generique_Transformation::completer "<<finl;
416 Cerr << nb_sources<<" were detected but "<<nb_locations<<" were found"<<finl;
417 Cerr << "Aborting..."<<finl;
419 }
420 Nom reference_location = sources_location[0];
421 for(int i=1; i<nb_locations; i++)
422 {
423 if( sources_location[i] != reference_location )
424 {
425 sources_location_ok = false;
426 Cerr << "Warning in Champ_Generique_Transformation::completer "<<finl;
427 Cerr << "All sources have location : "<<finl;
428 Cerr <<sources_location;
429 Cerr <<"But the specified location is "<<localisation_<<finl;
430 //Cerr << "Aborting..."<<finl;
431 //Process::abort( );
432 }
433 }
434 } //end dealing with nb_source_fictive <= 0
435
436 if( localisation_ == "??" )
437 {
438 if( sources_location_ok )
439 {
440 Cerr <<"sources have same location : "<< sources_location[0]<<finl;
441 }
442 else
443 {
444 Cerr << "Warning sources have not the same location, taking "<<sources_location[0]<<" as location"<<finl;
445 }
446 localisation_ = sources_location[0] ;
447 }
448 else
449 {
450 if( ! fictive_source_ && localisation_ != sources_location[0] )
451 {
452 Cerr << "Warning first source is located to "<<sources_location[0]<<" but the user has specified "<< localisation_<<finl;
453 }
454 }
455
458
459 if (Motcle(methode_)=="formule")
460 {
461 // on redemande le nb_sources car on a ajoute des sources par completer
462 nb_sources = get_nb_sources();
463 fxyz.dimensionner(1);
464 fxyz[0].setNbVar(4+nb_sources);
465 fxyz[0].setString(les_fct[0]);
466 fxyz[0].addVar("x");
467 fxyz[0].addVar("y");
468 fxyz[0].addVar("z");
469 fxyz[0].addVar("t");
470 for (int i=0; i<nb_sources; i++)
471 {
472 const Noms nom = get_source(i).get_property("nom");
473 fxyz[0].addVar(nom[0]);
474 Journal()<<" Name of source "<<nom[0]<<finl;
475 }
476 fxyz[0].parseString();
477 }
478}
479
480
481void projette(DoubleTab& valeurs_espace,const DoubleTab& val_source,const Domaine_VF& zvf,const Motcle& loc,bool champ_normal_faces)
482{
483 const Nom& type_elem=zvf.domaine().type_elem()->que_suis_je();
484 if ((champ_normal_faces)||(loc!="elem")|| (type_elem!="Quadrangle"))
485 {
486 Cerr<<"option composante_normale not coded in this case"<<finl;
488 }
489 const DoubleTab& coord=zvf.domaine().coord_sommets();
490 const IntTab& elems=zvf.domaine().les_elems();
491
492 int nb_v= valeurs_espace.dimension(0);
493 assert(nb_v==zvf.nb_elem());
494 assert(val_source.dimension(1)==Objet_U::dimension);
495 ToDo_Kokkos("critical");
496 for (int i=0; i<nb_v; i++)
497 {
498 Vecteur3 v1,v2,normal,val;
499 int s0=elems(i,0);
500 int s1=elems(i,1);
501 int s2=elems(i,2);
502 if (Objet_U::dimension!=3)
503 {
504 Cerr<<"not implemented "<<finl;
505 assert(0);
507 }
508 v1.set(coord(s1,0)-coord(s0,0),coord(s1,1)-coord(s0,1),coord(s1,2)-coord(s0,2));
509 v2.set(coord(s2,0)-coord(s0,0),coord(s2,1)-coord(s0,1),coord(s2,2)-coord(s0,2));
510 val.set(val_source(i,0),val_source(i,1),val_source(i,2));
511
512 Vecteur3::produit_vectoriel(v1,v2,normal);
513 double norm=Vecteur3::produit_scalaire(normal,normal);
514 double inv=1./sqrt(norm);
515 normal*=inv;
516
517
518 double prod_scal= Vecteur3::produit_scalaire(normal,val);
519 valeurs_espace(i)=prod_scal;
520 }
521
522}
523//Construction de l espace de stockage rendu par ce champ de postraitement
524//-Caracterisation de l espace de stockage rendu par ce champ de postraitement (Typage ...)
525//-Construction du tableau positions qui contient les coordonnees des points de calcul (support)
526//-Interpolation des valeurs des sources sur le support retenu
527//-Evaluation des valeurs de l espace de stockage en fonction de la fonction (les_fct)
528
530{
531 if (!espace_stockage_)
532 creer_espace_stockage(nature_ch,nb_comp_,espace_stockage_);
533 else
534 espace_stockage_->changer_temps(get_source(0).get_time());
535 return espace_stockage_;
536}
538{
539 const Domaine_dis_base& domaine_dis = get_ref_domaine_dis_base();
540 if (!espace_stockage_)
541 creer_espace_stockage(nature_ch,nb_comp_,espace_stockage_);
542 else
543 espace_stockage_->changer_temps(get_source(0).get_time());
544 DoubleTab& valeurs_espace = espace_stockage_->valeurs();
545 const Domaine_VF& zvf = ref_cast(Domaine_VF,domaine_dis);
546 int nb_elem_tot = zvf.nb_elem_tot();
547 int nb_som_tot = get_ref_domain().nb_som_tot();
548 const Motcle directive = get_directive_pour_discr();
549 bool champ_normal_faces = 0;
550 if (get_source(0).get_discretisation().is_vdf() || get_source(0).get_discretisation().is_poly_family())
551 champ_normal_faces = 1;
552
553 //Construction du tableau positions qui contient les coordonnees
554 //des points (support) ou vont etre evaluees les valeurs de l espace
555 //de stockage
556 DoubleTrav positions;
557 if (localisation_ == "elem")
558 {
559 if (zvf.xp().nb_dim() != 2) /* xp() non initialise */
560 zvf.domaine().calculer_centres_gravite(positions);
561 else
562 zvf.get_position(positions);
563 }
564 else if (localisation_ == "som")
565 positions = get_ref_domain().coord_sommets();
566 else if (localisation_ == "faces")
567 positions = zvf.xv();
568 else if (localisation_ == "elem_som")
569 {
570 const DoubleTab& som = get_ref_domain().coord_sommets();
571 int dim = som.dimension(1);
572 positions = zvf.xp();
573 positions.resize(nb_elem_tot+nb_som_tot,dim);
574 ToDo_Kokkos("critical loop");
575 for (int i1=nb_elem_tot; i1<nb_elem_tot+nb_som_tot; i1++)
576 for (int i2=0; i2<dim; i2++)
577 positions(i1,i2) = som(i1-nb_elem_tot,i2);
578 }
579 else
580 {
581 Cerr<<"Problem in " <<que_suis_je()<<finl;
582 Cerr<<"Item "<<localisation_<<" is not recognized."<<finl;
583 exit();
584 }
585
586 //Interpolation des valeurs des sources sur le support retenu et stockage dans sources_val
587
588 int nb_sources = get_nb_sources();
589 int nb_pos = positions.dimension(0);
590 assert(nb_pos>0||(methode_=="formule")||(methode_=="composante_normale")||(methode_=="vecteur"));
591 using DoubleTravs = TRUST_Vector<DoubleTrav>; // remplace VECT(DoubleTrav)
592 const int max_nb_sources = 14;
593 if (nb_sources>max_nb_sources)
594 {
595 Cerr << "Increase max_nb_sources to " << nb_sources << " in Champ_base& Champ_Generique_Transformation::get_champ() !" << finl;
597 }
598 DoubleTravs sources_val(nb_sources);
599 IntTrav nb_comps(nb_sources);
600 Noms nom_source(nb_sources);
601 int dim_compo = 2*dimension;
602 Noms compo(dim_compo);
603 double temps;
604 temps = get_time();
605 int nb_compso = 0; // deplacement du parametre pour qu'il soit reconnu par l'ensemble des methodes en vue test (voir methode composante ci-dessous)
606 for (int so=0; so<nb_sources; so++)
607 {
608 const Champ_Generique_base& source = get_source(so);
609 OWN_PTR(Champ_base) stockage_so;
610 const Champ_base& source_so = source.get_champ(stockage_so);
611 const DoubleTab& source_so_val = source_so.valeurs();
612 const Motcle directive_so = source.get_directive_pour_discr();
613
614 //int nb_compso = source_so.nb_comp();
615 nb_compso = source_so.nb_comp();
616 nb_comps(so) = nb_compso;
617 const Noms nom_champ = source.get_property("nom");
618 nom_source[so] = nom_champ[0];
619 if ((Motcle(methode_)=="produit_scalaire") || (Motcle(methode_)=="norme"))
620 {
621 const Noms compo_ch = source.get_property("composantes");
622 for (int comp=0; comp<dimension; comp++)
623 compo[so*dimension+comp] = compo_ch[comp];
624 }
625
626 //Si VDF et traitement d un produit scalaire ou d une norme alors on interpole
627 //pour recuperer un tableau avec autant de composantes que la dimension du probleme
628 if (directive!=directive_so)
629 {
630 sources_val[so].resize(nb_pos,nb_compso);
631 if (directive == "CHAMP_FACE") source_so.valeur_aux_faces(sources_val[so]);
632 else if (directive == "CHAMP_ELEM" && nb_pos==domaine_dis.domaine().nb_elem()) source_so.valeur_aux_centres_de_gravite(domaine_dis.domaine(), sources_val[so]);
633 else if (directive == "CHAMP_FONC_QUAD_DG" and directive_so == "CHAMP_ELEM_DG")
634 {
635 int nelem = valeurs_espace.dimension(0);
636 int npoints = valeurs_espace.dimension(1);
637 if (methode_=="vecteur") npoints /= dimension; //TODO DG will be cleaner when quadrature is in Kernel
638 sources_val[so].resize(nelem,npoints);
639 if (!fictive_source_) source_so.eval_elem(sources_val[so]);
640 }
641 else source_so.valeur_aux(positions,sources_val[so]);
642 }
643 else
644 {
645 if (source_so_val.line_size()==1)
646 {
647 int nn=source_so_val.dimension_tot(0);
648 sources_val[so].resize(nn,1);
649 sources_val[so] = source_so_val;
650 }
651 else
652 sources_val[so] = source_so_val;
653 }
654
655 if ((nb_pos==0)&&(valeurs_espace.dimension_tot(0)!=0))
656 {
657 int nb_pos_tmp=valeurs_espace.dimension(0);
658 if (nb_pos_tmp > sources_val[so].size())
659 {
660 Cerr << "\nError in Champ_Generique_Transformation::get_champ" << finl;
661 Cerr << nom_source[so] << " : Wrong number of elements." << finl;
662 exit();
663 }
664 }
665 }
666 //Fin du remplissage de sources_val
667
668 //Calcul des valeurs de l espace de stockage en fonction de methode_ selectionne
669 if ((Motcle(methode_)=="produit_scalaire") || (Motcle(methode_)=="norme"))
670 {
671 ParserView parser(fxyz[0]);
672 parser.parseString();
673 int dim = dimension;
674 Kokkos::Array<CDoubleTabView, max_nb_sources> sources;
675 for (int so=0; so<nb_sources; so++)
676 sources[so] = sources_val[so].view_ro();
677 DoubleArrView valeurs = static_cast<ArrOfDouble&>(valeurs_espace).view_wo();
678 if (directive == "champ_fonc_quad_dg") //This is for DG
679 {
680 ToDo_Kokkos("Code but check test!");
681 int nb_elem = valeurs_espace.dimension(0);
682 IntTab nb_points, ind_integ_points;
683 zvf.get_ind_integ_points(ind_integ_points);
684 zvf.get_nb_integ_points(nb_points);
685 int nb_pts_integ_max = zvf.get_max_nb_integ_points();
686 CIntArrView ind_integ_points_w = static_cast<const ArrOfInt&>(ind_integ_points).view_ro();
687 CIntArrView nb_points_w = static_cast<const ArrOfInt&>(nb_points).view_ro();
688 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), nb_elem, KOKKOS_LAMBDA(const int i)
689 {
690 for (int pt=0; pt<nb_points_w(i); pt++)
691 {
692 int threadId = parser.acquire();
693 int k = ind_integ_points_w(i)+pt;
694 for (int so=0; so<nb_sources; so++)
695 for (int j=0; j<dim; j++)
696 parser.setVar(so*dim+j,sources[so](i,j*nb_pts_integ_max+pt), threadId);
697 valeurs(k) = parser.eval(threadId);
698 parser.release(threadId);
699 }
700 });
701 end_gpu_timer(__KERNEL_NAME__);
702 }
703 else
704 {
705 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), nb_pos, KOKKOS_LAMBDA(const int i)
706 {
707 int threadId = parser.acquire();
708 for (int so=0; so<nb_sources; so++)
709 for (int j=0; j<dim; j++)
710 parser.setVar(so*dim+j,sources[so](i,j), threadId);
711 valeurs(i) = parser.eval(threadId);
712 parser.release(threadId);
713 });
714 end_gpu_timer(__KERNEL_NAME__);
715 }
716 }
717 else if (Motcle(methode_)=="vecteur")
718 {
719 if ((champ_normal_faces) && (localisation_=="faces"))
720 {
721 assert(nb_comp_==dimension);
722 int dim = dimension;
723 ParserView fxyz0(fxyz[0]);
724 ParserView fxyz1(fxyz[1]);
725 ParserView fxyz2(fxyz[dim-1]); // Trick to support 2D/3D
726 fxyz0.parseString();
727 fxyz1.parseString();
728 if (dim==3) fxyz2.parseString();
729 Kokkos::Array<CDoubleTabView, max_nb_sources> sources;
730 for (int so=0; so<nb_sources; so++)
731 sources[so] = sources_val[so].view_ro();
732 CDoubleTabView face_normales = zvf.face_normales().view_ro();
733 CDoubleArrView surface = zvf.face_surfaces().view_ro();
734 CDoubleTabView pos = positions.view_ro();
735 //CIntArrView nb_comp_sources = static_cast<const ArrOfInt&>(nb_comps).view_ro();
736 DoubleArrView valeurs = static_cast<ArrOfDouble&>(valeurs_espace).view_wo();
737 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), nb_pos, KOKKOS_LAMBDA(const int i)
738 {
739 int threadId = fxyz0.acquire();
740 for (int j=0; j<dim; j++)
741 {
742 double pos_i_j = pos(i, j);
743 fxyz0.setVar(j, pos_i_j, threadId);
744 fxyz1.setVar(j, pos_i_j, threadId);
745 if (dim==3) fxyz2.setVar(j, pos_i_j, threadId);
746 }
747 fxyz0.setVar(3, temps, threadId);
748 fxyz1.setVar(3, temps, threadId);
749 if (dim==3) fxyz2.setVar(3, temps, threadId);
750 for (int so=0; so<nb_sources; so++)
751 {
752 double var = sources[so](i,0);
753 fxyz0.setVar(so+4,var, threadId);
754 fxyz1.setVar(so+4,var, threadId);
755 if (dim==3) fxyz2.setVar(so+4,var, threadId);
756 }
757 valeurs(i) = fxyz0.eval(threadId) * face_normales(i, 0) / surface(i);
758 valeurs(i) += fxyz1.eval(threadId) * face_normales(i, 1) / surface(i);
759 if (dim==3) valeurs(i) += fxyz2.eval(threadId) * face_normales(i, 2) / surface(i);
760 fxyz0.release(threadId);
761 });
762 end_gpu_timer(__KERNEL_NAME__);
763 }
764 else
765 {
766 if (directive=="champ_fonc_quad_dg") //This is for DG
767 {
768 ToDo_Kokkos("critical");
769 IntTab nb_points, ind_integ_points;
770 int nb_elem = valeurs_espace.dimension(0);
771 zvf.get_ind_integ_points(ind_integ_points);
772 zvf.get_nb_integ_points(nb_points);
773 int nb_pts_integ_max = zvf.get_max_nb_integ_points();
774
775 for (int i=0; i<nb_elem; i++)
776 {
777 for (int pt=0; pt<nb_points[i]; pt++)
778 {
779 int k = ind_integ_points[i]+pt;
780 double x = positions(k,0);
781 double y = positions(k,1);
782 double z = (dimension>2 ? positions(k,2) : 0);
783
784 for (int j=0; j<nb_comp_; j++)
785 {
786 fxyz[j].setVar(0,x);
787 fxyz[j].setVar(1,y);
788 fxyz[j].setVar(2,z);
789 fxyz[j].setVar(3,temps);
790 for (int so=0; so<nb_sources; so++)
791 {
792 const DoubleTab& source_so_val = sources_val[so];
793 fxyz[j].setVar(so+4,source_so_val(i,pt));
794 }
795 int l = nb_pts_integ_max*j + pt;
796 valeurs_espace(i,l) = fxyz[j].eval();
797 }
798 }
799 }
800 }
801 else
802 {
803 Kokkos::Array<CDoubleTabView, max_nb_sources> sources;
804 for (int so=0; so<nb_sources; so++)
805 sources[so] = sources_val[so].view_ro();
806 int dim = dimension;
807 CDoubleTabView pos = positions.view_ro();
808 DoubleTabView valeurs = valeurs_espace.view_wo();
809 for (int j=0; j<nb_comp_; j++)
810 {
811 ParserView fxyzj(fxyz[j]);
812 fxyzj.parseString();
813 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), nb_pos, KOKKOS_LAMBDA(const int i)
814 {
815 double x = pos(i,0);
816 double y = pos(i,1);
817 double z = (dim>2 ? pos(i,2) : 0);
818 int threadId = fxyzj.acquire();
819 fxyzj.setVar(0,x,threadId);
820 fxyzj.setVar(1,y,threadId);
821 fxyzj.setVar(2,z,threadId);
822 fxyzj.setVar(3,temps,threadId);
823 for (int so=0; so<nb_sources; so++)
824 fxyzj.setVar(so+4,sources[so](i,0),threadId);
825 valeurs(i,j) = fxyzj.eval(threadId);
826 fxyzj.release(threadId);
827 });
828 end_gpu_timer(__KERNEL_NAME__);
829 }
830 }
831 }
832 }
833 else if (Motcle(methode_)=="composante_normale")
834 {
835 const DoubleTab& source_so_val = sources_val[0];
836 projette(valeurs_espace,source_so_val,zvf,localisation_,champ_normal_faces);
837 }
838 else if (Motcle(methode_)=="composante")
839 {
840 int num_compo = les_fct.size()-1;
841 if ((num_compo<0)||(num_compo>=nb_compso))
842 {
843 Cerr<<"Component number must be >=0 and < "<<nb_compso<<" for composante option."<<finl;
844 exit();
845 }
846
847 CDoubleTabView source_so_val = sources_val[0].view_ro();
848 DoubleArrView v = static_cast<ArrOfDouble&>(valeurs_espace).view_wo();
849 if ((champ_normal_faces) && (localisation_=="faces"))
850 {
851 CDoubleTabView face_normales = zvf.face_normales().view_ro();
852 CDoubleArrView surface = zvf.face_surfaces().view_ro();
853 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), nb_pos, KOKKOS_LAMBDA(const int i)
854 {
855 v(i) = source_so_val(i, 0) * face_normales(i, num_compo) / surface(i);
856 });
857 end_gpu_timer(__KERNEL_NAME__);
858 }
859 else
860 {
861 if (directive=="champ_fonc_quad_dg") //This is for DG
862 {
863 ToDo_Kokkos("Code but check test!");
864 IntTab nb_points, ind_integ_points;
865 int nb_elem = valeurs_espace.dimension(0);
866 zvf.get_ind_integ_points(ind_integ_points);
867 zvf.get_nb_integ_points(nb_points);
868 int nb_pts_integ_max = zvf.get_max_nb_integ_points();
869 CIntArrView ind_integ_points_w = static_cast<const ArrOfInt&>(ind_integ_points).view_ro();
870 CIntArrView nb_points_w = static_cast<const ArrOfInt&>(nb_points).view_ro();
871
872 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), nb_elem, KOKKOS_LAMBDA(const int i)
873 {
874 for (int pt=0; pt<nb_points_w[i]; pt++)
875 {
876 int k = ind_integ_points_w[i]+pt;
877 v(k) = source_so_val(i, num_compo*nb_pts_integ_max+pt);
878 }
879 });
880 end_gpu_timer(__KERNEL_NAME__);
881 }
882 else
883 {
884 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), nb_pos, KOKKOS_LAMBDA(const int i)
885 {
886 v(i) = source_so_val(i, num_compo);
887 });
888 end_gpu_timer(__KERNEL_NAME__);
889 }
890 }
891 }
892 else if (Motcle(methode_)=="formule")
893 {
894 //Evaluation des valeurs de l espace de stockage en fonction de la fonction (les_fct)
895 ParserView parser(fxyz[0]);
896 parser.parseString();
897 int special=0;
898 if (nb_pos==0 && valeurs_espace.dimension_tot(0)!=0)
899 {
900 special = 1;
901 nb_pos = valeurs_espace.dimension(0);
902 }
903
904 if (directive == "champ_fonc_quad_dg") //This is for DG
905 {
906 ToDo_Kokkos("Code but check test!");
907 int dim = dimension;
908 int nb_elem = valeurs_espace.dimension(0);
909 Kokkos::Array<CDoubleTabView, max_nb_sources> sources;
910 for (int so=0; so<nb_sources; so++)
911 sources[so] = sources_val[so].view_ro();
912 IntTab nb_points, ind_integ_points;
913 zvf.get_ind_integ_points(ind_integ_points);
914 zvf.get_nb_integ_points(nb_points);
915 int nb_pts_integ_max = zvf.get_max_nb_integ_points();
916
917 CIntArrView ind_integ_points_w = static_cast<const ArrOfInt&>(ind_integ_points).view_ro();
918 CIntArrView nb_points_w = static_cast<const ArrOfInt&>(nb_points).view_ro();
919 CDoubleTabView pos = positions.view_ro();
920 DoubleTabView valeurs = valeurs_espace.view_wo();
921 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), nb_elem, KOKKOS_LAMBDA(const int i)
922 {
923 for (int pt=0; pt<nb_points_w(i); pt++)
924 {
925 int threadId = parser.acquire();
926 int k = ind_integ_points_w(i)+pt;
927 double x = special ? 1e38 : pos(k,0);
928 double y = special ? 1e38 : pos(k,1);
929 double z = special ? 1e38 : (dim>2 ? pos(k,2) : 0);
930 parser.setVar(0,x,threadId);
931 parser.setVar(1,y,threadId);
932 parser.setVar(2,z,threadId);
933 parser.setVar(3,temps,threadId);
934
935 for (int d = 0; d < nb_comp_; d++)
936 {
937 int j = nb_pts_integ_max*d + pt;
938 for (int so=0; so<nb_sources; so++)
939 parser.setVar(so+4,sources[so](i,j),threadId);
940 valeurs(i, j) = parser.eval(threadId);
941 }
942 }
943 });
944 end_gpu_timer(__KERNEL_NAME__);
945 }
946 else
947 {
948 int line_size = valeurs_espace.line_size();
949 int dim = dimension;
950 int nb_comp = nb_comp_;
951 Kokkos::Array<CDoubleTabView, max_nb_sources> sources;
952 for (int so=0; so<nb_sources; so++)
953 sources[so] = sources_val[so].view_ro();
954 CDoubleTabView pos = positions.view_ro();
955 CIntArrView nb_comp_sources = static_cast<const ArrOfInt&>(nb_comps).view_ro();
956 DoubleTabView valeurs = valeurs_espace.view_wo();
957 Kokkos::parallel_for(start_gpu_timer(__KERNEL_NAME__), nb_pos, KOKKOS_LAMBDA(const int i)
958 {
959 double x = special ? 1e38 : pos(i,0);
960 double y = special ? 1e38 : pos(i,1);
961 double z = special ? 1e38 : (dim>2 ? pos(i,2) : 0);
962 int threadId = parser.acquire();
963 parser.setVar(0,x,threadId);
964 parser.setVar(1,y,threadId);
965 parser.setVar(2,z,threadId);
966 parser.setVar(3,temps,threadId);
967 if (line_size == 1)
968 {
969 for (int so=0; so<nb_sources; so++)
970 parser.setVar(so+4,sources[so](i,0),threadId);
971 valeurs(i, 0) = parser.eval(threadId);
972 }
973 else // line_size > 1
974 {
975 for (int j=0; j<nb_comp; j++)
976 {
977 for (int so=0; so<nb_sources; so++)
978 {
979 int nbcomp_loc = nb_comp_sources(so);
980 if (nbcomp_loc == nb_comp)
981 parser.setVar(so+4,sources[so](i,j),threadId);
982 else if (nbcomp_loc == 1)
983 parser.setVar(so+4,sources[so](i,0),threadId);
984 else
985 Process::Kokkos_exit("The arrays of values don't have compatibles dimensions in Champ_Generique_Transformation::get_champ()");
986 }
987 valeurs(i,j) = parser.eval(threadId);
988 }
989 }
990 parser.release(threadId);
991 });
992 end_gpu_timer(__KERNEL_NAME__);
993 }
994 }
995 // PL: Suppression d'une synchronisation couteuse tres souvent inutile
996 // Voir Champ_Generique_Interpolation (localisation = som) pour le report de l'echange_espace_virtuel
997 // valeurs_espace.echange_espace_virtuel();
998 return espace_stockage_;
999}
1000
1001//Les localisations elem som faces peuvent etre retenues pour le postraitement
1002//La localisation elem_som sert uniquement pour l evaluation des valeurs de l espace
1003//de stockage mais ne peut pas etre retenue comme localisation de postraitement
1004
1006{
1007 Entity loc;
1008 if (localisation_=="elem")
1009 loc = Entity::ELEMENT;
1010 else if (localisation_=="som")
1011 loc = Entity::NODE;
1012 else if (localisation_=="faces")
1013 loc = Entity::FACE;
1014 else
1015 {
1016 Cerr << "Error of type : localisation should be specified to elem or som or faces for the defined field " << nom_post_ << finl;
1017 throw Champ_Generique_erreur("INVALID");
1018 }
1019 return loc;
1020}
1021
1023{
1024 Motcles motcles(2);
1025 motcles[0] = "composantes";
1026 motcles[1] = "unites";
1027 int rang = motcles.search(query);
1028 switch(rang)
1029 {
1030 case 0:
1031 {
1032 Noms compo(nb_comp_);
1033 for (int i=0; i<nb_comp_; i++)
1034 {
1035 Nom nume(i);
1036 compo[i] = nom_post_+nume;
1037 }
1038 return compo;
1039 }
1040 case 1:
1041 {
1042 Noms unites(nb_comp_);
1043 for (int comp=0; comp<nb_comp_; comp++)
1044 unites[comp] = unite_;
1045 return unites;
1046 }
1047 }
1049}
1050
1052{
1053 Motcle directive;
1054 if (localisation_=="elem")
1055 {
1056 OWN_PTR(Champ_base) source_espace_stockage;
1057 const Champ_base& source = get_source(0).get_champ_without_evaluation(source_espace_stockage);
1058 directive = (source.is_basis_function() || source.is_quadrature()) ? "champ_fonc_quad_dg" : "champ_elem";
1059 }
1060 else if (localisation_=="som")
1061 {
1062 directive = "champ_sommets";
1063 }
1064 else if (localisation_=="faces")
1065 {
1066 directive = "champ_face";
1067 }
1068 else if (localisation_=="elem_som")
1069 {
1070 directive = "pression";
1071 }
1072 else
1073 {
1074 Cerr<<"Localisation "<<localisation_<<" is not recognized by "<<que_suis_je()<<finl;
1075 exit();
1076 }
1077 return directive;
1078}
1079
1080//Nomme le champ en tant que source par defaut
1081//"Combinaison_"+"les_fct"
1083{
1084 if (nom_post_=="??")
1085 {
1086 Nom nom_post_source;
1087 nom_post_source = "Combinaison_";
1088
1089 // PDI doesn't understand mathematical symbol inside variable name, so we replace them
1090 std::string fonction = les_fct[0].getString();
1091 auto replace = [&](std::string oldS, std::string newS)
1092 {
1093 size_t start_pos = 0;
1094 while((start_pos = fonction.find(oldS, start_pos)) != std::string::npos)
1095 {
1096 fonction.replace(start_pos, oldS.length(), newS);
1097 start_pos += newS.length();
1098 }
1099 };
1100 replace("*", "x");
1101 replace("+", "PLUS");
1102 replace("-", "MINUS");
1103 replace("/", "DIV");
1104 replace("(", "_BEGINPAR_");
1105 replace(")", "_ENDPAR_");
1106 nom_post_source += fonction;
1107 nommer(nom_post_source);
1108 }
1109}
1110
1111//Renvoie le nombre de composantes a manipuler dans l expression
1112//Verifie la coherence des donnees pour la methode choisie
1114{
1115 int nb_sources = get_nb_sources();
1116 int nb_var = 0;
1117 int erreur = 0;
1118 Nom msg;
1119
1120 if ((Motcle(methode_)=="produit_scalaire") || (Motcle(methode_)=="norme"))
1121 {
1122 for (int i=0; i<nb_sources; i++)
1123 {
1124 OWN_PTR(Champ_base) source_espace_stockage;
1125 const Champ_base& source = get_source(i).get_champ(source_espace_stockage);
1126 int nb_comp = source.nb_comp();
1127 if (!source.is_vectorial() && source.nature_du_champ()!=multi_scalaire)
1128 {
1129 msg = "At least one of the source fields is not of vector nature.";
1130 erreur = 1;
1131 }
1132 nb_var += nb_comp;
1133 }
1134
1135 if ((Motcle(methode_)=="produit_scalaire") && (nb_sources!=2))
1136 {
1137 msg = "Exactly two vector source fields must be specified.";
1138 erreur = 1;
1139 }
1140 else if ((Motcle(methode_)=="norme") && (nb_sources!=1))
1141 {
1142 msg = "Exactly one vector source field must be specified.";
1143 erreur = 1;
1144 }
1145 // la suite est faite si on n a pas d'erreur
1146 if ( erreur==0 )
1147 {
1148 nb_comp_ = 1;
1149 nature_ch = scalaire;
1150 // L'appel a creer_expression_macro est fait si on a un vecteur car elle fait appel aux composantes !
1152 fxyz.dimensionner(1);
1153 fxyz[0].setNbVar(nb_var);
1154 fxyz[0].setString(les_fct[0]);
1155 for (int i=0; i<nb_sources; i++)
1156 {
1157 OWN_PTR(Champ_base) source_espace_stockage;
1158 const Champ_base& source = get_source(i).get_champ(source_espace_stockage);
1159 int nb_comp = source.nb_vect_comp();
1160 const Noms compo = get_source(i).get_property("composantes");
1161 for (int comp=0; comp<nb_comp; comp++)
1162 {
1163 fxyz[0].addVar(compo[comp]);
1164 Journal()<<" Source compo "<<compo[comp]<<finl;
1165 }
1166 }
1167 fxyz[0].parseString();
1168 }
1169 }
1170 else if (Motcle(methode_)=="vecteur")
1171 {
1172 nb_comp_ = les_fct.size();
1173 nature_ch = vectoriel;
1174 fxyz.dimensionner(nb_comp_);
1175
1176 for (int comp=0; comp<nb_comp_; comp++)
1177 {
1178 fxyz[comp].setNbVar(4+nb_sources);
1179 fxyz[comp].setString(les_fct[comp]);
1180 fxyz[comp].addVar("x");
1181 fxyz[comp].addVar("y");
1182 fxyz[comp].addVar("z");
1183 fxyz[comp].addVar("t");
1184 for (int i=0; i<nb_sources; i++)
1185 {
1186 const Noms nom = get_source(i).get_property("nom");
1187 fxyz[comp].addVar(nom[0]);
1188 Journal()<<" Name of source "<<nom[0]<<finl;
1189 }
1190 fxyz[comp].parseString();
1191 }
1192 }
1193 else if ((Motcle(methode_)=="composante")|| ((Motcle(methode_)=="composante_normale") ))
1194 {
1195 if (nb_sources!=1)
1196 {
1197 msg = "Exactly one vector source field must be specified.";
1198 erreur = 1;
1199 }
1200 // La suite est faite si on n'a pas d'erreur !!
1201 if (erreur==0) // 1 source pas la peine de faire une boucle
1202 {
1203 OWN_PTR(Champ_base) source_espace_stockage;
1204 const Champ_base& source = get_source(0).get_champ_without_evaluation(source_espace_stockage);
1205 if (source.nature_du_champ()!=vectoriel && source.nature_du_champ()!=multi_scalaire)
1206 {
1207 msg = "The source field is not of vector nature.";
1208 erreur = 1;
1209 }
1210 }
1211 nb_comp_ = 1;
1212 nature_ch = scalaire;
1213 }
1214 else if (Motcle(methode_)=="formule")
1215 nb_var = -1;
1216
1217 if ((nature_ch==scalaire) && (localisation_!="elem"))
1218 {
1219 if (get_source(0).get_discretisation().is_vdf())
1220 {
1221 msg = "The nature of the generated storing field will be scalar.\n";
1222 msg += "In that case the location elem is required since VDF discretization is considered.";
1223 erreur = 1;
1224 }
1225 }
1226
1227 if (erreur)
1228 {
1229 Cerr<<"Please check the syntax of the Transformation generic field "<<nom_post_<<finl;
1230 Cerr<<"for wich the selected option is : "<<methode_<<finl;
1231 Cerr<<msg<<finl;
1232 exit();
1233 }
1234 return nb_var;
1235}
1236
1237//Cree des expressions pour des operations specifiques :
1238//produit scalaire et norme
1240{
1241 if ((Motcle(methode_)=="produit_scalaire") || (Motcle(methode_)=="norme"))
1242 {
1243 const Noms compo0 = get_source(0).get_property("composantes");
1244
1245 if (Motcle(methode_)=="norme")
1246 {
1247 les_fct[0] = "sqrt(";
1248 les_fct[0] += compo0[0];
1249 les_fct[0] += "*";
1250 les_fct[0] += compo0[0];
1251 les_fct[0] += "+";
1252 les_fct[0] += compo0[1];
1253 les_fct[0] += "*";
1254 les_fct[0] += compo0[1];
1255 if (dimension==3)
1256 {
1257 les_fct[0] += "+";
1258 les_fct[0] += compo0[2];
1259 les_fct[0] += "*";
1260 les_fct[0] += compo0[2];
1261 }
1262 les_fct[0] +=")";
1263 }
1264
1265 if (Motcle(methode_)=="produit_scalaire")
1266 {
1267 const Noms compo1 = get_source(1).get_property("composantes");
1268 les_fct[0] = compo0[0];
1269 les_fct[0] += "*";
1270 les_fct[0] += compo1[0];
1271 les_fct[0] += "+";
1272 les_fct[0] += compo0[1];
1273 les_fct[0] += "*";
1274 les_fct[0] += compo1[1];
1275 if (dimension==3)
1276 {
1277 les_fct[0] += "+";
1278 les_fct[0] += compo0[2];
1279 les_fct[0] += "*";
1280 les_fct[0] += compo1[2];
1281 }
1282 }
1283 }
1284}
Classe de base des champs generiques ayant comme source d'autres champs generiques L'utilisation des ...
const Noms get_property(const Motcle &query) const override
Renvoie la propriete demandee.
void completer(const Postraitement_base &post) override
const Domaine & get_ref_domain() const override
Renvoie une ref au domaine sur lequel sera evalue l espace de stockage.
virtual const Champ_Generique_base & get_source(int i) const
void set_param(Param &param) const override
const Discretisation_base & get_discretisation() const override
Renvoie la discretisation associee au probleme.
const Domaine_dis_base & get_ref_domaine_dis_base() const override
Renvoie une ref au domaine_discretisee du domaine sur lequel sera evalue l espace de stockage.
double get_time() const override
Renvoie le temps du Champ_Generique_base.
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.
class Champ_Generique_Transformation
const Motcle get_directive_pour_discr() const override
Renvoie la directive (champ_elem, champ_sommets, champ_face ou pression) pour lancer la discretisatio...
const Champ_base & get_champ_without_evaluation(OWN_PTR(Champ_base)&espace_stockage) const override
const Noms get_property(const Motcle &query) const override
Renvoie la propriete demandee.
Entity get_localisation(const int index=-1) const override
Renvoie le type des entites geometriques sur auxquelles les valeurs discretes sont attachees (NODE po...
const Champ_base & get_champ(OWN_PTR(Champ_base)&espace_stockage) const override
void completer(const Postraitement_base &post) override
void set_param(Param &param) const override
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.
class Champ_Generique_base
virtual const Noms get_property(const Motcle &query) const
Renvoie la propriete demandee.
virtual const Domaine_dis_base & get_ref_domaine_dis_base() const
Renvoie une ref au domaine_discretisee du domaine sur lequel sera evalue l espace de stockage.
virtual const Champ_base & get_champ(OWN_PTR(Champ_base) &espace_stockage) const =0
virtual const Champ_base & get_champ_without_evaluation(OWN_PTR(Champ_base)&espace_stockage) const =0
void nommer(const Nom &nom) override
Donne un nom a l'Objet_U Methode virtuelle a surcharger.
virtual const Motcle get_directive_pour_discr() const
Renvoie la directive (champ_elem, champ_sommets, champ_face ou pression) pour lancer la discretisatio...
virtual DoubleTab & valeurs()=0
classe Champ_base Cette classe est la base de la hierarchie des champs.
Definition Champ_base.h:43
virtual int a_un_domaine_dis_base() const
Definition Champ_base.h:69
virtual const Domaine_dis_base & domaine_dis_base() const
virtual DoubleTab & eval_elem(DoubleTab &valeurs) const
virtual DoubleTab & valeur_aux(const DoubleTab &positions, DoubleTab &valeurs) const
Provoque une erreur ! Doit etre surchargee par les classes derivees.
virtual DoubleTab & valeur_aux_faces(DoubleTab &result) const
renvoie la valeur du champ aux faces
virtual DoubleTab & valeur_aux_centres_de_gravite(const Domaine &, DoubleTab &valeurs) const
Cette methode, generique mais lente (calcul des centres de gravite, remplissage les_poly,...
void calculer_centres_gravite(DoubleTab_t &xp) const
Calcule les centres de gravites des elements du domaine.
Definition Domaine.h:503
DoubleTab_t & les_sommets()
Definition Domaine.h:113
IntTab_t & les_elems()
Definition Domaine.h:129
int_t nb_elem() const
Definition Domaine.h:131
const DoubleTab_t & coord_sommets() const
Definition Domaine.h:112
int_t nb_som_tot() const
Renvoie le nombre total de sommets du domaine i.e. le nombre de sommets reels et virtuels sur le proc...
Definition Domaine.h:123
class Domaine_VF
Definition Domaine_VF.h:44
virtual const DoubleVect & face_surfaces() const
Definition Domaine_VF.h:51
virtual void get_ind_integ_points(IntTab &nelem) const
double xa(int num_arete, int k) const
Definition Domaine_VF.h:78
virtual double face_normales(int face, int comp) const
Definition Domaine_VF.h:47
double xv(int num_face, int k) const
Definition Domaine_VF.h:76
virtual int get_max_nb_integ_points() const
int face_sommets(int i, int j) const
renvoie le numero du ieme sommet de la face num_face.
Definition Domaine_VF.h:583
virtual void get_position(DoubleTab &positions) const
double xp(int num_elem, int k) const
Definition Domaine_VF.h:77
virtual void get_nb_integ_points(IntTab &nelem) const
classe Domaine_dis_base Cette classe est la base de la hierarchie des domaines discretisees.
int nb_elem_tot() const
const Domaine & domaine() const
Cette classe se comporte comme EChaine tant que l'on n'est pas a la fin de la chaine.
Class defining operators and methods for all reading operation in an input flow (file,...
Definition Entree.h:42
virtual const Champ_Inc_base & inconnue() const =0
const Nom & le_nom() const override
Renvoie le nom du champ.
virtual int nb_vect_comp() const
virtual int nb_comp() const
Definition Field_base.h:56
bool is_quadrature() const
Definition Field_base.h:81
bool is_vectorial() const
Definition Field_base.h:82
virtual Nature_du_champ nature_du_champ() const
Definition Field_base.h:77
bool is_basis_function() const
Definition Field_base.h:80
static Objet_U & objet(const Nom &)
Voir Interprete_bloc::objet_global() BM: la classe Interprete n'est pas le meilleur endroit pour cett...
Metadata for a distributed composite vector.
: Cette classe est un OWN_PTR mais l'objet pointe est partage entre plusieurs
Definition MD_Vector.h:48
const MD_Vector_base & valeur() const
Definition MD_Vector.h:77
Une chaine de caractere (Nom) en majuscules.
Definition Motcle.h:26
Un tableau d'objets de la classe Motcle.
Definition Motcle.h:63
int search(const Motcle &t) const
Definition Motcle.cpp:321
class Nom Une chaine de caractere pour nommer les objets de TRUST
Definition Nom.h:31
const Nom & le_nom() const override
Renvoie *this;.
Definition Nom.cpp:563
Un tableau de chaine de caracteres (VECT(Nom)).
Definition Noms.h:26
friend class Entree
Definition Objet_U.h:76
const Interprete & interprete() const
Definition Objet_U.cpp:212
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
Objet_U()
Constructeur par defaut : attribue un numero d'identifiant unique a l'objet (object_id_),...
Definition Objet_U.cpp:55
virtual const Nom & le_nom() const
Donne le nom de l'Objet_U Methode a surcharger : renvoie "neant" dans cette implementation.
Definition Objet_U.cpp:319
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
KOKKOS_INLINE_FUNCTION int acquire() const
Definition ParserView.h:77
KOKKOS_INLINE_FUNCTION void setVar(int i, double val, int threadId) const
Definition ParserView.h:64
void parseString() override
Definition ParserView.h:52
KOKKOS_INLINE_FUNCTION void release(int threadId) const
Definition ParserView.h:79
KOKKOS_INLINE_FUNCTION double eval(int threadId) const
Definition ParserView.h:69
Classe de base pour l'ensemble des postraitements.
classe Postraitement La classe est dotee -d une liste de champs generiques champs_post_complet_ qui c...
const Nom & le_nom() const override
Donne le nom de l'Objet_U Methode a surcharger : renvoie "neant" dans cette implementation.
Definition Probleme_U.h:109
classe Probleme_base C'est un Probleme_U qui n'est pas un couplage.
virtual const Equation_base & equation(int) const =0
static KOKKOS_INLINE_FUNCTION void Kokkos_exit(const char *)
Routine de sortie de TRUST dans une region Kokkos.
Definition Process.h:173
static Sortie & Journal(int message_level=0)
Renvoie un objet statique de type Sortie qui sert de journal d'evenements.
Definition Process.cpp:588
static void abort()
Routine de sortie de Trio-U sur une erreur abort().
Definition Process.cpp:570
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
std::enable_if_t< is_default_exec_space< EXEC_SPACE >, View< _TYPE_, _SHAPE_ > > view_wo()
Definition TRUSTTab.h:276
void resize(_SIZE_ n, RESIZE_OPTIONS opt=RESIZE_OPTIONS::COPY_INIT)
Definition TRUSTTab.tpp:469
_SIZE_ dimension_tot(int) const override
Definition TRUSTTab.tpp:160
std::enable_if_t< is_default_exec_space< EXEC_SPACE >, ConstView< _TYPE_, _SHAPE_ > > view_ro() const
Definition TRUSTTab.h:261
_SIZE_ dimension(int d) const
Definition TRUSTTab.tpp:133
int line_size() const
Definition TRUSTVect.tpp:67
virtual const MD_Vector & get_md_vector() const
Definition TRUSTVect.h:123
classe TRUST_Vector
static double produit_scalaire(const Vecteur3 &x, const Vecteur3 &y)
static void produit_vectoriel(const Vecteur3 &x, const Vecteur3 &y, Vecteur3 &resu)
void set(double x, double y, double z)
Definition Vecteur3.h:36