Salome HOME
Merge from V6_main 01/04/2013
[samples/component.git] / src / CalculatorComponent / CalculatorEngine.cxx
1 // Copyright (C) 2007-2013  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
10 //
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 // Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22
23 //  File   : CalculatorEngine.cxx
24 //  Author : Laurent DADA, CEA
25 //  Module : CalculatorComponent
26 //  $Header$
27 //
28 #include <unistd.h>
29
30 #include <iostream>
31 #include <sstream>
32
33 #include "COMPONENT_version.h"
34 #include "CalculatorEngine.hxx"
35 #include "MEDMEM_Support_i.hxx"
36 #include "SUPPORTClient.hxx"
37
38 #include "MEDMEM_define.hxx"
39 #include "MEDMEM_STRING.hxx"
40 #include "MEDMEM_Exception.hxx"
41 #include "MEDMEM_Unit.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_SNAME_SIZE
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   delete _NS;
110 }
111
112 char* CalculatorEngine::getVersion()
113 {
114 #if COMPONENT_DEVELOPMENT
115   return CORBA::string_dup(COMPONENT_VERSION_STR"dev");
116 #else
117   return CORBA::string_dup(COMPONENT_VERSION_STR);
118 #endif
119 }
120
121 static omni_mutex aPutToStudyMutex;
122 SALOME_MED::FIELDDOUBLE_ptr CalculatorEngine::PutToStudy(SALOME_MED::FIELDDOUBLE_ptr theField1,
123                                                          CORBA::Long theStudyId) {
124   omni_mutex_lock aLock(aPutToStudyMutex);
125
126   CORBA::Object_var anObj = _NS->Resolve("/myStudyManager");
127   SALOMEDS::StudyManager_var aManager  = SALOMEDS::StudyManager::_narrow(anObj);
128 //   SALOMEDS::ListOfOpenStudies_var aList = aManager->GetOpenStudies();
129 //   SALOMEDS::Study_var aStudy = aManager->GetStudyByName(aList[0]);
130   SALOMEDS::Study_var aStudy = aManager->GetStudyByID(theStudyId);
131   SALOMEDS::StudyBuilder_var aBuilder = aStudy->NewBuilder();
132
133   SALOMEDS::SComponent_var aComponent = aStudy->FindComponent("Calculator");
134   if (aComponent->_is_nil()) aComponent = aBuilder->NewComponent("Calculator");
135   SALOMEDS::GenericAttribute_var anAttr = aBuilder->FindOrCreateAttribute(aComponent, "AttributeName");
136   SALOMEDS::AttributeName_var aName = SALOMEDS::AttributeName::_narrow(anAttr);
137   aName->SetValue("Calculator");
138   
139   SALOMEDS::SObject_var aSO = aBuilder->NewObject(aComponent);
140   anAttr = aBuilder->FindOrCreateAttribute(aSO, "AttributeName");
141   aName = SALOMEDS::AttributeName::_narrow(anAttr);
142   char aFieldName[10];
143   sprintf(aFieldName, "Field_%d", (int)aSO->Tag());
144   aName->SetValue(strdup(aFieldName));
145   
146   ORB_INIT &init = *SINGLETON_<ORB_INIT>::Instance() ;
147   ASSERT(SINGLETON_<ORB_INIT>::IsAlreadyExisting()) ;
148   CORBA::ORB_var &orb = init(0,0);
149
150   string iorStr = orb->object_to_string(theField1);
151   anAttr = aBuilder->FindOrCreateAttribute(aSO, "AttributeIOR");
152   SALOMEDS::AttributeIOR_var anIOR = SALOMEDS::AttributeIOR::_narrow(anAttr);
153   anIOR->SetValue(iorStr.c_str());
154
155   return SALOME_MED::FIELDDOUBLE::_duplicate(theField1);
156 }
157
158
159 //=======================================================================================
160 //  Addition of 2 FieldNodeDouble (based on Med library)
161 //
162 //  We assume that :
163 //     - support
164 //     - number of components
165 //     - name, type, unit and description of components
166 //  are the same for the 2 fields.
167 //
168 //  Otherwise,
169 //  the result will be a copy of the first field.
170 //
171 //=======================================================================================
172
173 static omni_mutex anAddMutex;
174 SALOME_MED::FIELDDOUBLE_ptr CalculatorEngine::Add(SALOME_MED::FIELDDOUBLE_ptr FirstField,
175                                                   SALOME_MED::FIELDDOUBLE_ptr SecondField)
176 {
177   omni_mutex_lock aLock(anAddMutex);
178
179   ostringstream tmp;
180   bool          same_support = true;
181   
182   beginService("CalculatorEngine::Add");
183   
184   sendMessage(NOTIF_TRACE, "CalculatorEngine::Add is Computing");
185   
186   const char* LOC = "CalculatorEngine::Add(SALOME_MED::FIELDDOUBLE_ptr FirstField,SALOME_MED::FIELDDOUBLE_ptr SecondField)";
187   BEGIN_OF(LOC);
188
189   SCRUTE(FirstField);
190   SCRUTE(SecondField);
191
192   CORBA::String_var field1_name        = FirstField -> getName();
193   CORBA::String_var field2_name        = SecondField -> getName();
194   CORBA::String_var field_description = FirstField -> getDescription();
195
196   string message = string("\n             CalculatorEngine::Add : ") +
197                    string("\n                               first field name  --> ") + string(field1_name.in()) +
198                    string("\n                               second field name --> ") + string(field2_name.in());
199
200   sendMessage(NOTIF_TRACE, message.c_str());
201
202   // Number of components
203   int nb_comp1  = FirstField -> getNumberOfComponents();
204   int nb_comp2  = SecondField -> getNumberOfComponents();
205   if (nb_comp1 != nb_comp2) same_support = false;
206    MESSAGE( "  nb_comp1 --> " << nb_comp1 <<endl );
207    MESSAGE( "  nb_comp2 --> " << nb_comp2 <<endl );
208
209
210   /* Name Description and Unit of each component of the field */
211
212   string * component_name = new string[nb_comp1];
213   string * component_unit = new string[nb_comp1];
214
215   for (int i=0 ; i<nb_comp1 ; i++) {
216     CORBA::String_var name = FirstField -> getComponentName(i+1);
217     CORBA::String_var unit = FirstField -> getComponentUnit(i+1);
218     component_name[i].assign(name.in());
219     component_unit[i].assign(unit.in());
220
221     if (same_support) {
222       CORBA::String_var name2 = SecondField -> getComponentName(i+1);
223       CORBA::String_var unit2 = SecondField -> getComponentUnit(i+1);
224       if ( (component_name[i] != name2.in()) || (component_unit[i] != unit2.in()))
225         same_support = false;
226     }
227   }
228
229   MESSAGE("CalculatorEngine::Add Number of entities in the Support of each fields");
230  
231   // Number of entities in the Support of the field
232
233   int len_value1 = 0;
234   int len_value2 = 0;
235   SALOME_MED::SUPPORT_var support1 = FirstField -> getSupport();
236   SALOME_MED::SUPPORT_var support2 = SecondField -> getSupport();
237
238   SCRUTE(support1);
239
240   SCRUTE(support2);
241
242   SALOME_MED::GMESH_var mesh1 = support1 -> getMesh();
243   SALOME_MED::GMESH_var mesh2 = support2 -> getMesh();
244
245   SCRUTE(mesh1);
246   SCRUTE(mesh2);
247
248   if (same_support && support1 != support2) same_support = false;
249
250   if (support1 -> isOnAllElements())
251     len_value1 = mesh1-> getNumberOfElements(support1 -> getEntity(),SALOME_MED::MED_ALL_ELEMENTS);
252   else
253     len_value1 = support1 -> getNumberOfElements(SALOME_MED::MED_ALL_ELEMENTS);
254
255   SCRUTE(len_value1);
256
257   if (support2 -> isOnAllElements())
258     len_value2 = mesh2-> getNumberOfElements(support2 -> getEntity(),SALOME_MED::MED_ALL_ELEMENTS);
259   else
260     len_value2 = support2 -> getNumberOfElements(SALOME_MED::MED_ALL_ELEMENTS);
261
262   if (same_support && len_value1 != len_value2) same_support = false;
263
264   SCRUTE(len_value2);
265
266   // Values of new field
267   SALOME_TYPES::ListOfDouble * first_value = FirstField -> getValue(SALOME_MED::MED_FULL_INTERLACE);
268   SALOME_TYPES::ListOfDouble * second_value;
269   if (same_support) {
270     second_value = SecondField -> getValue(SALOME_MED::MED_FULL_INTERLACE);
271     tmp << "\n             CalculatorEngine::Add : " ;
272     tmp << "\n                               Number of entities in the Support of first field  = " << len_value1 ;
273     tmp << "\n                               Number of entities in the Support of second field = " << len_value2 ;
274     message = tmp.str();
275
276     sendMessage(NOTIF_TRACE, message.c_str());
277
278   }
279
280   int totalLength = nb_comp1*len_value1;
281   double * new_value = new double[totalLength];
282   if (same_support) 
283     {
284       sendMessage(NOTIF_TRACE, "CalculatorEngine::Add - field1 and field2 have the same support");
285
286       for(int i=0 ; i<totalLength ; i++) 
287         new_value[i] = ((*first_value)[i]) + ((*second_value)[i]);
288     }
289   else {
290     for(int i=0 ; i<totalLength ; i++) 
291       new_value[i] = ((*first_value)[i]) ;
292   }
293   
294   // Creation of a Local Field
295   
296   MESSAGE("CalculatorEngine::Add Creation of the local field "<< totalLength);
297   
298   TFieldDouble * fieldloc =  new TFieldDouble();
299   fieldloc -> allocValue(nb_comp1,len_value1);
300   fieldloc  -> setValue(new_value);
301   fieldloc  -> setName("-new_Add-");
302   fieldloc  -> setDescription( field_description.in() );
303   fieldloc -> setComponentsNames(component_name);
304   fieldloc -> setMEDComponentsUnits(component_unit);
305
306   delete [] new_value;
307   delete first_value;
308   if (same_support) 
309     delete second_value;
310   delete [] component_name;
311   delete [] component_unit;
312   mesh1->UnRegister();
313   mesh2->UnRegister();
314   support2->UnRegister();
315
316   // Control
317   int until_index = ( 20 > len_value1)? len_value1 : 20;
318   PrintFieldValues (fieldloc,until_index);
319
320   sendMessage(NOTIF_TRACE, "CalculatorEngine::Add - new field created");
321
322   // Export result
323   // Creation of the new CORBA field
324
325   MESSAGE("CalculatorEngine::Add Creation of the CORBA field");
326
327   SUPPORT *support1Clt=new SUPPORTClient(support1);
328   fieldloc->setSupport(support1Clt);
329   support1Clt->removeReference();
330
331   TFieldDouble_i * NewField = new TFieldDouble_i(fieldloc,true) ;
332   SALOME_MED::FIELDDOUBLE_ptr myFieldIOR = NewField->_this() ;
333
334   //sleep(4);
335
336   END_OF(LOC);
337
338   endService("CalculatorEngine::Add");
339   return myFieldIOR;
340 }
341
342
343 //===============================================================================
344 //  Multiplication of a FieldNodeDouble by a double value (based on Med library)
345 //===============================================================================
346
347 static omni_mutex aMulMutex;
348 SALOME_MED::FIELDDOUBLE_ptr CalculatorEngine::Mul(SALOME_MED::FIELDDOUBLE_ptr OldField,
349                                                   CORBA::Double x1)
350 {
351   omni_mutex_lock aLock(aMulMutex);
352
353   beginService("CalculatorEngine::Mul");
354   const char* LOC = "CalculatorEngine::Mul(SALOME_MED::FIELDDOUBLE_ptr OldField,CORBA::Double x1)";
355   BEGIN_OF(LOC);
356
357   SCRUTE(OldField);
358   SCRUTE(x1);
359
360   // Name and description of field
361   CORBA::String_var field_name        = OldField -> getName();
362   CORBA::String_var field_description = OldField -> getDescription();
363
364   // Number of components
365   int nb_comp  = OldField -> getNumberOfComponents();
366   string * component_name = new string[nb_comp];
367   string * component_unit = new string[nb_comp];
368
369   for (int i=0 ; i<nb_comp ; i++) {
370     CORBA::String_var name = OldField -> getComponentName(i+1);
371     component_name[i] = name.in();
372     CORBA::String_var unit = OldField -> getComponentUnit(i+1);
373     component_unit[i] = unit.in();
374   }
375
376   MESSAGE("CalculatorEngine::Mul Number of entities in the Support of the field");
377
378   // Number of entities in the Support of the field
379   int len_value = 0;
380
381   SALOME_MED::SUPPORT_var support = OldField -> getSupport();
382
383   SCRUTE(support);
384
385   SALOME_MED::GMESH_var mesh = support -> getMesh();
386
387   SCRUTE(mesh);
388
389   if (support -> isOnAllElements())
390     len_value = mesh-> getNumberOfElements(support -> getEntity(),SALOME_MED::MED_ALL_ELEMENTS);
391   else
392     len_value = support -> getNumberOfElements(SALOME_MED::MED_ALL_ELEMENTS);
393
394   SCRUTE(len_value);
395
396   // Values of new field
397   SALOME_TYPES::ListOfDouble * old_value = OldField -> getValue(SALOME_MED::MED_FULL_INTERLACE);
398
399   int totalLength = nb_comp*len_value;
400   double * new_value = new double[totalLength];
401   for(int i=0 ; i<totalLength ; i++) {
402     new_value[i] = x1 * ((*old_value)[i]);
403   }
404
405   // Creation of a Local Field
406
407   MESSAGE("CalculatorEngine::Mul Creation of the local field "<< totalLength);
408
409   TFieldDouble * fieldloc =  new TFieldDouble();
410   fieldloc -> allocValue(nb_comp,len_value);
411   fieldloc  -> setValue(new_value);
412   fieldloc  -> setName("-new_Mul-");
413   fieldloc  -> setDescription(field_description.in());
414   fieldloc -> setComponentsNames(component_name);
415   fieldloc -> setMEDComponentsUnits(component_unit);
416
417   delete old_value;
418   delete [] new_value;
419   delete [] component_name;
420   delete [] component_unit;
421   mesh->UnRegister();
422
423   // Creation of the new CORBA field
424
425   MESSAGE("CalculatorEngine::Mul Creation of the CORBA field");
426
427   SUPPORT *supportClt=new SUPPORTClient(support);
428   fieldloc->setSupport(supportClt);
429   supportClt->removeReference();
430   TFieldDouble_i * NewField = new TFieldDouble_i(fieldloc,true) ;
431   SALOME_MED::FIELDDOUBLE_ptr myFieldIOR = NewField->_this() ;
432
433   //sleep(4);
434
435   END_OF(LOC);
436
437   endService("CalculatorEngine::Mul");
438   return myFieldIOR;
439 }
440
441
442 //================================================================================
443 //  Build a constant field of double based on first field support (Med library)
444 //================================================================================
445
446 static omni_mutex aConstantMutex;
447 SALOME_MED::FIELDDOUBLE_ptr CalculatorEngine::Constant(SALOME_MED::FIELDDOUBLE_ptr FirstField,
448                                                        CORBA::Double x1)
449 {
450   omni_mutex_lock aLock(aConstantMutex);
451
452   beginService("CalculatorEngine::Const");
453   const char* LOC = "CalculatorEngine::Constant(SALOME_MED::FIELDDOUBLE_ptr FirstField,CORBA::Double x1)";
454   BEGIN_OF(LOC);
455
456   // Name and description of field
457   CORBA::String_var field_name        = FirstField -> getName();
458   CORBA::String_var field_description = FirstField -> getDescription();
459
460   SALOME_MED::SUPPORT_var FirstSupport = FirstField -> getSupport();
461
462   // Number of components
463   int nb_comp  = FirstField -> getNumberOfComponents();
464
465   // Type, name, unit and description of components
466   string * component_name = new string[nb_comp];
467   string * component_unit = new string[nb_comp];
468
469   for (int i = 0 ; i<nb_comp ; i++) {
470     CORBA::String_var name = FirstField -> getComponentName(i+1);
471     component_name[i] = name.in();
472     CORBA::String_var unit = FirstField -> getComponentUnit(i+1);
473     component_unit[i] = unit.in();
474   }
475
476   MESSAGE("CalculatorEngine::Constant Number of entities in the Support of the field");
477
478   // Number of entities in the Support of the field
479   int len_value = 0;
480
481   SCRUTE(FirstSupport);
482
483   SALOME_MED::GMESH_var mesh = FirstSupport -> getMesh();
484
485   SCRUTE(mesh);
486
487   if ( FirstSupport -> isOnAllElements() )
488     len_value = mesh -> getNumberOfElements(FirstSupport -> getEntity(),SALOME_MED::MED_ALL_ELEMENTS);
489   else
490     len_value = FirstSupport -> getNumberOfElements(SALOME_MED::MED_ALL_ELEMENTS);
491
492   // Values of new field
493   int totalLength = nb_comp*len_value;
494   double * new_value = new double[totalLength];
495
496   for(int i=0 ; i<totalLength ; i++) 
497     new_value[i] = x1 ;
498  
499
500   // Creation of a Local Field
501
502   MESSAGE("CalculatorEngine::Constant Creation of the local field "<< totalLength);
503
504   TFieldDouble * fieldloc =  new TFieldDouble();
505   fieldloc -> allocValue(nb_comp,len_value);
506   fieldloc  -> setValue(new_value);
507   fieldloc  -> setName("-new_Const_Field-");
508   fieldloc  -> setDescription(field_description.in());
509   fieldloc -> setComponentsNames(component_name);
510   fieldloc -> setMEDComponentsUnits(component_unit);
511
512   delete [] new_value;
513   delete [] component_name;
514   delete [] component_unit;
515   mesh->UnRegister();
516
517   // Control
518   int until_index = ( 20 > len_value)? len_value : 20 ;
519   PrintFieldValues (fieldloc,until_index);
520
521   // Creation of the new CORBA field
522
523   MESSAGE("CalculatorEngine::Constant Creation of the CORBA field");
524
525   SUPPORT *supportClt=new SUPPORTClient(FirstSupport);
526   fieldloc->setSupport(supportClt);
527   supportClt->removeReference();
528   TFieldDouble_i * NewField = new TFieldDouble_i(fieldloc,true) ;
529
530   SALOME_MED::FIELDDOUBLE_ptr myFieldIOR = NewField->_this() ;
531   
532   //sleep(4);
533
534   endService("CalculatorEngine::Const");
535   
536   END_OF(LOC);
537   
538   return myFieldIOR;
539 }
540
541 //================================================================================
542 //  write a field in a MED file
543 //================================================================================
544
545 static omni_mutex aWriteMEDfileMutex;
546 void CalculatorEngine::writeMEDfile(SALOME_MED::FIELDDOUBLE_ptr field, const char *filename)
547 {
548   omni_mutex_lock aLock(aWriteMEDfileMutex);
549   
550   const char * LOC = "CalculatorEngine::writeMEDfile ";
551
552   beginService("CalculatorEngine::writeMEDfile");
553   BEGIN_OF(LOC);
554   MESSAGE("fichier d'impression du champ resultat:"<<filename);
555
556   // get support of the field
557
558   SALOME_MED::SUPPORT_ptr support = field -> getSupport();
559   
560   // get mesh from this support
561   
562   SALOME_MED::GMESH_ptr mesh = support -> getMesh();
563   
564   // write the mesh
565   
566   int index_m = mesh->addDriver(SALOME_MED::MED_DRIVER,filename,mesh->getName());
567
568   mesh -> write(index_m,"");
569
570   //write the field
571   
572   MESSAGE("fichier :"<<filename);
573
574   med_2_3::med_idt _medIdt = med_2_3::MEDfileOpen(const_cast <char *> (filename) , med_2_3::MED_ACC_RDWR);
575   SCRUTE(_medIdt);
576
577   if (_medIdt<0) return;
578   
579   int err ;
580
581   int component_count= field->getNumberOfComponents();
582   string   component_name(component_count*MED_TAILLE_PNOM,' ') ;
583   string   component_unit(component_count*MED_TAILLE_PNOM,' ') ;
584   
585   for (int i=0; i < component_count ; i++) {
586     component_name.replace(i*MED_TAILLE_PNOM,MED_TAILLE_PNOM,(field -> getComponentName(i+1)),0,MED_TAILLE_PNOM);
587     component_unit.replace(i*MED_TAILLE_PNOM,MED_TAILLE_PNOM,(field -> getComponentUnit(i+1)),0,MED_TAILLE_PNOM);
588   }
589   
590   MESSAGE("component_name=|"<<component_name<<"|");
591   MESSAGE("component_unit=|"<<component_unit<<"|");
592   
593   // already existing ?
594   
595   char * champName  = new char[MED_NAME_SIZE+1] ;
596   char * meshName   = new char[MED_NAME_SIZE+1] ;
597   char * compDtunit = new char[MED_SNAME_SIZE+1];
598   char * compName,  * compUnit;
599   bool Find = false ;
600
601   int n = med_2_3::MEDnField(_medIdt);
602   
603   med_2_3::med_int nbComp ;
604   med_2_3::med_field_type type ;
605   med_2_3::med_bool _local;
606
607   for (int i = 1;  i <= n;  i++) 
608   {
609     nbComp = med_2_3::MEDnField(_medIdt);
610     compName   = new char[MED_TAILLE_PNOM*nbComp+1];
611     compUnit   = new char[MED_TAILLE_PNOM*nbComp+1];
612     
613     err = med_2_3::MEDfieldInfo(_medIdt,i,champName,meshName,&_local,&type,compName,compUnit,compDtunit,&nbComp);
614     if (err == 0) {
615       if (strcmp(champName, field->getName())==0) { // Found !
616         Find = true ;
617         break ;
618       }
619     }
620     delete[] compName ;
621     delete[] compUnit ;
622   }
623   
624   
625   if (Find)
626   {
627     // the same ?
628     if (nbComp != component_count)
629       throw MEDEXCEPTION ( LOCALIZED (STRING(LOC)
630                           <<": Field exist in file, but number of component are different : " \
631                           <<nbComp<<" in file and "<<component_count<<" in CORBA object."
632                           )
633                           );
634                           
635     // component name and unit
636     MESSAGE(LOC<<" Component name in file : "<<compName);
637     MESSAGE(LOC<<" Component name in CORBA object : "<<component_name);
638     MESSAGE(LOC<<" Component unit in file : "<<compUnit);
639     MESSAGE(LOC<<" Component unit in CORBA object : "<<component_unit);
640     delete[] compName ;
641     delete[] compUnit ;
642
643   }
644   else
645   {
646     // Verify the field doesn't exist
647     string dataGroupName =  "/CHA/"+ string(field->getName());
648     
649     MESSAGE(LOC << "|" << dataGroupName << "|" );
650     
651     med_2_3::med_idt gid =  H5Gopen(_medIdt, dataGroupName.c_str() );
652     
653     if ( gid < 0 )
654     {
655       // create field :
656       err=med_2_3::MEDfieldCr(_medIdt,
657                               const_cast <char*> (field->getName()),
658                               med_2_3::MED_FLOAT64,
659                               component_count,
660                               const_cast <char*> ( component_name.c_str() ),
661                               const_cast <char*> ( component_unit.c_str() ),
662                               compDtunit,
663                               meshName);
664       if ( err < 0 )
665         throw MEDEXCEPTION( LOCALIZED (STRING(LOC) << ": Error MEDfieldCr : "<<err ));
666     }
667     else
668       H5Gclose(gid);
669   }
670   
671   SALOME_MED::SUPPORT_ptr mySupport = field -> getSupport();
672   SCRUTE(mySupport);
673   
674   if (! mySupport->isOnAllElements())
675     throw MEDEXCEPTION ( LOCALIZED (STRING(LOC) 
676                         <<": Field must be on all entity"
677                         )
678                         );
679   SALOME_MED::MESH_ptr myMesh = mySupport -> getMesh()->convertInMESH();
680   SCRUTE(mesh);
681
682   SALOME_MED::medGeometryElement_array* Types = mySupport->getTypes() ;
683
684   int NumberOfType = Types->length() ;
685
686   for ( int i = 0; i < NumberOfType; i++ ) 
687   {
688     int NumberOfElements   = mySupport->getNumberOfElements ( (*Types)[i] ) ;
689     //Temporarily commented to avoid compilation errors:int NumberOfGaussPoint = mySupport->getNumberOfGaussPoint ( (*Types)[i] ) ;
690     int NumberOfGaussPoint = 1; //Temporary line instead of the above one
691
692     MESSAGE( " " << field->getName() );
693     MESSAGE( " " << NumberOfElements );
694     //!!!tmp commented:MESSAGE( " " << NumberOfGaussPoint );
695     MESSAGE( "Attention! NumberOfGaussPoint is invalid: " << NumberOfGaussPoint ); //tmp line!!!
696     MESSAGE( " " << (int) (convertIdlEntToMedEnt(mySupport->getEntity())) );
697     MESSAGE( " " << (int)(convertIdlEltToMedElt((*Types)[i])) );
698     MESSAGE( " " << field->getIterationNumber() );
699     MESSAGE( " " << field->getTime() );
700     MESSAGE( " " << field->getOrderNumber() );
701     MESSAGE( "MEDchampEcr :" << myMesh->getName() );
702
703     SALOME_TYPES::ListOfDouble * value = field->getValue( SALOME_MED::MED_FULL_INTERLACE ) ;
704     double *locvalue = new double[NumberOfElements];
705     for (int k = 0; k < NumberOfElements; k++) 
706       locvalue[k] = (*value) [k];
707     
708     err=med_2_3::MEDfieldValueWithProfileWr(_medIdt,
709                                             const_cast <char*> (field->getName()),
710                                             MED_NO_DT,
711                                             MED_NO_IT,
712                                             field->getTime(),
713                                             (med_2_3::med_entity_type)convertIdlEntToMedEnt(mySupport->getEntity()),
714                                             (med_2_3::med_geometry_type)(convertIdlEltToMedElt((*Types)[i])),
715                                             med_2_3::MED_COMPACT_PFLMODE,
716                                             MED_ALLENTITIES_PROFILE,
717                                             " ",
718                                             med_2_3::MED_FULL_INTERLACE,
719                                             SALOME_MED::MED_ALL_ELEMENTS,
720                                             1,
721                                             (unsigned char*)locvalue
722                                             );
723
724     delete locvalue;
725     
726     if (err < MED_VALID )
727       throw MEDEXCEPTION(LOCALIZED( STRING(LOC)
728       <<": Error in writing Field "<< field->getName() <<", type "<<(*Types)[i]
729       )
730       );
731   }
732   END_OF(LOC);
733
734   SCRUTE( err );
735   if (err < 0 ) return;
736
737   med_2_3::MEDfileClose(_medIdt);
738
739   endService("CalculatorEngine::writeMEDfile");
740   return;
741 }
742
743 extern "C"
744 {
745   //===========================================================================
746   // CalculatorEngine_factory
747   //===========================================================================
748   PortableServer::ObjectId * CalculatorEngine_factory
749      (CORBA::ORB_ptr orb,
750       PortableServer::POA_ptr poa, 
751       PortableServer::ObjectId * contId,
752       const char *instanceName,
753       const char *interfaceName)
754   {
755     MESSAGE("CalculatorEngine_factory CalculatorEngine ("
756             << instanceName << "," << interfaceName << ")");
757     CalculatorEngine * myCalculator 
758       = new CalculatorEngine(orb, poa, contId, instanceName, interfaceName);
759     return myCalculator->getId() ;
760   }
761 }