1 // Copyright (C) 2007-2012 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.
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 // Authors : Guillaume Boulant (EDF) - 01/06/2011
25 #include "MEDDataManager_i.hxx"
26 #include "SALOME_KernelServices.hxx"
27 #include "Basics_DirUtils.hxx"
28 #include "Basics_Utils.hxx"
30 #include "MEDLoader.hxx"
31 using namespace ParaMEDMEM;
37 MEDDataManager_i * MEDDataManager_i::_instance = NULL;
38 long MEDDataManager_i::LONG_UNDEFINED = -1;
40 MEDDataManager_i * MEDDataManager_i::getInstance() {
41 // _GBO_ we will certainly need to define one single DataManager per
42 // SALOME study and not one singleton for the whole session
43 if ( _instance == NULL ) {
44 _instance = new MEDDataManager_i();
49 #define IOR_UNDEF "IOR UNDEFINED"
50 MEDDataManager_i::MEDDataManager_i()
52 LOG("Creating a MEDDataManager_i instance");
56 _fieldseriesLastId = 0;
57 _medEventListenerIOR = NULL;
59 MEDDataManager_i::~MEDDataManager_i()
61 LOG("Deleting MEDDataManager_i instance");
64 const char * MEDDataManager_i::file_to_source(const char * filepath)
66 string * source = new string("file://");
67 source->append(filepath);
68 return source->c_str();;
70 const char * MEDDataManager_i::source_to_file(const char * source)
72 string * filepath = new string(source);
73 filepath->replace(0,7,"");
74 return filepath->c_str();
78 * This function loads the meta-data from the specified med file and
79 * returns the associated datasource handler. The data source handler
80 * is a key to retrieve all informations concerning the data (meshes,
83 MEDOP::DatasourceHandler * MEDDataManager_i::addDatasource(const char *filepath) {
85 // We first check that this datasource is not already registered
86 long sourceid = getDatasourceId(filepath);
87 if ( sourceid != LONG_UNDEFINED ) {
88 // The file is already registered under the identifier sourceid
89 LOG("WRN: The file "<<filepath<<" is already registered with id="<<ToString(sourceid));
90 return new MEDOP::DatasourceHandler(*_datasourceHandlerMap[sourceid]);
93 // Then we check that the file is readable by MEDLoader
94 MEDLoader::CheckFileForRead(filepath);
96 // Initialise the datasource handler
97 MEDOP::DatasourceHandler * datasourceHandler = new MEDOP::DatasourceHandler();
98 datasourceHandler->id = _sourceLastId; _sourceLastId++;
99 datasourceHandler->name = (Kernel_Utils::GetBaseName(filepath)).c_str();
100 datasourceHandler->uri = file_to_source(filepath);
101 _datasourceHandlerMap[datasourceHandler->id] = datasourceHandler;
103 // We start by read the list of meshes (spatial supports of fields)
104 vector<string> meshNames = MEDLoader::GetMeshNames(filepath);
105 int nbOfMeshes = meshNames.size();
106 for (int iMesh = 0; iMesh < nbOfMeshes; iMesh++) {
107 const char * meshName = meshNames[iMesh].c_str();
108 LOG("name of mesh " << iMesh << " = " << meshName);
110 MEDOP::MeshHandler * meshHandler = new MEDOP::MeshHandler();
111 meshHandler->id = _meshLastId; _meshLastId++;
112 meshHandler->name = meshName;
113 meshHandler->sourceid = datasourceHandler->id;
115 _meshHandlerMap[meshHandler->id] = meshHandler;
117 // For each mesh, we can read the list of the names of the
118 // associated fields, i.e. fields whose spatial support is this
120 vector<string> fieldNames = MEDLoader::GetAllFieldNamesOnMesh(filepath,
122 int nbOfFields = fieldNames.size();
123 for (int iField = 0; iField < nbOfFields; iField++) {
124 const char * fieldName = fieldNames[iField].c_str();
125 LOG("-- name of field " << iField << " = " << fieldName);
127 // A field name could identify several MEDCoupling fields, that
128 // differ by their spatial discretization on the mesh (values on
129 // cells, values on nodes, ...). This spatial discretization is
130 // specified by the TypeOfField that is an integer value in this
137 // As a consequence, before loading values of a field, we have
138 // to determine the types of spatial discretization defined for
139 // this field and to chooose one.
141 vector<TypeOfField> listOfTypes = MEDLoader::GetTypesOfField(filepath,
144 int nbOfTypes = listOfTypes.size();
145 for (int iType = 0; iType < nbOfTypes; iType++) {
146 LOG("---- type "<<iType<<" of field "<<iField<< " = " << listOfTypes[iType]);
148 // Then, we can get the iterations associated to this field on
149 // this type of spatial discretization:
150 std::vector< std::pair<int,int> > fieldIterations =
151 MEDLoader::GetFieldIterations(listOfTypes[iType],
156 int nbFieldIterations = fieldIterations.size();
157 LOG("---- nb. iterations = " << nbFieldIterations);
159 // We can define the timeseries of fields (fieldseries) for
160 // this type. A fieldseries is a macro object that handle the whole
161 // set of time iterations of a field.
162 MEDOP::FieldseriesHandler * fieldseriesHandler = new MEDOP::FieldseriesHandler();
163 fieldseriesHandler->id = _fieldseriesLastId; _fieldseriesLastId++;
164 fieldseriesHandler->name = fieldName;
165 fieldseriesHandler->type = listOfTypes[iType];
166 fieldseriesHandler->meshid = meshHandler->id;
167 fieldseriesHandler->nbIter = nbFieldIterations;
168 _fieldseriesHandlerMap[fieldseriesHandler->id] = fieldseriesHandler;
170 // We can then load meta-data concerning all iterations
171 for (int iterationIdx=0; iterationIdx<nbFieldIterations; iterationIdx++) {
173 int iteration = fieldIterations[iterationIdx].first;
174 int order = fieldIterations[iterationIdx].second;
176 const char * source = datasourceHandler->uri;
177 MEDOP::FieldHandler * fieldHandler = newFieldHandler(fieldName,
184 fieldHandler->meshid = meshHandler->id;
185 fieldHandler->fieldseriesId = fieldseriesHandler->id;
186 _fieldHandlerMap[fieldHandler->id] = fieldHandler;
192 return new MEDOP::DatasourceHandler(*datasourceHandler);
195 long MEDDataManager_i::getDatasourceId(const char *filepath) {
196 const char * uri = file_to_source(filepath);
197 DatasourceHandlerMapIterator it = _datasourceHandlerMap.begin();
198 while ( it != _datasourceHandlerMap.end() ) {
199 if ( strcmp(it->second->uri,uri) == 0 ) {
204 return LONG_UNDEFINED;
208 MEDOP::MeshHandler * MEDDataManager_i::getMesh(CORBA::Long meshId) {
209 if ( _meshHandlerMap.count(meshId) == 0 ) {
210 std::string message =
211 std::string("The mesh of id=") + ToString(meshId) +
212 std::string(" does not exist in the data manager");
214 throw KERNEL::createSalomeException(message.c_str());
216 return new MEDOP::MeshHandler(*(_meshHandlerMap[meshId]));
221 * This function returns the list of mesh handlers associated to the
222 * specified datasource. It corresponds to the list ofmeshes defined
225 MEDOP::MeshHandlerList * MEDDataManager_i::getMeshList(CORBA::Long datasourceId) {
227 // We initiate a list with the maximum lentgh
228 MEDOP::MeshHandlerList_var meshHandlerList = new MEDOP::MeshHandlerList();
229 meshHandlerList->length(_meshHandlerMap.size());
231 // Scan the map looking for meshes associated to the specified datasource
233 MeshHandlerMapIterator meshIt;
234 for ( meshIt=_meshHandlerMap.begin(); meshIt != _meshHandlerMap.end(); meshIt++) {
235 if ( meshIt->second->sourceid == datasourceId ) {
236 meshHandlerList[itemIdx] = *(meshIt->second);
241 // Adjust the length to the real number of elements
242 meshHandlerList->length(itemIdx);
243 return meshHandlerList._retn();
247 * This function returns the list of fieldseries defined on the
250 MEDOP::FieldseriesHandlerList * MEDDataManager_i::getFieldseriesListOnMesh(CORBA::Long meshId) {
251 // We initiate a list with the maximum lentgh
252 MEDOP::FieldseriesHandlerList_var
253 fieldseriesHandlerList = new MEDOP::FieldseriesHandlerList();
254 fieldseriesHandlerList->length(_fieldseriesHandlerMap.size());
256 // Scan the map looking for fieldseries defined on the specified mesh
258 FieldseriesHandlerMapIterator it;
259 for ( it=_fieldseriesHandlerMap.begin(); it != _fieldseriesHandlerMap.end(); it++) {
260 if ( it->second->meshid == meshId ) {
261 fieldseriesHandlerList[itemIdx] = *(it->second);
266 // Adjust the length to the real number of elements
267 fieldseriesHandlerList->length(itemIdx);
268 return fieldseriesHandlerList._retn();
272 * A fieldseries is a timeseries of fields. Then the list of fields is
273 * the different time iterations defined for the specified field id.
275 MEDOP::FieldHandlerList * MEDDataManager_i::getFieldListInFieldseries(CORBA::Long fieldseriesId) {
277 // We initiate a list with the maximum lentgh
278 MEDOP::FieldHandlerList_var fieldHandlerList = new MEDOP::FieldHandlerList();
279 fieldHandlerList->length(_fieldHandlerMap.size());
281 // Scan the map looking for field defined on the specified mesh
283 FieldHandlerMapIterator it;
284 for ( it=_fieldHandlerMap.begin(); it != _fieldHandlerMap.end(); it++) {
285 if ( it->second->fieldseriesId == fieldseriesId ) {
286 fieldHandlerList[itemIdx] = *(it->second);
291 // Adjust the length to the real number of elements
292 fieldHandlerList->length(itemIdx);
293 return fieldHandlerList._retn();
297 * This returns the whole set of fields handlers for all datasource
298 * that have been loaded using addDatasource.
300 MEDOP::FieldHandlerList * MEDDataManager_i::getFieldHandlerList() {
301 MEDOP::FieldHandlerList_var fieldHandlerSeq = new MEDOP::FieldHandlerList();
302 fieldHandlerSeq->length(_fieldHandlerMap.size());
305 FieldHandlerMapIterator fieldIt;
306 for ( fieldIt=_fieldHandlerMap.begin(); fieldIt != _fieldHandlerMap.end(); fieldIt++) {
307 fieldHandlerSeq[sequenceId] = *(fieldIt->second);
310 return fieldHandlerSeq._retn();
314 * This returns a copy of the fieldHandler associated to the specified id.
316 MEDOP::FieldHandler * MEDDataManager_i::getFieldHandler(CORBA::Long fieldHandlerId) {
317 LOG("getFieldHandler: START")
319 FieldHandlerMapIterator fieldIt = _fieldHandlerMap.find(fieldHandlerId);
320 if ( fieldIt != _fieldHandlerMap.end() ) {
321 // >>> WARNING: CORBA struct specification indicates that the
322 // assignement acts as a desctructor for the structure that is
323 // pointed to. The values of the fields are copy first in the new
324 // structure that receives the assignement and finally the initial
325 // structure is destroyed. In the present case, WE WANT to keep
326 // the initial fieldHandler in the map. We must then make a deep
327 // copy of the structure found in the map and return the copy. The
328 // CORBA struct specification indicates that a deep copy can be
329 // done using the copy constructor. <<<
330 return new MEDOP::FieldHandler(*(fieldIt->second));
336 * This returns a string representation of the field associated to the specified id.
338 char * MEDDataManager_i::getFieldRepresentation(CORBA::Long fieldHandlerId) {
339 LOG("getFieldRepresentation: START")
340 MEDOP::FieldHandler * fieldHandler = getFieldHandler(fieldHandlerId);
341 MEDCouplingFieldDouble* fieldDouble = getFieldDouble(fieldHandler);
342 return CORBA::string_dup(fieldDouble->getArray()->repr().c_str());
345 void MEDDataManager_i::saveFields(const char * filepath,
346 const MEDOP::FieldIdList & fieldIdList)
348 LOG("saveFields to : " << filepath);
350 // We first have to check if the target filepath is writable
351 // (segmentation fault in med otherwise)
352 if (!Kernel_Utils::IsWritable(Kernel_Utils::GetDirName(std::string(filepath)))) {
353 std::string message =
354 std::string("The target filepath ") +
355 std::string(filepath) +
356 std::string(" is not writable");
358 throw KERNEL::createSalomeException(message.c_str());
361 if ( fieldIdList.length() == 0 ) {
362 throw KERNEL::createSalomeException("No fields to save");
365 // Consider the first field to initiate the med file
366 CORBA::Long fieldHandlerId = fieldIdList[0];
367 MEDOP::FieldHandler * fieldHandler = getFieldHandler(fieldHandlerId);
368 MEDCouplingFieldDouble* fieldDouble = getFieldDouble(fieldHandler);
371 bool writeFromScratch = true;
372 MEDLoader::WriteField(filepath, fieldDouble, writeFromScratch);
374 writeFromScratch = false;
375 for(CORBA::ULong i=1; i<fieldIdList.length(); i++) {
376 fieldHandlerId = fieldIdList[i];
377 fieldHandler = getFieldHandler(fieldHandlerId);
378 fieldDouble = getFieldDouble(fieldHandler);
379 MEDLoader::WriteField(filepath, fieldDouble, writeFromScratch);
382 catch (INTERP_KERNEL::Exception &ex) {
383 std::string message =
384 std::string("Error when saving file ") +
385 std::string(filepath) + std::string(" : ") + ex.what();
386 throw KERNEL::createSalomeException(message.c_str());
388 catch (const std::exception& ex) {
389 std::string message =
390 std::string("Error when saving file ") +
391 std::string(filepath) + std::string(" : ") + ex.what();
392 throw KERNEL::createSalomeException(message.c_str());
398 * This function must be used to indicate that the field with the
399 * specified id must be considered as persistent (if persistent is
400 * true) or not persistent (if persistent is false). If a field is
401 * marked as persistent, then it is automatically saved when the
402 * function savePersistentFields is called.
404 void MEDDataManager_i::markAsPersistent(CORBA::Long fieldHandlerId, bool persistent) {
405 LOG("mark as persistant : id="<<fieldHandlerId);
406 _fieldPersistencyMap[fieldHandlerId] = persistent;
409 void MEDDataManager_i::savePersistentFields(const char * filepath) {
410 LOG("savePersistentFields to : " << filepath);
411 std::vector<long> listId;
413 FieldPersistencyMapIterator mapIt;
414 for ( mapIt = _fieldPersistencyMap.begin(); mapIt != _fieldPersistencyMap.end(); mapIt++) {
415 if ( mapIt->second == true ) {
416 listId.push_back(mapIt->first);
420 MEDOP::FieldIdList fieldIdList;
421 fieldIdList.length(listId.size());
422 for (int i=0; i<listId.size(); i++) {
423 fieldIdList[i] = CORBA::Long(listId[i]);
427 this->saveFields(filepath, fieldIdList);
429 catch (const SALOME::SALOME_Exception & ex) {
432 catch (const std::exception& ex) {
433 std::string message =
434 std::string("Error when saving file ") +
435 std::string(filepath) + std::string(" : ") + ex.what();
436 throw KERNEL::createSalomeException(message.c_str());
441 * This function is responsible for creating the FieldHandler
442 * instances. You must use this function because it manages
443 * automatically the identifier value (autoincrementation of a static
446 MEDOP::FieldHandler * MEDDataManager_i::newFieldHandler(const char * fieldname,
447 const char * meshname,
453 MEDOP::FieldHandler * fieldHandler = new MEDOP::FieldHandler();
454 fieldHandler->id = _fieldLastId; _fieldLastId++;
455 fieldHandler->fieldname = fieldname;
456 fieldHandler->meshname = meshname;
457 fieldHandler->type = type;
458 fieldHandler->iteration = iteration;
459 fieldHandler->order = order;
460 fieldHandler->source = source;
465 * This updates the metadata of the field identified by its id with
466 * the data of the given field handler. Returns a copy of the updated
467 * handler (that should be identical to the given field handler for
468 * all data but not for the id that is an invariant for all session
470 * WARN: you should be warned that this function could leave the data
471 * model in a non-coherent state, by example if you change the mesh
472 * name while the mesh has not been updated.
474 MEDOP::FieldHandler * MEDDataManager_i::updateFieldHandler(CORBA::Long fieldHandlerId,
475 const char * fieldname,
478 const char * source) {
479 FieldHandlerMapIterator fieldIt = _fieldHandlerMap.find(fieldHandlerId);
480 if ( fieldIt != _fieldHandlerMap.end() ) {
481 // Update the attributes
482 // >>> WARN: note that the id of a handler registered in the map
483 // SHOULD NEVER be modified because it is the identifier used in
484 // the whole application for this field all the session long.
486 fieldIt->second->fieldname = fieldname;
487 fieldIt->second->iteration = iteration;
488 fieldIt->second->order = order;
489 fieldIt->second->source = source;
491 return new MEDOP::FieldHandler(*fieldIt->second);
496 MEDCouplingUMesh * MEDDataManager_i::getUMesh(long meshHandlerId) {
498 LOG("getUMesh: START")
500 MEDCouplingUMesh * myMesh = NULL;
501 if ( _meshMap.count(meshHandlerId) > 0 ) {
502 // The mesh has been found in the map
503 myMesh = _meshMap[meshHandlerId];
505 // The mesh is not loaded yet ==> load it and register it in the map
506 LOG("getUMesh: the mesh must be loaded. meshid="<<meshHandlerId);
507 if ( _meshHandlerMap[meshHandlerId] == NULL ) {
508 std::string message =
509 std::string("No mesh for id=") + ToString(meshHandlerId);
510 LOG("getUMesh: "<<message);
511 throw KERNEL::createSalomeException(message.c_str());
514 long sourceid = _meshHandlerMap[meshHandlerId]->sourceid;
515 const char * filepath = source_to_file((_datasourceHandlerMap[sourceid])->uri);
516 const char * meshName = _meshHandlerMap[meshHandlerId]->name;
517 int meshDimRelToMax = 0;
518 myMesh = MEDLoader::ReadUMeshFromFile(filepath,meshName,meshDimRelToMax);
519 _meshMap[meshHandlerId] = myMesh;
525 * Try to retrieve the id of the specified mesh, i.e. the key it is
526 * registered with in the internal meshes map.
528 long MEDDataManager_i::getUMeshId(const MEDCouplingMesh * mesh) {
530 MeshMapIterator it = _meshMap.begin();
531 while ( it != _meshMap.end() ) {
532 found = (it->second == mesh);
538 return LONG_UNDEFINED;
542 * This method returns the physical data of the specified field,
543 * i.e. the MEDCoupling field associated to the specified field
544 * handler. If the field source is a file and the data ar not loaded
545 * yet, the this function load the data from the file in a MEDCoupling
546 * field instance. Otherwize, it just returns the MEDCoupling field
549 MEDCouplingFieldDouble * MEDDataManager_i::getFieldDouble(const MEDOP::FieldHandler * fieldHandler)
552 LOG("getFieldDouble: START with id="<<fieldHandler->id);
554 if ( _fieldDoubleMap.count(fieldHandler->id) > 0 ) {
555 // The MEDCoupling field data are already loaded. Just return the
556 // reference of the MEDCouplingFieldDouble pointer
557 return _fieldDoubleMap[fieldHandler->id];
560 // The MEDCoupling field data are not loaded yet. Load the data and
561 // register the MEDCoupling field in our internal map an all the
562 // associated data if needed (i.e. the underlying mesh).
564 // At this step, the mesh handler needs a meshid correctly
565 // set. Normally, we should arrive at this step only in the case
566 // where the field is loaded from a file ==> the meshid is defined
567 // (see the addDatasource function).
569 // >>>> __GBO__ TO BE CHECKED AND SERIOUSLY TESTED. There at least
570 // one case where we can arrive here with no previous call to
571 // addDataSource: for example the field handler list can be obtained
572 // from a call to addFieldsFromFile instead of addDataSource (see
573 // for exemple the getFieldRepresentation service of the
574 // dataManager, that comes here and then calls getUMesh where we
575 // need a map initialized only in addDataSource) <<<<
576 long meshid = fieldHandler->meshid;
578 // We first have to check if the associated mesh is already loaded
579 // and to load it if needed. The loaded meshes are registered in a
580 // map whose key is the mesh handler id. This checking is
581 // automatically done by the function getUMesh. It's important to do
582 // it before the loading of field data to prevent from the case
583 // where the mesh would not have been loaded already (in the
584 // previous field loading).
585 MEDCouplingUMesh * myMesh =this->getUMesh(meshid);
587 long sourceid = _meshHandlerMap[meshid]->sourceid;
589 const char * filepath = source_to_file((_datasourceHandlerMap[sourceid])->uri);
590 const char * meshName = myMesh->getName();
591 LOG("getFieldDouble: field "<<fieldHandler->fieldname<<" loaded from file "<<filepath);
592 TypeOfField type = (TypeOfField)fieldHandler->type;
593 int meshDimRelToMax = 0;
594 MEDCouplingFieldDouble * myField = MEDLoader::ReadField(type,
598 fieldHandler->fieldname,
599 fieldHandler->iteration,
600 fieldHandler->order);
601 myField->setMesh(myMesh);
602 _fieldDoubleMap[fieldHandler->id] = myField;
607 * This adds the specified MEDCoupling field in the collection managed
608 * by this DataManager. The associated FieldHandler is returned. This
609 * is typically used in a context where the MEDCoupling field is
610 * created from scratch, for example by operations in the
612 * @param[in] fieldDouble the MEDCouplingFieldDouble instance to add
613 * @param[in] meshHandlerId the id of the meshHandler this filed is associated to.
614 * @return a copy of the FieldHandler registered in the internal map for this field.
616 MEDOP::FieldHandler * MEDDataManager_i::addField(MEDCouplingFieldDouble * fieldDouble,
619 const char * fieldName = fieldDouble->getName();
620 const char * meshName = fieldDouble->getMesh()->getName();
621 TypeOfField type = fieldDouble->getTypeOfField();
623 int iteration, order;
624 // WARN: note that the variables "iteration" and "order" are passed
625 // by reference to the function getTime (see documentation of
626 // MEDCouplingField). As a consequence, the values of these
627 // variables are updated by this function call. This is the mean to
628 // retrieve the iteration and order of the field.
629 double timestamp = fieldDouble->getTime(iteration, order);
631 // For the fields that are created in memory (by operations for
632 // example), the convention for the source attribute is to specify
633 // the fielddouble name, because this name describes the operation
634 // the field has been created with.
635 string * source = new string("mem://"); source->append(fieldName);
636 MEDOP::FieldHandler * fieldHandler = newFieldHandler(fieldName,
643 if ( meshHandlerId == LONG_UNDEFINED ) {
644 // We have to gess the id of the underlying mesh to preserve data
645 // integrity (a fieldHandler must have an attribute that contains
646 // the id of its underlying mesh):
648 // WARNING: it's better to let the client code (the one who calls the
649 // function addField) to specify this meshid. This guess procedure is
650 // not reliable, it's just to have a second chance.
652 LOG("addField: The mesh id is not defined. Trying to guess from the mesh name "<<meshName);
653 long meshid = this->getUMeshId(fieldDouble->getMesh());
654 fieldHandler->meshid = meshid;
655 if ( meshid == LONG_UNDEFINED ) {
656 // No mesh has been found in the internal map
657 LOG("addField: The mesh id for the mesh "<<meshName<<" can't be retrieved from the field "<<fieldName);
658 // _GBO_ : Maybe it could be better to raise an exception
662 fieldHandler->meshid = meshHandlerId;
665 _fieldHandlerMap[fieldHandler->id] = fieldHandler;
666 _fieldDoubleMap[fieldHandler->id] = fieldDouble;
667 // >>> WARNING: CORBA structure assignement specification ==> return
668 // >>> a deep copy to avoid the destruction of the fieldHandler
669 // >>> registered in the map (assignement acts as a destructor for
670 // >>> CORBA struct).
671 return new MEDOP::FieldHandler(*fieldHandler);
675 * This function updates the meta-data "fieldname" associated to the
678 void MEDDataManager_i::updateFieldMetadata(CORBA::Long fieldHandlerId,
679 const char * fieldname,
680 CORBA::Long iteration,
684 // We have to update the field handler registered in the internal
685 // map AND the associated fieldDouble loaded in memory.
686 MEDOP::FieldHandler * fieldHandler = getFieldHandler(fieldHandlerId);
687 updateFieldHandler(fieldHandlerId,fieldname,iteration,order,source);
689 MEDCouplingFieldDouble* fieldDouble = getFieldDouble(fieldHandler);
690 fieldDouble->setName(fieldname);
692 // _GBO_ TO BE IMPLEMENTED: iteration and order
696 * This can be used to associate to the specified field another mesh
697 * support than its current one. This is typically needed to operate 2
698 * fields defined on the same mesh but coming from different med
699 * files. In this case, the underlying meshes are different mesh
700 * objects (from the MEDCoupling point of view) and then no operation
701 * can be allowed by MEDCoupling. The operation of course fails if the
702 * new mesh is not identical to the old one.
704 void MEDDataManager_i::changeUnderlyingMesh(CORBA::Long fieldHandlerId, CORBA::Long meshHandlerId) {
706 MEDOP::FieldHandler * fieldHandler = getFieldHandler(fieldHandlerId);
707 MEDCouplingFieldDouble* fieldDouble = getFieldDouble(fieldHandler);
708 MEDCouplingMesh * newMesh = getUMesh(meshHandlerId);
711 fieldDouble->changeUnderlyingMesh(newMesh,10,1e-12);
713 catch (INTERP_KERNEL::Exception &ex) {
714 std::string * message = new std::string("Error when changing the underlying mesh : ");
715 message->append(ex.what());
716 throw KERNEL::createSalomeException(message->c_str());
719 // The change of mesh is OK, then we can update the meta-data
720 _fieldHandlerMap[fieldHandlerId]->meshid = meshHandlerId;
721 _fieldHandlerMap[fieldHandlerId]->meshname = _meshHandlerMap[meshHandlerId]->name;
724 // WARN: if this field has already been request by the tui for
725 // manipulation (in a fieldproxy), then the data should be
732 * This functions display the internal data of the MEDDataManager on
733 * the server side (data in the SALOME container).
735 void MEDDataManager_i::serverlog() {
737 LOG("==== Field Handler Map ====================================================");
738 LOG("Size = "<<_fieldHandlerMap.size());
739 FieldHandlerMapIterator fhmIt;
740 for ( fhmIt = _fieldHandlerMap.begin(); fhmIt != _fieldHandlerMap.end(); fhmIt++) {
741 long id = fhmIt->first;
742 LOG("------------------------------------- id = "<<ToString(id));
743 LOG("- id \t= "<<fhmIt->second->id);
744 LOG("- fieldname \t= "<<fhmIt->second->fieldname);
745 LOG("- meshname \t= "<<fhmIt->second->meshname);
748 LOG("==== Field Double Map ====================================================");
749 LOG("Size = "<<_fieldDoubleMap.size());
750 FieldDoubleMapIterator fdmIt;
751 for ( fdmIt = _fieldDoubleMap.begin(); fdmIt != _fieldDoubleMap.end(); fdmIt++) {
752 long id = (*fdmIt).first;
753 MEDCouplingFieldDouble * fieldDouble = (*fdmIt).second;
754 LOG("------------------------------------- id = "<<ToString(id));
755 LOG("- fieldname \t= "<<fieldDouble->getName());
756 LOG("- meshname \t= "<<fieldDouble->getMesh()->getName());
761 * The event listener is created inside the GUI by the
762 * WorkspaceController. This function is called by the WorkspaceController to
763 * store the event listener IOR for the time of the session. Then this
764 * IOR can be available to any point of the application that can
765 * request the data manager (the python console for example).
767 void MEDDataManager_i::setEventListenerIOR(const char * ior) {
768 if ( _medEventListenerIOR != NULL ) {
769 free(_medEventListenerIOR);
771 _medEventListenerIOR = (char *)malloc(sizeof(char)*strlen(ior));
772 strcpy(_medEventListenerIOR, ior);
775 * Return the IOR of the event listener that resides in the
776 * GUI. Having the IOR, you can restore the CORBA object by using:
778 * In a python SALOME context:
781 * >>> salome.salome_init()
782 * >>> myobject = salome.orb.string_to_object(ior)
784 * In a C++ SALOME context: (to do if needed)
786 char * MEDDataManager_i::getEventListenerIOR() {
787 if ( _medEventListenerIOR == NULL ) {
788 throw KERNEL::createSalomeException("The event listener IOR is not defined");
790 // WARN: return a copy because the pointer memory will be released
791 // (CORBA specification)
792 char * ior = (char *)malloc(sizeof(char)*strlen(_medEventListenerIOR));
793 strcpy(ior, _medEventListenerIOR);