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);
48 CALCULATOR::~CALCULATOR()
52 CORBA::Double CALCULATOR::norm2(SALOME_MED::FIELDDOUBLE_ptr field1)
54 beginService( "CALCULATOR::norm2");
55 BEGIN_OF("CALCULATOR::Norm2(SALOME_MED::FIELDDOUBLE_ptr field1)");
56 // Create a local field from corba field, apply method normMax on it.
57 // When exiting the function, f1 is deleted, and with it the remote corba field.
58 TFieldDouble_c f1(field1);
59 CORBA::Double norme = f1.norm2();
60 END_OF("CALCULATOR::Norm2(SALOME_MED::FIELDDOUBLE_ptr field1)");
61 endService( "CALCULATOR::norm2");
65 CORBA::Double CALCULATOR::normL2(SALOME_MED::FIELDDOUBLE_ptr field1)
67 beginService( "CALCULATOR::normL2");
68 BEGIN_OF("CALCULATOR::NormL2(SALOME_MED::FIELDDOUBLE_ptr field1)");
70 // Create a local field (on the stack) from corba field, apply method normMax on it.
71 // When exiting the function, FIELDClient f1 is deleted, and with it the remote corba field.
72 TFieldDouble_c f1(field1);
73 CORBA::Double norme = f1.normL2();
74 // Send a notification message to supervision
75 ostringstream message("CALCULATOR::normL2 : ");
77 sendMessage("warning",message.str().c_str());
78 END_OF("CALCULATOR::NormL2(SALOME_MED::FIELDDOUBLE_ptr field1)");
79 endService( "CALCULATOR::normL2");
83 CORBA::Double CALCULATOR::normMax(SALOME_MED::FIELDDOUBLE_ptr field1)
85 beginService( "CALCULATOR::normMax");
86 BEGIN_OF("CALCULATOR::NormMax(SALOME_MED::FIELDDOUBLE_ptr field1)");
87 // An other way to do it : create an local field on the heap, inside an auto_ptr.
88 // When exiting the function, auto_ptr is deleted, and with it the local field and
89 // the remote field if ownership was transferred.
90 auto_ptr<TFieldDouble> f1 (new TFieldDouble_c(field1) );
91 CORBA::Double norme = f1->normMax();
92 END_OF("CALCULATOR::NormMax(SALOME_MED::FIELDDOUBLE_ptr field1)");
93 endService( "CALCULATOR::normMax");
97 CORBA::Double CALCULATOR::normL1(SALOME_MED::FIELDDOUBLE_ptr field1)
99 beginService( "CALCULATOR::normL1");
100 BEGIN_OF("CALCULATOR::NormL1(SALOME_MED::FIELDDOUBLE_ptr field1)");
101 auto_ptr<TFieldDouble> f1 (new TFieldDouble_c(field1) );
102 CORBA::Double norme = f1->normL1();
103 END_OF("CALCULATOR::Norm2(SALOME_MED::FIELDDOUBLE_ptr field1)");
104 endService( "CALCULATOR::normL1");
109 SALOME_MED::FIELDDOUBLE_ptr CALCULATOR::applyLin(SALOME_MED::FIELDDOUBLE_ptr field1,CORBA::Double a,CORBA::Double b)
111 beginService( "CALCULATOR::applyLin");
112 BEGIN_OF("applyLin(SALOME_MED::FIELDDOUBLE_ptr field1,CORBA::Double a,CORBA::Double b)");
113 // create a local field on the heap, because it has to remain after exiting the function
114 TFieldDouble * f1 = new TFieldDouble_c(field1);
117 // create servant from f1, give it the property of c++ field (parameter true).
118 // This imply that when the client will release it's field, it will delete NewField,
120 TFieldDouble_i * NewField = new TFieldDouble_i(f1,true) ;
122 SALOME_MED::FIELDDOUBLE_ptr myFieldIOR = NewField->_this() ;
124 END_OF("applyLin(SALOME_MED::FIELDDOUBLE_ptr field1,CORBA::Double a,CORBA::Double b)");
125 endService( "CALCULATOR::applyLin");
129 SALOME_MED::FIELDDOUBLE_ptr CALCULATOR::add(SALOME_MED::FIELDDOUBLE_ptr field1, SALOME_MED::FIELDDOUBLE_ptr field2)
130 throw ( SALOME::SALOME_Exception )
132 beginService( "CALCULATOR::add");
133 BEGIN_OF("CALCULATOR::add(SALOME_MED::FIELDDOUBLE_ptr field1, SALOME_MED::FIELDDOUBLE_ptr field2)");
134 // Create local fields from corba field
135 TFieldDouble_c f1(field1);
136 TFieldDouble_c f2(field2);
138 // Create new c++ field on the heap by copying f1, add f2 to it.
139 TFieldDouble* fres = new TFieldDouble(f1);
140 // catch exception for non compatible fields
147 throw(SALOME_Exception(LOCALIZED("Fields are not compatible")));
149 // create CORBA field from c++ toField. give property to servant (true)
150 TFieldDouble_i * myFieldDoubleI = new TFieldDouble_i(fres,true);
151 SALOME_MED::FIELDDOUBLE_ptr myFieldIOR = myFieldDoubleI->_this() ;
153 END_OF("CALCULATOR::add(SALOME_MED::FIELDDOUBLE_ptr field1, SALOME_MED::FIELDDOUBLE_ptr field2)");
154 endService( "CALCULATOR::add");
158 void CALCULATOR::cloneField(SALOME_MED::FIELDDOUBLE_ptr field,
159 SALOME_MED::FIELDDOUBLE_out clone1, SALOME_MED::FIELDDOUBLE_out clone2,
160 SALOME_MED::FIELDDOUBLE_out clone3, SALOME_MED::FIELDDOUBLE_out clone4)
162 beginService( "CALCULATOR::cloneField");
163 BEGIN_OF("CALCULATOR::cloneField");
165 // load local field, using MED ressource file pointe.med
166 TFieldDouble_c f(field);
168 // create three c++ field on the heap by copying myField_
169 // All this fields share with f the same SUPPORT and MESH client.
170 // Both SUPPORT and MESH client are connected to a reference count, and will
171 // be deleted after release of all the fields.
172 TFieldDouble* fc1 = new TFieldDouble(f);
173 TFieldDouble* fc2 = new TFieldDouble(f);
174 TFieldDouble* fc3 = new TFieldDouble(f);
175 TFieldDouble* fc4 = new TFieldDouble(f);
177 // Initialize out references :
178 // Create three CORBA clones with cloned c++ fields - give property of c++ fields to servant (true)
179 TFieldDouble_i * myClone1 = new TFieldDouble_i(fc1, true);
180 TFieldDouble_i * myClone2 = new TFieldDouble_i(fc2, true);
181 TFieldDouble_i * myClone3 = new TFieldDouble_i(fc3, true);
182 TFieldDouble_i * myClone4 = new TFieldDouble_i(fc4, true);
183 clone1 = myClone1->_this();
184 clone2 = myClone2->_this();
185 clone3 = myClone3->_this();
186 clone4 = myClone4->_this();
187 END_OF("CALCULATOR::cloneField");
188 endService( "CALCULATOR::cloneField");
192 void CALCULATOR::printField(SALOME_MED::FIELDDOUBLE_ptr field)
194 beginService( "CALCULATOR::printField");
196 // Create a local field from corba field.
197 // Use auto_ptr to perform automatic deletion after usage.
198 // The deletion of the FIELDClient will delete the remote Corba object.
199 auto_ptr<TFieldDouble> myField (new TFieldDouble_c(field) );
201 const SUPPORT * mySupport = myField->getSupport();
202 cout << "\n------------------ Field "<< myField->getName() << " : " <<myField->getDescription() << "------------------" << endl ;
203 int NumberOfComponents = myField->getNumberOfComponents() ;
204 cout << "- Type : " << mySupport->getEntity() << endl;
205 cout << "- Nombre de composantes : "<< NumberOfComponents << endl ;
206 cout << "- Nombre de valeurs : "<< myField->getNumberOfValues() << endl ;
207 for (int i=1; i<NumberOfComponents+1; i++) {
208 cout << " - composante "<<i<<" :"<<endl ;
209 cout << " - nom : "<<myField->getComponentName(i)<< endl;
210 cout << " - description : "<<myField->getComponentDescription(i) << endl;
211 cout << " - units : "<<myField->getMEDComponentUnit(i) << endl;
213 cout << "- iteration :" << endl ;
214 cout << " - numero : " << myField->getIterationNumber()<< endl ;
215 cout << " - ordre : " << myField->getOrderNumber()<< endl ;
216 cout << " - temps : " << myField->getTime()<< endl ;
217 cout << "- Type : " << myField->getValueType()<< endl;
219 cout << "- Valeurs :"<<endl;
220 int NumberOf = mySupport->getNumberOfElements(MED_ALL_ELEMENTS);
222 bool displayNode = mySupport->isOnAllElements() && mySupport->getEntity()==MED_NODE;
223 bool displayBary = mySupport->isOnAllElements() && mySupport->getEntity()==MED_CELL;
224 int dim_space = mySupport->getMesh()->getSpaceDimension();
225 const double * coord = mySupport->getMesh()->getCoordinates(MED_FULL_INTERLACE);
227 auto_ptr<TFieldDouble> barycenter(0);
229 barycenter=auto_ptr<TFieldDouble>(mySupport->getMesh()->getBarycenter(mySupport)) ;
232 for (int i=1; i<NumberOf+1; i++) {
233 const double * value = myField->getRow(i) ;
236 int N=(i-1)*dim_space;
237 cout << setw(width) << i << setw(width) << coord[N] << " " << setw(width) << coord[N+1]<< " " << setw(width) << coord[N+2] << " : " ;
240 cout << setw(width) << i << setw(width) << barycenter->getValueIJ(i,1) << " " << setw(width) << barycenter->getValueIJ(i,2)
241 << " " << setw(width) << barycenter->getValueIJ(i,3) << " : " ;
242 for (int j=0; j<NumberOfComponents; j++)
243 cout << value[j]<< " ";
247 cout << "Norme euclidienne : " << myField->norm2() << endl;
248 cout << "Norme max : " << myField->normMax() << endl;
249 cout << "------------------------------------------------------------------------" << endl << endl;
250 endService( "CALCULATOR::printField");
255 CORBA::Double CALCULATOR::convergenceCriteria(SALOME_MED::FIELDDOUBLE_ptr field)
257 beginService( "CALCULATOR::convergenceCriteria");
258 BEGIN_OF("CALCULATOR::convergenceCriteria(SALOME_MED::FIELDDOUBLE_ptr field)");
261 static auto_ptr<TFieldDouble> fold(0);
262 auto_ptr<TFieldDouble> fnew (new TFieldDouble_c(field) );
263 if (fold.get() == NULL) // if old field is not set, set it and return 1
267 // if size of fields are not equal, return 1
268 const int size=fold->getNumberOfValues()*fold->getNumberOfComponents();
269 if ( size == fnew->getNumberOfValues()*fnew->getNumberOfComponents() )
271 MED_EN::medModeSwitch mode=fold->getInterlacingType(); // storage mode
272 const double* oldVal= fold->getValue(); // retrieve values
273 const double* newVal= fnew->getValue();
275 double ecart_rel=0.0;
276 for (unsigned i=0; i!=size; ++i) // compute criteria
278 if ( oldVal[i] != 0.0)
280 ecart_rel = std::abs( (oldVal[i]-newVal[i])/oldVal[i] );
281 if ( ecart_rel>criteria )
289 endService( "CALCULATOR::convergenceCriteria");
290 END_OF("CALCULATOR::convergenceCriteria(SALOME_MED::FIELDDOUBLE_ptr field1)");
298 PortableServer::ObjectId * CALCULATOREngine_factory(
300 PortableServer::POA_ptr poa,
301 PortableServer::ObjectId * contId,
302 const char *instanceName,
303 const char *interfaceName)
305 MESSAGE("PortableServer::ObjectId * CALCULATOREngine_factory()");
306 SCRUTE(interfaceName);
307 CALCULATOR * myCALCULATOR
308 = new CALCULATOR(orb, poa, contId, instanceName, interfaceName);
309 return myCALCULATOR->getId() ;