TrioCFD 1.9.9_beta
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 of transformation to perform
58// possible methods :
59// formule : function of generic source fields, x, y, z and t
60// vecteur : construction of a vector from the provided data
61// produit_scalaire : dot product of two specified vectors
62// norme : norm of a specified vector
63// composante : creation of a scalar field from a component of a vector field
64//-expression : expression of the transformation (for the formule and vecteur methods)
65//-numero : number of the component to extract (only for the composante method)
66//-localisation : localization of the storage field
67//-unite : to specify the unit of a field to improve the readability of post-processings
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 component number: we cannot rely on the space dimension in the case of a multi_scalaire field
115 Problem: it is nb_comp_ that will subsequently carry the component dimension and it is initialized to 1 here to avoid a bug
116 The test is moved to 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 // We try to set the number of components immediately with vecteur
163 nb_comp_ = les_fct.size();
164
165 // the verification of sources is done during completer for reference sources
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 // a source was added unnecessarily ...
229 sources_.vide();
230 nb_source_fictive = 0;
231 }
232 }
233
234 nb_sources = get_nb_sources();
235
236 //Determine the number of components to be assigned
237 //to the storage space returned by this post-processing field by
238 //searching for the source that has the largest number of components
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 //If no source field was specified, we add one
269 //to provide access to the discretized domain ...
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 // Take the localization of the unknown
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 // we re-query nb_sources because sources may have been added by 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 of the storage space returned by this post-processing field
524//-Characterization of the storage space returned by this post-processing field (typing ...)
525//-Construction of the positions array containing the coordinates of the computation points (support)
526//-Interpolation of source values on the retained support
527//-Evaluation of the storage space values as a function of (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 of the positions array containing the coordinates
554 //of the points (support) where the values of the storage
555 //space will be evaluated
556 DoubleTrav positions;
557 if (localisation_ == "elem")
558 {
559 if (zvf.xp().nb_dim() != 2) /* xp() not initialized */
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 of source values on the retained support and storage in 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; // parameter offset so that it is recognized by all methods under test (see the composante method below)
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 //If VDF and processing a dot product or a norm, then interpolate
627 //to retrieve an array with as many components as the problem dimension
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 //End of filling sources_val
667
668 //Computation of storage space values according to the selected methode_
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 of the storage space values as a function of (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: Removal of a costly synchronization that is very often unnecessary
996 // See Champ_Generique_Interpolation (localization = som) for the deferred echange_espace_virtuel
997 // valeurs_espace.echange_espace_virtuel();
998 return espace_stockage_;
999}
1000
1001//The elem, som and faces localizations can be retained for post-processing
1002//The elem_som localization is used only for evaluating the values of the storage space
1003//but cannot be retained as a post-processing localization
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//Names the field as default source
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//Returns the number of components to manipulate in the expression
1112//Verifies the consistency of the data for the chosen method
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 // the rest is done if there is no error
1146 if ( erreur==0 )
1147 {
1148 nb_comp_ = 1;
1149 nature_ch = scalaire;
1150 // The call to creer_expression_macro is done if we have a vector because it uses the components!
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 // The rest is done if there is no error !!
1201 if (erreur==0) // 1 source, no need to loop
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//Creates expressions for specific operations:
1238//dot product and norm
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}
Base class of generic fields having other generic fields as source. The use of the class methods reli...
const Noms get_property(const Motcle &query) const override
Returns the requested property.
void completer(const Postraitement_base &post) override
const Domaine & get_ref_domain() const override
Returns a ref to the domain on which the storage space will be evaluated.
virtual const Champ_Generique_base & get_source(int i) const
void set_param(Param &param) const override
const Discretisation_base & get_discretisation() const override
Returns the discretization associated with the problem.
const Domaine_dis_base & get_ref_domaine_dis_base() const override
Returns a ref to the discretized domain on which the storage space will be evaluated.
double get_time() const override
Returns the time of the Champ_Generique_base.
int lire_motcle_non_standard(const Motcle &, Entree &) override
Reads non-simple-type parameters of an Objet_U from an input stream.
class Champ_Generique_Transformation
const Motcle get_directive_pour_discr() const override
Returns the directive (champ_elem, champ_sommets, champ_face or pression) to launch the discretizatio...
const Champ_base & get_champ_without_evaluation(OWN_PTR(Champ_base)&espace_stockage) const override
const Noms get_property(const Motcle &query) const override
Returns the requested property.
Entity get_localisation(const int index=-1) const override
Returns the type of geometric entities on which the discrete values are attached (NODE for a P1 field...
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
Reads non-simple-type parameters of an Objet_U from an input stream.
class Champ_Generique_base
virtual const Noms get_property(const Motcle &query) const
Returns the requested property.
virtual const Domaine_dis_base & get_ref_domaine_dis_base() const
Returns a ref to the discretized domain on which the storage space will be evaluated.
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
Assigns a name to the Objet_U. Virtual method to override.
virtual const Motcle get_directive_pour_discr() const
Returns the directive (champ_elem, champ_sommets, champ_face or pression) to launch the discretizatio...
virtual DoubleTab & valeurs()=0
class Champ_base This class is the base of the fields hierarchy.
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
Causes an error! Must be overridden by derived classes.
virtual DoubleTab & valeur_aux_faces(DoubleTab &result) const
Returns the field value at the faces.
virtual DoubleTab & valeur_aux_centres_de_gravite(const Domaine &, DoubleTab &valeurs) const
This method, generic but slow (calculation of gravity centers, filling les_poly, use of shape functio...
void calculer_centres_gravite(DoubleTab_t &xp) const
Calculates the centers of gravity of the domain elements.
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
Returns the total number of vertices of the domain i.e. the number of real and virtual vertices on th...
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
Returns the index of the i-th vertex of face num_face.
Definition Domaine_VF.h:582
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
class Domaine_dis_base This class is the base of the hierarchy of discretized domains.
int nb_elem_tot() const
const Domaine & domaine() const
This class behaves like EChaine until the end of the string is reached.
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
Returns the name of the field.
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 &)
See Interprete_bloc::objet_global(). BM: the Interprete class is not the best place for this.
Metadata for a distributed composite vector.
: This class is an OWN_PTR but the pointed object is shared among multiple
Definition MD_Vector.h:48
const MD_Vector_base & valeur() const
Definition MD_Vector.h:77
A character string (Nom) in uppercase.
Definition Motcle.h:26
An array of Motcle objects.
Definition Motcle.h:63
int search(const Motcle &t) const
Definition Motcle.cpp:319
class Nom: a character string for naming TRUST objects.
Definition Nom.h:31
const Nom & le_nom() const override
Returns *this.
Definition Nom.cpp:555
An array of character strings (VECT(Nom)).
Definition Noms.h:26
friend class Entree
Definition Objet_U.h:71
const Interprete & interprete() const
Definition Objet_U.cpp:211
static int dimension
Definition Objet_U.h:94
const Nom & que_suis_je() const
Returns the string identifying the class.
Definition Objet_U.cpp:104
virtual Entree & readOn(Entree &)
Reads an Objet_U from an input stream. Virtual method to override.
Definition Objet_U.cpp:289
Objet_U()
Default constructor: assigns a unique identifier to the object (object_id_) and registers the object ...
Definition Objet_U.cpp:54
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
@ 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
Base class for all post-processing objects.
class Postraitement. The class holds -a list of generic fields champs_post_complet_ containing
const Nom & le_nom() const override
Returns the name of the Objet_U. Virtual method to override: returns "neant" in this implementation.
Definition Probleme_U.h:109
class Probleme_base It is a Probleme_U that is not a coupling.
virtual const Equation_base & equation(int) const =0
static KOKKOS_INLINE_FUNCTION void Kokkos_exit(const char *)
Exit routine for TRUST within a Kokkos region.
Definition Process.h:172
static Sortie & Journal(int message_level=0)
Returns a static Sortie object used as an event journal.
Definition Process.cpp:592
static void abort()
Abort routine for TRUST on a fatal error.
Definition Process.cpp:573
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
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
TRUST_Vector class.
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