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 //================================================================================
49 // static PrintFieldValues - shows field contents
50 //================================================================================
52 static void PrintFieldValues (FIELD<double> * field, int until_index)
54 const double * values = field -> getValue(MED_EN::MED_FULL_INTERLACE);
55 int nb_comp = field -> getNumberOfComponents();
56 MESSAGE( "Field : " << field -> getName() );
57 MESSAGE( " Description : " << field -> getDescription() );
58 MESSAGE( " Number of components : " << nb_comp );
60 for (int i=0 ; i<nb_comp ; i++) {
61 MESSAGE ( " Component " << field -> getComponentName(i+1) << endl \
62 << " Unit : " << field -> getMEDComponentUnit(i+1) << endl \
63 << " Description : " << field -> getComponentDescription(i+1) );
65 MESSAGE( " First " << until_index << " values : " );
67 for (int j=0 ; j < until_index ; j++) {
68 for (int i=0;i<nb_comp;i++) MESSAGE( values[i+j*nb_comp] << " " );
73 //================================================================================
75 //================================================================================
77 CalculatorEngine::CalculatorEngine(CORBA::ORB_ptr orb,
78 PortableServer::POA_ptr poa,
79 PortableServer::ObjectId * contId,
80 const char *instanceName,
81 const char *interfaceName) :
82 Engines_Component_i(orb, poa, contId, instanceName, interfaceName,true)
84 MESSAGE("CalculatorEngine::CalculatorEngine activate object instanceName("
85 << instanceName << ") interfaceName(" << interfaceName << ")" )
87 _id = _poa->activate_object(_thisObj);
88 SALOME_NamingService *NS = new SALOME_NamingService(orb);
92 CalculatorEngine::CalculatorEngine()
96 //================================================================================
98 //================================================================================
100 CalculatorEngine::~CalculatorEngine()
104 static omni_mutex aPutToStudyMutex;
105 SALOME_MED::FIELDDOUBLE_ptr CalculatorEngine::PutToStudy(SALOME_MED::FIELDDOUBLE_ptr theField1,
106 long int theStudyId) {
107 omni_mutex_lock aLock(aPutToStudyMutex);
109 CORBA::Object_var anObj = _NS->Resolve("/myStudyManager");
110 SALOMEDS::StudyManager_var aManager = SALOMEDS::StudyManager::_narrow(anObj);
111 // SALOMEDS::ListOfOpenStudies_var aList = aManager->GetOpenStudies();
112 // SALOMEDS::Study_var aStudy = aManager->GetStudyByName(aList[0]);
113 SALOMEDS::Study_var aStudy = aManager->GetStudyByID(theStudyId);
114 SALOMEDS::StudyBuilder_var aBuilder = aStudy->NewBuilder();
116 SALOMEDS::SComponent_var aComponent = aStudy->FindComponent("Calculator");
117 if (aComponent->_is_nil()) aComponent = aBuilder->NewComponent("Calculator");
118 SALOMEDS::GenericAttribute_var anAttr = aBuilder->FindOrCreateAttribute(aComponent, "AttributeName");
119 SALOMEDS::AttributeName_var aName = SALOMEDS::AttributeName::_narrow(anAttr);
120 aName->SetValue("Calculator");
122 SALOMEDS::SObject_var aSO = aBuilder->NewObject(aComponent);
123 anAttr = aBuilder->FindOrCreateAttribute(aSO, "AttributeName");
124 aName = SALOMEDS::AttributeName::_narrow(anAttr);
126 sprintf(aFieldName, "Field_%d", (int)aSO->Tag());
127 aName->SetValue(strdup(aFieldName));
129 ORB_INIT &init = *SINGLETON_<ORB_INIT>::Instance() ;
130 ASSERT(SINGLETON_<ORB_INIT>::IsAlreadyExisting()) ;
131 CORBA::ORB_var &orb = init(0,0);
133 string iorStr = orb->object_to_string(theField1);
134 anAttr = aBuilder->FindOrCreateAttribute(aSO, "AttributeIOR");
135 SALOMEDS::AttributeIOR_var anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
136 anIOR->SetValue(iorStr.c_str());
138 return SALOME_MED::FIELDDOUBLE::_duplicate(theField1);
142 //=======================================================================================
143 // Addition of 2 FieldNodeDouble (based on Med library)
147 // - number of components
148 // - name, type, unit and description of components
149 // are the same for the 2 fields.
152 // the result will be a copy of the first field.
154 //=======================================================================================
156 static omni_mutex anAddMutex;
157 SALOME_MED::FIELDDOUBLE_ptr CalculatorEngine::Add(SALOME_MED::FIELDDOUBLE_ptr FirstField,
158 SALOME_MED::FIELDDOUBLE_ptr SecondField)
160 omni_mutex_lock aLock(anAddMutex);
163 bool same_support = true;
165 beginService("CalculatorEngine::Add");
167 sendMessage(NOTIF_TRACE, "CalculatorEngine::Add is Computing");
169 BEGIN_OF("CalculatorEngine::Add(SALOME_MED::FIELDDOUBLE_ptr FirstField,SALOME_MED::FIELDDOUBLE_ptr SecondField)");
174 string message = string("\n CalculatorEngine::Add : ") +
175 string("\n first field name --> ") + FirstField -> getName() +
176 string("\n second field name --> ") + SecondField -> getName();
178 sendMessage(NOTIF_TRACE, message.c_str());
180 // Number of components
181 int nb_comp1 = FirstField -> getNumberOfComponents();
182 int nb_comp2 = SecondField -> getNumberOfComponents();
183 if (nb_comp1 != nb_comp2) same_support = false;
184 MESSAGE( " nb_comp1 --> " << nb_comp1 <<endl );
185 MESSAGE( " nb_comp2 --> " << nb_comp2 <<endl );
188 /* Name Description and Unit of each component of the field */
190 string * component_name = new string[nb_comp1];
191 string * component_unit = new string[nb_comp1];
193 for (int i=0 ; i<nb_comp1 ; i++) {
194 component_name[i].assign(FirstField -> getComponentName(i+1));
195 component_unit[i].assign(FirstField -> getComponentUnit(i+1));
199 (component_name[i] != SecondField -> getComponentName(i+1)) ||
200 (component_unit[i] != SecondField -> getComponentUnit(i+1)))
201 same_support = false;
205 MESSAGE("CalculatorEngine::Add Number of entities in the Support of each fields");
207 // Number of entities in the Support of the field
211 SALOME_MED::SUPPORT_ptr support1 = FirstField -> getSupport();
212 SALOME_MED::SUPPORT_ptr support2 = SecondField -> getSupport();
218 SALOME_MED::MESH_ptr mesh1 = support1 -> getMesh();
219 SALOME_MED::MESH_ptr mesh2 = support2 -> getMesh();
224 if (same_support && support1 != support2) same_support = false;
226 if (support1 -> isOnAllElements())
227 len_value1 = support1 -> getMesh() -> getNumberOfElements(support1 -> getEntity(),SALOME_MED::MED_ALL_ELEMENTS);
229 len_value1 = support1 -> getNumberOfElements(SALOME_MED::MED_ALL_ELEMENTS);
233 if (support2 -> isOnAllElements())
234 len_value2 = support2 -> getMesh() -> getNumberOfElements(support2 -> getEntity(),SALOME_MED::MED_ALL_ELEMENTS);
236 len_value2 = support2 -> getNumberOfElements(SALOME_MED::MED_ALL_ELEMENTS);
238 if (same_support && len_value1 != len_value2) same_support = false;
242 // Values of new field
243 SALOME_MED::double_array * first_value = FirstField -> getValue(SALOME_MED::MED_FULL_INTERLACE);
244 SALOME_MED::double_array * second_value;
246 second_value = SecondField -> getValue(SALOME_MED::MED_FULL_INTERLACE);
247 tmp << "\n CalculatorEngine::Add : " ;
248 tmp << "\n Number of entities in the Support of first field = " << len_value1 ;
249 tmp << "\n Number of entities in the Support of second field = " << len_value2 ;
252 sendMessage(NOTIF_TRACE, message.c_str());
256 int totalLength = nb_comp1*len_value1;
257 double * new_value = new double[totalLength];
260 sendMessage(NOTIF_TRACE, "CalculatorEngine::Add - field1 and field2 have the same support");
262 for(int i=0 ; i<totalLength ; i++)
263 new_value[i] = ((*first_value)[i]) + ((*second_value)[i]);
266 for(int i=0 ; i<totalLength ; i++)
267 new_value[i] = ((*first_value)[i]) ;
270 // Creation of a Local Field
272 MESSAGE("CalculatorEngine::Add Creation of the local field "<< totalLength);
274 FIELD<double> * fieldloc = new FIELD<double>();
275 fieldloc -> allocValue(nb_comp1,len_value1);
276 fieldloc -> setValue(MED_EN::MED_FULL_INTERLACE,new_value);
277 fieldloc -> setValueType(MED_EN::MED_REEL64);
278 fieldloc -> setName("-new_Add-");
279 fieldloc -> setDescription( FirstField -> getDescription() );
280 fieldloc -> setComponentsNames(component_name);
281 fieldloc -> setMEDComponentsUnits(component_unit);
284 int until_index = ( 20 > len_value1)? len_value1 : 20;
285 PrintFieldValues (fieldloc,until_index);
287 sendMessage(NOTIF_TRACE, "CalculatorEngine::Add - new field created");
290 // Creation of the new CORBA field
292 MESSAGE("CalculatorEngine::Add Creation of the CORBA field");
294 SUPPORT *support1Clt=new SUPPORTClient(support1);
295 fieldloc->setSupport(support1Clt);
296 FIELDDOUBLE_i * NewField = new FIELDDOUBLE_i(fieldloc) ;
297 SALOME_MED::FIELDDOUBLE_ptr myFieldIOR = NewField->_this() ;
301 END_OF("CalculatorEngine::Add(SALOME_MED::FIELDDOUBLE_ptr FirstField,SALOME_MED::FIELDDOUBLE_ptr SecondField)");
303 endService("CalculatorEngine::Add");
309 //===============================================================================
310 // Multiplication of a FieldNodeDouble by a double value (based on Med library)
311 //===============================================================================
313 static omni_mutex aMulMutex;
314 SALOME_MED::FIELDDOUBLE_ptr CalculatorEngine::Mul(SALOME_MED::FIELDDOUBLE_ptr OldField,
317 omni_mutex_lock aLock(aMulMutex);
319 beginService("CalculatorEngine::Mul");
320 BEGIN_OF("CalculatorEngine::Mul(SALOME_MED::FIELDDOUBLE_ptr OldField,CORBA::Double x1)");
325 // Name and description of field
326 string field_name = OldField -> getName();
327 string field_description = OldField -> getDescription();
329 // Number of components
330 int nb_comp = OldField -> getNumberOfComponents();
331 string * component_name = new string[nb_comp];
332 string * component_unit = new string[nb_comp];
334 for (int i=0 ; i<nb_comp ; i++) {
335 component_name[i] = OldField -> getComponentName(i+1);
336 component_unit[i] = OldField -> getComponentUnit(i+1);
339 MESSAGE("CalculatorEngine::Mul Number of entities in the Support of the field");
341 // Number of entities in the Support of the field
344 SALOME_MED::SUPPORT_ptr support = OldField -> getSupport();
348 SALOME_MED::MESH_ptr mesh = support -> getMesh();
352 if (support -> isOnAllElements())
353 len_value = support -> getMesh() -> getNumberOfElements(support -> getEntity(),SALOME_MED::MED_ALL_ELEMENTS);
355 len_value = support -> getNumberOfElements(SALOME_MED::MED_ALL_ELEMENTS);
359 // Values of new field
360 SALOME_MED::double_array * old_value = OldField -> getValue(SALOME_MED::MED_FULL_INTERLACE);
362 int totalLength = nb_comp*len_value;
363 double * new_value = new double[totalLength];
364 for(int i=0 ; i<totalLength ; i++) {
365 new_value[i] = x1 * ((*old_value)[i]);
368 // Creation of a Local Field
370 MESSAGE("CalculatorEngine::Mul Creation of the local field "<< totalLength);
372 FIELD<double> * fieldloc = new FIELD<double>();
373 fieldloc -> allocValue(nb_comp,len_value);
374 fieldloc -> setValue(MED_EN::MED_FULL_INTERLACE,new_value);
375 fieldloc -> setValueType(MED_EN::MED_REEL64);
376 fieldloc -> setName("-new_Mul-");
377 fieldloc -> setDescription(field_description);
378 fieldloc -> setComponentsNames(component_name);
379 fieldloc -> setMEDComponentsUnits(component_unit);
382 // Creation of the new CORBA field
384 MESSAGE("CalculatorEngine::Mul Creation of the CORBA field");
386 SUPPORT *supportClt=new SUPPORTClient(support);
387 fieldloc->setSupport(supportClt);
388 FIELDDOUBLE_i * NewField = new FIELDDOUBLE_i(fieldloc) ;
389 SALOME_MED::FIELDDOUBLE_ptr myFieldIOR = NewField->_this() ;
393 END_OF("CalculatorEngine::Mul(SALOME_MED::FIELDDOUBLE_ptr OldField,CORBA::Double x1)");
395 endService("CalculatorEngine::Mul");
400 //================================================================================
401 // Build a constant field of double based on first field support (Med library)
402 //================================================================================
404 static omni_mutex aConstantMutex;
405 SALOME_MED::FIELDDOUBLE_ptr CalculatorEngine::Constant(SALOME_MED::FIELDDOUBLE_ptr FirstField,
408 omni_mutex_lock aLock(aConstantMutex);
410 beginService("CalculatorEngine::Const");
411 BEGIN_OF("CalculatorEngine::Constant(SALOME_MED::FIELDDOUBLE_ptr FirstField,CORBA::Double x1)");
413 // Name and description of field
414 string field_name = FirstField -> getName();
415 string field_description = FirstField -> getDescription();
417 SALOME_MED::SUPPORT_ptr FirstSupport = FirstField -> getSupport();
419 // Number of components
420 int nb_comp = FirstField -> getNumberOfComponents();
422 // Type, name, unit and description of components
423 string * component_name = new string[nb_comp];
424 string * component_unit = new string[nb_comp];
426 for (int i = 0 ; i<nb_comp ; i++) {
427 component_name[i] = FirstField -> getComponentName(i+1);
428 component_unit[i] = FirstField -> getComponentUnit(i+1);
431 MESSAGE("CalculatorEngine::Constant Number of entities in the Support of the field");
433 // Number of entities in the Support of the field
436 SCRUTE(FirstSupport);
438 SALOME_MED::MESH_ptr mesh = FirstSupport -> getMesh();
442 if ( FirstSupport -> isOnAllElements() )
443 len_value = FirstSupport -> getMesh() -> getNumberOfElements(FirstSupport -> getEntity(),SALOME_MED::MED_ALL_ELEMENTS);
445 len_value = FirstSupport -> getNumberOfElements(SALOME_MED::MED_ALL_ELEMENTS);
447 // Values of new field
448 int totalLength = nb_comp*len_value;
449 double * new_value = new double[totalLength];
451 for(int i=0 ; i<totalLength ; i++)
455 // Creation of a Local Field
457 MESSAGE("CalculatorEngine::Constant Creation of the local field "<< totalLength);
459 FIELD<double> * fieldloc = new FIELD<double>();
460 fieldloc -> allocValue(nb_comp,len_value);
461 fieldloc -> setValue(MED_EN::MED_FULL_INTERLACE,new_value);
462 fieldloc -> setValueType(MED_EN::MED_REEL64);
463 fieldloc -> setName("-new_Const_Field-");
464 fieldloc -> setDescription(field_description);
465 fieldloc -> setComponentsNames(component_name);
466 fieldloc -> setMEDComponentsUnits(component_unit);
469 int until_index = ( 20 > len_value)? len_value : 20 ;
470 PrintFieldValues (fieldloc,until_index);
472 // Creation of the new CORBA field
474 MESSAGE("CalculatorEngine::Constant Creation of the CORBA field");
476 SUPPORT *supportClt=new SUPPORTClient(FirstSupport);
477 fieldloc->setSupport(supportClt);
478 FIELDDOUBLE_i * NewField = new FIELDDOUBLE_i(fieldloc) ;
480 SALOME_MED::FIELDDOUBLE_ptr myFieldIOR = NewField->_this() ;
484 endService("CalculatorEngine::Const");
486 END_OF("CalculatorEngine::Constant(SALOME_MED::FIELDDOUBLE_ptr FirstField,CORBA::Double x1)");
492 //================================================================================
493 // write a field in a MED file
494 //================================================================================
496 static omni_mutex aWriteMEDfileMutex;
497 void CalculatorEngine::writeMEDfile(SALOME_MED::FIELDDOUBLE_ptr field, const char *filename)
499 omni_mutex_lock aLock(aWriteMEDfileMutex);
501 beginService("CalculatorEngine::writeMEDfile");
502 MESSAGE("fichier d'impression du champ resultat:"<<filename);
504 // get support of the field
506 SALOME_MED::SUPPORT_ptr support = field -> getSupport();
508 // get mesh from this support
510 SALOME_MED::MESH_ptr mesh = support -> getMesh();
514 int index_m = mesh->addDriver(SALOME_MED::MED_DRIVER,filename,mesh->getName());
516 mesh -> write(index_m,"");
520 const char * LOC = "CalculatorEngine::writeMEDfile ";
522 MESSAGE("fichier :"<<filename);
524 med_2_1::med_idt _medIdt = med_2_1::MEDouvrir(const_cast <char *> (filename) , med_2_1::MED_ECRI);
527 if (_medIdt<0) return;
531 int component_count= field->getNumberOfComponents();
532 string component_name(component_count*MED_TAILLE_PNOM,' ') ;
533 string component_unit(component_count*MED_TAILLE_PNOM,' ') ;
535 for (int i=0; i < component_count ; i++) {
536 component_name.replace(i*MED_TAILLE_PNOM,MED_TAILLE_PNOM,(field -> getComponentName(i+1)),0,MED_TAILLE_PNOM);
537 component_unit.replace(i*MED_TAILLE_PNOM,MED_TAILLE_PNOM,(field -> getComponentUnit(i+1)),0,MED_TAILLE_PNOM);
540 MESSAGE("component_name=|"<<component_name<<"|");
541 MESSAGE("component_unit=|"<<component_unit<<"|");
543 // already existing ?
545 char * champName = new char[MED_TAILLE_NOM+1] ;
546 char * compName, * compUnit ;
549 int n = med_2_1::MEDnChamp(_medIdt,0);
552 med_2_1::med_type_champ type ;
554 for (int i = 1; i <= n; i++)
556 nbComp = med_2_1::MEDnChamp(_medIdt,i);
557 compName = new char[MED_TAILLE_PNOM*nbComp+1];
558 compUnit = new char[MED_TAILLE_PNOM*nbComp+1];
560 err = med_2_1::MEDchampInfo(_medIdt,i,champName,&type,compName,compUnit,nbComp);
562 if (strcmp(champName, field->getName())==0) { // Found !
573 if (nbComp != component_count)
574 throw MEDEXCEPTION ( LOCALIZED (STRING(LOC)
575 <<": Field exist in file, but number of component are different : " \
576 <<nbComp<<" in file and "<<component_count<<" in CORBA object."
579 // component name and unit
580 MESSAGE(LOC<<" Component name in file : "<<compName);
581 MESSAGE(LOC<<" Component name in CORBA object : "<<component_name);
582 MESSAGE(LOC<<" Component unit in file : "<<compUnit);
583 MESSAGE(LOC<<" Component unit in CORBA object : "<<component_unit);
588 // Verify the field doesn't exist
590 string dataGroupName = "/CHA/"+ string(field->getName());
592 MESSAGE(LOC << "|" << dataGroupName << "|" );
594 med_2_1::med_idt gid = H5Gopen(_medIdt, dataGroupName.c_str() );
598 err=med_2_1::MEDchampCr(_medIdt,
599 const_cast <char*> (field->getName()),
601 const_cast <char*> ( component_name.c_str() ),
602 const_cast <char*> ( component_unit.c_str() ),
605 throw MEDEXCEPTION( LOCALIZED (STRING(LOC)
606 << ": Error MEDchampCr : "<<err
613 SALOME_MED::SUPPORT_ptr mySupport = field -> getSupport();
616 if (! mySupport->isOnAllElements())
617 throw MEDEXCEPTION ( LOCALIZED (STRING(LOC)
618 <<": Field must be on all entity"
622 SALOME_MED::MESH_ptr myMesh = mySupport -> getMesh();
625 SALOME_MED::medGeometryElement_array* Types = mySupport->getTypes() ;
627 int NumberOfType = Types->length() ;
629 for ( int i = 0; i < NumberOfType; i++ )
631 int NumberOfElements = mySupport->getNumberOfElements ( (*Types)[i] ) ;
632 int NumberOfGaussPoint = mySupport->getNumberOfGaussPoint ( (*Types)[i] ) ;
634 MESSAGE( " " << field->getName() );
635 MESSAGE( " " << NumberOfElements );
636 MESSAGE( " " << NumberOfGaussPoint );
637 MESSAGE( " " << (int) (convertIdlEntToMedEnt(mySupport->getEntity())) );
638 MESSAGE( " " << (int)(convertIdlEltToMedElt((*Types)[i])) );
639 MESSAGE( " " << field->getIterationNumber() );
640 MESSAGE( " " << field->getTime() );
641 MESSAGE( " " << field->getOrderNumber() );
642 MESSAGE( "MEDchampEcr :" << myMesh->getName() );
644 SALOME_MED::double_array * value = field->getValue( SALOME_MED::MED_FULL_INTERLACE ) ;
645 double *locvalue = new double[NumberOfElements];
646 for (int k = 0; k < NumberOfElements; k++)
647 locvalue[k] = (*value) [k];
649 err=med_2_1::MEDchampEcr(_medIdt,
650 const_cast <char*> (myMesh->getName()) ,
651 const_cast <char*> (field->getName()),
652 (unsigned char*)locvalue,
653 med_2_1::MED_FULL_INTERLACE,
659 (med_2_1::med_entite_maillage)convertIdlEntToMedEnt(mySupport->getEntity()),
660 (med_2_1::med_geometrie_element)(convertIdlEltToMedElt((*Types)[i])),
661 field->getIterationNumber(),
664 field->getOrderNumber()
668 if (err < MED_VALID )
669 throw MEDEXCEPTION(LOCALIZED( STRING(LOC)
670 <<": Error in writing Field "<< field->getName() <<", type "<<(*Types)[i]
677 if (err < 0 ) return ;
679 med_2_1::MEDfermer(_medIdt) ;
681 endService("CalculatorEngine::writeMEDfile");
688 //===========================================================================
689 // CalculatorEngine_factory
690 //===========================================================================
691 PortableServer::ObjectId * CalculatorEngine_factory
693 PortableServer::POA_ptr poa,
694 PortableServer::ObjectId * contId,
695 const char *instanceName,
696 const char *interfaceName)
698 MESSAGE("CalculatorEngine_factory CalculatorEngine ("
699 << instanceName << "," << interfaceName << ")");
700 CalculatorEngine * myCalculator
701 = new CalculatorEngine(orb, poa, contId, instanceName, interfaceName);
702 return myCalculator->getId() ;