1 #include "CALCULATOR.hxx"
2 #include "FIELDClient.hxx"
3 #include "MESHClient.hxx"
6 #include "MEDMEM_Mesh_i.hxx"
7 #include "MEDMEM_Support_i.hxx"
8 #include "MEDMEM_FieldTemplate_i.hxx"
12 using namespace MEDMEM;
14 typedef FIELD<double,MEDMEM::FullInterlace> TFieldDouble;
15 typedef FIELDClient<double,MEDMEM::FullInterlace> TFieldDouble_c;
16 typedef FIELDTEMPLATE_I<double,MEDMEM::FullInterlace> TFieldDouble_i;
18 CALCULATOR::CALCULATOR(CORBA::ORB_ptr orb,
19 PortableServer::POA_ptr poa,
20 PortableServer::ObjectId * contId,
21 const char *instanceName,
22 const char *interfaceName) :
23 Engines_Component_i(orb, poa, contId, instanceName, interfaceName,true)
25 MESSAGE("activate object");
27 _id = _poa->activate_object(_thisObj);
30 CALCULATOR::~CALCULATOR()
34 CORBA::Double CALCULATOR::norm2(SALOME_MED::FIELDDOUBLE_ptr field1)
36 beginService( "CALCULATOR::norm2");
37 BEGIN_OF("CALCULATOR::Norm2(SALOME_MED::FIELDDOUBLE_ptr field1)");
38 // Create a local field from corba field, apply method normMax on it.
39 // When exiting the function, f1 is deleted, and with it the remote corba field.
40 TFieldDouble_c f1(field1);
41 CORBA::Double norme = f1.norm2();
42 END_OF("CALCULATOR::Norm2(SALOME_MED::FIELDDOUBLE_ptr field1)");
43 endService( "CALCULATOR::norm2");
47 CORBA::Double CALCULATOR::normL2(SALOME_MED::FIELDDOUBLE_ptr field1)
49 beginService( "CALCULATOR::normL2");
50 BEGIN_OF("CALCULATOR::NormL2(SALOME_MED::FIELDDOUBLE_ptr field1)");
52 // Create a local field (on the stack) from corba field, apply method normMax on it.
53 // When exiting the function, FIELDClient f1 is deleted, and with it the remote corba field.
54 TFieldDouble_c f1(field1);
55 CORBA::Double norme = f1.normL2();
56 // Send a notification message to supervision
57 ostringstream message("CALCULATOR::normL2 : ");
59 sendMessage("warning",message.str().c_str());
60 END_OF("CALCULATOR::NormL2(SALOME_MED::FIELDDOUBLE_ptr field1)");
61 endService( "CALCULATOR::normL2");
65 CORBA::Double CALCULATOR::normMax(SALOME_MED::FIELDDOUBLE_ptr field1)
67 beginService( "CALCULATOR::normMax");
68 BEGIN_OF("CALCULATOR::NormMax(SALOME_MED::FIELDDOUBLE_ptr field1)");
69 // An other way to do it : create an local field on the heap, inside an auto_ptr.
70 // When exiting the function, auto_ptr is deleted, and with it the local field and
71 // the remote field if ownership was transferred.
72 auto_ptr<TFieldDouble> f1 (new TFieldDouble_c(field1) );
73 CORBA::Double norme = f1->normMax();
74 END_OF("CALCULATOR::NormMax(SALOME_MED::FIELDDOUBLE_ptr field1)");
75 endService( "CALCULATOR::normMax");
79 CORBA::Double CALCULATOR::normL1(SALOME_MED::FIELDDOUBLE_ptr field1)
81 beginService( "CALCULATOR::normL1");
82 BEGIN_OF("CALCULATOR::NormL1(SALOME_MED::FIELDDOUBLE_ptr field1)");
83 auto_ptr<TFieldDouble> f1 (new TFieldDouble_c(field1) );
84 CORBA::Double norme = f1->normL1();
85 END_OF("CALCULATOR::Norm2(SALOME_MED::FIELDDOUBLE_ptr field1)");
86 endService( "CALCULATOR::normL1");
91 SALOME_MED::FIELDDOUBLE_ptr CALCULATOR::applyLin(SALOME_MED::FIELDDOUBLE_ptr field1,CORBA::Double a,CORBA::Double b)
93 beginService( "CALCULATOR::applyLin");
94 BEGIN_OF("applyLin(SALOME_MED::FIELDDOUBLE_ptr field1,CORBA::Double a,CORBA::Double b)");
95 // create a local field on the heap, because it has to remain after exiting the function
96 TFieldDouble * f1 = new TFieldDouble_c(field1);
99 // create servant from f1, give it the property of c++ field (parameter true).
100 // This imply that when the client will release it's field, it will delete NewField,
102 TFieldDouble_i * NewField = new TFieldDouble_i(f1,true) ;
104 SALOME_MED::FIELDDOUBLE_ptr myFieldIOR = NewField->_this() ;
106 END_OF("applyLin(SALOME_MED::FIELDDOUBLE_ptr field1,CORBA::Double a,CORBA::Double b)");
107 endService( "CALCULATOR::applyLin");
111 SALOME_MED::FIELDDOUBLE_ptr CALCULATOR::add(SALOME_MED::FIELDDOUBLE_ptr field1, SALOME_MED::FIELDDOUBLE_ptr field2)
112 throw ( SALOME::SALOME_Exception )
114 beginService( "CALCULATOR::add");
115 BEGIN_OF("CALCULATOR::add(SALOME_MED::FIELDDOUBLE_ptr field1, SALOME_MED::FIELDDOUBLE_ptr field2)");
116 // Create local fields from corba field
117 TFieldDouble_c f1(field1);
118 TFieldDouble_c f2(field2);
120 // Create new c++ field on the heap by copying f1, add f2 to it.
121 TFieldDouble* fres = new TFieldDouble(f1);
122 // catch exception for non compatible fields
129 throw(SALOME_Exception(LOCALIZED("Fields are not compatible")));
131 // create CORBA field from c++ toField. give property to servant (true)
132 TFieldDouble_i * myFieldDoubleI = new TFieldDouble_i(fres,true);
133 SALOME_MED::FIELDDOUBLE_ptr myFieldIOR = myFieldDoubleI->_this() ;
135 END_OF("CALCULATOR::add(SALOME_MED::FIELDDOUBLE_ptr field1, SALOME_MED::FIELDDOUBLE_ptr field2)");
136 endService( "CALCULATOR::add");
140 void CALCULATOR::cloneField(SALOME_MED::FIELDDOUBLE_ptr field,
141 SALOME_MED::FIELDDOUBLE_out clone1, SALOME_MED::FIELDDOUBLE_out clone2,
142 SALOME_MED::FIELDDOUBLE_out clone3, SALOME_MED::FIELDDOUBLE_out clone4)
144 beginService( "CALCULATOR::cloneField");
145 BEGIN_OF("CALCULATOR::cloneField");
147 // load local field, using MED ressource file pointe.med
148 TFieldDouble_c f(field);
150 // create three c++ field on the heap by copying myField_
151 // All this fields share with f the same SUPPORT and MESH client.
152 // Both SUPPORT and MESH client are connected to a reference count, and will
153 // be deleted after release of all the fields.
154 TFieldDouble* fc1 = new TFieldDouble(f);
155 TFieldDouble* fc2 = new TFieldDouble(f);
156 TFieldDouble* fc3 = new TFieldDouble(f);
157 TFieldDouble* fc4 = new TFieldDouble(f);
159 // Initialize out references :
160 // Create three CORBA clones with cloned c++ fields - give property of c++ fields to servant (true)
161 TFieldDouble_i * myClone1 = new TFieldDouble_i(fc1, true);
162 TFieldDouble_i * myClone2 = new TFieldDouble_i(fc2, true);
163 TFieldDouble_i * myClone3 = new TFieldDouble_i(fc3, true);
164 TFieldDouble_i * myClone4 = new TFieldDouble_i(fc4, true);
165 clone1 = myClone1->_this();
166 clone2 = myClone2->_this();
167 clone3 = myClone3->_this();
168 clone4 = myClone4->_this();
169 END_OF("CALCULATOR::cloneField");
170 endService( "CALCULATOR::cloneField");
174 void CALCULATOR::printField(SALOME_MED::FIELDDOUBLE_ptr field)
176 beginService( "CALCULATOR::printField");
178 // Create a local field from corba field.
179 // Use auto_ptr to perform automatic deletion after usage.
180 // The deletion of the FIELDClient will delete the remote Corba object.
181 auto_ptr<TFieldDouble> myField (new TFieldDouble_c(field) );
183 const SUPPORT * mySupport = myField->getSupport();
184 cout << "\n------------------ Field "<< myField->getName() << " : " <<myField->getDescription() << "------------------" << endl ;
185 int NumberOfComponents = myField->getNumberOfComponents() ;
186 cout << "- Type : " << mySupport->getEntity() << endl;
187 cout << "- Nombre de composantes : "<< NumberOfComponents << endl ;
188 cout << "- Nombre de valeurs : "<< myField->getNumberOfValues() << endl ;
189 for (int i=1; i<NumberOfComponents+1; i++) {
190 cout << " - composante "<<i<<" :"<<endl ;
191 cout << " - nom : "<<myField->getComponentName(i)<< endl;
192 cout << " - description : "<<myField->getComponentDescription(i) << endl;
193 cout << " - units : "<<myField->getMEDComponentUnit(i) << endl;
195 cout << "- iteration :" << endl ;
196 cout << " - numero : " << myField->getIterationNumber()<< endl ;
197 cout << " - ordre : " << myField->getOrderNumber()<< endl ;
198 cout << " - temps : " << myField->getTime()<< endl ;
199 cout << "- Type : " << myField->getValueType()<< endl;
201 cout << "- Valeurs :"<<endl;
202 int NumberOf = mySupport->getNumberOfElements(MED_ALL_ELEMENTS);
204 bool displayNode = mySupport->isOnAllElements() && mySupport->getEntity()==MED_NODE;
205 bool displayBary = mySupport->isOnAllElements() && mySupport->getEntity()==MED_CELL;
206 int dim_space = mySupport->getMesh()->getSpaceDimension();
207 const double * coord = mySupport->getMesh()->getCoordinates(MED_FULL_INTERLACE);
209 auto_ptr<TFieldDouble> barycenter(0);
211 barycenter=auto_ptr<TFieldDouble>(mySupport->getMesh()->getBarycenter(mySupport)) ;
214 for (int i=1; i<NumberOf+1; i++) {
215 const double * value = myField->getRow(i) ;
218 int N=(i-1)*dim_space;
219 cout << setw(width) << i << setw(width) << coord[N] << " " << setw(width) << coord[N+1]<< " " << setw(width) << coord[N+2] << " : " ;
222 cout << setw(width) << i << setw(width) << barycenter->getValueIJ(i,1) << " " << setw(width) << barycenter->getValueIJ(i,2)
223 << " " << setw(width) << barycenter->getValueIJ(i,3) << " : " ;
224 for (int j=0; j<NumberOfComponents; j++)
225 cout << value[j]<< " ";
229 cout << "Norme euclidienne : " << myField->norm2() << endl;
230 cout << "Norme max : " << myField->normMax() << endl;
231 cout << "------------------------------------------------------------------------" << endl << endl;
232 endService( "CALCULATOR::printField");
237 CORBA::Double CALCULATOR::convergenceCriteria(SALOME_MED::FIELDDOUBLE_ptr field)
239 beginService( "CALCULATOR::convergenceCriteria");
240 BEGIN_OF("CALCULATOR::convergenceCriteria(SALOME_MED::FIELDDOUBLE_ptr field)");
243 static auto_ptr<TFieldDouble> fold(0);
244 auto_ptr<TFieldDouble> fnew (new TFieldDouble_c(field) );
245 if (fold.get() == NULL) // if old field is not set, set it and return 1
249 // if size of fields are not equal, return 1
250 const int size=fold->getNumberOfValues()*fold->getNumberOfComponents();
251 if ( size == fnew->getNumberOfValues()*fnew->getNumberOfComponents() )
253 MED_EN::medModeSwitch mode=fold->getInterlacingType(); // storage mode
254 const double* oldVal= fold->getValue(); // retrieve values
255 const double* newVal= fnew->getValue();
257 double ecart_rel=0.0;
258 for (unsigned i=0; i!=size; ++i) // compute criteria
260 if ( oldVal[i] != 0.0)
262 ecart_rel = std::abs( (oldVal[i]-newVal[i])/oldVal[i] );
263 if ( ecart_rel>criteria )
271 endService( "CALCULATOR::convergenceCriteria");
272 END_OF("CALCULATOR::convergenceCriteria(SALOME_MED::FIELDDOUBLE_ptr field1)");
280 PortableServer::ObjectId * CALCULATOREngine_factory(
282 PortableServer::POA_ptr poa,
283 PortableServer::ObjectId * contId,
284 const char *instanceName,
285 const char *interfaceName)
287 MESSAGE("PortableServer::ObjectId * CALCULATOREngine_factory()");
288 SCRUTE(interfaceName);
289 CALCULATOR * myCALCULATOR
290 = new CALCULATOR(orb, poa, contId, instanceName, interfaceName);
291 return myCALCULATOR->getId() ;