1 #include "CALCULATOR.hxx"
2 #include "FIELDClient.hxx"
3 #include "MESHClient.hxx"
7 #include "MEDMEM_Mesh_i.hxx"
8 #include "MEDMEM_Support_i.hxx"
9 #include "MEDMEM_FieldDouble_i.hxx"
12 using namespace MEDMEM;
14 CALCULATOR::CALCULATOR(CORBA::ORB_ptr orb,
15 PortableServer::POA_ptr poa,
16 PortableServer::ObjectId * contId,
17 const char *instanceName,
18 const char *interfaceName) :
19 Engines_Component_i(orb, poa, contId, instanceName, interfaceName,true)
21 MESSAGE("activate object");
23 _id = _poa->activate_object(_thisObj);
26 CALCULATOR::~CALCULATOR()
30 CORBA::Double CALCULATOR::norm2(SALOME_MED::FIELDDOUBLE_ptr field1)
32 beginService( "CALCULATOR::norm2");
33 BEGIN_OF("CALCULATOR::Norm2(SALOME_MED::FIELDDOUBLE_ptr field1)");
34 // Create a local field from corba field, apply method normMax on it.
35 // When exiting the function, f1 is deleted, and with it the remote corba field.
36 FIELDClient<double> f1(field1);
37 CORBA::Double norme = f1.norm2();
38 END_OF("CALCULATOR::Norm2(SALOME_MED::FIELDDOUBLE_ptr field1)");
39 endService( "CALCULATOR::norm2");
43 CORBA::Double CALCULATOR::normL2(SALOME_MED::FIELDDOUBLE_ptr field1)
45 beginService( "CALCULATOR::normL2");
46 BEGIN_OF("CALCULATOR::NormL2(SALOME_MED::FIELDDOUBLE_ptr field1)");
48 // Create a local field (on the stack) from corba field, apply method normMax on it.
49 // When exiting the function, FIELDClient f1 is deleted, and with it the remote corba field.
50 FIELDClient<double>f1(field1);
51 CORBA::Double norme = f1.normL2();
52 // Send a notification message to supervision
53 ostringstream message("CALCULATOR::normL2 : ");
55 sendMessage("warning",message.str().c_str());
56 END_OF("CALCULATOR::NormL2(SALOME_MED::FIELDDOUBLE_ptr field1)");
57 endService( "CALCULATOR::normL2");
61 CORBA::Double CALCULATOR::normMax(SALOME_MED::FIELDDOUBLE_ptr field1)
63 beginService( "CALCULATOR::normMax");
64 BEGIN_OF("CALCULATOR::NormMax(SALOME_MED::FIELDDOUBLE_ptr field1)");
65 // An other way to do it : create an local field on the heap, inside an auto_ptr.
66 // When exiting the function, auto_ptr is deleted, and with it the local field and
67 // the remote field if ownership was transferred.
68 auto_ptr<FIELD<double> > f1 (new FIELDClient<double> (field1) );
69 CORBA::Double norme = f1->normMax();
70 END_OF("CALCULATOR::NormMax(SALOME_MED::FIELDDOUBLE_ptr field1)");
71 endService( "CALCULATOR::normMax");
75 CORBA::Double CALCULATOR::normL1(SALOME_MED::FIELDDOUBLE_ptr field1)
77 beginService( "CALCULATOR::normL1");
78 BEGIN_OF("CALCULATOR::NormL1(SALOME_MED::FIELDDOUBLE_ptr field1)");
79 auto_ptr<FIELD<double> > f1 (new FIELDClient<double> (field1) );
80 CORBA::Double norme = f1->normL1();
81 END_OF("CALCULATOR::Norm2(SALOME_MED::FIELDDOUBLE_ptr field1)");
82 endService( "CALCULATOR::normL1");
87 SALOME_MED::FIELDDOUBLE_ptr CALCULATOR::applyLin(SALOME_MED::FIELDDOUBLE_ptr field1,CORBA::Double a,CORBA::Double b)
89 beginService( "CALCULATOR::applyLin");
90 BEGIN_OF("applyLin(SALOME_MED::FIELDDOUBLE_ptr field1,CORBA::Double a,CORBA::Double b)");
91 // create a local field on the heap, because it has to remain after exiting the function
92 FIELD<double> * f1 = new FIELDClient<double>(field1);
95 // create servant from f1, give it the property of c++ field (parameter true).
96 // This imply that when the client will release it's field, it will delete NewField,
98 FIELDDOUBLE_i * NewField = new FIELDDOUBLE_i(f1,true) ;
100 SALOME_MED::FIELDDOUBLE_ptr myFieldIOR = NewField->_this() ;
102 END_OF("applyLin(SALOME_MED::FIELDDOUBLE_ptr field1,CORBA::Double a,CORBA::Double b)");
103 endService( "CALCULATOR::applyLin");
107 SALOME_MED::FIELDDOUBLE_ptr CALCULATOR::add(SALOME_MED::FIELDDOUBLE_ptr field1, SALOME_MED::FIELDDOUBLE_ptr field2)
108 throw ( SALOME::SALOME_Exception )
110 beginService( "CALCULATOR::add");
111 BEGIN_OF("CALCULATOR::add(SALOME_MED::FIELDDOUBLE_ptr field1, SALOME_MED::FIELDDOUBLE_ptr field2)");
112 // Create local fields from corba field
113 FIELDClient<double> f1(field1);
114 FIELDClient<double> f2(field2);
116 // Create new c++ field on the heap by copying f1, add f2 to it.
117 FIELD<double>* fres = new FIELD<double>(f1);
118 // catch exception for non compatible fields
125 throw(SALOME_Exception(LOCALIZED("Fields are not compatible")));
127 // create CORBA field from c++ toField. give property to servant (true)
128 FIELDDOUBLE_i * myFieldDoubleI = new FIELDDOUBLE_i(fres,true);
129 SALOME_MED::FIELDDOUBLE_ptr myFieldIOR = myFieldDoubleI->_this() ;
131 END_OF("CALCULATOR::add(SALOME_MED::FIELDDOUBLE_ptr field1, SALOME_MED::FIELDDOUBLE_ptr field2)");
132 endService( "CALCULATOR::add");
136 void CALCULATOR::cloneField(SALOME_MED::FIELDDOUBLE_ptr field,
137 SALOME_MED::FIELDDOUBLE_out clone1, SALOME_MED::FIELDDOUBLE_out clone2,
138 SALOME_MED::FIELDDOUBLE_out clone3, SALOME_MED::FIELDDOUBLE_out clone4)
140 beginService( "CALCULATOR::cloneField");
141 BEGIN_OF("CALCULATOR::cloneField");
143 // load local field, using MED ressource file pointe.med
144 FIELDClient<double> f(field);
146 // create three c++ field on the heap by copying myField_
147 // All this fields share with f the same SUPPORT and MESH client.
148 // Both SUPPORT and MESH client are connected to a reference count, and will
149 // be deleted after release of all the fields.
150 FIELD<double>* fc1 = new FIELD<double>(f);
151 FIELD<double>* fc2 = new FIELD<double>(f);
152 FIELD<double>* fc3 = new FIELD<double>(f);
153 FIELD<double>* fc4 = new FIELD<double>(f);
155 // Initialize out references :
156 // Create three CORBA clones with cloned c++ fields - give property of c++ fields to servant (true)
157 FIELDDOUBLE_i * myClone1 = new FIELDDOUBLE_i(fc1, true);
158 FIELDDOUBLE_i * myClone2 = new FIELDDOUBLE_i(fc2, true);
159 FIELDDOUBLE_i * myClone3 = new FIELDDOUBLE_i(fc3, true);
160 FIELDDOUBLE_i * myClone4 = new FIELDDOUBLE_i(fc4, true);
161 clone1 = myClone1->_this();
162 clone2 = myClone2->_this();
163 clone3 = myClone3->_this();
164 clone4 = myClone4->_this();
165 END_OF("CALCULATOR::cloneField");
166 endService( "CALCULATOR::cloneField");
170 void CALCULATOR::printField(SALOME_MED::FIELDDOUBLE_ptr field)
172 beginService( "CALCULATOR::printField");
174 // Create a local field from corba field.
175 // Use auto_ptr to perform automatic deletion after usage.
176 // The deletion of the FIELDClient will delete the remote Corba object.
177 auto_ptr<FIELD<double> > myField (new FIELDClient<double> (field) );
179 const SUPPORT * mySupport = myField->getSupport();
180 cout << "\n------------------ Field "<< myField->getName() << " : " <<myField->getDescription() << "------------------" << endl ;
181 int NumberOfComponents = myField->getNumberOfComponents() ;
182 cout << "- Type : " << mySupport->getEntity() << endl;
183 cout << "- Nombre de composantes : "<< NumberOfComponents << endl ;
184 cout << "- Nombre de valeurs : "<< myField->getNumberOfValues() << endl ;
185 for (int i=1; i<NumberOfComponents+1; i++) {
186 cout << " - composante "<<i<<" :"<<endl ;
187 cout << " - nom : "<<myField->getComponentName(i)<< endl;
188 cout << " - description : "<<myField->getComponentDescription(i) << endl;
189 cout << " - units : "<<myField->getMEDComponentUnit(i) << endl;
191 cout << "- iteration :" << endl ;
192 cout << " - numero : " << myField->getIterationNumber()<< endl ;
193 cout << " - ordre : " << myField->getOrderNumber()<< endl ;
194 cout << " - temps : " << myField->getTime()<< endl ;
195 cout << "- Type : " << myField->getValueType()<< endl;
197 cout << "- Valeurs :"<<endl;
198 int NumberOf = mySupport->getNumberOfElements(MED_ALL_ELEMENTS);
200 bool displayNode = mySupport->isOnAllElements() && mySupport->getEntity()==MED_NODE;
201 bool displayBary = mySupport->isOnAllElements() && mySupport->getEntity()==MED_CELL;
202 int dim_space = mySupport->getMesh()->getSpaceDimension();
203 const double * coord = mySupport->getMesh()->getCoordinates(MED_FULL_INTERLACE);
205 auto_ptr<FIELD<double> > barycenter(0);
207 barycenter=auto_ptr<FIELD<double> > (mySupport->getMesh()->getBarycenter(mySupport)) ;
210 for (int i=1; i<NumberOf+1; i++) {
211 const double * value = myField->getValueI(MED_FULL_INTERLACE,i) ;
214 int N=(i-1)*dim_space;
215 cout << setw(width) << i << setw(width) << coord[N] << " " << setw(width) << coord[N+1]<< " " << setw(width) << coord[N+2] << " : " ;
218 cout << setw(width) << i << setw(width) << barycenter->getValueIJ(i,1) << " " << setw(width) << barycenter->getValueIJ(i,2)
219 << " " << setw(width) << barycenter->getValueIJ(i,3) << " : " ;
220 for (int j=0; j<NumberOfComponents; j++)
221 cout << value[j]<< " ";
225 cout << "Norme euclidienne : " << myField->norm2() << endl;
226 cout << "Norme max : " << myField->normMax() << endl;
227 cout << "------------------------------------------------------------------------" << endl << endl;
228 endService( "CALCULATOR::printField");
233 CORBA::Double CALCULATOR::convergenceCriteria(SALOME_MED::FIELDDOUBLE_ptr field)
235 beginService( "CALCULATOR::convergenceCriteria");
236 BEGIN_OF("CALCULATOR::convergenceCriteria(SALOME_MED::FIELDDOUBLE_ptr field)");
239 static auto_ptr<FIELD<double> > fold(0);
240 auto_ptr<FIELD<double> > fnew (new FIELDClient<double> (field) );
241 if (fold.get() == NULL) // if old field is not set, set it and return 1
245 // if size of fields are not equal, return 1
246 const int size=fold->getNumberOfValues()*fold->getNumberOfComponents();
247 if ( size == fnew->getNumberOfValues()*fnew->getNumberOfComponents() )
249 MED_EN::medModeSwitch mode=fold->getvalue()->getMode(); // storage mode
250 const double* oldVal= fold->getValue(mode); // retrieve values
251 const double* newVal= fnew->getValue(mode);
253 double ecart_rel=0.0;
254 for (unsigned i=0; i!=size; ++i) // compute criteria
256 if ( oldVal[i] != 0.0)
258 ecart_rel = std::abs( (oldVal[i]-newVal[i])/oldVal[i] );
259 if ( ecart_rel>criteria )
267 endService( "CALCULATOR::convergenceCriteria");
268 END_OF("CALCULATOR::convergenceCriteria(SALOME_MED::FIELDDOUBLE_ptr field1)");
276 PortableServer::ObjectId * CALCULATOREngine_factory(
278 PortableServer::POA_ptr poa,
279 PortableServer::ObjectId * contId,
280 const char *instanceName,
281 const char *interfaceName)
283 MESSAGE("PortableServer::ObjectId * CALCULATOREngine_factory()");
284 SCRUTE(interfaceName);
285 CALCULATOR * myCALCULATOR
286 = new CALCULATOR(orb, poa, contId, instanceName, interfaceName);
287 return myCALCULATOR->getId() ;