1 // Copyright (C) 2007-2012 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"
25 #include "MEDCouplingFieldDoubleClient.hxx"
26 #include "MEDCouplingMeshClient.hxx"
28 #include "MEDCouplingMeshServant.hxx"
29 #include "MEDCouplingFieldDoubleServant.hxx"
31 #include "MEDCouplingAutoRefCountObjectPtr.hxx"
32 #include "MEDCouplingMemArray.hxx"
45 CALCULATOR::CALCULATOR (CORBA::ORB_ptr orb,
46 PortableServer::POA_ptr poa,
47 PortableServer::ObjectId * contId,
48 const char *instanceName,
49 const char *interfaceName)
50 : Engines_Component_i(orb, poa, contId, instanceName, interfaceName, true),
51 _errorCode(CALCULATOR_ORB::NO_ERROR)
54 _id = _poa->activate_object(_thisObj);
57 CALCULATOR::~CALCULATOR()
61 CORBA::Double CALCULATOR::norm2(SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_ptr field1)
63 beginService( "CALCULATOR::norm2");
64 _errorCode = CALCULATOR_ORB::NO_ERROR;
65 //const char* LOC = "CALCULATOR::Norm2(SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_ptr field1)";
67 if(CORBA::is_nil(field1))
69 _errorCode = CALCULATOR_ORB::INVALID_FIELD;
73 CORBA::Double norme = 0.0;
74 // Create a local field from corba field, apply method normMax on it.
75 // When exiting the function, f1 is deleted, and with it the remote corba field.
76 ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingFieldDouble> f1=ParaMEDMEM::MEDCouplingFieldDoubleClient::New(field1);
77 /*ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::DataArrayDouble> d=ParaMEDMEM::DataArrayDouble::Multiply(f1->getArray(),f1->getArray());
80 norme = d->accumulate(0);
83 _errorCode = CALCULATOR_ORB::EXCEPTION_RAISED;
91 _errorCode = CALCULATOR_ORB::EXCEPTION_RAISED;
94 endService( "CALCULATOR::norm2");
98 CORBA::Double CALCULATOR::normL2(SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_ptr field1)
100 beginService( "CALCULATOR::normL2");
101 _errorCode = CALCULATOR_ORB::NO_ERROR;
102 //const char* LOC = "CALCULATOR::NormL2(SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_ptr field1)";
105 if(CORBA::is_nil(field1))
107 _errorCode = CALCULATOR_ORB::INVALID_FIELD;
111 //Check that the Field is not on the Nodes (a limitation of normL2)
112 ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingFieldDouble> f1=ParaMEDMEM::MEDCouplingFieldDoubleClient::New(field1);
114 if(f1->getTypeOfField()==ParaMEDMEM::ON_NODES)
116 _errorCode = CALCULATOR_ORB::NOT_COMPATIBLE;
120 CORBA::Double norme = 0.0;
123 norme = f1->normL2(0);
127 _errorCode = CALCULATOR_ORB::EXCEPTION_RAISED;
130 // Send a notification message to supervision
131 ostringstream message("CALCULATOR::normL2 : ");
133 sendMessage("warning",message.str().c_str());
135 endService( "CALCULATOR::normL2");
139 CORBA::Double CALCULATOR::normMax(SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_ptr field1)
141 beginService( "CALCULATOR::normMax");
142 _errorCode = CALCULATOR_ORB::NO_ERROR;
144 if(CORBA::is_nil(field1))
146 _errorCode = CALCULATOR_ORB::INVALID_FIELD;
150 CORBA::Double norme = 0.0;
151 ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingFieldDouble> f1=ParaMEDMEM::MEDCouplingFieldDoubleClient::New(field1);
154 norme = f1->normMax();
158 _errorCode = CALCULATOR_ORB::EXCEPTION_RAISED;
162 endService( "CALCULATOR::normMax");
166 CORBA::Double CALCULATOR::normL1(SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_ptr field1)
168 beginService( "CALCULATOR::normL1");
169 _errorCode = CALCULATOR_ORB::NO_ERROR;
171 if(CORBA::is_nil(field1)) {
172 _errorCode = CALCULATOR_ORB::INVALID_FIELD;
176 //Check that the Field is not on the Nodes (a limitation of normL1)
177 ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingFieldDouble> f1=ParaMEDMEM::MEDCouplingFieldDoubleClient::New(field1);
178 if (f1->getTypeOfField()==ParaMEDMEM::ON_NODES) {
179 _errorCode = CALCULATOR_ORB::NOT_COMPATIBLE;
183 CORBA::Double norme = 0.0;
185 norme = f1->normL1(0);
188 _errorCode = CALCULATOR_ORB::EXCEPTION_RAISED;
191 endService( "CALCULATOR::normL1");
195 SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_ptr CALCULATOR::applyLin(SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_ptr field1,CORBA::Double a,CORBA::Double b)
197 beginService( "CALCULATOR::applyLin");
198 _errorCode = CALCULATOR_ORB::NO_ERROR;
200 if(CORBA::is_nil(field1))
202 _errorCode = CALCULATOR_ORB::INVALID_FIELD;
206 // create a local field on the heap, because it has to remain after exiting the function
207 ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingFieldDouble> f1=ParaMEDMEM::MEDCouplingFieldDoubleClient::New(field1);
208 int nbOfCompo=f1->getArray()->getNumberOfComponents();
209 f1->getArray()->rearrange(1);
210 ParaMEDMEM::MEDCouplingFieldDoubleServant *NewField=NULL;
211 SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_ptr myFieldIOR = NULL;
216 f1->getArray()->rearrange(nbOfCompo);
217 // create servant from f1, give it the property of c++ field (parameter true).
218 // This imply that when the client will release it's field, it will delete NewField,
220 NewField = new ParaMEDMEM::MEDCouplingFieldDoubleServant(f1);
222 myFieldIOR = NewField->_this() ;
226 _errorCode = CALCULATOR_ORB::EXCEPTION_RAISED;
229 endService( "CALCULATOR::applyLin");
233 SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_ptr CALCULATOR::add(SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_ptr field1, SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_ptr field2)
235 beginService( "CALCULATOR::add");
236 _errorCode = CALCULATOR_ORB::NO_ERROR;
237 //const char* LOC = "CALCULATOR::add(SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_ptr field1, SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_ptr field2)";
239 if(CORBA::is_nil(field1) || CORBA::is_nil(field2))
241 _errorCode = CALCULATOR_ORB::INVALID_FIELD;
245 // Create local fields from corba field
246 ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingFieldDouble> f1=ParaMEDMEM::MEDCouplingFieldDoubleClient::New(field1);
247 ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingFieldDouble> f2=ParaMEDMEM::MEDCouplingFieldDoubleClient::New(field2);
249 // catch exception for non compatible fields
250 ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingFieldDouble> fres;
253 f2->changeUnderlyingMesh(f1->getMesh(),0,1e-12);
256 catch(INTERP_KERNEL::Exception)
258 _errorCode = CALCULATOR_ORB::NOT_COMPATIBLE;
262 // create CORBA field from c++ toField. give property to servant (true)
263 ParaMEDMEM::MEDCouplingFieldDoubleServant *myFieldDoubleI=new ParaMEDMEM::MEDCouplingFieldDoubleServant(fres);
264 SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_ptr myFieldIOR = myFieldDoubleI->_this();
265 endService( "CALCULATOR::add");
269 void CALCULATOR::cloneField(SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_ptr field,
270 SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_out clone1, SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_out clone2,
271 SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_out clone3, SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_out clone4)
273 beginService( "CALCULATOR::cloneField");
274 _errorCode = CALCULATOR_ORB::NO_ERROR;
276 if(CORBA::is_nil(field))
278 _errorCode = CALCULATOR_ORB::INVALID_FIELD;
282 // load local field, using MED ressource file pointe.med
283 ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingFieldDouble> f=ParaMEDMEM::MEDCouplingFieldDoubleClient::New(field);
285 // create three c++ field on the heap by copying myField_
286 // All this fields share with f the same SUPPORT and MESH client.
287 // Both SUPPORT and MESH client are connected to a reference count, and will
288 // be deleted after release of all the fields.
289 ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingFieldDouble> fc1=ParaMEDMEM::MEDCouplingFieldDoubleClient::New(field);
290 ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingFieldDouble> fc2=ParaMEDMEM::MEDCouplingFieldDoubleClient::New(field);
291 ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingFieldDouble> fc3=ParaMEDMEM::MEDCouplingFieldDoubleClient::New(field);
292 ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingFieldDouble> fc4=ParaMEDMEM::MEDCouplingFieldDoubleClient::New(field);
294 // Initialize out references :
295 // Create three CORBA clones with cloned c++ fields - give property of c++ fields to servant (true)
296 ParaMEDMEM::MEDCouplingFieldDoubleServant * myClone1 = new ParaMEDMEM::MEDCouplingFieldDoubleServant(fc1);
297 ParaMEDMEM::MEDCouplingFieldDoubleServant * myClone2 = new ParaMEDMEM::MEDCouplingFieldDoubleServant(fc2);
298 ParaMEDMEM::MEDCouplingFieldDoubleServant * myClone3 = new ParaMEDMEM::MEDCouplingFieldDoubleServant(fc3);
299 ParaMEDMEM::MEDCouplingFieldDoubleServant * myClone4 = new ParaMEDMEM::MEDCouplingFieldDoubleServant(fc4);
300 clone1 = myClone1->_this();
301 clone2 = myClone2->_this();
302 clone3 = myClone3->_this();
303 clone4 = myClone4->_this();
304 endService( "CALCULATOR::cloneField");
308 void CALCULATOR::printField(SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_ptr field)
310 beginService( "CALCULATOR::printField");
311 _errorCode = CALCULATOR_ORB::NO_ERROR;
313 if(CORBA::is_nil(field))
315 _errorCode = CALCULATOR_ORB::INVALID_FIELD;
319 // Create a local field from corba field.
320 // Use auto_ptr to perform automatic deletion after usage.
321 // The deletion of the FIELDClient will delete the remote Corba object.
322 ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingFieldDouble> myField=ParaMEDMEM::MEDCouplingFieldDoubleClient::New(field);
323 cout << myField->advancedRepr() ;
326 cout << "Norme euclidienne : " << myField->norm2() << endl;
327 cout << "Norme max : " << myField->normMax() << endl;
328 cout << "------------------------------------------------------------------------" << endl << endl;
329 endService( "CALCULATOR::printField");
334 CORBA::Double CALCULATOR::convergenceCriteria(SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_ptr field)
336 beginService( "CALCULATOR::convergenceCriteria");
337 _errorCode = CALCULATOR_ORB::NO_ERROR;
339 if(CORBA::is_nil(field))
341 _errorCode = CALCULATOR_ORB::INVALID_FIELD;
346 static ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingFieldDouble> fold(0);
347 ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingFieldDouble> fnew=ParaMEDMEM::MEDCouplingFieldDoubleClient::New(field);
351 if ((ParaMEDMEM::MEDCouplingFieldDouble*)fold == NULL) // if old field is not set, set it and return 1
355 // if size of fields are not equal, return 1
356 // catch exception for non compatible fields
357 ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingFieldDouble> fres;
360 fnew->changeUnderlyingMesh(fold->getMesh(),0,1e-12);
361 fres = (*fnew)-(*fold);
362 criteria = fres->normMax();
364 catch(INTERP_KERNEL::Exception)
366 _errorCode = CALCULATOR_ORB::NOT_COMPATIBLE;
372 _errorCode = CALCULATOR_ORB::EXCEPTION_RAISED;
375 endService( "CALCULATOR::convergenceCriteria");
379 CORBA::Boolean CALCULATOR::isDone()
381 return (_errorCode == CALCULATOR_ORB::NO_ERROR);
384 CALCULATOR_ORB::ErrorCode CALCULATOR::getErrorCode()
390 //=============================================================================
392 * CALCULATOREngine_factory
394 * C factory, accessible with dlsym, after dlopen
396 //=============================================================================
400 PortableServer::ObjectId * CALCULATOREngine_factory (CORBA::ORB_ptr orb,
401 PortableServer::POA_ptr poa,
402 PortableServer::ObjectId * contId,
403 const char *instanceName,
404 const char *interfaceName)
406 CALCULATOR * myCALCULATOR = new CALCULATOR (orb, poa, contId, instanceName, interfaceName);
407 return myCALCULATOR->getId();