Salome HOME
Join modifications from branch V3_1_0_For_CCRT
[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 #ifndef MED_TAILLE_PNOM
49 #define MED_TAILLE_PNOM MED_TAILLE_PNOM21
50 #endif
51
52 typedef FIELD<double,MEDMEM::FullInterlace> TFieldDouble;
53 typedef FIELDTEMPLATE_I<double,MEDMEM::FullInterlace> TFieldDouble_i;
54
55 //================================================================================
56 // static PrintFieldValues - shows field contents
57 //================================================================================
58
59 static void PrintFieldValues (TFieldDouble * field, int until_index) 
60 {
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 );
66
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) );
71   }
72   MESSAGE( "    First " << until_index << " values   : " );
73   
74   for (int j=0 ; j < until_index ; j++) {
75     for (int i=0;i<nb_comp;i++) MESSAGE( values[i+j*nb_comp] << " " );
76   }
77 }
78
79
80 //================================================================================
81 // Constructors
82 //================================================================================
83
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)
90 {
91   MESSAGE("CalculatorEngine::CalculatorEngine activate object instanceName("
92           << instanceName << ") interfaceName(" << interfaceName << ")" )
93     _thisObj = this ;
94   _id = _poa->activate_object(_thisObj);
95   SALOME_NamingService *NS = new SALOME_NamingService(orb);
96   _NS=NS;
97 }
98
99 CalculatorEngine::CalculatorEngine()
100 {
101 }
102
103 //================================================================================
104 // Destructors
105 //================================================================================
106
107 CalculatorEngine::~CalculatorEngine()
108 {
109 }
110
111 static omni_mutex aPutToStudyMutex;
112 SALOME_MED::FIELDDOUBLE_ptr CalculatorEngine::PutToStudy(SALOME_MED::FIELDDOUBLE_ptr theField1,
113                                                          CORBA::Long theStudyId) {
114   omni_mutex_lock aLock(aPutToStudyMutex);
115
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();
122
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");
128   
129   SALOMEDS::SObject_var aSO = aBuilder->NewObject(aComponent);
130   anAttr = aBuilder->FindOrCreateAttribute(aSO, "AttributeName");
131   aName = SALOMEDS::AttributeName::_narrow(anAttr);
132   char aFieldName[10];
133   sprintf(aFieldName, "Field_%d", (int)aSO->Tag());
134   aName->SetValue(strdup(aFieldName));
135   
136   ORB_INIT &init = *SINGLETON_<ORB_INIT>::Instance() ;
137   ASSERT(SINGLETON_<ORB_INIT>::IsAlreadyExisting()) ;
138   CORBA::ORB_var &orb = init(0,0);
139
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());
144
145   return SALOME_MED::FIELDDOUBLE::_duplicate(theField1);
146 }
147
148
149 //=======================================================================================
150 //  Addition of 2 FieldNodeDouble (based on Med library)
151 //
152 //  We assume that :
153 //     - support
154 //     - number of components
155 //     - name, type, unit and description of components
156 //  are the same for the 2 fields.
157 //
158 //  Otherwise,
159 //  the result will be a copy of the first field.
160 //
161 //=======================================================================================
162
163 static omni_mutex anAddMutex;
164 SALOME_MED::FIELDDOUBLE_ptr CalculatorEngine::Add(SALOME_MED::FIELDDOUBLE_ptr FirstField,
165                                                   SALOME_MED::FIELDDOUBLE_ptr SecondField)
166 {
167   omni_mutex_lock aLock(anAddMutex);
168
169   ostringstream tmp;
170   bool          same_support = true;
171   
172   beginService("CalculatorEngine::Add");
173   
174   sendMessage(NOTIF_TRACE, "CalculatorEngine::Add is Computing");
175   
176   BEGIN_OF("CalculatorEngine::Add(SALOME_MED::FIELDDOUBLE_ptr FirstField,SALOME_MED::FIELDDOUBLE_ptr SecondField)");
177
178   SCRUTE(FirstField);
179   SCRUTE(SecondField);
180
181   string message = string("\n             CalculatorEngine::Add : ") +
182                    string("\n                               first field name  --> ") + FirstField -> getName() +
183                    string("\n                               second field name --> ") + SecondField -> getName();
184
185   sendMessage(NOTIF_TRACE, message.c_str());
186
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 );
193
194
195   /* Name Description and Unit of each component of the field */
196
197   string * component_name = new string[nb_comp1];
198   string * component_unit = new string[nb_comp1];
199
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));
203
204     if (same_support) {
205       if (
206           (component_name[i] != SecondField -> getComponentName(i+1)) ||
207           (component_unit[i] != SecondField -> getComponentUnit(i+1)))
208         same_support = false;
209     }
210   }
211
212   MESSAGE("CalculatorEngine::Add Number of entities in the Support of each fields");
213  
214   // Number of entities in the Support of the field
215
216   int len_value1 = 0;
217   int len_value2 = 0;
218   SALOME_MED::SUPPORT_ptr support1 = FirstField -> getSupport();
219   SALOME_MED::SUPPORT_ptr support2 = SecondField -> getSupport();
220
221   SCRUTE(support1);
222
223   SCRUTE(support2);
224
225   SALOME_MED::MESH_ptr mesh1 = support1 -> getMesh();
226   SALOME_MED::MESH_ptr mesh2 = support2 -> getMesh();
227
228   SCRUTE(mesh1);
229   SCRUTE(mesh2);
230
231   if (same_support && support1 != support2) same_support = false;
232
233   if (support1 -> isOnAllElements())
234     len_value1 = support1 -> getMesh() -> getNumberOfElements(support1 -> getEntity(),SALOME_MED::MED_ALL_ELEMENTS);
235   else
236     len_value1 = support1 -> getNumberOfElements(SALOME_MED::MED_ALL_ELEMENTS);
237
238   SCRUTE(len_value1);
239
240   if (support2 -> isOnAllElements())
241     len_value2 = support2 -> getMesh() -> getNumberOfElements(support2 -> getEntity(),SALOME_MED::MED_ALL_ELEMENTS);
242   else
243     len_value2 = support2 -> getNumberOfElements(SALOME_MED::MED_ALL_ELEMENTS);
244
245   if (same_support && len_value1 != len_value2) same_support = false;
246
247   SCRUTE(len_value2);
248
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;
252   if (same_support) {
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 ;
257     message = tmp.str();
258
259     sendMessage(NOTIF_TRACE, message.c_str());
260
261   }
262
263   int totalLength = nb_comp1*len_value1;
264   double * new_value = new double[totalLength];
265   if (same_support) 
266     {
267       sendMessage(NOTIF_TRACE, "CalculatorEngine::Add - field1 and field2 have the same support");
268
269       for(int i=0 ; i<totalLength ; i++) 
270         new_value[i] = ((*first_value)[i]) + ((*second_value)[i]);
271     }
272   else {
273     for(int i=0 ; i<totalLength ; i++) 
274       new_value[i] = ((*first_value)[i]) ;
275   }
276   
277   // Creation of a Local Field
278   
279   MESSAGE("CalculatorEngine::Add Creation of the local field "<< totalLength);
280   
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);
288
289   // Control
290   int until_index = ( 20 > len_value1)? len_value1 : 20;
291   PrintFieldValues (fieldloc,until_index);
292
293   sendMessage(NOTIF_TRACE, "CalculatorEngine::Add - new field created");
294
295   // Export result
296   // Creation of the new CORBA field
297
298   MESSAGE("CalculatorEngine::Add Creation of the CORBA field");
299
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() ;
304
305   //sleep(4);
306
307   END_OF("CalculatorEngine::Add(SALOME_MED::FIELDDOUBLE_ptr FirstField,SALOME_MED::FIELDDOUBLE_ptr SecondField)");
308
309   endService("CalculatorEngine::Add");
310   return myFieldIOR;
311
312 }
313
314
315 //===============================================================================
316 //  Multiplication of a FieldNodeDouble by a double value (based on Med library)
317 //===============================================================================
318
319 static omni_mutex aMulMutex;
320 SALOME_MED::FIELDDOUBLE_ptr CalculatorEngine::Mul(SALOME_MED::FIELDDOUBLE_ptr OldField,
321                                                   CORBA::Double x1)
322 {
323   omni_mutex_lock aLock(aMulMutex);
324
325   beginService("CalculatorEngine::Mul");
326   BEGIN_OF("CalculatorEngine::Mul(SALOME_MED::FIELDDOUBLE_ptr OldField,CORBA::Double x1)");
327
328   SCRUTE(OldField);
329   SCRUTE(x1);
330
331   // Name and description of field
332   string field_name        = OldField -> getName();
333   string field_description = OldField -> getDescription();
334
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];
339
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);
343   }
344
345   MESSAGE("CalculatorEngine::Mul Number of entities in the Support of the field");
346
347   // Number of entities in the Support of the field
348   int len_value = 0;
349
350   SALOME_MED::SUPPORT_ptr support = OldField -> getSupport();
351
352   SCRUTE(support);
353
354   SALOME_MED::MESH_ptr mesh = support -> getMesh();
355
356   SCRUTE(mesh);
357
358   if (support -> isOnAllElements())
359     len_value = support -> getMesh() -> getNumberOfElements(support -> getEntity(),SALOME_MED::MED_ALL_ELEMENTS);
360   else
361     len_value = support -> getNumberOfElements(SALOME_MED::MED_ALL_ELEMENTS);
362
363   SCRUTE(len_value);
364
365   // Values of new field
366   SALOME_MED::double_array * old_value = OldField -> getValue(SALOME_MED::MED_FULL_INTERLACE);
367
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]);
372   }
373
374   // Creation of a Local Field
375
376   MESSAGE("CalculatorEngine::Mul Creation of the local field "<< totalLength);
377
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);
385
386
387   // Creation of the new CORBA field
388
389   MESSAGE("CalculatorEngine::Mul Creation of the CORBA field");
390
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() ;
395
396   //sleep(4);
397
398   END_OF("CalculatorEngine::Mul(SALOME_MED::FIELDDOUBLE_ptr OldField,CORBA::Double x1)");
399
400   endService("CalculatorEngine::Mul");
401   return myFieldIOR;
402 }
403
404
405 //================================================================================
406 //  Build a constant field of double based on first field support (Med library)
407 //================================================================================
408
409 static omni_mutex aConstantMutex;
410 SALOME_MED::FIELDDOUBLE_ptr CalculatorEngine::Constant(SALOME_MED::FIELDDOUBLE_ptr FirstField,
411                                                        CORBA::Double x1)
412 {
413   omni_mutex_lock aLock(aConstantMutex);
414
415   beginService("CalculatorEngine::Const");
416   BEGIN_OF("CalculatorEngine::Constant(SALOME_MED::FIELDDOUBLE_ptr FirstField,CORBA::Double x1)");
417
418   // Name and description of field
419   string field_name        = FirstField -> getName();
420   string field_description = FirstField -> getDescription();
421
422   SALOME_MED::SUPPORT_ptr FirstSupport = FirstField -> getSupport();
423
424   // Number of components
425   int nb_comp  = FirstField -> getNumberOfComponents();
426
427   // Type, name, unit and description of components
428   string * component_name = new string[nb_comp];
429   string * component_unit = new string[nb_comp];
430
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);
434   }
435
436   MESSAGE("CalculatorEngine::Constant Number of entities in the Support of the field");
437
438   // Number of entities in the Support of the field
439   int len_value = 0;
440
441   SCRUTE(FirstSupport);
442
443   SALOME_MED::MESH_ptr mesh = FirstSupport -> getMesh();
444
445   SCRUTE(mesh);
446
447   if ( FirstSupport -> isOnAllElements() )
448     len_value = FirstSupport -> getMesh() -> getNumberOfElements(FirstSupport -> getEntity(),SALOME_MED::MED_ALL_ELEMENTS);
449   else
450     len_value = FirstSupport -> getNumberOfElements(SALOME_MED::MED_ALL_ELEMENTS);
451
452   // Values of new field
453   int totalLength = nb_comp*len_value;
454   double * new_value = new double[totalLength];
455
456   for(int i=0 ; i<totalLength ; i++) 
457     new_value[i] = x1 ;
458  
459
460   // Creation of a Local Field
461
462   MESSAGE("CalculatorEngine::Constant Creation of the local field "<< totalLength);
463
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);
471
472   // Control
473   int until_index = ( 20 > len_value)? len_value : 20 ;
474   PrintFieldValues (fieldloc,until_index);
475
476   // Creation of the new CORBA field
477
478   MESSAGE("CalculatorEngine::Constant Creation of the CORBA field");
479
480   SUPPORT *supportClt=new SUPPORTClient(FirstSupport);
481   fieldloc->setSupport(supportClt);
482   TFieldDouble_i * NewField = new TFieldDouble_i(fieldloc) ;
483
484   SALOME_MED::FIELDDOUBLE_ptr myFieldIOR = NewField->_this() ;
485   
486   //sleep(4);
487
488   endService("CalculatorEngine::Const");
489   
490   END_OF("CalculatorEngine::Constant(SALOME_MED::FIELDDOUBLE_ptr FirstField,CORBA::Double x1)");
491   
492   return myFieldIOR;
493   
494 }
495
496 //================================================================================
497 //  write a field in a MED file
498 //================================================================================
499
500 static omni_mutex aWriteMEDfileMutex;
501 void CalculatorEngine::writeMEDfile(SALOME_MED::FIELDDOUBLE_ptr field, const char *filename)
502 {
503   omni_mutex_lock aLock(aWriteMEDfileMutex);
504
505   beginService("CalculatorEngine::writeMEDfile");
506   MESSAGE("fichier d'impression du champ resultat:"<<filename);
507
508   // get support of the field
509
510   SALOME_MED::SUPPORT_ptr support = field -> getSupport();
511   
512   // get mesh from this support
513   
514   SALOME_MED::MESH_ptr mesh = support -> getMesh();
515   
516   // write the mesh
517   
518   int index_m = mesh->addDriver(SALOME_MED::MED_DRIVER,filename,mesh->getName());
519
520   mesh -> write(index_m,"");
521
522   //write the field
523   
524   const char * LOC = "CalculatorEngine::writeMEDfile ";
525   
526   MESSAGE("fichier :"<<filename);
527
528   med_2_1::med_idt _medIdt = med_2_1::MEDouvrir(const_cast <char *> (filename) , med_2_1::MED_ECRI);
529   SCRUTE(_medIdt);
530
531   if (_medIdt<0) return;
532   
533   int err ;
534
535   int component_count= field->getNumberOfComponents();
536   string   component_name(component_count*MED_TAILLE_PNOM,' ') ;
537   string   component_unit(component_count*MED_TAILLE_PNOM,' ') ;
538   
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);
542   }
543   
544   MESSAGE("component_name=|"<<component_name<<"|");
545   MESSAGE("component_unit=|"<<component_unit<<"|");
546   
547   // already existing ?
548   
549   char * champName = new char[MED_TAILLE_NOM+1] ;
550   char * compName,  * compUnit  ;
551   bool Find = false ;
552
553   int n = med_2_1::MEDnChamp(_medIdt,0);
554   int nbComp ;
555
556   med_2_1::med_type_champ type ;
557
558   for (int i = 1;  i <= n;  i++) 
559     {
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];
563
564       err = med_2_1::MEDchampInfo(_medIdt,i,champName,&type,compName,compUnit,nbComp);
565       if (err == 0)
566         if (strcmp(champName, field->getName())==0) { // Found !
567           Find = true ;
568           break ;
569         }
570
571       delete[] compName ;
572       delete[] compUnit ;
573
574     }
575   if (Find) {
576     // the same ?
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."
581                                      )
582                          );
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);
588     delete[] compName ;
589     delete[] compUnit ;
590     
591   } else { 
592     // Verify the field doesn't exist
593     
594     string dataGroupName =  "/CHA/"+ string(field->getName());
595
596     MESSAGE(LOC << "|" << dataGroupName << "|" );
597
598     med_2_1::med_idt gid =  H5Gopen(_medIdt, dataGroupName.c_str() );
599     
600     if ( gid < 0 ) {
601       // create field :
602       err=med_2_1::MEDchampCr(_medIdt, 
603                              const_cast <char*> (field->getName()),
604                              med_2_1::MED_REEL64,
605                              const_cast <char*> ( component_name.c_str() ),
606                              const_cast <char*> ( component_unit.c_str() ),
607                              component_count);
608       if ( err < 0 )
609         throw MEDEXCEPTION( LOCALIZED (STRING(LOC) 
610                                        << ": Error MEDchampCr : "<<err
611                                        )
612                            );
613     }
614         else H5Gclose(gid);
615   }
616   
617   SALOME_MED::SUPPORT_ptr mySupport = field -> getSupport();
618   SCRUTE(mySupport);
619   
620   if (! mySupport->isOnAllElements())
621     throw MEDEXCEPTION ( LOCALIZED (STRING(LOC) 
622                                    <<": Field must be on all entity"
623                                     )
624                         );
625   
626   SALOME_MED::MESH_ptr myMesh = mySupport -> getMesh();
627   SCRUTE(mesh);
628
629   SALOME_MED::medGeometryElement_array* Types = mySupport->getTypes() ;
630
631   int NumberOfType = Types->length() ;
632
633   for ( int i = 0; i < NumberOfType; i++ ) 
634     {
635       int NumberOfElements   = mySupport->getNumberOfElements ( (*Types)[i] ) ;
636       int NumberOfGaussPoint = mySupport->getNumberOfGaussPoint ( (*Types)[i] ) ;
637     
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() );
647     
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];
652
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,
658                               NumberOfElements,
659                               NumberOfGaussPoint,
660                               MED_ALL, 
661                               MED_NOPFL, 
662                               med_2_1::MED_REMP,  
663                               (med_2_1::med_entite_maillage)convertIdlEntToMedEnt(mySupport->getEntity()),
664                               (med_2_1::med_geometrie_element)(convertIdlEltToMedElt((*Types)[i])),
665                               field->getIterationNumber(),
666                               "        ",
667                               field->getTime(),
668                               field->getOrderNumber()
669                               );
670       delete locvalue;
671       
672       if (err < MED_VALID )
673         throw MEDEXCEPTION(LOCALIZED( STRING(LOC)
674                                      <<": Error in writing Field "<< field->getName() <<", type "<<(*Types)[i]
675                                      )
676                            );
677     }
678   END_OF( LOC );
679   
680   SCRUTE( err );
681   if (err < 0 ) return ;
682   
683   med_2_1::MEDfermer(_medIdt) ;
684   
685   endService("CalculatorEngine::writeMEDfile");
686   return ;
687   
688 }
689
690 extern "C"
691 {
692   //===========================================================================
693   // CalculatorEngine_factory
694   //===========================================================================
695   PortableServer::ObjectId * CalculatorEngine_factory
696      (CORBA::ORB_ptr orb,
697       PortableServer::POA_ptr poa, 
698       PortableServer::ObjectId * contId,
699       const char *instanceName,
700       const char *interfaceName)
701   {
702     MESSAGE("CalculatorEngine_factory CalculatorEngine ("
703             << instanceName << "," << interfaceName << ")");
704     CalculatorEngine * myCalculator 
705       = new CalculatorEngine(orb, poa, contId, instanceName, interfaceName);
706     return myCalculator->getId() ;
707   }
708 }
709
710