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