1 // Copyright (C) 2007-2016 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, or (at your option) any later version.
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 <MEDCouplingAutoRefCountObjectPtr.hxx>
27 #include <MEDCouplingFieldDoubleClient.hxx>
28 #include <MEDCouplingFieldDoubleServant.hxx>
29 #include <MEDCouplingMemArray.hxx>
30 #include <MEDCouplingMeshClient.hxx>
31 #include <MEDCouplingMeshServant.hxx>
35 CALCULATOR::CALCULATOR( CORBA::ORB_ptr orb,
36 PortableServer::POA_ptr poa,
37 PortableServer::ObjectId* contId,
38 const char* instanceName,
39 const char* interfaceName )
40 : Engines_Component_i( orb, poa, contId, instanceName, interfaceName, true ),
41 _errorCode( CALCULATOR_ORB::RES_OK )
44 _id = _poa->activate_object( _thisObj );
47 CALCULATOR::~CALCULATOR()
51 CORBA::Double CALCULATOR::norm2( SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_ptr field1 )
53 beginService( "CALCULATOR::norm2" );
54 _errorCode = CALCULATOR_ORB::RES_OK;
56 if ( CORBA::is_nil( field1 ) )
58 _errorCode = CALCULATOR_ORB::INVALID_FIELD;
62 ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingFieldDouble> f1 =
63 ParaMEDMEM::MEDCouplingFieldDoubleClient::New( field1 );
65 CORBA::Double norme = 0.0;
73 _errorCode = CALCULATOR_ORB::EXCEPTION_RAISED;
76 endService( "CALCULATOR::norm2" );
80 CORBA::Double CALCULATOR::normL2( SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_ptr field1 )
82 beginService( "CALCULATOR::normL2" );
83 _errorCode = CALCULATOR_ORB::RES_OK;
85 if ( CORBA::is_nil( field1 ) )
87 _errorCode = CALCULATOR_ORB::INVALID_FIELD;
91 ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingFieldDouble> f1 =
92 ParaMEDMEM::MEDCouplingFieldDoubleClient::New( field1 );
94 // Check that the source field is not on the nodes (a limitation of normL2)
95 if ( f1->getTypeOfField() == ParaMEDMEM::ON_NODES)
97 _errorCode = CALCULATOR_ORB::NOT_COMPATIBLE;
101 CORBA::Double norme = 0.0;
105 norme = f1->normL2( 0 );
109 _errorCode = CALCULATOR_ORB::EXCEPTION_RAISED;
112 endService( "CALCULATOR::normL2" );
116 CORBA::Double CALCULATOR::normMax( SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_ptr field1 )
118 beginService( "CALCULATOR::normMax" );
119 _errorCode = CALCULATOR_ORB::RES_OK;
121 if ( CORBA::is_nil( field1 ) )
123 _errorCode = CALCULATOR_ORB::INVALID_FIELD;
127 ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingFieldDouble> f1 =
128 ParaMEDMEM::MEDCouplingFieldDoubleClient::New( field1 );
130 CORBA::Double norme = 0.0;
134 norme = f1->normMax();
138 _errorCode = CALCULATOR_ORB::EXCEPTION_RAISED;
141 endService( "CALCULATOR::normMax" );
145 CORBA::Double CALCULATOR::normL1( SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_ptr field1 )
147 beginService( "CALCULATOR::normL1" );
148 _errorCode = CALCULATOR_ORB::RES_OK;
150 if ( CORBA::is_nil( field1 ) )
152 _errorCode = CALCULATOR_ORB::INVALID_FIELD;
156 ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingFieldDouble> f1 =
157 ParaMEDMEM::MEDCouplingFieldDoubleClient::New(field1);
159 // Check that the source field is not on the nodes (a limitation of normL1)
160 if ( f1->getTypeOfField() == ParaMEDMEM::ON_NODES ) {
161 _errorCode = CALCULATOR_ORB::NOT_COMPATIBLE;
165 CORBA::Double norme = 0.0;
168 norme = f1->normL1( 0 );
172 _errorCode = CALCULATOR_ORB::EXCEPTION_RAISED;
175 endService( "CALCULATOR::normL1" );
179 SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_ptr CALCULATOR::applyLin( SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_ptr field1,
180 CORBA::Double a, CORBA::Double b )
182 beginService( "CALCULATOR::applyLin" );
183 _errorCode = CALCULATOR_ORB::RES_OK;
185 if ( CORBA::is_nil( field1 ) )
187 _errorCode = CALCULATOR_ORB::INVALID_FIELD;
191 // Create a local field on the heap, because it has to remain after exiting the function
192 ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingFieldDouble> f1 =
193 ParaMEDMEM::MEDCouplingFieldDoubleClient::New( field1 );
195 int nbOfCompo = f1->getArray()->getNumberOfComponents();
196 f1->getArray()->rearrange(1);
197 ParaMEDMEM::MEDCouplingFieldDoubleServant* NewField = NULL;
198 SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_ptr myFieldIOR;
202 f1->applyLin( a, b, 0 );
203 f1->getArray()->rearrange( nbOfCompo );
204 // Create servant from f1, give it the property of c++ field (parameter true).
205 // This implies that when the client will release it's field, it will delete NewField,
207 NewField = new ParaMEDMEM::MEDCouplingFieldDoubleServant( f1 );
209 myFieldIOR = NewField->_this();
213 _errorCode = CALCULATOR_ORB::EXCEPTION_RAISED;
216 endService( "CALCULATOR::applyLin" );
220 SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_ptr CALCULATOR::add( SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_ptr field1,
221 SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_ptr field2 )
223 beginService( "CALCULATOR::add" );
224 _errorCode = CALCULATOR_ORB::RES_OK;
226 if ( CORBA::is_nil( field1 ) || CORBA::is_nil( field2 ) )
228 _errorCode = CALCULATOR_ORB::INVALID_FIELD;
232 // Create local fields from source corba fields
233 ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingFieldDouble> f1 =
234 ParaMEDMEM::MEDCouplingFieldDoubleClient::New( field1 );
235 ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingFieldDouble> f2 =
236 ParaMEDMEM::MEDCouplingFieldDoubleClient::New( field2 );
238 ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingFieldDouble> fres;
242 f2->changeUnderlyingMesh( f1->getMesh(), 0, 1e-12 );
243 fres = (*f1) + (*f2);
245 catch ( INTERP_KERNEL::Exception )
247 _errorCode = CALCULATOR_ORB::NOT_COMPATIBLE;
251 // Create CORBA field from c++ field fres; give property to servant (true).
252 ParaMEDMEM::MEDCouplingFieldDoubleServant* myFieldDoubleI = new ParaMEDMEM::MEDCouplingFieldDoubleServant( fres );
254 SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_ptr myFieldIOR = myFieldDoubleI->_this();
256 endService( "CALCULATOR::add" );
260 void CALCULATOR::cloneField( SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_ptr field,
261 SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_out clone1,
262 SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_out clone2,
263 SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_out clone3,
264 SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_out clone4 )
266 beginService( "CALCULATOR::cloneField" );
267 _errorCode = CALCULATOR_ORB::RES_OK;
269 if ( CORBA::is_nil( field ) )
271 _errorCode = CALCULATOR_ORB::INVALID_FIELD;
275 ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingFieldDouble> f =
276 ParaMEDMEM::MEDCouplingFieldDoubleClient::New( field );
278 // Create four c++ fields on the heap by copying source field.
279 ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingFieldDouble> fc1 =
280 ParaMEDMEM::MEDCouplingFieldDoubleClient::New( field );
281 ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingFieldDouble> fc2 =
282 ParaMEDMEM::MEDCouplingFieldDoubleClient::New( field );
283 ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingFieldDouble> fc3 =
284 ParaMEDMEM::MEDCouplingFieldDoubleClient::New( field );
285 ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingFieldDouble> fc4 =
286 ParaMEDMEM::MEDCouplingFieldDoubleClient::New( field );
288 // Initialize out references:
289 // Create CORBA clones from c++ fields - give property of c++ fields to servant (true)
290 ParaMEDMEM::MEDCouplingFieldDoubleServant* myClone1 = new ParaMEDMEM::MEDCouplingFieldDoubleServant( fc1 );
291 ParaMEDMEM::MEDCouplingFieldDoubleServant* myClone2 = new ParaMEDMEM::MEDCouplingFieldDoubleServant( fc2 );
292 ParaMEDMEM::MEDCouplingFieldDoubleServant* myClone3 = new ParaMEDMEM::MEDCouplingFieldDoubleServant( fc3 );
293 ParaMEDMEM::MEDCouplingFieldDoubleServant* myClone4 = new ParaMEDMEM::MEDCouplingFieldDoubleServant( fc4 );
295 clone1 = myClone1->_this();
296 clone2 = myClone2->_this();
297 clone3 = myClone3->_this();
298 clone4 = myClone4->_this();
300 endService( "CALCULATOR::cloneField" );
303 void CALCULATOR::printField( SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_ptr field )
305 beginService( "CALCULATOR::printField" );
306 _errorCode = CALCULATOR_ORB::RES_OK;
308 if ( CORBA::is_nil( field ) )
310 _errorCode = CALCULATOR_ORB::INVALID_FIELD;
314 // Create a local field from source corba field.
315 // Use auto_ptr to perform automatic deletion after usage.
316 // The deletion of the client object will delete the remote corba object.
317 ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingFieldDouble> myField =
318 ParaMEDMEM::MEDCouplingFieldDoubleClient::New( field );
320 std::cout << myField->advancedRepr();
321 std::cout << std::endl;
322 std::cout << "Euclidian norm: " << myField->norm2() << std::endl;
323 std::cout << "Max norm: " << myField->normMax() << std::endl;
324 std::cout << "------------------------------------------------------------------------" << std::endl << std::endl;
326 endService( "CALCULATOR::printField" );
329 CORBA::Double CALCULATOR::convergenceCriteria( SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_ptr field )
331 beginService( "CALCULATOR::convergenceCriteria" );
332 _errorCode = CALCULATOR_ORB::RES_OK;
334 if ( CORBA::is_nil( field ) )
336 _errorCode = CALCULATOR_ORB::INVALID_FIELD;
341 static ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingFieldDouble> fold;
342 ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingFieldDouble> fnew =
343 ParaMEDMEM::MEDCouplingFieldDoubleClient::New( field );
347 if ( (ParaMEDMEM::MEDCouplingFieldDouble*)fold == NULL )
349 // if old field is not set, set it and return 1
354 // if size of fields are not equal, return 1
355 // catch exception for non compatible fields
356 ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingFieldDouble> fres;
359 fnew->changeUnderlyingMesh( fold->getMesh(), 0, 1e-12 );
360 fres = (*fnew) - (*fold);
361 criteria = fres->normMax();
363 catch ( INTERP_KERNEL::Exception )
365 _errorCode = CALCULATOR_ORB::NOT_COMPATIBLE;
371 _errorCode = CALCULATOR_ORB::EXCEPTION_RAISED;
374 endService( "CALCULATOR::convergenceCriteria" );
378 CORBA::Boolean CALCULATOR::isDone()
380 return (_errorCode == CALCULATOR_ORB::RES_OK );
383 CALCULATOR_ORB::ErrorCode CALCULATOR::getErrorCode()
388 // Version information
389 char* CALCULATOR::getVersion()
391 #if defined(CALCULATOR_DEVELOPMENT)
392 return CORBA::string_dup( CALCULATOR_VERSION_STR"dev" );
394 return CORBA::string_dup( CALCULATOR_VERSION_STR );
400 CALCULATORENGINE_EXPORT
401 PortableServer::ObjectId* CALCULATOREngine_factory( CORBA::ORB_ptr orb,
402 PortableServer::POA_ptr poa,
403 PortableServer::ObjectId* contId,
404 const char* instanceName,
405 const char* interfaceName )
407 CALCULATOR* myCALCULATOR = new CALCULATOR( orb, poa, contId, instanceName, interfaceName );
408 return myCALCULATOR->getId();