1 // Copyright (C) 2007-2013 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
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.
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.
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
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
23 #include "CALCULATOR.hxx"
24 #include "CALCULATOR_version.h"
26 #include "MEDCouplingFieldDoubleClient.hxx"
27 #include "MEDCouplingMeshClient.hxx"
29 #include "MEDCouplingMeshServant.hxx"
30 #include "MEDCouplingFieldDoubleServant.hxx"
32 #include "MEDCouplingAutoRefCountObjectPtr.hxx"
33 #include "MEDCouplingMemArray.hxx"
46 CALCULATOR::CALCULATOR (CORBA::ORB_ptr orb,
47 PortableServer::POA_ptr poa,
48 PortableServer::ObjectId * contId,
49 const char *instanceName,
50 const char *interfaceName)
51 : Engines_Component_i(orb, poa, contId, instanceName, interfaceName, true),
52 _errorCode(CALCULATOR_ORB::NO_ERROR)
55 _id = _poa->activate_object(_thisObj);
58 CALCULATOR::~CALCULATOR()
62 CORBA::Double CALCULATOR::norm2(SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_ptr field1)
64 beginService( "CALCULATOR::norm2");
65 _errorCode = CALCULATOR_ORB::NO_ERROR;
66 //const char* LOC = "CALCULATOR::Norm2(SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_ptr field1)";
68 if(CORBA::is_nil(field1))
70 _errorCode = CALCULATOR_ORB::INVALID_FIELD;
74 CORBA::Double norme = 0.0;
75 // Create a local field from corba field, apply method normMax on it.
76 // When exiting the function, f1 is deleted, and with it the remote corba field.
77 ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingFieldDouble> f1=ParaMEDMEM::MEDCouplingFieldDoubleClient::New(field1);
78 /*ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::DataArrayDouble> d=ParaMEDMEM::DataArrayDouble::Multiply(f1->getArray(),f1->getArray());
81 norme = d->accumulate(0);
84 _errorCode = CALCULATOR_ORB::EXCEPTION_RAISED;
92 _errorCode = CALCULATOR_ORB::EXCEPTION_RAISED;
95 endService( "CALCULATOR::norm2");
99 CORBA::Double CALCULATOR::normL2(SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_ptr field1)
101 beginService( "CALCULATOR::normL2");
102 _errorCode = CALCULATOR_ORB::NO_ERROR;
103 //const char* LOC = "CALCULATOR::NormL2(SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_ptr field1)";
106 if(CORBA::is_nil(field1))
108 _errorCode = CALCULATOR_ORB::INVALID_FIELD;
112 //Check that the Field is not on the Nodes (a limitation of normL2)
113 ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingFieldDouble> f1=ParaMEDMEM::MEDCouplingFieldDoubleClient::New(field1);
115 if(f1->getTypeOfField()==ParaMEDMEM::ON_NODES)
117 _errorCode = CALCULATOR_ORB::NOT_COMPATIBLE;
121 CORBA::Double norme = 0.0;
124 norme = f1->normL2(0);
128 _errorCode = CALCULATOR_ORB::EXCEPTION_RAISED;
131 // Send a notification message to supervision
132 ostringstream message("CALCULATOR::normL2 : ");
134 sendMessage("warning",message.str().c_str());
136 endService( "CALCULATOR::normL2");
140 CORBA::Double CALCULATOR::normMax(SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_ptr field1)
142 beginService( "CALCULATOR::normMax");
143 _errorCode = CALCULATOR_ORB::NO_ERROR;
145 if(CORBA::is_nil(field1))
147 _errorCode = CALCULATOR_ORB::INVALID_FIELD;
151 CORBA::Double norme = 0.0;
152 ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingFieldDouble> f1=ParaMEDMEM::MEDCouplingFieldDoubleClient::New(field1);
155 norme = f1->normMax();
159 _errorCode = CALCULATOR_ORB::EXCEPTION_RAISED;
163 endService( "CALCULATOR::normMax");
167 CORBA::Double CALCULATOR::normL1(SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_ptr field1)
169 beginService( "CALCULATOR::normL1");
170 _errorCode = CALCULATOR_ORB::NO_ERROR;
172 if(CORBA::is_nil(field1)) {
173 _errorCode = CALCULATOR_ORB::INVALID_FIELD;
177 //Check that the Field is not on the Nodes (a limitation of normL1)
178 ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingFieldDouble> f1=ParaMEDMEM::MEDCouplingFieldDoubleClient::New(field1);
179 if (f1->getTypeOfField()==ParaMEDMEM::ON_NODES) {
180 _errorCode = CALCULATOR_ORB::NOT_COMPATIBLE;
184 CORBA::Double norme = 0.0;
186 norme = f1->normL1(0);
189 _errorCode = CALCULATOR_ORB::EXCEPTION_RAISED;
192 endService( "CALCULATOR::normL1");
196 SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_ptr CALCULATOR::applyLin(SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_ptr field1,CORBA::Double a,CORBA::Double b)
198 beginService( "CALCULATOR::applyLin");
199 _errorCode = CALCULATOR_ORB::NO_ERROR;
201 if(CORBA::is_nil(field1))
203 _errorCode = CALCULATOR_ORB::INVALID_FIELD;
207 // create a local field on the heap, because it has to remain after exiting the function
208 ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingFieldDouble> f1=ParaMEDMEM::MEDCouplingFieldDoubleClient::New(field1);
209 int nbOfCompo=f1->getArray()->getNumberOfComponents();
210 f1->getArray()->rearrange(1);
211 ParaMEDMEM::MEDCouplingFieldDoubleServant *NewField=NULL;
212 SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_ptr myFieldIOR = NULL;
217 f1->getArray()->rearrange(nbOfCompo);
218 // create servant from f1, give it the property of c++ field (parameter true).
219 // This imply that when the client will release it's field, it will delete NewField,
221 NewField = new ParaMEDMEM::MEDCouplingFieldDoubleServant(f1);
223 myFieldIOR = NewField->_this() ;
227 _errorCode = CALCULATOR_ORB::EXCEPTION_RAISED;
230 endService( "CALCULATOR::applyLin");
234 SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_ptr CALCULATOR::add(SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_ptr field1, SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_ptr field2)
236 beginService( "CALCULATOR::add");
237 _errorCode = CALCULATOR_ORB::NO_ERROR;
238 //const char* LOC = "CALCULATOR::add(SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_ptr field1, SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_ptr field2)";
240 if(CORBA::is_nil(field1) || CORBA::is_nil(field2))
242 _errorCode = CALCULATOR_ORB::INVALID_FIELD;
246 // Create local fields from corba field
247 ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingFieldDouble> f1=ParaMEDMEM::MEDCouplingFieldDoubleClient::New(field1);
248 ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingFieldDouble> f2=ParaMEDMEM::MEDCouplingFieldDoubleClient::New(field2);
250 // catch exception for non compatible fields
251 ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingFieldDouble> fres;
254 f2->changeUnderlyingMesh(f1->getMesh(),0,1e-12);
257 catch(INTERP_KERNEL::Exception)
259 _errorCode = CALCULATOR_ORB::NOT_COMPATIBLE;
263 // create CORBA field from c++ toField. give property to servant (true)
264 ParaMEDMEM::MEDCouplingFieldDoubleServant *myFieldDoubleI=new ParaMEDMEM::MEDCouplingFieldDoubleServant(fres);
265 SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_ptr myFieldIOR = myFieldDoubleI->_this();
266 endService( "CALCULATOR::add");
270 void CALCULATOR::cloneField(SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_ptr field,
271 SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_out clone1, SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_out clone2,
272 SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_out clone3, SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_out clone4)
274 beginService( "CALCULATOR::cloneField");
275 _errorCode = CALCULATOR_ORB::NO_ERROR;
277 if(CORBA::is_nil(field))
279 _errorCode = CALCULATOR_ORB::INVALID_FIELD;
283 // load local field, using MED ressource file pointe.med
284 ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingFieldDouble> f=ParaMEDMEM::MEDCouplingFieldDoubleClient::New(field);
286 // create three c++ field on the heap by copying myField_
287 // All this fields share with f the same SUPPORT and MESH client.
288 // Both SUPPORT and MESH client are connected to a reference count, and will
289 // be deleted after release of all the fields.
290 ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingFieldDouble> fc1=ParaMEDMEM::MEDCouplingFieldDoubleClient::New(field);
291 ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingFieldDouble> fc2=ParaMEDMEM::MEDCouplingFieldDoubleClient::New(field);
292 ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingFieldDouble> fc3=ParaMEDMEM::MEDCouplingFieldDoubleClient::New(field);
293 ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingFieldDouble> fc4=ParaMEDMEM::MEDCouplingFieldDoubleClient::New(field);
295 // Initialize out references :
296 // Create three CORBA clones with cloned c++ fields - give property of c++ fields to servant (true)
297 ParaMEDMEM::MEDCouplingFieldDoubleServant * myClone1 = new ParaMEDMEM::MEDCouplingFieldDoubleServant(fc1);
298 ParaMEDMEM::MEDCouplingFieldDoubleServant * myClone2 = new ParaMEDMEM::MEDCouplingFieldDoubleServant(fc2);
299 ParaMEDMEM::MEDCouplingFieldDoubleServant * myClone3 = new ParaMEDMEM::MEDCouplingFieldDoubleServant(fc3);
300 ParaMEDMEM::MEDCouplingFieldDoubleServant * myClone4 = new ParaMEDMEM::MEDCouplingFieldDoubleServant(fc4);
301 clone1 = myClone1->_this();
302 clone2 = myClone2->_this();
303 clone3 = myClone3->_this();
304 clone4 = myClone4->_this();
305 endService( "CALCULATOR::cloneField");
309 void CALCULATOR::printField(SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_ptr field)
311 beginService( "CALCULATOR::printField");
312 _errorCode = CALCULATOR_ORB::NO_ERROR;
314 if(CORBA::is_nil(field))
316 _errorCode = CALCULATOR_ORB::INVALID_FIELD;
320 // Create a local field from corba field.
321 // Use auto_ptr to perform automatic deletion after usage.
322 // The deletion of the FIELDClient will delete the remote Corba object.
323 ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingFieldDouble> myField=ParaMEDMEM::MEDCouplingFieldDoubleClient::New(field);
324 cout << myField->advancedRepr() ;
327 cout << "Norme euclidienne : " << myField->norm2() << endl;
328 cout << "Norme max : " << myField->normMax() << endl;
329 cout << "------------------------------------------------------------------------" << endl << endl;
330 endService( "CALCULATOR::printField");
335 CORBA::Double CALCULATOR::convergenceCriteria(SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_ptr field)
337 beginService( "CALCULATOR::convergenceCriteria");
338 _errorCode = CALCULATOR_ORB::NO_ERROR;
340 if(CORBA::is_nil(field))
342 _errorCode = CALCULATOR_ORB::INVALID_FIELD;
347 static ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingFieldDouble> fold(0);
348 ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingFieldDouble> fnew=ParaMEDMEM::MEDCouplingFieldDoubleClient::New(field);
352 if ((ParaMEDMEM::MEDCouplingFieldDouble*)fold == NULL) // if old field is not set, set it and return 1
356 // if size of fields are not equal, return 1
357 // catch exception for non compatible fields
358 ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingFieldDouble> fres;
361 fnew->changeUnderlyingMesh(fold->getMesh(),0,1e-12);
362 fres = (*fnew)-(*fold);
363 criteria = fres->normMax();
365 catch(INTERP_KERNEL::Exception)
367 _errorCode = CALCULATOR_ORB::NOT_COMPATIBLE;
373 _errorCode = CALCULATOR_ORB::EXCEPTION_RAISED;
376 endService( "CALCULATOR::convergenceCriteria");
380 CORBA::Boolean CALCULATOR::isDone()
382 return (_errorCode == CALCULATOR_ORB::NO_ERROR);
385 CALCULATOR_ORB::ErrorCode CALCULATOR::getErrorCode()
390 // Version information
391 char* CALCULATOR::getVersion()
393 #if CALCULATOR_DEVELOPMENT
394 return CORBA::string_dup(CALCULATOR_VERSION_STR"dev");
396 return CORBA::string_dup(CALCULATOR_VERSION_STR);
400 //=============================================================================
402 * CALCULATOREngine_factory
404 * C factory, accessible with dlsym, after dlopen
406 //=============================================================================
410 PortableServer::ObjectId * CALCULATOREngine_factory (CORBA::ORB_ptr orb,
411 PortableServer::POA_ptr poa,
412 PortableServer::ObjectId * contId,
413 const char *instanceName,
414 const char *interfaceName)
416 CALCULATOR * myCALCULATOR = new CALCULATOR (orb, poa, contId, instanceName, interfaceName);
417 return myCALCULATOR->getId();