1 // Copyright (C) 2007-2023 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, or (at your option) any later version.
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
20 #include "MEDPARTITIONER_ParallelTopology.hxx"
21 #include "MEDPARTITIONER_MeshCollectionDriver.hxx"
22 #include "MEDPARTITIONER_MeshCollection.hxx"
23 #include "MEDPARTITIONER_MeshCollectionMedAsciiDriver.hxx"
24 #include "MEDPARTITIONER_ParaDomainSelector.hxx"
25 #include "MEDPARTITIONER_Utils.hxx"
27 #include "MEDCouplingUMesh.hxx"
28 #include "MEDLoader.hxx"
38 #include <libxml/tree.h>
39 #include <libxml/parser.h>
40 #include <libxml/xpath.h>
41 #include <libxml/xpathInternals.h>
43 using namespace MEDPARTITIONER;
45 MeshCollectionMedAsciiDriver::MeshCollectionMedAsciiDriver(MeshCollection* collection):MeshCollectionDriver(collection)
49 /*!reads a MED File v>=2.3
50 * and mounts the corresponding meshes in memory
51 * the connect zones are created from the joints
53 *\param filename ascii file containing the list of MED v2.3 files
56 int MeshCollectionMedAsciiDriver::read(MEDCoupling::MEDFileData* filedata)
58 readMEDFileData(filedata);
60 std::vector<MEDPARTITIONER::ConnectZone*> cz; // to fill from filedata
61 std::vector<mcIdType*> cellglobal;
62 std::vector<mcIdType*> nodeglobal;
63 std::vector<mcIdType*> faceglobal;
64 std::size_t size = _collection->getMesh().size();
65 cellglobal.resize(size);
66 nodeglobal.resize(size);
67 faceglobal.resize(size);
68 for ( unsigned int idomain = 0; idomain < size; ++idomain )
70 cellglobal[idomain]=0;
71 faceglobal[idomain]=0;
72 nodeglobal[idomain]=0;
73 if ( (_collection->getMesh())[idomain] && (_collection->getMesh())[idomain]->getNumberOfNodes() > 0 )
74 _collection->setNonEmptyMesh(idomain);
76 //creation of topology from mesh and connect zones
77 ParallelTopology* aPT = new ParallelTopology((_collection->getMesh()), cz, cellglobal, nodeglobal, faceglobal);
78 _collection->setTopology(aPT,true);
83 /*!reads a MED File v>=2.3
84 * and mounts the corresponding meshes in memory
85 * the connect zones are created from the joints
87 *\param filename ascii file containing the list of MED v2.3 files
90 int MeshCollectionMedAsciiDriver::read(const char* filename, ParaDomainSelector* domainSelector)
93 std::vector<mcIdType*> cellglobal;
94 std::vector<mcIdType*> nodeglobal;
95 std::vector<mcIdType*> faceglobal;
98 //reading ascii master file
101 std::ifstream asciiinput(filename);
103 throw INTERP_KERNEL::Exception("Master ASCII File does not exist");
104 char charbuffer[512];
105 asciiinput.getline(charbuffer,512);
107 while (charbuffer[0]=='#')
109 asciiinput.getline(charbuffer,512);
112 //reading number of domains
113 nbdomain=atoi(charbuffer);
114 MyGlobals::_File_Names.resize(nbdomain);
115 MyGlobals::_Mesh_Names.resize(nbdomain);
116 (_collection->getMesh()).resize(nbdomain);
117 cellglobal.resize(nbdomain);
118 nodeglobal.resize(nbdomain);
119 faceglobal.resize(nbdomain);
122 throw INTERP_KERNEL::Exception("Empty ASCII master file");
123 for (int i=0; i<nbdomain;i++)
125 //reading information about the domain
126 std::string mesh,host;
132 asciiinput >> mesh >> idomain >> MyGlobals::_Mesh_Names[i] >> host >> MyGlobals::_File_Names[i];
134 //Setting the name of the global mesh (which should be is the same for all the subdomains)
136 _collection->setName(mesh);
140 throw INTERP_KERNEL::Exception("domain must be written from 1 to N in ASCII file descriptor");
142 if ( !domainSelector || domainSelector->isMyDomain(i))
149 throw INTERP_KERNEL::Exception("I/O error reading parallel MED file");
152 //creation of topology from mesh and connect zones
153 ParallelTopology* aPT = new ParallelTopology((_collection->getMesh()), (_collection->getCZ()), cellglobal, nodeglobal, faceglobal);
154 _collection->setTopology(aPT, true);
156 for (int i=0; i<nbdomain; i++)
158 delete [] cellglobal[i];
159 delete [] nodeglobal[i];
160 delete [] faceglobal[i];
165 /*! writes the collection of meshes in a MED v2.3 file
166 * with the connect zones being written as joints
167 * \param filename name of the ascii file containing the meshes description
169 void MeshCollectionMedAsciiDriver::write(const char* filename, ParaDomainSelector* domainSelector) const
171 std::size_t nbdomains=_collection->getMesh().size();
172 std::vector<std::string> filenames;
173 filenames.resize(nbdomains);
175 //loop on the domains
176 for (unsigned idomain=0; idomain<nbdomains; idomain++)
178 std::string distfilename;
179 std::ostringstream suffix;
180 suffix << filename << idomain+1 << ".med";
181 distfilename=suffix.str();
182 filenames[idomain]=distfilename;
184 if ( !domainSelector || domainSelector->isMyDomain( idomain ) )
186 // [ABN] spurious test in 8.2 - fixed as I think it should be:
187 if ( _collection->getMesh()[idomain]->getNumberOfCells() == 0 ) continue;
188 WriteUMesh(distfilename.c_str(),(_collection->getMesh())[idomain],true);
189 //writeSubdomain(idomain, nbdomains, distfilename.c_str(), domainSelector);
194 if ( !domainSelector || domainSelector->rank() == 0 )
196 std::ofstream file(filename);
197 file << "#MED Fichier V 2.3"<<" " << std::endl;
198 file << "#" << " " << std::endl;
199 file << _collection->getMesh().size() << " " << std::endl;
201 for (std::size_t idomain=0; idomain<nbdomains; idomain++)
202 file << _collection->getName() <<" "<< idomain+1 << " "
203 << (_collection->getMesh())[idomain]->getName() << " localhost "
204 << filenames[idomain] << " "<< std::endl;