Salome HOME
DCQ : Merge with Ecole_Ete_a6.
[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 using namespace std;
28 #include <unistd.h>
29 #include "utilities.h"
30 #include "CalculatorEngine.hxx"
31 #include <iostream>
32 #include <sstream>
33 #include "MEDMEM_Support_i.hxx"
34
35 #include "MEDMEM_define.hxx"
36 #include "MEDMEM_STRING.hxx"
37 #include "MEDMEM_Exception.hxx"
38 #include "MEDMEM_Unit.hxx"
39
40
41 //================================================================================
42 // static PrintFieldValues - shows field contents
43 //================================================================================
44
45 static void PrintFieldValues (FIELD<double> * field, int until_index) 
46 {
47   const double * values = field -> getValue(MED_FULL_INTERLACE);
48   int nb_comp     = field -> getNumberOfComponents();
49   MESSAGE( "Field                    : " << field -> getName() );
50   MESSAGE( "    Description          : " << field -> getDescription() );
51   MESSAGE( "    Number of components : " << nb_comp );
52
53   for (int i=0 ; i<nb_comp ; i++) {
54     MESSAGE ( "       Component " << field -> getComponentName(i+1) << endl \
55              << "                   Unit        : " << field -> getMEDComponentUnit(i+1) << endl \
56              << "                   Description : " << field -> getComponentDescription(i+1) );
57   }
58   MESSAGE( "    First " << until_index << " values   : " );
59   
60   for (int j=0 ; j < until_index ; j++) {
61     for (int i=0;i<nb_comp;i++) MESSAGE( values[i+j*nb_comp] << " " );
62   }
63 }
64
65
66 //================================================================================
67 // Constructors
68 //================================================================================
69
70 CalculatorEngine::CalculatorEngine(CORBA::ORB_ptr orb,
71                                    PortableServer::POA_ptr poa,
72                                    PortableServer::ObjectId * contId, 
73                                    const char *instanceName,
74                                    const char *interfaceName) :
75                                    Engines_Component_i(orb, poa, contId, instanceName, interfaceName,true)
76 {
77   MESSAGE("CalculatorEngine::CalculatorEngine activate object instanceName("
78           << instanceName << ") interfaceName(" << interfaceName << ")" )
79     _thisObj = this ;
80   _id = _poa->activate_object(_thisObj);
81   SALOME_NamingService *NS = new SALOME_NamingService(orb);
82   _NS=NS;
83 }
84
85 CalculatorEngine::CalculatorEngine()
86 {
87 }
88
89 //================================================================================
90 // Destructors
91 //================================================================================
92
93 CalculatorEngine::~CalculatorEngine()
94 {
95 }
96
97 SALOME_MED::FIELDDOUBLE_ptr CalculatorEngine::PutToStudy(SALOME_MED::FIELDDOUBLE_ptr theField1,
98                                                          long int theStudyId) {
99   CORBA::Object_var anObj = _NS->Resolve("/myStudyManager");
100   SALOMEDS::StudyManager_var aManager  = SALOMEDS::StudyManager::_narrow(anObj);
101 //   SALOMEDS::ListOfOpenStudies_var aList = aManager->GetOpenStudies();
102 //   SALOMEDS::Study_var aStudy = aManager->GetStudyByName(aList[0]);
103   SALOMEDS::Study_var aStudy = aManager->GetStudyByID(theStudyId);
104   SALOMEDS::StudyBuilder_var aBuilder = aStudy->NewBuilder();
105
106   SALOMEDS::SComponent_var aComponent = aStudy->FindComponent("Calculator");
107   if (aComponent->_is_nil()) aComponent = aBuilder->NewComponent("Calculator");
108   SALOMEDS::GenericAttribute_var anAttr = aBuilder->FindOrCreateAttribute(aComponent, "AttributeName");
109   SALOMEDS::AttributeName_var aName = SALOMEDS::AttributeName::_narrow(anAttr);
110   aName->SetValue("Calculator");
111   
112   SALOMEDS::SObject_var aSO = aBuilder->NewObject(aComponent);
113   anAttr = aBuilder->FindOrCreateAttribute(aSO, "AttributeName");
114   aName = SALOMEDS::AttributeName::_narrow(anAttr);
115   char aFieldName[10];
116   sprintf(aFieldName, "Field_%d", (int)aSO->Tag());
117   aName->SetValue(strdup(aFieldName));
118   
119   ORB_INIT &init = *SINGLETON_<ORB_INIT>::Instance() ;
120   ASSERT(SINGLETON_<ORB_INIT>::IsAlreadyExisting()) ;
121   CORBA::ORB_var &orb = init(0,0);
122
123   string iorStr = orb->object_to_string(theField1);
124   anAttr = aBuilder->FindOrCreateAttribute(aSO, "AttributeIOR");
125   SALOMEDS::AttributeIOR_var anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
126   anIOR->SetValue(iorStr.c_str());
127
128   return SALOME_MED::FIELDDOUBLE::_duplicate(theField1);
129 }
130
131
132 //=======================================================================================
133 //  Addition of 2 FieldNodeDouble (based on Med library)
134 //
135 //  We assume that :
136 //     - support
137 //     - number of components
138 //     - name, type, unit and description of components
139 //  are the same for the 2 fields.
140 //
141 //  Otherwise,
142 //  the result will be a copy of the first field.
143 //
144 //=======================================================================================
145
146 SALOME_MED::FIELDDOUBLE_ptr CalculatorEngine::Add(SALOME_MED::FIELDDOUBLE_ptr FirstField,
147                                                   SALOME_MED::FIELDDOUBLE_ptr SecondField)
148 {
149   ostringstream tmp;
150   bool          same_support = true;
151   
152   beginService("CalculatorEngine::Add");
153   
154   sendMessage(NOTIF_TRACE, "CalculatorEngine::Add is Computing");
155   
156   BEGIN_OF("CalculatorEngine::Add(SALOME_MED::FIELDDOUBLE_ptr FirstField,SALOME_MED::FIELDDOUBLE_ptr SecondField)");
157
158   SCRUTE(FirstField);
159   SCRUTE(SecondField);
160
161   string message = string("\n             CalculatorEngine::Add : ") +
162                    string("\n                               first field name  --> ") + FirstField -> getName() +
163                    string("\n                               second field name --> ") + SecondField -> getName();
164
165   sendMessage(NOTIF_TRACE, message.c_str());
166
167   // Number of components
168   int nb_comp1  = FirstField -> getNumberOfComponents();
169   int nb_comp2  = SecondField -> getNumberOfComponents();
170   if (nb_comp1 != nb_comp2) same_support = false;
171    MESSAGE( "  nb_comp1 --> " << nb_comp1 <<endl );
172    MESSAGE( "  nb_comp2 --> " << nb_comp2 <<endl );
173
174
175   /* Name Description and Unit of each component of the field */
176
177   string * component_name = new string[nb_comp1];
178   string * component_unit = new string[nb_comp1];
179
180   for (int i=0 ; i<nb_comp1 ; i++) {
181     component_name[i].assign(FirstField -> getComponentName(i+1));
182     component_unit[i].assign(FirstField -> getComponentUnit(i+1));
183
184     if (same_support) {
185       if (
186           (component_name[i] != SecondField -> getComponentName(i+1)) ||
187           (component_unit[i] != SecondField -> getComponentUnit(i+1)))
188         same_support = false;
189     }
190   }
191
192   MESSAGE("CalculatorEngine::Add Number of entities in the Support of each fields");
193  
194   // Number of entities in the Support of the field
195
196   int len_value1 = 0;
197   int len_value2 = 0;
198   SALOME_MED::SUPPORT_ptr support1 = FirstField -> getSupport();
199   SALOME_MED::SUPPORT_ptr support2 = SecondField -> getSupport();
200
201   SCRUTE(support1);
202
203   SCRUTE(support2);
204
205   SALOME_MED::MESH_ptr mesh1 = support1 -> getMesh();
206   SALOME_MED::MESH_ptr mesh2 = support2 -> getMesh();
207
208   SCRUTE(mesh1);
209   SCRUTE(mesh2);
210
211   if (same_support && support1 != support2) same_support = false;
212
213   if (support1 -> isOnAllElements())
214     len_value1 = support1 -> getMesh() -> getNumberOfElements(support1 -> getEntity(),SALOME_MED::MED_ALL_ELEMENTS);
215   else
216     len_value1 = support1 -> getNumberOfElements(SALOME_MED::MED_ALL_ELEMENTS);
217
218   SCRUTE(len_value1);
219
220   if (support2 -> isOnAllElements())
221     len_value2 = support2 -> getMesh() -> getNumberOfElements(support2 -> getEntity(),SALOME_MED::MED_ALL_ELEMENTS);
222   else
223     len_value2 = support2 -> getNumberOfElements(SALOME_MED::MED_ALL_ELEMENTS);
224
225   if (same_support && len_value1 != len_value2) same_support = false;
226
227   SCRUTE(len_value2);
228
229   // Values of new field
230   SALOME_MED::double_array * first_value = FirstField -> getValue(SALOME_MED::MED_FULL_INTERLACE);
231   SALOME_MED::double_array * second_value;
232   if (same_support) {
233     second_value = SecondField -> getValue(SALOME_MED::MED_FULL_INTERLACE);
234     tmp << "\n             CalculatorEngine::Add : " ;
235     tmp << "\n                               Number of entities in the Support of first field  = " << len_value1 ;
236     tmp << "\n                               Number of entities in the Support of second field = " << len_value2 ;
237     message = tmp.str();
238
239     sendMessage(NOTIF_TRACE, message.c_str());
240
241   }
242
243   int totalLength = nb_comp1*len_value1;
244   double * new_value = new double[totalLength];
245   if (same_support) 
246     {
247       sendMessage(NOTIF_TRACE, "CalculatorEngine::Add - field1 and field2 have the same support");
248
249       for(int i=0 ; i<totalLength ; i++) 
250         new_value[i] = ((*first_value)[i]) + ((*second_value)[i]);
251     }
252   else {
253     for(int i=0 ; i<totalLength ; i++) 
254       new_value[i] = ((*first_value)[i]) ;
255   }
256   
257   // Creation of a Local Field
258   
259   MESSAGE("CalculatorEngine::Add Creation of the local field "<< totalLength);
260   
261   FIELD<double> * fieldloc =  new FIELD<double>();
262   fieldloc -> allocValue(nb_comp1,len_value1);
263   fieldloc  -> setValue(MED_FULL_INTERLACE,new_value);
264   fieldloc  -> setValueType(MED_EN::MED_REEL64);
265   fieldloc  -> setName("-new_Add-");
266   fieldloc  -> setDescription( FirstField -> getDescription() );
267   fieldloc -> setComponentsNames(component_name);
268   fieldloc -> setMEDComponentsUnits(component_unit);
269
270   // Control
271   int until_index = ( 20 > len_value1)? len_value1 : 20;
272   PrintFieldValues (fieldloc,until_index);
273
274   sendMessage(NOTIF_TRACE, "CalculatorEngine::Add - new field created");
275
276   // Export result
277   // Creation of the new CORBA field
278
279   MESSAGE("CalculatorEngine::Add Creation of the CORBA field");
280
281   FIELDDOUBLE_i * NewField = new FIELDDOUBLE_i(support1,fieldloc) ;
282
283   POA_SALOME_MED::FIELDDOUBLE_tie<FIELDDOUBLE_i> * myFieldTie = new POA_SALOME_MED::FIELDDOUBLE_tie<FIELDDOUBLE_i>(NewField) ;
284   SALOME_MED::FIELDDOUBLE_ptr myFieldIOR = myFieldTie->_this() ;
285
286   sleep(4);
287
288   END_OF("CalculatorEngine::Add(SALOME_MED::FIELDDOUBLE_ptr FirstField,SALOME_MED::FIELDDOUBLE_ptr SecondField)");
289
290   endService("CalculatorEngine::Add");
291   return myFieldIOR;
292
293 }
294
295
296 //===============================================================================
297 //  Multiplication of a FieldNodeDouble by a double value (based on Med library)
298 //===============================================================================
299
300 SALOME_MED::FIELDDOUBLE_ptr CalculatorEngine::Mul(SALOME_MED::FIELDDOUBLE_ptr OldField,
301                                                   CORBA::Double x1)
302 {
303   beginService("CalculatorEngine::Mul");
304
305   BEGIN_OF("CalculatorEngine::Mul(SALOME_MED::FIELDDOUBLE_ptr OldField,CORBA::Double x1)");
306
307   SCRUTE(OldField);
308   SCRUTE(x1);
309
310   // Name and description of field
311   string field_name        = OldField -> getName();
312   string field_description = OldField -> getDescription();
313
314   // Number of components
315   int nb_comp  = OldField -> getNumberOfComponents();
316   string * component_name = new string[nb_comp];
317   string * component_unit = new string[nb_comp];
318
319   for (int i=0 ; i<nb_comp ; i++) {
320     component_name[i] = OldField -> getComponentName(i+1);
321     component_unit[i] = OldField -> getComponentUnit(i+1);
322   }
323
324   MESSAGE("CalculatorEngine::Mul Number of entities in the Support of the field");
325
326   // Number of entities in the Support of the field
327   int len_value = 0;
328
329   SALOME_MED::SUPPORT_ptr support = OldField -> getSupport();
330
331   SCRUTE(support);
332
333   SALOME_MED::MESH_ptr mesh = support -> getMesh();
334
335   SCRUTE(mesh);
336
337   if (support -> isOnAllElements())
338     len_value = support -> getMesh() -> getNumberOfElements(support -> getEntity(),SALOME_MED::MED_ALL_ELEMENTS);
339   else
340     len_value = support -> getNumberOfElements(SALOME_MED::MED_ALL_ELEMENTS);
341
342   SCRUTE(len_value);
343
344   // Values of new field
345   SALOME_MED::double_array * old_value = OldField -> getValue(SALOME_MED::MED_FULL_INTERLACE);
346
347   int totalLength = nb_comp*len_value;
348   double * new_value = new double[totalLength];
349   for(int i=0 ; i<totalLength ; i++) {
350     new_value[i] = x1 * ((*old_value)[i]);
351   }
352
353   // Creation of a Local Field
354
355   MESSAGE("CalculatorEngine::Mul Creation of the local field "<< totalLength);
356
357   FIELD<double> * fieldloc =  new FIELD<double>();
358   fieldloc -> allocValue(nb_comp,len_value);
359   fieldloc  -> setValue(MED_FULL_INTERLACE,new_value);
360   fieldloc  -> setValueType(MED_EN::MED_REEL64);
361   fieldloc  -> setName("-new_Mul-");
362   fieldloc  -> setDescription(field_description);
363   fieldloc -> setComponentsNames(component_name);
364   fieldloc -> setMEDComponentsUnits(component_unit);
365
366
367   // Creation of the new CORBA field
368
369   MESSAGE("CalculatorEngine::Mul Creation of the CORBA field");
370
371   FIELDDOUBLE_i * NewField = new FIELDDOUBLE_i(support,fieldloc) ;
372
373   POA_SALOME_MED::FIELDDOUBLE_tie<FIELDDOUBLE_i> * myFieldTie = new POA_SALOME_MED::FIELDDOUBLE_tie<FIELDDOUBLE_i>(NewField) ;
374   SALOME_MED::FIELDDOUBLE_ptr myFieldIOR = myFieldTie->_this() ;
375
376   sleep(4);
377
378   END_OF("CalculatorEngine::Mul(SALOME_MED::FIELDDOUBLE_ptr OldField,CORBA::Double x1)");
379
380   endService("CalculatorEngine::Mul");
381   return myFieldIOR;
382 }
383
384
385 //================================================================================
386 //  Build a constant field of double based on first field support (Med library)
387 //================================================================================
388
389 SALOME_MED::FIELDDOUBLE_ptr CalculatorEngine::Constant(SALOME_MED::FIELDDOUBLE_ptr FirstField,
390                                                        CORBA::Double x1)
391 {
392
393   beginService("CalculatorEngine::Const");
394
395   BEGIN_OF("CalculatorEngine::Constant(SALOME_MED::FIELDDOUBLE_ptr FirstField,CORBA::Double x1)");
396
397   // Name and description of field
398   string field_name        = FirstField -> getName();
399   string field_description = FirstField -> getDescription();
400
401   SALOME_MED::SUPPORT_ptr FirstSupport = FirstField -> getSupport();
402
403   // Number of components
404   int nb_comp  = FirstField -> getNumberOfComponents();
405
406   // Type, name, unit and description of components
407   string * component_name = new string[nb_comp];
408   string * component_unit = new string[nb_comp];
409
410   for (int i = 0 ; i<nb_comp ; i++) {
411     component_name[i] = FirstField -> getComponentName(i+1);
412     component_unit[i] = FirstField -> getComponentUnit(i+1);
413   }
414
415   MESSAGE("CalculatorEngine::Constant Number of entities in the Support of the field");
416
417   // Number of entities in the Support of the field
418   int len_value = 0;
419
420   SCRUTE(FirstSupport);
421
422   SALOME_MED::MESH_ptr mesh = FirstSupport -> getMesh();
423
424   SCRUTE(mesh);
425
426   if ( FirstSupport -> isOnAllElements() )
427     len_value = FirstSupport -> getMesh() -> getNumberOfElements(FirstSupport -> getEntity(),SALOME_MED::MED_ALL_ELEMENTS);
428   else
429     len_value = FirstSupport -> getNumberOfElements(SALOME_MED::MED_ALL_ELEMENTS);
430
431   // Values of new field
432   SALOME_MED::double_array * old_value = FirstField -> getValue(SALOME_MED::MED_FULL_INTERLACE);
433
434   int totalLength = nb_comp*len_value;
435   double * new_value = new double[totalLength];
436
437   for(int i=0 ; i<totalLength ; i++) 
438     new_value[i] = x1 ;
439  
440
441   // Creation of a Local Field
442
443   MESSAGE("CalculatorEngine::Constant Creation of the local field "<< totalLength);
444
445   FIELD<double> * fieldloc =  new FIELD<double>();
446   fieldloc -> allocValue(nb_comp,len_value);
447   fieldloc  -> setValue(MED_FULL_INTERLACE,new_value);
448   fieldloc  -> setValueType(MED_EN::MED_REEL64);
449   fieldloc  -> setName("-new_Const_Field-");
450   fieldloc  -> setDescription(field_description);
451   fieldloc -> setComponentsNames(component_name);
452   fieldloc -> setMEDComponentsUnits(component_unit);
453
454   // Control
455   int until_index = ( 20 > len_value)? len_value : 20 ;
456   PrintFieldValues (fieldloc,until_index);
457
458   // Creation of the new CORBA field
459
460   MESSAGE("CalculatorEngine::Constant Creation of the CORBA field");
461
462   FIELDDOUBLE_i * NewField = new FIELDDOUBLE_i(FirstSupport,fieldloc) ;
463
464   POA_SALOME_MED::FIELDDOUBLE_tie<FIELDDOUBLE_i> * myFieldTie = new POA_SALOME_MED::FIELDDOUBLE_tie<FIELDDOUBLE_i>(NewField) ;
465   SALOME_MED::FIELDDOUBLE_ptr myFieldIOR = myFieldTie->_this() ;
466   
467   sleep(4);
468
469   endService("CalculatorEngine::Const");
470   
471   END_OF("CalculatorEngine::Constant(SALOME_MED::FIELDDOUBLE_ptr FirstField,CORBA::Double x1)");
472   
473   return myFieldIOR;
474   
475 }
476
477 //================================================================================
478 //  write a field in a MED file
479 //================================================================================
480
481 void CalculatorEngine::writeMEDfile(SALOME_MED::FIELDDOUBLE_ptr field, const char *filename)
482 {
483   beginService("CalculatorEngine::writeMEDfile");
484   MESSAGE("fichier d'impression du champ resultat:"<<filename);
485
486   // get support of the field
487
488   SALOME_MED::SUPPORT_ptr support = field -> getSupport();
489   
490   // get mesh from this support
491   
492   SALOME_MED::MESH_ptr mesh = support -> getMesh();
493   
494   // write the mesh
495   
496   int index_m = mesh->addDriver(SALOME_MED::MED_DRIVER,filename,mesh->getName());
497
498   mesh -> write(index_m,"");
499
500   //write the field
501   
502   const char * LOC = "CalculatorEngine::writeMEDfile ";
503   
504   MESSAGE("fichier :"<<filename);
505
506   MED_FR::med_idt _medIdt=MED_FR::MEDouvrir(const_cast <char *> (filename) ,(MED_FR::med_mode_acces) MED_ECRI);
507   SCRUTE(_medIdt);
508
509   if (_medIdt<0) return;
510   
511   int err ;
512
513   int component_count= field->getNumberOfComponents();
514   string   component_name(component_count*MED_TAILLE_PNOM,' ') ;
515   string   component_unit(component_count*MED_TAILLE_PNOM,' ') ;
516   
517   for (int i=0; i < component_count ; i++) {
518     component_name.replace(i*MED_TAILLE_PNOM,MED_TAILLE_PNOM,(field -> getComponentName(i+1)),0,MED_TAILLE_PNOM);
519     component_unit.replace(i*MED_TAILLE_PNOM,MED_TAILLE_PNOM,(field -> getComponentUnit(i+1)),0,MED_TAILLE_PNOM);
520   }
521   
522   MESSAGE("component_name=|"<<component_name<<"|");
523   MESSAGE("component_unit=|"<<component_unit<<"|");
524   
525   // already existing ?
526   
527   char * champName = new char[MED_TAILLE_NOM+1] ;
528   char * compName,  * compUnit  ;
529   bool Find = false ;
530
531   int n = MED_FR::MEDnChamp(_medIdt,0);
532   int nbComp ;
533
534   MED_FR::med_type_champ type ;
535
536   for (int i = 1;  i <= n;  i++) 
537     {
538       nbComp = MED_FR::MEDnChamp(_medIdt,i);
539       compName = new char[MED_TAILLE_PNOM*nbComp+1];
540       compUnit = new char[MED_TAILLE_PNOM*nbComp+1];
541
542       err = MED_FR::MEDchampInfo(_medIdt,i,champName,&type,compName,compUnit,nbComp);
543       if (err == 0)
544         if (strcmp(champName, field->getName())==0) { // Found !
545           Find = true ;
546           break ;
547         }
548
549       delete[] compName ;
550       delete[] compUnit ;
551
552     }
553   if (Find) {
554     // the same ?
555     if (nbComp != component_count)
556       throw MEDEXCEPTION ( LOCALIZED (STRING(LOC)
557                                      <<": Field exist in file, but number of component are different : " \
558                                      <<nbComp<<" in file and "<<component_count<<" in CORBA object."
559                                      )
560                          );
561     // component name and unit
562     MESSAGE(LOC<<" Component name in file : "<<compName);
563     MESSAGE(LOC<<" Component name in CORBA object : "<<component_name);
564     MESSAGE(LOC<<" Component unit in file : "<<compUnit);
565     MESSAGE(LOC<<" Component unit in CORBA object : "<<component_unit);
566     delete[] compName ;
567     delete[] compUnit ;
568     
569   } else { 
570     // Verify the field doesn't exist
571     
572     string dataGroupName =  "/CHA/"+ string(field->getName());
573
574     MESSAGE(LOC << "|" << dataGroupName << "|" );
575
576     med_idt gid =  H5Gopen(_medIdt, dataGroupName.c_str() );
577     
578     if ( gid < 0 ) {
579       // create field :
580       err=MED_FR::MEDchampCr(_medIdt, 
581                              const_cast <char*> (field->getName()),
582                              MED_FR::MED_REEL64,
583                              const_cast <char*> ( component_name.c_str() ),
584                              const_cast <char*> ( component_unit.c_str() ),
585                              component_count);
586       if ( err < 0 )
587         throw MEDEXCEPTION( LOCALIZED (STRING(LOC) 
588                                        << ": Error MEDchampCr : "<<err
589                                        )
590                            );
591     }
592         else H5Gclose(gid);
593   }
594   
595   SALOME_MED::SUPPORT_ptr mySupport = field -> getSupport();
596   SCRUTE(mySupport);
597   
598   if (! mySupport->isOnAllElements())
599     throw MEDEXCEPTION ( LOCALIZED (STRING(LOC) 
600                                    <<": Field must be on all entity"
601                                     )
602                         );
603   
604   SALOME_MED::MESH_ptr myMesh = mySupport -> getMesh();
605   SCRUTE(mesh);
606
607   SALOME_MED::medGeometryElement_array* Types = mySupport->getTypes() ;
608
609   int NumberOfType = Types->length() ;
610
611   for ( int i = 0; i < NumberOfType; i++ ) 
612     {
613       int NumberOfElements   = mySupport->getNumberOfElements ( (*Types)[i] ) ;
614       int NumberOfGaussPoint = mySupport->getNumberOfGaussPoint ( (*Types)[i] ) ;
615     
616       MESSAGE( " " << field->getName() );
617       MESSAGE( " " << NumberOfElements );
618       MESSAGE( " " << NumberOfGaussPoint );
619       MESSAGE( " " << (int) (convertIdlEntToMedEnt(mySupport->getEntity())) );
620       MESSAGE( " " << (int)(convertIdlEltToMedElt((*Types)[i])) );
621       MESSAGE( " " << field->getIterationNumber() );
622       MESSAGE( " " << field->getTime() );
623       MESSAGE( " " << field->getOrderNumber() );
624       MESSAGE( "MEDchampEcr :" << myMesh->getName() );
625     
626       SALOME_MED::double_array * value = field->getValue( SALOME_MED::MED_FULL_INTERLACE ) ;
627       double *locvalue = new double[NumberOfElements];
628       for (int k = 0; k < NumberOfElements; k++) 
629         locvalue[k] = (*value) [k];
630
631       err=MED_FR::MEDchampEcr(_medIdt, 
632                               const_cast <char*> (myMesh->getName()) , 
633                               const_cast <char*> (field->getName()),
634                               (unsigned char*)locvalue, 
635                               MED_FR::MED_FULL_INTERLACE,
636                               NumberOfElements,
637                               NumberOfGaussPoint,
638                               MED_ALL, 
639                               MED_NOPFL, 
640                               MED_FR::MED_REMP,  
641                               (MED_FR::med_entite_maillage)convertIdlEntToMedEnt(mySupport->getEntity()),
642                               (MED_FR::med_geometrie_element)(convertIdlEltToMedElt((*Types)[i])),
643                               field->getIterationNumber(),
644                               "        ",
645                               field->getTime(),
646                               field->getOrderNumber()
647                               );
648       delete locvalue;
649       
650       if (err < MED_VALID )
651         throw MEDEXCEPTION(LOCALIZED( STRING(LOC)
652                                      <<": Error in writing Field "<< field->getName() <<", type "<<(*Types)[i]
653                                      )
654                            );
655     }
656   END_OF( LOC );
657   
658   SCRUTE( err );
659   if (err < 0 ) return ;
660   
661   MED_FR::MEDfermer(_medIdt) ;
662   
663   endService("CalculatorEngine::writeMEDfile");
664   return ;
665   
666 }
667
668 extern "C"
669 {
670   //===========================================================================
671   // CalculatorEngine_factory
672   //===========================================================================
673   PortableServer::ObjectId * CalculatorEngine_factory
674      (CORBA::ORB_ptr orb,
675       PortableServer::POA_ptr poa, 
676       PortableServer::ObjectId * contId,
677       const char *instanceName,
678       const char *interfaceName)
679   {
680     MESSAGE("CalculatorEngine_factory CalculatorEngine ("
681             << instanceName << "," << interfaceName << ")");
682     CalculatorEngine * myCalculator 
683       = new CalculatorEngine(orb, poa, contId, instanceName, interfaceName);
684     return myCalculator->getId() ;
685   }
686 }
687