1 // Copyright (C) 2007-2024 CEA, EDF, 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"
27 #include <MEDCouplingFieldDoubleClient.hxx>
28 #include <MEDCouplingFieldDoubleServant.hxx>
29 #include <MEDCouplingMemArray.hxx>
30 #include <MEDCouplingMeshClient.hxx>
31 #include <MEDCouplingMeshServant.hxx>
37 \param orb Reference to CORBA ORB
38 \param poa Reference to Root POA
39 \param contId Parent SALOME container ID
40 \param instanceName Instance name of this engine
41 \param interfaceName Interface name of this engine
43 CALCULATOR_Abstract::CALCULATOR_Abstract( CORBA::ORB_ptr orb,
44 PortableServer::POA_ptr poa,
45 PortableServer::ObjectId* contId,
46 const char* instanceName,
47 const char* interfaceName,
49 : Engines_Component_i( orb, poa, contId, instanceName, interfaceName, true, withRegistry ),
50 _errorCode( CALCULATOR_ORB::RES_OK )
53 _id = _poa->activate_object( _thisObj );
59 CALCULATOR_Abstract::~CALCULATOR_Abstract()
64 \brief Get Euclidian norm of field
65 \param field Input field
66 \return Euclidian norm value
68 CORBA::Double CALCULATOR_Abstract::norm2( SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_ptr field )
70 beginService( "CALCULATOR_Abstract::norm2" );
71 _errorCode = CALCULATOR_ORB::RES_OK;
73 if ( CORBA::is_nil( field ) )
75 _errorCode = CALCULATOR_ORB::INVALID_FIELD;
79 MEDCoupling::MCAuto<MEDCoupling::MEDCouplingFieldDouble> f1 =
80 MEDCoupling::MEDCouplingFieldDoubleClient::New( field );
82 CORBA::Double norme = 0.0;
90 _errorCode = CALCULATOR_ORB::EXCEPTION_RAISED;
93 endService( "CALCULATOR_Abstract::norm2" );
98 \brief Get L2 norm of field
99 \param field Input field
100 \return L2 norm value
102 CORBA::Double CALCULATOR_Abstract::normL2( SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_ptr field )
104 beginService( "CALCULATOR_Abstract::normL2" );
105 _errorCode = CALCULATOR_ORB::RES_OK;
107 if ( CORBA::is_nil( field ) )
109 _errorCode = CALCULATOR_ORB::INVALID_FIELD;
113 MEDCoupling::MCAuto<MEDCoupling::MEDCouplingFieldDouble> f1 =
114 MEDCoupling::MEDCouplingFieldDoubleClient::New( field );
116 // Check that the source field is not on the nodes (a limitation of normL2)
117 if ( f1->getTypeOfField() == MEDCoupling::ON_NODES)
119 _errorCode = CALCULATOR_ORB::NOT_COMPATIBLE;
123 CORBA::Double norme = 0.0;
127 norme = f1->normL2( 0 );
131 _errorCode = CALCULATOR_ORB::EXCEPTION_RAISED;
134 endService( "CALCULATOR_Abstract::normL2" );
139 \brief Get max norm of field
140 \param field Input field
141 \return Max norm value
143 CORBA::Double CALCULATOR_Abstract::normMax( SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_ptr field )
145 beginService( "CALCULATOR_Abstract::normMax" );
146 _errorCode = CALCULATOR_ORB::RES_OK;
148 if ( CORBA::is_nil( field ) )
150 _errorCode = CALCULATOR_ORB::INVALID_FIELD;
154 MEDCoupling::MCAuto<MEDCoupling::MEDCouplingFieldDouble> f1 =
155 MEDCoupling::MEDCouplingFieldDoubleClient::New( field );
157 CORBA::Double norme = 0.0;
161 norme = f1->normMax( 0 );
165 _errorCode = CALCULATOR_ORB::EXCEPTION_RAISED;
168 endService( "CALCULATOR_Abstract::normMax" );
173 \brief Get L1 norm of field
174 \param field Input field
175 \return L1 norm value
177 CORBA::Double CALCULATOR_Abstract::normL1( SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_ptr field )
179 beginService( "CALCULATOR_Abstract::normL1" );
180 _errorCode = CALCULATOR_ORB::RES_OK;
182 if ( CORBA::is_nil( field ) )
184 _errorCode = CALCULATOR_ORB::INVALID_FIELD;
188 MEDCoupling::MCAuto<MEDCoupling::MEDCouplingFieldDouble> f1 =
189 MEDCoupling::MEDCouplingFieldDoubleClient::New( field );
191 // Check that the source field is not on the nodes (a limitation of normL1)
192 if ( f1->getTypeOfField() == MEDCoupling::ON_NODES ) {
193 _errorCode = CALCULATOR_ORB::NOT_COMPATIBLE;
197 CORBA::Double norme = 0.0;
200 norme = f1->normL1( 0 );
204 _errorCode = CALCULATOR_ORB::EXCEPTION_RAISED;
207 endService( "CALCULATOR_Abstract::normL1" );
212 \brief Apply to each (scalar) field component the linear function x -> ax+b
213 \param field Input field
214 \param a First coefficient of linear function
215 \param b Second coefficient of linear function
216 \return Resulting field
218 SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_ptr
219 CALCULATOR_Abstract::applyLin( SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_ptr field,
220 CORBA::Double a, CORBA::Double b )
222 beginService( "CALCULATOR_Abstract::applyLin" );
223 _errorCode = CALCULATOR_ORB::RES_OK;
225 if ( CORBA::is_nil( field ) )
227 _errorCode = CALCULATOR_ORB::INVALID_FIELD;
231 // Create a local field on the heap, because it has to remain after exiting the function
232 MEDCoupling::MCAuto<MEDCoupling::MEDCouplingFieldDouble> f1 =
233 MEDCoupling::MEDCouplingFieldDoubleClient::New( field );
235 int nbOfCompo = f1->getArray()->getNumberOfComponents();
236 f1->getArray()->rearrange(1);
237 MEDCoupling::MEDCouplingFieldDoubleServant* NewField = NULL;
238 SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_ptr myFieldIOR;
242 f1->applyLin( a, b, 0 );
243 f1->getArray()->rearrange( nbOfCompo );
244 // Create servant from f1, give it the property of c++ field (parameter true).
245 // This implies that when the client will release it's field, it will delete NewField,
247 NewField = new MEDCoupling::MEDCouplingFieldDoubleServant( f1 );
249 myFieldIOR = NewField->_this();
253 _errorCode = CALCULATOR_ORB::EXCEPTION_RAISED;
256 endService( "CALCULATOR_Abstract::applyLin" );
261 \brief Sum two fields
262 \param field1 First input field
263 \param field2 Second input field
264 \return Resulting field
266 SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_ptr
267 CALCULATOR_Abstract::add( SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_ptr field1,
268 SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_ptr field2 )
270 beginService( "CALCULATOR_Abstract::add" );
271 _errorCode = CALCULATOR_ORB::RES_OK;
273 if ( CORBA::is_nil( field1 ) || CORBA::is_nil( field2 ) )
275 _errorCode = CALCULATOR_ORB::INVALID_FIELD;
279 // Create local fields from source corba fields
280 MEDCoupling::MCAuto<MEDCoupling::MEDCouplingFieldDouble> f1 =
281 MEDCoupling::MEDCouplingFieldDoubleClient::New( field1 );
282 MEDCoupling::MCAuto<MEDCoupling::MEDCouplingFieldDouble> f2 =
283 MEDCoupling::MEDCouplingFieldDoubleClient::New( field2 );
285 MEDCoupling::MCAuto<MEDCoupling::MEDCouplingFieldDouble> fres;
289 f2->changeUnderlyingMesh( f1->getMesh(), 0, 1e-12 );
290 fres = (*f1) + (*f2);
292 catch ( INTERP_KERNEL::Exception )
294 _errorCode = CALCULATOR_ORB::NOT_COMPATIBLE;
298 // Create CORBA field from c++ field fres; give property to servant (true).
299 MEDCoupling::MEDCouplingFieldDoubleServant* myFieldDoubleI = new MEDCoupling::MEDCouplingFieldDoubleServant( fres );
301 SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_ptr myFieldIOR = myFieldDoubleI->_this();
303 endService( "CALCULATOR_Abstract::add" );
308 \brief Clone source field into four copies
309 \param field Input field
310 \param clone1 First resulting clone field
311 \param clone2 Second resulting clone field
312 \param clone3 Third resulting clone field
313 \param clone4 Fourth resulting clone field
315 void CALCULATOR_Abstract::cloneField( SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_ptr field,
316 SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_out clone1,
317 SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_out clone2,
318 SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_out clone3,
319 SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_out clone4 )
321 beginService( "CALCULATOR_Abstract::cloneField" );
322 _errorCode = CALCULATOR_ORB::RES_OK;
324 if ( CORBA::is_nil( field ) )
326 _errorCode = CALCULATOR_ORB::INVALID_FIELD;
330 MEDCoupling::MCAuto<MEDCoupling::MEDCouplingFieldDouble> f =
331 MEDCoupling::MEDCouplingFieldDoubleClient::New( field );
333 // Create four c++ fields on the heap by copying source field.
334 MEDCoupling::MCAuto<MEDCoupling::MEDCouplingFieldDouble> fc1 =
335 MEDCoupling::MEDCouplingFieldDoubleClient::New( field );
336 MEDCoupling::MCAuto<MEDCoupling::MEDCouplingFieldDouble> fc2 =
337 MEDCoupling::MEDCouplingFieldDoubleClient::New( field );
338 MEDCoupling::MCAuto<MEDCoupling::MEDCouplingFieldDouble> fc3 =
339 MEDCoupling::MEDCouplingFieldDoubleClient::New( field );
340 MEDCoupling::MCAuto<MEDCoupling::MEDCouplingFieldDouble> fc4 =
341 MEDCoupling::MEDCouplingFieldDoubleClient::New( field );
343 // Initialize out references:
344 // Create CORBA clones from c++ fields - give property of c++ fields to servant (true)
345 MEDCoupling::MEDCouplingFieldDoubleServant* myClone1 = new MEDCoupling::MEDCouplingFieldDoubleServant( fc1 );
346 MEDCoupling::MEDCouplingFieldDoubleServant* myClone2 = new MEDCoupling::MEDCouplingFieldDoubleServant( fc2 );
347 MEDCoupling::MEDCouplingFieldDoubleServant* myClone3 = new MEDCoupling::MEDCouplingFieldDoubleServant( fc3 );
348 MEDCoupling::MEDCouplingFieldDoubleServant* myClone4 = new MEDCoupling::MEDCouplingFieldDoubleServant( fc4 );
350 clone1 = myClone1->_this();
351 clone2 = myClone2->_this();
352 clone3 = myClone3->_this();
353 clone4 = myClone4->_this();
355 endService( "CALCULATOR_Abstract::cloneField" );
359 \brief Print out the coordinates and field values to standard output
360 \param field Input field
362 void CALCULATOR_Abstract::printField( SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_ptr field )
364 beginService( "CALCULATOR_Abstract::printField" );
365 _errorCode = CALCULATOR_ORB::RES_OK;
367 if ( CORBA::is_nil( field ) )
369 _errorCode = CALCULATOR_ORB::INVALID_FIELD;
373 // Create a local field from source corba field.
374 // Use auto_ptr to perform automatic deletion after usage.
375 // The deletion of the client object will delete the remote corba object.
376 MEDCoupling::MCAuto<MEDCoupling::MEDCouplingFieldDouble> myField =
377 MEDCoupling::MEDCouplingFieldDoubleClient::New( field );
379 std::cout << myField->advancedRepr();
380 std::cout << std::endl;
381 std::cout << "Euclidian norm: " << myField->norm2() << std::endl;
382 std::cout << "Max norm: " << myField->normMax( 0 ) << std::endl;
383 std::cout << "------------------------------------------------------------------------" << std::endl << std::endl;
385 endService( "CALCULATOR_Abstract::printField" );
389 \brief Calculate maximum relative difference of field with the previous one
390 \param field Input field
391 \return Convergence criterion value
393 CORBA::Double CALCULATOR_Abstract::convergenceCriteria( SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_ptr field )
395 beginService( "CALCULATOR_Abstract::convergenceCriteria" );
396 _errorCode = CALCULATOR_ORB::RES_OK;
398 if ( CORBA::is_nil( field ) )
400 _errorCode = CALCULATOR_ORB::INVALID_FIELD;
405 static MEDCoupling::MCAuto<MEDCoupling::MEDCouplingFieldDouble> fold;
406 MEDCoupling::MCAuto<MEDCoupling::MEDCouplingFieldDouble> fnew =
407 MEDCoupling::MEDCouplingFieldDoubleClient::New( field );
411 if ( (MEDCoupling::MEDCouplingFieldDouble*)fold == NULL )
413 // if old field is not set, set it and return 1
418 // if size of fields are not equal, return 1
419 // catch exception for non compatible fields
420 MEDCoupling::MCAuto<MEDCoupling::MEDCouplingFieldDouble> fres;
423 fnew->changeUnderlyingMesh( fold->getMesh(), 0, 1e-12 );
424 fres = (*fnew) - (*fold);
425 criteria = fres->normMax( 0 );
427 catch ( INTERP_KERNEL::Exception )
429 _errorCode = CALCULATOR_ORB::NOT_COMPATIBLE;
435 _errorCode = CALCULATOR_ORB::EXCEPTION_RAISED;
438 endService( "CALCULATOR_Abstract::convergenceCriteria" );
443 \brief Get last operation status
444 \return Last operation status: \c true if last operation succeded or \c false otherwise
446 CORBA::Boolean CALCULATOR_Abstract::isDone()
448 return (_errorCode == CALCULATOR_ORB::RES_OK );
452 \brief Get last operation status
453 \return Last error code
455 CALCULATOR_ORB::ErrorCode CALCULATOR_Abstract::getErrorCode()
461 \brief Get version information
462 \return Version of CALCULATOR engine
464 char* CALCULATOR_Abstract::getVersion()
466 #if defined(CALCULATOR_DEVELOPMENT)
467 return CORBA::string_dup( CALCULATOR_VERSION_STR"dev" );
469 return CORBA::string_dup( CALCULATOR_VERSION_STR );
475 CALCULATORENGINE_EXPORT
476 PortableServer::ObjectId* CALCULATOREngine_factory( CORBA::ORB_ptr orb,
477 PortableServer::POA_ptr poa,
478 PortableServer::ObjectId* contId,
479 const char* instanceName,
480 const char* interfaceName )
482 CORBA::Object_var o = poa->id_to_reference(*contId);
483 Engines::Container_var cont = Engines::Container::_narrow(o);
484 if (cont->is_SSL_mode())
486 CALCULATOR_No_Session* calc = new CALCULATOR_No_Session(orb, poa, contId, instanceName, interfaceName);
487 return calc->getId();
491 CALCULATOR_Session* calc = new CALCULATOR_Session( orb, poa, contId, instanceName, interfaceName );
492 return calc->getId();