1 // Copyright (C) 2005 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
8 // This library is distributed in the hope that it will be useful
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 #include "CALCULATOR.hxx"
20 #include "FIELDClient.hxx"
21 #include "MESHClient.hxx"
24 #include "MEDMEM_Mesh_i.hxx"
25 #include "MEDMEM_Support_i.hxx"
26 #include "MEDMEM_FieldTemplate_i.hxx"
30 using namespace MEDMEM;
32 typedef FIELD<double,MEDMEM::FullInterlace> TFieldDouble;
33 typedef FIELDClient<double,MEDMEM::FullInterlace> TFieldDouble_c;
34 typedef FIELDTEMPLATE_I<double,MEDMEM::FullInterlace> TFieldDouble_i;
36 CALCULATOR::CALCULATOR(CORBA::ORB_ptr orb,
37 PortableServer::POA_ptr poa,
38 PortableServer::ObjectId * contId,
39 const char *instanceName,
40 const char *interfaceName) :
41 Engines_Component_i(orb, poa, contId, instanceName, interfaceName,true)
43 MESSAGE("activate object");
45 _id = _poa->activate_object(_thisObj);
47 _errorCode = CALCULATOR_ORB::NO_ERROR;
50 CALCULATOR::~CALCULATOR()
54 CORBA::Double CALCULATOR::norm2(SALOME_MED::FIELDDOUBLE_ptr field1)
56 beginService( "CALCULATOR::norm2");
57 _errorCode = CALCULATOR_ORB::NO_ERROR;
58 BEGIN_OF("CALCULATOR::Norm2(SALOME_MED::FIELDDOUBLE_ptr field1)");
60 if(CORBA::is_nil(field1)) {
61 _errorCode = CALCULATOR_ORB::INVALID_FIELD;
65 CORBA::Double norme = 0.0;
66 // Create a local field from corba field, apply method normMax on it.
67 // When exiting the function, f1 is deleted, and with it the remote corba field.
68 TFieldDouble_c f1(field1);
74 _errorCode = CALCULATOR_ORB::EXCEPTION_RAISED;
77 END_OF("CALCULATOR::Norm2(SALOME_MED::FIELDDOUBLE_ptr field1)");
78 endService( "CALCULATOR::norm2");
82 CORBA::Double CALCULATOR::normL2(SALOME_MED::FIELDDOUBLE_ptr field1)
84 beginService( "CALCULATOR::normL2");
85 _errorCode = CALCULATOR_ORB::NO_ERROR;
86 BEGIN_OF("CALCULATOR::NormL2(SALOME_MED::FIELDDOUBLE_ptr field1)");
88 if(CORBA::is_nil(field1)) {
89 _errorCode = CALCULATOR_ORB::INVALID_FIELD;
93 //Check that the Field is not on the Nodes (a limitation of normL2)
94 SALOME_MED::SUPPORT_var aSupport = field1->getSupport();
95 if(CORBA::is_nil(aSupport) || aSupport->getEntity() == SALOME_MED::MED_NODE) {
96 _errorCode = CALCULATOR_ORB::NOT_COMPATIBLE;
100 // Create a local field (on the stack) from corba field, apply method normMax on it.
101 // When exiting the function, FIELDClient f1 is deleted, and with it the remote corba field.
102 TFieldDouble_c f1(field1);
104 CORBA::Double norme = 0.0;
109 _errorCode = CALCULATOR_ORB::EXCEPTION_RAISED;
112 // Send a notification message to supervision
113 ostringstream message("CALCULATOR::normL2 : ");
115 sendMessage("warning",message.str().c_str());
116 END_OF("CALCULATOR::NormL2(SALOME_MED::FIELDDOUBLE_ptr field1)");
117 endService( "CALCULATOR::normL2");
121 CORBA::Double CALCULATOR::normMax(SALOME_MED::FIELDDOUBLE_ptr field1)
123 beginService( "CALCULATOR::normMax");
124 _errorCode = CALCULATOR_ORB::NO_ERROR;
125 BEGIN_OF("CALCULATOR::NormMax(SALOME_MED::FIELDDOUBLE_ptr field1)");
127 if(CORBA::is_nil(field1)) {
128 _errorCode = CALCULATOR_ORB::INVALID_FIELD;
132 CORBA::Double norme = 0.0;
133 // An other way to do it : create an local field on the heap, inside an auto_ptr.
134 // When exiting the function, auto_ptr is deleted, and with it the local field and
135 // the remote field if ownership was transferred.
136 auto_ptr<TFieldDouble> f1 (new TFieldDouble_c(field1) );
139 norme = f1->normMax();
142 _errorCode = CALCULATOR_ORB::EXCEPTION_RAISED;
145 END_OF("CALCULATOR::NormMax(SALOME_MED::FIELDDOUBLE_ptr field1)");
146 endService( "CALCULATOR::normMax");
150 CORBA::Double CALCULATOR::normL1(SALOME_MED::FIELDDOUBLE_ptr field1)
152 beginService( "CALCULATOR::normL1");
153 _errorCode = CALCULATOR_ORB::NO_ERROR;
154 BEGIN_OF("CALCULATOR::NormL1(SALOME_MED::FIELDDOUBLE_ptr field1)");
156 if(CORBA::is_nil(field1)) {
157 _errorCode = CALCULATOR_ORB::INVALID_FIELD;
161 //Check that the Field is not on the Nodes (a limitation of normL1)
162 SALOME_MED::SUPPORT_var aSupport = field1->getSupport();
164 if(CORBA::is_nil(aSupport) || aSupport->getEntity() == SALOME_MED::MED_NODE) {
165 _errorCode = CALCULATOR_ORB::NOT_COMPATIBLE;
169 CORBA::Double norme = 0.0;
170 auto_ptr<TFieldDouble> f1 (new TFieldDouble_c(field1) );
173 norme = f1->normL1();
176 _errorCode = CALCULATOR_ORB::EXCEPTION_RAISED;
179 END_OF("CALCULATOR::Norm2(SALOME_MED::FIELDDOUBLE_ptr field1)");
180 endService( "CALCULATOR::normL1");
185 SALOME_MED::FIELDDOUBLE_ptr CALCULATOR::applyLin(SALOME_MED::FIELDDOUBLE_ptr field1,CORBA::Double a,CORBA::Double b)
187 beginService( "CALCULATOR::applyLin");
188 _errorCode = CALCULATOR_ORB::NO_ERROR;
189 BEGIN_OF("applyLin(SALOME_MED::FIELDDOUBLE_ptr field1,CORBA::Double a,CORBA::Double b)");
191 if(CORBA::is_nil(field1)) {
192 _errorCode = CALCULATOR_ORB::INVALID_FIELD;
196 SALOME_MED::FIELDDOUBLE_ptr myFieldIOR = NULL;
197 // create a local field on the heap, because it has to remain after exiting the function
198 TFieldDouble * f1 = new TFieldDouble_c(field1);
199 TFieldDouble_i * NewField = NULL;
203 // create servant from f1, give it the property of c++ field (parameter true).
204 // This imply that when the client will release it's field, it will delete NewField,
206 NewField = new TFieldDouble_i(f1,true) ;
208 myFieldIOR = NewField->_this() ;
211 _errorCode = CALCULATOR_ORB::EXCEPTION_RAISED;
214 END_OF("applyLin(SALOME_MED::FIELDDOUBLE_ptr field1,CORBA::Double a,CORBA::Double b)");
215 endService( "CALCULATOR::applyLin");
219 SALOME_MED::FIELDDOUBLE_ptr CALCULATOR::add(SALOME_MED::FIELDDOUBLE_ptr field1, SALOME_MED::FIELDDOUBLE_ptr field2)
221 beginService( "CALCULATOR::add");
222 _errorCode = CALCULATOR_ORB::NO_ERROR;
223 BEGIN_OF("CALCULATOR::add(SALOME_MED::FIELDDOUBLE_ptr field1, SALOME_MED::FIELDDOUBLE_ptr field2)");
225 if(CORBA::is_nil(field1) || CORBA::is_nil(field2)) {
226 _errorCode = CALCULATOR_ORB::INVALID_FIELD;
230 // Create local fields from corba field
231 TFieldDouble_c f1(field1);
232 TFieldDouble_c f2(field2);
234 // Create new c++ field on the heap by copying f1, add f2 to it.
235 TFieldDouble* fres = new TFieldDouble(f1);
237 // catch exception for non compatible fields
244 _errorCode = CALCULATOR_ORB::NOT_COMPATIBLE;
248 // create CORBA field from c++ toField. give property to servant (true)
249 TFieldDouble_i * myFieldDoubleI = new TFieldDouble_i(fres,true);
250 SALOME_MED::FIELDDOUBLE_ptr myFieldIOR = myFieldDoubleI->_this() ;
252 END_OF("CALCULATOR::add(SALOME_MED::FIELDDOUBLE_ptr field1, SALOME_MED::FIELDDOUBLE_ptr field2)");
253 endService( "CALCULATOR::add");
257 void CALCULATOR::cloneField(SALOME_MED::FIELDDOUBLE_ptr field,
258 SALOME_MED::FIELDDOUBLE_out clone1, SALOME_MED::FIELDDOUBLE_out clone2,
259 SALOME_MED::FIELDDOUBLE_out clone3, SALOME_MED::FIELDDOUBLE_out clone4)
261 beginService( "CALCULATOR::cloneField");
262 _errorCode = CALCULATOR_ORB::NO_ERROR;
263 BEGIN_OF("CALCULATOR::cloneField");
265 if(CORBA::is_nil(field)) {
266 _errorCode = CALCULATOR_ORB::INVALID_FIELD;
270 // load local field, using MED ressource file pointe.med
271 TFieldDouble_c f(field);
273 // create three c++ field on the heap by copying myField_
274 // All this fields share with f the same SUPPORT and MESH client.
275 // Both SUPPORT and MESH client are connected to a reference count, and will
276 // be deleted after release of all the fields.
277 TFieldDouble* fc1 = new TFieldDouble(f);
278 TFieldDouble* fc2 = new TFieldDouble(f);
279 TFieldDouble* fc3 = new TFieldDouble(f);
280 TFieldDouble* fc4 = new TFieldDouble(f);
282 // Initialize out references :
283 // Create three CORBA clones with cloned c++ fields - give property of c++ fields to servant (true)
284 TFieldDouble_i * myClone1 = new TFieldDouble_i(fc1, true);
285 TFieldDouble_i * myClone2 = new TFieldDouble_i(fc2, true);
286 TFieldDouble_i * myClone3 = new TFieldDouble_i(fc3, true);
287 TFieldDouble_i * myClone4 = new TFieldDouble_i(fc4, true);
288 clone1 = myClone1->_this();
289 clone2 = myClone2->_this();
290 clone3 = myClone3->_this();
291 clone4 = myClone4->_this();
292 END_OF("CALCULATOR::cloneField");
293 endService( "CALCULATOR::cloneField");
297 void CALCULATOR::printField(SALOME_MED::FIELDDOUBLE_ptr field)
299 beginService( "CALCULATOR::printField");
300 _errorCode = CALCULATOR_ORB::NO_ERROR;
302 if(CORBA::is_nil(field)) {
303 _errorCode = CALCULATOR_ORB::INVALID_FIELD;
307 // Create a local field from corba field.
308 // Use auto_ptr to perform automatic deletion after usage.
309 // The deletion of the FIELDClient will delete the remote Corba object.
310 auto_ptr<TFieldDouble> myField (new TFieldDouble_c(field) );
312 const SUPPORT * mySupport = myField->getSupport();
313 cout << "\n------------------ Field "<< myField->getName() << " : " <<myField->getDescription() << "------------------" << endl ;
314 int NumberOfComponents = myField->getNumberOfComponents() ;
315 cout << "- Type : " << mySupport->getEntity() << endl;
316 cout << "- Nombre de composantes : "<< NumberOfComponents << endl ;
317 cout << "- Nombre de valeurs : "<< myField->getNumberOfValues() << endl ;
318 for (int i=1; i<NumberOfComponents+1; i++) {
319 cout << " - composante "<<i<<" :"<<endl ;
320 cout << " - nom : "<<myField->getComponentName(i)<< endl;
321 cout << " - description : "<<myField->getComponentDescription(i) << endl;
322 cout << " - units : "<<myField->getMEDComponentUnit(i) << endl;
324 cout << "- iteration :" << endl ;
325 cout << " - numero : " << myField->getIterationNumber()<< endl ;
326 cout << " - ordre : " << myField->getOrderNumber()<< endl ;
327 cout << " - temps : " << myField->getTime()<< endl ;
328 cout << "- Type : " << myField->getValueType()<< endl;
330 cout << "- Valeurs :"<<endl;
331 int NumberOf = mySupport->getNumberOfElements(MED_ALL_ELEMENTS);
333 bool displayNode = mySupport->isOnAllElements() && mySupport->getEntity()==MED_NODE;
334 bool displayBary = mySupport->isOnAllElements() && mySupport->getEntity()==MED_CELL;
335 int dim_space = mySupport->getMesh()->getSpaceDimension();
336 const double * coord = mySupport->getMesh()->getCoordinates(MED_FULL_INTERLACE);
338 auto_ptr<TFieldDouble> barycenter(0);
340 barycenter=auto_ptr<TFieldDouble>(mySupport->getMesh()->getBarycenter(mySupport)) ;
343 for (int i=1; i<NumberOf+1; i++) {
344 const double * value = myField->getRow(i) ;
347 int N=(i-1)*dim_space;
348 cout << setw(width) << i << setw(width) << coord[N] << " " << setw(width) << coord[N+1]<< " " << setw(width) << coord[N+2] << " : " ;
351 cout << setw(width) << i << setw(width) << barycenter->getValueIJ(i,1) << " " << setw(width) << barycenter->getValueIJ(i,2)
352 << " " << setw(width) << barycenter->getValueIJ(i,3) << " : " ;
353 for (int j=0; j<NumberOfComponents; j++)
354 cout << value[j]<< " ";
358 cout << "Norme euclidienne : " << myField->norm2() << endl;
359 cout << "Norme max : " << myField->normMax() << endl;
360 cout << "------------------------------------------------------------------------" << endl << endl;
361 endService( "CALCULATOR::printField");
366 CORBA::Double CALCULATOR::convergenceCriteria(SALOME_MED::FIELDDOUBLE_ptr field)
368 beginService( "CALCULATOR::convergenceCriteria");
369 _errorCode = CALCULATOR_ORB::NO_ERROR;
370 BEGIN_OF("CALCULATOR::convergenceCriteria(SALOME_MED::FIELDDOUBLE_ptr field)");
372 if(CORBA::is_nil(field)) {
373 _errorCode = CALCULATOR_ORB::INVALID_FIELD;
378 static auto_ptr<TFieldDouble> fold(0);
379 auto_ptr<TFieldDouble> fnew (new TFieldDouble_c(field) );
382 if (fold.get() == NULL) // if old field is not set, set it and return 1
386 // if size of fields are not equal, return 1
387 const int size=fold->getNumberOfValues()*fold->getNumberOfComponents();
388 if ( size == fnew->getNumberOfValues()*fnew->getNumberOfComponents() )
390 //MED_EN::medModeSwitch mode=fold->getInterlacingType(); // storage mode
391 const double* oldVal= fold->getValue(); // retrieve values
392 const double* newVal= fnew->getValue();
394 double ecart_rel=0.0;
395 for (unsigned i=0; i!=size; ++i) // compute criteria
397 if ( oldVal[i] != 0.0)
399 ecart_rel = std::abs( (oldVal[i]-newVal[i])/oldVal[i] );
400 if ( ecart_rel>criteria )
408 _errorCode = CALCULATOR_ORB::EXCEPTION_RAISED;
411 endService( "CALCULATOR::convergenceCriteria");
412 END_OF("CALCULATOR::convergenceCriteria(SALOME_MED::FIELDDOUBLE_ptr field1)");
416 CORBA::Boolean CALCULATOR::isDone()
418 return (_errorCode == CALCULATOR_ORB::NO_ERROR);
421 CALCULATOR_ORB::ErrorCode CALCULATOR::getErrorCode()
429 PortableServer::ObjectId * CALCULATOREngine_factory(
431 PortableServer::POA_ptr poa,
432 PortableServer::ObjectId * contId,
433 const char *instanceName,
434 const char *interfaceName)
436 MESSAGE("PortableServer::ObjectId * CALCULATOREngine_factory()");
437 SCRUTE(interfaceName);
438 CALCULATOR * myCALCULATOR
439 = new CALCULATOR(orb, poa, contId, instanceName, interfaceName);
440 return myCALCULATOR->getId() ;