1 // Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License.
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 // See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
22 // File : CalculatorEngine.cxx
23 // Author : Laurent DADA, CEA
24 // Module : CalculatorComponent
32 #include "CalculatorEngine.hxx"
33 #include "MEDMEM_Support_i.hxx"
34 #include "SUPPORTClient.hxx"
36 #include "MEDMEM_define.hxx"
37 #include "MEDMEM_STRING.hxx"
38 #include "MEDMEM_Exception.hxx"
39 #include "MEDMEM_Unit.hxx"
43 #include "utilities.h"
45 using namespace MEDMEM;
48 #ifndef MED_TAILLE_PNOM
49 #define MED_TAILLE_PNOM MED_TAILLE_PNOM21
52 typedef FIELD<double,MEDMEM::FullInterlace> TFieldDouble;
53 typedef FIELDTEMPLATE_I<double,MEDMEM::FullInterlace> TFieldDouble_i;
55 //================================================================================
56 // static PrintFieldValues - shows field contents
57 //================================================================================
59 static void PrintFieldValues (TFieldDouble * field, int until_index)
61 const double * values = field -> getValue();
62 int nb_comp = field -> getNumberOfComponents();
63 MESSAGE( "Field : " << field -> getName() );
64 MESSAGE( " Description : " << field -> getDescription() );
65 MESSAGE( " Number of components : " << nb_comp );
67 for (int i=0 ; i<nb_comp ; i++) {
68 MESSAGE ( " Component " << field -> getComponentName(i+1) << endl \
69 << " Unit : " << field -> getMEDComponentUnit(i+1) << endl \
70 << " Description : " << field -> getComponentDescription(i+1) );
72 MESSAGE( " First " << until_index << " values : " );
74 for (int j=0 ; j < until_index ; j++) {
75 for (int i=0;i<nb_comp;i++) MESSAGE( values[i+j*nb_comp] << " " );
80 //================================================================================
82 //================================================================================
84 CalculatorEngine::CalculatorEngine(CORBA::ORB_ptr orb,
85 PortableServer::POA_ptr poa,
86 PortableServer::ObjectId * contId,
87 const char *instanceName,
88 const char *interfaceName) :
89 Engines_Component_i(orb, poa, contId, instanceName, interfaceName,true)
91 MESSAGE("CalculatorEngine::CalculatorEngine activate object instanceName("
92 << instanceName << ") interfaceName(" << interfaceName << ")" )
94 _id = _poa->activate_object(_thisObj);
95 SALOME_NamingService *NS = new SALOME_NamingService(orb);
99 CalculatorEngine::CalculatorEngine()
103 //================================================================================
105 //================================================================================
107 CalculatorEngine::~CalculatorEngine()
111 static omni_mutex aPutToStudyMutex;
112 SALOME_MED::FIELDDOUBLE_ptr CalculatorEngine::PutToStudy(SALOME_MED::FIELDDOUBLE_ptr theField1,
113 long int theStudyId) {
114 omni_mutex_lock aLock(aPutToStudyMutex);
116 CORBA::Object_var anObj = _NS->Resolve("/myStudyManager");
117 SALOMEDS::StudyManager_var aManager = SALOMEDS::StudyManager::_narrow(anObj);
118 // SALOMEDS::ListOfOpenStudies_var aList = aManager->GetOpenStudies();
119 // SALOMEDS::Study_var aStudy = aManager->GetStudyByName(aList[0]);
120 SALOMEDS::Study_var aStudy = aManager->GetStudyByID(theStudyId);
121 SALOMEDS::StudyBuilder_var aBuilder = aStudy->NewBuilder();
123 SALOMEDS::SComponent_var aComponent = aStudy->FindComponent("Calculator");
124 if (aComponent->_is_nil()) aComponent = aBuilder->NewComponent("Calculator");
125 SALOMEDS::GenericAttribute_var anAttr = aBuilder->FindOrCreateAttribute(aComponent, "AttributeName");
126 SALOMEDS::AttributeName_var aName = SALOMEDS::AttributeName::_narrow(anAttr);
127 aName->SetValue("Calculator");
129 SALOMEDS::SObject_var aSO = aBuilder->NewObject(aComponent);
130 anAttr = aBuilder->FindOrCreateAttribute(aSO, "AttributeName");
131 aName = SALOMEDS::AttributeName::_narrow(anAttr);
133 sprintf(aFieldName, "Field_%d", (int)aSO->Tag());
134 aName->SetValue(strdup(aFieldName));
136 ORB_INIT &init = *SINGLETON_<ORB_INIT>::Instance() ;
137 ASSERT(SINGLETON_<ORB_INIT>::IsAlreadyExisting()) ;
138 CORBA::ORB_var &orb = init(0,0);
140 string iorStr = orb->object_to_string(theField1);
141 anAttr = aBuilder->FindOrCreateAttribute(aSO, "AttributeIOR");
142 SALOMEDS::AttributeIOR_var anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
143 anIOR->SetValue(iorStr.c_str());
145 return SALOME_MED::FIELDDOUBLE::_duplicate(theField1);
149 //=======================================================================================
150 // Addition of 2 FieldNodeDouble (based on Med library)
154 // - number of components
155 // - name, type, unit and description of components
156 // are the same for the 2 fields.
159 // the result will be a copy of the first field.
161 //=======================================================================================
163 static omni_mutex anAddMutex;
164 SALOME_MED::FIELDDOUBLE_ptr CalculatorEngine::Add(SALOME_MED::FIELDDOUBLE_ptr FirstField,
165 SALOME_MED::FIELDDOUBLE_ptr SecondField)
167 omni_mutex_lock aLock(anAddMutex);
170 bool same_support = true;
172 beginService("CalculatorEngine::Add");
174 sendMessage(NOTIF_TRACE, "CalculatorEngine::Add is Computing");
176 BEGIN_OF("CalculatorEngine::Add(SALOME_MED::FIELDDOUBLE_ptr FirstField,SALOME_MED::FIELDDOUBLE_ptr SecondField)");
181 string message = string("\n CalculatorEngine::Add : ") +
182 string("\n first field name --> ") + FirstField -> getName() +
183 string("\n second field name --> ") + SecondField -> getName();
185 sendMessage(NOTIF_TRACE, message.c_str());
187 // Number of components
188 int nb_comp1 = FirstField -> getNumberOfComponents();
189 int nb_comp2 = SecondField -> getNumberOfComponents();
190 if (nb_comp1 != nb_comp2) same_support = false;
191 MESSAGE( " nb_comp1 --> " << nb_comp1 <<endl );
192 MESSAGE( " nb_comp2 --> " << nb_comp2 <<endl );
195 /* Name Description and Unit of each component of the field */
197 string * component_name = new string[nb_comp1];
198 string * component_unit = new string[nb_comp1];
200 for (int i=0 ; i<nb_comp1 ; i++) {
201 component_name[i].assign(FirstField -> getComponentName(i+1));
202 component_unit[i].assign(FirstField -> getComponentUnit(i+1));
206 (component_name[i] != SecondField -> getComponentName(i+1)) ||
207 (component_unit[i] != SecondField -> getComponentUnit(i+1)))
208 same_support = false;
212 MESSAGE("CalculatorEngine::Add Number of entities in the Support of each fields");
214 // Number of entities in the Support of the field
218 SALOME_MED::SUPPORT_ptr support1 = FirstField -> getSupport();
219 SALOME_MED::SUPPORT_ptr support2 = SecondField -> getSupport();
225 SALOME_MED::MESH_ptr mesh1 = support1 -> getMesh();
226 SALOME_MED::MESH_ptr mesh2 = support2 -> getMesh();
231 if (same_support && support1 != support2) same_support = false;
233 if (support1 -> isOnAllElements())
234 len_value1 = support1 -> getMesh() -> getNumberOfElements(support1 -> getEntity(),SALOME_MED::MED_ALL_ELEMENTS);
236 len_value1 = support1 -> getNumberOfElements(SALOME_MED::MED_ALL_ELEMENTS);
240 if (support2 -> isOnAllElements())
241 len_value2 = support2 -> getMesh() -> getNumberOfElements(support2 -> getEntity(),SALOME_MED::MED_ALL_ELEMENTS);
243 len_value2 = support2 -> getNumberOfElements(SALOME_MED::MED_ALL_ELEMENTS);
245 if (same_support && len_value1 != len_value2) same_support = false;
249 // Values of new field
250 SALOME_MED::double_array * first_value = FirstField -> getValue(SALOME_MED::MED_FULL_INTERLACE);
251 SALOME_MED::double_array * second_value;
253 second_value = SecondField -> getValue(SALOME_MED::MED_FULL_INTERLACE);
254 tmp << "\n CalculatorEngine::Add : " ;
255 tmp << "\n Number of entities in the Support of first field = " << len_value1 ;
256 tmp << "\n Number of entities in the Support of second field = " << len_value2 ;
259 sendMessage(NOTIF_TRACE, message.c_str());
263 int totalLength = nb_comp1*len_value1;
264 double * new_value = new double[totalLength];
267 sendMessage(NOTIF_TRACE, "CalculatorEngine::Add - field1 and field2 have the same support");
269 for(int i=0 ; i<totalLength ; i++)
270 new_value[i] = ((*first_value)[i]) + ((*second_value)[i]);
273 for(int i=0 ; i<totalLength ; i++)
274 new_value[i] = ((*first_value)[i]) ;
277 // Creation of a Local Field
279 MESSAGE("CalculatorEngine::Add Creation of the local field "<< totalLength);
281 TFieldDouble * fieldloc = new TFieldDouble();
282 fieldloc -> allocValue(nb_comp1,len_value1);
283 fieldloc -> setValue(new_value);
284 fieldloc -> setName("-new_Add-");
285 fieldloc -> setDescription( FirstField -> getDescription() );
286 fieldloc -> setComponentsNames(component_name);
287 fieldloc -> setMEDComponentsUnits(component_unit);
290 int until_index = ( 20 > len_value1)? len_value1 : 20;
291 PrintFieldValues (fieldloc,until_index);
293 sendMessage(NOTIF_TRACE, "CalculatorEngine::Add - new field created");
296 // Creation of the new CORBA field
298 MESSAGE("CalculatorEngine::Add Creation of the CORBA field");
300 SUPPORT *support1Clt=new SUPPORTClient(support1);
301 fieldloc->setSupport(support1Clt);
302 TFieldDouble_i * NewField = new TFieldDouble_i(fieldloc) ;
303 SALOME_MED::FIELDDOUBLE_ptr myFieldIOR = NewField->_this() ;
307 END_OF("CalculatorEngine::Add(SALOME_MED::FIELDDOUBLE_ptr FirstField,SALOME_MED::FIELDDOUBLE_ptr SecondField)");
309 endService("CalculatorEngine::Add");
315 //===============================================================================
316 // Multiplication of a FieldNodeDouble by a double value (based on Med library)
317 //===============================================================================
319 static omni_mutex aMulMutex;
320 SALOME_MED::FIELDDOUBLE_ptr CalculatorEngine::Mul(SALOME_MED::FIELDDOUBLE_ptr OldField,
323 omni_mutex_lock aLock(aMulMutex);
325 beginService("CalculatorEngine::Mul");
326 BEGIN_OF("CalculatorEngine::Mul(SALOME_MED::FIELDDOUBLE_ptr OldField,CORBA::Double x1)");
331 // Name and description of field
332 string field_name = OldField -> getName();
333 string field_description = OldField -> getDescription();
335 // Number of components
336 int nb_comp = OldField -> getNumberOfComponents();
337 string * component_name = new string[nb_comp];
338 string * component_unit = new string[nb_comp];
340 for (int i=0 ; i<nb_comp ; i++) {
341 component_name[i] = OldField -> getComponentName(i+1);
342 component_unit[i] = OldField -> getComponentUnit(i+1);
345 MESSAGE("CalculatorEngine::Mul Number of entities in the Support of the field");
347 // Number of entities in the Support of the field
350 SALOME_MED::SUPPORT_ptr support = OldField -> getSupport();
354 SALOME_MED::MESH_ptr mesh = support -> getMesh();
358 if (support -> isOnAllElements())
359 len_value = support -> getMesh() -> getNumberOfElements(support -> getEntity(),SALOME_MED::MED_ALL_ELEMENTS);
361 len_value = support -> getNumberOfElements(SALOME_MED::MED_ALL_ELEMENTS);
365 // Values of new field
366 SALOME_MED::double_array * old_value = OldField -> getValue(SALOME_MED::MED_FULL_INTERLACE);
368 int totalLength = nb_comp*len_value;
369 double * new_value = new double[totalLength];
370 for(int i=0 ; i<totalLength ; i++) {
371 new_value[i] = x1 * ((*old_value)[i]);
374 // Creation of a Local Field
376 MESSAGE("CalculatorEngine::Mul Creation of the local field "<< totalLength);
378 TFieldDouble * fieldloc = new TFieldDouble();
379 fieldloc -> allocValue(nb_comp,len_value);
380 fieldloc -> setValue(new_value);
381 fieldloc -> setName("-new_Mul-");
382 fieldloc -> setDescription(field_description);
383 fieldloc -> setComponentsNames(component_name);
384 fieldloc -> setMEDComponentsUnits(component_unit);
387 // Creation of the new CORBA field
389 MESSAGE("CalculatorEngine::Mul Creation of the CORBA field");
391 SUPPORT *supportClt=new SUPPORTClient(support);
392 fieldloc->setSupport(supportClt);
393 TFieldDouble_i * NewField = new TFieldDouble_i(fieldloc) ;
394 SALOME_MED::FIELDDOUBLE_ptr myFieldIOR = NewField->_this() ;
398 END_OF("CalculatorEngine::Mul(SALOME_MED::FIELDDOUBLE_ptr OldField,CORBA::Double x1)");
400 endService("CalculatorEngine::Mul");
405 //================================================================================
406 // Build a constant field of double based on first field support (Med library)
407 //================================================================================
409 static omni_mutex aConstantMutex;
410 SALOME_MED::FIELDDOUBLE_ptr CalculatorEngine::Constant(SALOME_MED::FIELDDOUBLE_ptr FirstField,
413 omni_mutex_lock aLock(aConstantMutex);
415 beginService("CalculatorEngine::Const");
416 BEGIN_OF("CalculatorEngine::Constant(SALOME_MED::FIELDDOUBLE_ptr FirstField,CORBA::Double x1)");
418 // Name and description of field
419 string field_name = FirstField -> getName();
420 string field_description = FirstField -> getDescription();
422 SALOME_MED::SUPPORT_ptr FirstSupport = FirstField -> getSupport();
424 // Number of components
425 int nb_comp = FirstField -> getNumberOfComponents();
427 // Type, name, unit and description of components
428 string * component_name = new string[nb_comp];
429 string * component_unit = new string[nb_comp];
431 for (int i = 0 ; i<nb_comp ; i++) {
432 component_name[i] = FirstField -> getComponentName(i+1);
433 component_unit[i] = FirstField -> getComponentUnit(i+1);
436 MESSAGE("CalculatorEngine::Constant Number of entities in the Support of the field");
438 // Number of entities in the Support of the field
441 SCRUTE(FirstSupport);
443 SALOME_MED::MESH_ptr mesh = FirstSupport -> getMesh();
447 if ( FirstSupport -> isOnAllElements() )
448 len_value = FirstSupport -> getMesh() -> getNumberOfElements(FirstSupport -> getEntity(),SALOME_MED::MED_ALL_ELEMENTS);
450 len_value = FirstSupport -> getNumberOfElements(SALOME_MED::MED_ALL_ELEMENTS);
452 // Values of new field
453 int totalLength = nb_comp*len_value;
454 double * new_value = new double[totalLength];
456 for(int i=0 ; i<totalLength ; i++)
460 // Creation of a Local Field
462 MESSAGE("CalculatorEngine::Constant Creation of the local field "<< totalLength);
464 TFieldDouble * fieldloc = new TFieldDouble();
465 fieldloc -> allocValue(nb_comp,len_value);
466 fieldloc -> setValue(new_value);
467 fieldloc -> setName("-new_Const_Field-");
468 fieldloc -> setDescription(field_description);
469 fieldloc -> setComponentsNames(component_name);
470 fieldloc -> setMEDComponentsUnits(component_unit);
473 int until_index = ( 20 > len_value)? len_value : 20 ;
474 PrintFieldValues (fieldloc,until_index);
476 // Creation of the new CORBA field
478 MESSAGE("CalculatorEngine::Constant Creation of the CORBA field");
480 SUPPORT *supportClt=new SUPPORTClient(FirstSupport);
481 fieldloc->setSupport(supportClt);
482 TFieldDouble_i * NewField = new TFieldDouble_i(fieldloc) ;
484 SALOME_MED::FIELDDOUBLE_ptr myFieldIOR = NewField->_this() ;
488 endService("CalculatorEngine::Const");
490 END_OF("CalculatorEngine::Constant(SALOME_MED::FIELDDOUBLE_ptr FirstField,CORBA::Double x1)");
496 //================================================================================
497 // write a field in a MED file
498 //================================================================================
500 static omni_mutex aWriteMEDfileMutex;
501 void CalculatorEngine::writeMEDfile(SALOME_MED::FIELDDOUBLE_ptr field, const char *filename)
503 omni_mutex_lock aLock(aWriteMEDfileMutex);
505 beginService("CalculatorEngine::writeMEDfile");
506 MESSAGE("fichier d'impression du champ resultat:"<<filename);
508 // get support of the field
510 SALOME_MED::SUPPORT_ptr support = field -> getSupport();
512 // get mesh from this support
514 SALOME_MED::MESH_ptr mesh = support -> getMesh();
518 int index_m = mesh->addDriver(SALOME_MED::MED_DRIVER,filename,mesh->getName());
520 mesh -> write(index_m,"");
524 const char * LOC = "CalculatorEngine::writeMEDfile ";
526 MESSAGE("fichier :"<<filename);
528 med_2_1::med_idt _medIdt = med_2_1::MEDouvrir(const_cast <char *> (filename) , med_2_1::MED_ECRI);
531 if (_medIdt<0) return;
535 int component_count= field->getNumberOfComponents();
536 string component_name(component_count*MED_TAILLE_PNOM,' ') ;
537 string component_unit(component_count*MED_TAILLE_PNOM,' ') ;
539 for (int i=0; i < component_count ; i++) {
540 component_name.replace(i*MED_TAILLE_PNOM,MED_TAILLE_PNOM,(field -> getComponentName(i+1)),0,MED_TAILLE_PNOM);
541 component_unit.replace(i*MED_TAILLE_PNOM,MED_TAILLE_PNOM,(field -> getComponentUnit(i+1)),0,MED_TAILLE_PNOM);
544 MESSAGE("component_name=|"<<component_name<<"|");
545 MESSAGE("component_unit=|"<<component_unit<<"|");
547 // already existing ?
549 char * champName = new char[MED_TAILLE_NOM+1] ;
550 char * compName, * compUnit ;
553 int n = med_2_1::MEDnChamp(_medIdt,0);
556 med_2_1::med_type_champ type ;
558 for (int i = 1; i <= n; i++)
560 nbComp = med_2_1::MEDnChamp(_medIdt,i);
561 compName = new char[MED_TAILLE_PNOM*nbComp+1];
562 compUnit = new char[MED_TAILLE_PNOM*nbComp+1];
564 err = med_2_1::MEDchampInfo(_medIdt,i,champName,&type,compName,compUnit,nbComp);
566 if (strcmp(champName, field->getName())==0) { // Found !
577 if (nbComp != component_count)
578 throw MEDEXCEPTION ( LOCALIZED (STRING(LOC)
579 <<": Field exist in file, but number of component are different : " \
580 <<nbComp<<" in file and "<<component_count<<" in CORBA object."
583 // component name and unit
584 MESSAGE(LOC<<" Component name in file : "<<compName);
585 MESSAGE(LOC<<" Component name in CORBA object : "<<component_name);
586 MESSAGE(LOC<<" Component unit in file : "<<compUnit);
587 MESSAGE(LOC<<" Component unit in CORBA object : "<<component_unit);
592 // Verify the field doesn't exist
594 string dataGroupName = "/CHA/"+ string(field->getName());
596 MESSAGE(LOC << "|" << dataGroupName << "|" );
598 med_2_1::med_idt gid = H5Gopen(_medIdt, dataGroupName.c_str() );
602 err=med_2_1::MEDchampCr(_medIdt,
603 const_cast <char*> (field->getName()),
605 const_cast <char*> ( component_name.c_str() ),
606 const_cast <char*> ( component_unit.c_str() ),
609 throw MEDEXCEPTION( LOCALIZED (STRING(LOC)
610 << ": Error MEDchampCr : "<<err
617 SALOME_MED::SUPPORT_ptr mySupport = field -> getSupport();
620 if (! mySupport->isOnAllElements())
621 throw MEDEXCEPTION ( LOCALIZED (STRING(LOC)
622 <<": Field must be on all entity"
626 SALOME_MED::MESH_ptr myMesh = mySupport -> getMesh();
629 SALOME_MED::medGeometryElement_array* Types = mySupport->getTypes() ;
631 int NumberOfType = Types->length() ;
633 for ( int i = 0; i < NumberOfType; i++ )
635 int NumberOfElements = mySupport->getNumberOfElements ( (*Types)[i] ) ;
636 int NumberOfGaussPoint = mySupport->getNumberOfGaussPoint ( (*Types)[i] ) ;
638 MESSAGE( " " << field->getName() );
639 MESSAGE( " " << NumberOfElements );
640 MESSAGE( " " << NumberOfGaussPoint );
641 MESSAGE( " " << (int) (convertIdlEntToMedEnt(mySupport->getEntity())) );
642 MESSAGE( " " << (int)(convertIdlEltToMedElt((*Types)[i])) );
643 MESSAGE( " " << field->getIterationNumber() );
644 MESSAGE( " " << field->getTime() );
645 MESSAGE( " " << field->getOrderNumber() );
646 MESSAGE( "MEDchampEcr :" << myMesh->getName() );
648 SALOME_MED::double_array * value = field->getValue( SALOME_MED::MED_FULL_INTERLACE ) ;
649 double *locvalue = new double[NumberOfElements];
650 for (int k = 0; k < NumberOfElements; k++)
651 locvalue[k] = (*value) [k];
653 err=med_2_1::MEDchampEcr(_medIdt,
654 const_cast <char*> (myMesh->getName()) ,
655 const_cast <char*> (field->getName()),
656 (unsigned char*)locvalue,
657 med_2_1::MED_FULL_INTERLACE,
663 (med_2_1::med_entite_maillage)convertIdlEntToMedEnt(mySupport->getEntity()),
664 (med_2_1::med_geometrie_element)(convertIdlEltToMedElt((*Types)[i])),
665 field->getIterationNumber(),
668 field->getOrderNumber()
672 if (err < MED_VALID )
673 throw MEDEXCEPTION(LOCALIZED( STRING(LOC)
674 <<": Error in writing Field "<< field->getName() <<", type "<<(*Types)[i]
681 if (err < 0 ) return ;
683 med_2_1::MEDfermer(_medIdt) ;
685 endService("CalculatorEngine::writeMEDfile");
692 //===========================================================================
693 // CalculatorEngine_factory
694 //===========================================================================
695 PortableServer::ObjectId * CalculatorEngine_factory
697 PortableServer::POA_ptr poa,
698 PortableServer::ObjectId * contId,
699 const char *instanceName,
700 const char *interfaceName)
702 MESSAGE("CalculatorEngine_factory CalculatorEngine ("
703 << instanceName << "," << interfaceName << ")");
704 CalculatorEngine * myCalculator
705 = new CalculatorEngine(orb, poa, contId, instanceName, interfaceName);
706 return myCalculator->getId() ;