Salome HOME
[Bug PAL7356] 2.1.0_beta1: dataflow execution is aborted.
[samples/component.git] / src / CalculatorComponent / CalculatorEngine.cxx
1 //  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
2 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
3 // 
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. 
8 // 
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. 
13 // 
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 
17 // 
18 //  See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org 
19 //
20 //
21 //
22 //  File   : CalculatorEngine.cxx
23 //  Author : Laurent DADA, CEA
24 //  Module : CalculatorComponent
25 //  $Header$
26
27 #include <unistd.h>
28
29 #include <iostream>
30 #include <sstream>
31
32 #include "CalculatorEngine.hxx"
33 #include "MEDMEM_Support_i.hxx"
34 #include "SUPPORTClient.hxx"
35
36 #include "MEDMEM_define.hxx"
37 #include "MEDMEM_STRING.hxx"
38 #include "MEDMEM_Exception.hxx"
39 #include "MEDMEM_Unit.hxx"
40
41 #include "med.hxx"
42
43 #include "utilities.h"
44
45 using namespace MEDMEM;
46 using namespace std;
47
48 //================================================================================
49 // static PrintFieldValues - shows field contents
50 //================================================================================
51
52 static void PrintFieldValues (FIELD<double> * field, int until_index) 
53 {
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 );
59
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) );
64   }
65   MESSAGE( "    First " << until_index << " values   : " );
66   
67   for (int j=0 ; j < until_index ; j++) {
68     for (int i=0;i<nb_comp;i++) MESSAGE( values[i+j*nb_comp] << " " );
69   }
70 }
71
72
73 //================================================================================
74 // Constructors
75 //================================================================================
76
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)
83 {
84   MESSAGE("CalculatorEngine::CalculatorEngine activate object instanceName("
85           << instanceName << ") interfaceName(" << interfaceName << ")" )
86     _thisObj = this ;
87   _id = _poa->activate_object(_thisObj);
88   SALOME_NamingService *NS = new SALOME_NamingService(orb);
89   _NS=NS;
90 }
91
92 CalculatorEngine::CalculatorEngine()
93 {
94 }
95
96 //================================================================================
97 // Destructors
98 //================================================================================
99
100 CalculatorEngine::~CalculatorEngine()
101 {
102 }
103
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);
108
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();
115
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");
121   
122   SALOMEDS::SObject_var aSO = aBuilder->NewObject(aComponent);
123   anAttr = aBuilder->FindOrCreateAttribute(aSO, "AttributeName");
124   aName = SALOMEDS::AttributeName::_narrow(anAttr);
125   char aFieldName[10];
126   sprintf(aFieldName, "Field_%d", (int)aSO->Tag());
127   aName->SetValue(strdup(aFieldName));
128   
129   ORB_INIT &init = *SINGLETON_<ORB_INIT>::Instance() ;
130   ASSERT(SINGLETON_<ORB_INIT>::IsAlreadyExisting()) ;
131   CORBA::ORB_var &orb = init(0,0);
132
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());
137
138   return SALOME_MED::FIELDDOUBLE::_duplicate(theField1);
139 }
140
141
142 //=======================================================================================
143 //  Addition of 2 FieldNodeDouble (based on Med library)
144 //
145 //  We assume that :
146 //     - support
147 //     - number of components
148 //     - name, type, unit and description of components
149 //  are the same for the 2 fields.
150 //
151 //  Otherwise,
152 //  the result will be a copy of the first field.
153 //
154 //=======================================================================================
155
156 static omni_mutex anAddMutex;
157 SALOME_MED::FIELDDOUBLE_ptr CalculatorEngine::Add(SALOME_MED::FIELDDOUBLE_ptr FirstField,
158                                                   SALOME_MED::FIELDDOUBLE_ptr SecondField)
159 {
160   omni_mutex_lock aLock(anAddMutex);
161
162   ostringstream tmp;
163   bool          same_support = true;
164   
165   beginService("CalculatorEngine::Add");
166   
167   sendMessage(NOTIF_TRACE, "CalculatorEngine::Add is Computing");
168   
169   BEGIN_OF("CalculatorEngine::Add(SALOME_MED::FIELDDOUBLE_ptr FirstField,SALOME_MED::FIELDDOUBLE_ptr SecondField)");
170
171   SCRUTE(FirstField);
172   SCRUTE(SecondField);
173
174   string message = string("\n             CalculatorEngine::Add : ") +
175                    string("\n                               first field name  --> ") + FirstField -> getName() +
176                    string("\n                               second field name --> ") + SecondField -> getName();
177
178   sendMessage(NOTIF_TRACE, message.c_str());
179
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 );
186
187
188   /* Name Description and Unit of each component of the field */
189
190   string * component_name = new string[nb_comp1];
191   string * component_unit = new string[nb_comp1];
192
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));
196
197     if (same_support) {
198       if (
199           (component_name[i] != SecondField -> getComponentName(i+1)) ||
200           (component_unit[i] != SecondField -> getComponentUnit(i+1)))
201         same_support = false;
202     }
203   }
204
205   MESSAGE("CalculatorEngine::Add Number of entities in the Support of each fields");
206  
207   // Number of entities in the Support of the field
208
209   int len_value1 = 0;
210   int len_value2 = 0;
211   SALOME_MED::SUPPORT_ptr support1 = FirstField -> getSupport();
212   SALOME_MED::SUPPORT_ptr support2 = SecondField -> getSupport();
213
214   SCRUTE(support1);
215
216   SCRUTE(support2);
217
218   SALOME_MED::MESH_ptr mesh1 = support1 -> getMesh();
219   SALOME_MED::MESH_ptr mesh2 = support2 -> getMesh();
220
221   SCRUTE(mesh1);
222   SCRUTE(mesh2);
223
224   if (same_support && support1 != support2) same_support = false;
225
226   if (support1 -> isOnAllElements())
227     len_value1 = support1 -> getMesh() -> getNumberOfElements(support1 -> getEntity(),SALOME_MED::MED_ALL_ELEMENTS);
228   else
229     len_value1 = support1 -> getNumberOfElements(SALOME_MED::MED_ALL_ELEMENTS);
230
231   SCRUTE(len_value1);
232
233   if (support2 -> isOnAllElements())
234     len_value2 = support2 -> getMesh() -> getNumberOfElements(support2 -> getEntity(),SALOME_MED::MED_ALL_ELEMENTS);
235   else
236     len_value2 = support2 -> getNumberOfElements(SALOME_MED::MED_ALL_ELEMENTS);
237
238   if (same_support && len_value1 != len_value2) same_support = false;
239
240   SCRUTE(len_value2);
241
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;
245   if (same_support) {
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 ;
250     message = tmp.str();
251
252     sendMessage(NOTIF_TRACE, message.c_str());
253
254   }
255
256   int totalLength = nb_comp1*len_value1;
257   double * new_value = new double[totalLength];
258   if (same_support) 
259     {
260       sendMessage(NOTIF_TRACE, "CalculatorEngine::Add - field1 and field2 have the same support");
261
262       for(int i=0 ; i<totalLength ; i++) 
263         new_value[i] = ((*first_value)[i]) + ((*second_value)[i]);
264     }
265   else {
266     for(int i=0 ; i<totalLength ; i++) 
267       new_value[i] = ((*first_value)[i]) ;
268   }
269   
270   // Creation of a Local Field
271   
272   MESSAGE("CalculatorEngine::Add Creation of the local field "<< totalLength);
273   
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);
282
283   // Control
284   int until_index = ( 20 > len_value1)? len_value1 : 20;
285   PrintFieldValues (fieldloc,until_index);
286
287   sendMessage(NOTIF_TRACE, "CalculatorEngine::Add - new field created");
288
289   // Export result
290   // Creation of the new CORBA field
291
292   MESSAGE("CalculatorEngine::Add Creation of the CORBA field");
293
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() ;
298
299   //sleep(4);
300
301   END_OF("CalculatorEngine::Add(SALOME_MED::FIELDDOUBLE_ptr FirstField,SALOME_MED::FIELDDOUBLE_ptr SecondField)");
302
303   endService("CalculatorEngine::Add");
304   return myFieldIOR;
305
306 }
307
308
309 //===============================================================================
310 //  Multiplication of a FieldNodeDouble by a double value (based on Med library)
311 //===============================================================================
312
313 static omni_mutex aMulMutex;
314 SALOME_MED::FIELDDOUBLE_ptr CalculatorEngine::Mul(SALOME_MED::FIELDDOUBLE_ptr OldField,
315                                                   CORBA::Double x1)
316 {
317   omni_mutex_lock aLock(aMulMutex);
318
319   beginService("CalculatorEngine::Mul");
320   BEGIN_OF("CalculatorEngine::Mul(SALOME_MED::FIELDDOUBLE_ptr OldField,CORBA::Double x1)");
321
322   SCRUTE(OldField);
323   SCRUTE(x1);
324
325   // Name and description of field
326   string field_name        = OldField -> getName();
327   string field_description = OldField -> getDescription();
328
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];
333
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);
337   }
338
339   MESSAGE("CalculatorEngine::Mul Number of entities in the Support of the field");
340
341   // Number of entities in the Support of the field
342   int len_value = 0;
343
344   SALOME_MED::SUPPORT_ptr support = OldField -> getSupport();
345
346   SCRUTE(support);
347
348   SALOME_MED::MESH_ptr mesh = support -> getMesh();
349
350   SCRUTE(mesh);
351
352   if (support -> isOnAllElements())
353     len_value = support -> getMesh() -> getNumberOfElements(support -> getEntity(),SALOME_MED::MED_ALL_ELEMENTS);
354   else
355     len_value = support -> getNumberOfElements(SALOME_MED::MED_ALL_ELEMENTS);
356
357   SCRUTE(len_value);
358
359   // Values of new field
360   SALOME_MED::double_array * old_value = OldField -> getValue(SALOME_MED::MED_FULL_INTERLACE);
361
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]);
366   }
367
368   // Creation of a Local Field
369
370   MESSAGE("CalculatorEngine::Mul Creation of the local field "<< totalLength);
371
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);
380
381
382   // Creation of the new CORBA field
383
384   MESSAGE("CalculatorEngine::Mul Creation of the CORBA field");
385
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() ;
390
391   //sleep(4);
392
393   END_OF("CalculatorEngine::Mul(SALOME_MED::FIELDDOUBLE_ptr OldField,CORBA::Double x1)");
394
395   endService("CalculatorEngine::Mul");
396   return myFieldIOR;
397 }
398
399
400 //================================================================================
401 //  Build a constant field of double based on first field support (Med library)
402 //================================================================================
403
404 static omni_mutex aConstantMutex;
405 SALOME_MED::FIELDDOUBLE_ptr CalculatorEngine::Constant(SALOME_MED::FIELDDOUBLE_ptr FirstField,
406                                                        CORBA::Double x1)
407 {
408   omni_mutex_lock aLock(aConstantMutex);
409
410   beginService("CalculatorEngine::Const");
411   BEGIN_OF("CalculatorEngine::Constant(SALOME_MED::FIELDDOUBLE_ptr FirstField,CORBA::Double x1)");
412
413   // Name and description of field
414   string field_name        = FirstField -> getName();
415   string field_description = FirstField -> getDescription();
416
417   SALOME_MED::SUPPORT_ptr FirstSupport = FirstField -> getSupport();
418
419   // Number of components
420   int nb_comp  = FirstField -> getNumberOfComponents();
421
422   // Type, name, unit and description of components
423   string * component_name = new string[nb_comp];
424   string * component_unit = new string[nb_comp];
425
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);
429   }
430
431   MESSAGE("CalculatorEngine::Constant Number of entities in the Support of the field");
432
433   // Number of entities in the Support of the field
434   int len_value = 0;
435
436   SCRUTE(FirstSupport);
437
438   SALOME_MED::MESH_ptr mesh = FirstSupport -> getMesh();
439
440   SCRUTE(mesh);
441
442   if ( FirstSupport -> isOnAllElements() )
443     len_value = FirstSupport -> getMesh() -> getNumberOfElements(FirstSupport -> getEntity(),SALOME_MED::MED_ALL_ELEMENTS);
444   else
445     len_value = FirstSupport -> getNumberOfElements(SALOME_MED::MED_ALL_ELEMENTS);
446
447   // Values of new field
448   int totalLength = nb_comp*len_value;
449   double * new_value = new double[totalLength];
450
451   for(int i=0 ; i<totalLength ; i++) 
452     new_value[i] = x1 ;
453  
454
455   // Creation of a Local Field
456
457   MESSAGE("CalculatorEngine::Constant Creation of the local field "<< totalLength);
458
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);
467
468   // Control
469   int until_index = ( 20 > len_value)? len_value : 20 ;
470   PrintFieldValues (fieldloc,until_index);
471
472   // Creation of the new CORBA field
473
474   MESSAGE("CalculatorEngine::Constant Creation of the CORBA field");
475
476   SUPPORT *supportClt=new SUPPORTClient(FirstSupport);
477   fieldloc->setSupport(supportClt);
478   FIELDDOUBLE_i * NewField = new FIELDDOUBLE_i(fieldloc) ;
479
480   SALOME_MED::FIELDDOUBLE_ptr myFieldIOR = NewField->_this() ;
481   
482   //sleep(4);
483
484   endService("CalculatorEngine::Const");
485   
486   END_OF("CalculatorEngine::Constant(SALOME_MED::FIELDDOUBLE_ptr FirstField,CORBA::Double x1)");
487   
488   return myFieldIOR;
489   
490 }
491
492 //================================================================================
493 //  write a field in a MED file
494 //================================================================================
495
496 static omni_mutex aWriteMEDfileMutex;
497 void CalculatorEngine::writeMEDfile(SALOME_MED::FIELDDOUBLE_ptr field, const char *filename)
498 {
499   omni_mutex_lock aLock(aWriteMEDfileMutex);
500
501   beginService("CalculatorEngine::writeMEDfile");
502   MESSAGE("fichier d'impression du champ resultat:"<<filename);
503
504   // get support of the field
505
506   SALOME_MED::SUPPORT_ptr support = field -> getSupport();
507   
508   // get mesh from this support
509   
510   SALOME_MED::MESH_ptr mesh = support -> getMesh();
511   
512   // write the mesh
513   
514   int index_m = mesh->addDriver(SALOME_MED::MED_DRIVER,filename,mesh->getName());
515
516   mesh -> write(index_m,"");
517
518   //write the field
519   
520   const char * LOC = "CalculatorEngine::writeMEDfile ";
521   
522   MESSAGE("fichier :"<<filename);
523
524   med_2_1::med_idt _medIdt = med_2_1::MEDouvrir(const_cast <char *> (filename) , med_2_1::MED_ECRI);
525   SCRUTE(_medIdt);
526
527   if (_medIdt<0) return;
528   
529   int err ;
530
531   int component_count= field->getNumberOfComponents();
532   string   component_name(component_count*MED_TAILLE_PNOM,' ') ;
533   string   component_unit(component_count*MED_TAILLE_PNOM,' ') ;
534   
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);
538   }
539   
540   MESSAGE("component_name=|"<<component_name<<"|");
541   MESSAGE("component_unit=|"<<component_unit<<"|");
542   
543   // already existing ?
544   
545   char * champName = new char[MED_TAILLE_NOM+1] ;
546   char * compName,  * compUnit  ;
547   bool Find = false ;
548
549   int n = med_2_1::MEDnChamp(_medIdt,0);
550   int nbComp ;
551
552   med_2_1::med_type_champ type ;
553
554   for (int i = 1;  i <= n;  i++) 
555     {
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];
559
560       err = med_2_1::MEDchampInfo(_medIdt,i,champName,&type,compName,compUnit,nbComp);
561       if (err == 0)
562         if (strcmp(champName, field->getName())==0) { // Found !
563           Find = true ;
564           break ;
565         }
566
567       delete[] compName ;
568       delete[] compUnit ;
569
570     }
571   if (Find) {
572     // the same ?
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."
577                                      )
578                          );
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);
584     delete[] compName ;
585     delete[] compUnit ;
586     
587   } else { 
588     // Verify the field doesn't exist
589     
590     string dataGroupName =  "/CHA/"+ string(field->getName());
591
592     MESSAGE(LOC << "|" << dataGroupName << "|" );
593
594     med_2_1::med_idt gid =  H5Gopen(_medIdt, dataGroupName.c_str() );
595     
596     if ( gid < 0 ) {
597       // create field :
598       err=med_2_1::MEDchampCr(_medIdt, 
599                              const_cast <char*> (field->getName()),
600                              med_2_1::MED_REEL64,
601                              const_cast <char*> ( component_name.c_str() ),
602                              const_cast <char*> ( component_unit.c_str() ),
603                              component_count);
604       if ( err < 0 )
605         throw MEDEXCEPTION( LOCALIZED (STRING(LOC) 
606                                        << ": Error MEDchampCr : "<<err
607                                        )
608                            );
609     }
610         else H5Gclose(gid);
611   }
612   
613   SALOME_MED::SUPPORT_ptr mySupport = field -> getSupport();
614   SCRUTE(mySupport);
615   
616   if (! mySupport->isOnAllElements())
617     throw MEDEXCEPTION ( LOCALIZED (STRING(LOC) 
618                                    <<": Field must be on all entity"
619                                     )
620                         );
621   
622   SALOME_MED::MESH_ptr myMesh = mySupport -> getMesh();
623   SCRUTE(mesh);
624
625   SALOME_MED::medGeometryElement_array* Types = mySupport->getTypes() ;
626
627   int NumberOfType = Types->length() ;
628
629   for ( int i = 0; i < NumberOfType; i++ ) 
630     {
631       int NumberOfElements   = mySupport->getNumberOfElements ( (*Types)[i] ) ;
632       int NumberOfGaussPoint = mySupport->getNumberOfGaussPoint ( (*Types)[i] ) ;
633     
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() );
643     
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];
648
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,
654                               NumberOfElements,
655                               NumberOfGaussPoint,
656                               MED_ALL, 
657                               MED_NOPFL, 
658                               med_2_1::MED_REMP,  
659                               (med_2_1::med_entite_maillage)convertIdlEntToMedEnt(mySupport->getEntity()),
660                               (med_2_1::med_geometrie_element)(convertIdlEltToMedElt((*Types)[i])),
661                               field->getIterationNumber(),
662                               "        ",
663                               field->getTime(),
664                               field->getOrderNumber()
665                               );
666       delete locvalue;
667       
668       if (err < MED_VALID )
669         throw MEDEXCEPTION(LOCALIZED( STRING(LOC)
670                                      <<": Error in writing Field "<< field->getName() <<", type "<<(*Types)[i]
671                                      )
672                            );
673     }
674   END_OF( LOC );
675   
676   SCRUTE( err );
677   if (err < 0 ) return ;
678   
679   med_2_1::MEDfermer(_medIdt) ;
680   
681   endService("CalculatorEngine::writeMEDfile");
682   return ;
683   
684 }
685
686 extern "C"
687 {
688   //===========================================================================
689   // CalculatorEngine_factory
690   //===========================================================================
691   PortableServer::ObjectId * CalculatorEngine_factory
692      (CORBA::ORB_ptr orb,
693       PortableServer::POA_ptr poa, 
694       PortableServer::ObjectId * contId,
695       const char *instanceName,
696       const char *interfaceName)
697   {
698     MESSAGE("CalculatorEngine_factory CalculatorEngine ("
699             << instanceName << "," << interfaceName << ")");
700     CalculatorEngine * myCalculator 
701       = new CalculatorEngine(orb, poa, contId, instanceName, interfaceName);
702     return myCalculator->getId() ;
703   }
704 }
705
706