Salome HOME
81231dacedab16984cd180146375669fca7d3132
[tools/medcoupling.git] / src / MEDPartitioner / MEDPARTITIONER_MeshCollectionMedAsciiDriver.cxx
1 // Copyright (C) 2007-2016  CEA/DEN, EDF R&D
2 //
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.
7 //
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.
12 //
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
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
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"
26
27 #include "MEDCouplingUMesh.hxx"
28 #include "MEDLoader.hxx"
29
30 #include <map>
31 #include <set>
32 #include <vector>
33 #include <string>
34 #include <fstream>
35 #include <iostream>
36 #include <sstream>
37
38 #include <libxml/tree.h>
39 #include <libxml/parser.h>
40 #include <libxml/xpath.h>
41 #include <libxml/xpathInternals.h>
42
43 using namespace MEDPARTITIONER;
44
45 MeshCollectionMedAsciiDriver::MeshCollectionMedAsciiDriver(MeshCollection* collection):MeshCollectionDriver(collection)
46 {
47 }
48
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
52  * 
53  *\param filename ascii file containing the list of MED v2.3 files
54  * */
55
56 int MeshCollectionMedAsciiDriver::read(MEDCoupling::MEDFileData* filedata)
57 {
58   readMEDFileData(filedata);
59
60   std::vector<MEDPARTITIONER::ConnectZone*> cz; // to fill from filedata
61   std::vector<int*> cellglobal;
62   std::vector<int*> nodeglobal;
63   std::vector<int*> faceglobal;
64   int size = (_collection->getMesh()).size();
65   cellglobal.resize(size);
66   nodeglobal.resize(size);
67   faceglobal.resize(size);
68   for ( int idomain = 0; idomain < size; ++idomain )
69     {
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);
75     }
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);
79
80   return 0;
81 }
82
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
86  *
87  *\param filename ascii file containing the list of MED v2.3 files
88  * */
89
90 int MeshCollectionMedAsciiDriver::read(const char* filename, ParaDomainSelector* domainSelector)
91 {
92   //distributed meshes
93   std::vector<int*> cellglobal;
94   std::vector<int*> nodeglobal;
95   std::vector<int*> faceglobal;
96   int nbdomain;
97
98   //reading ascii master file
99   try
100     {
101       std::ifstream asciiinput(filename);
102       if (!asciiinput)
103         throw INTERP_KERNEL::Exception("Master ASCII File does not exist");
104       char charbuffer[512];
105       asciiinput.getline(charbuffer,512);
106
107       while (charbuffer[0]=='#')
108         {
109           asciiinput.getline(charbuffer,512);
110         }
111
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);
120
121       if (nbdomain == 0)
122         throw INTERP_KERNEL::Exception("Empty ASCII master file");
123       for (int i=0; i<nbdomain;i++)
124         {
125           //reading information about the domain
126           std::string mesh,host;
127           int idomain;
128           cellglobal[i]=0;
129           faceglobal[i]=0;
130           nodeglobal[i]=0;
131
132           asciiinput >> mesh >> idomain >> MyGlobals::_Mesh_Names[i] >> host >> MyGlobals::_File_Names[i];
133
134           //Setting the name of the global mesh (which should be is the same for all the subdomains)
135           if (i==0)
136             _collection->setName(mesh);
137
138           if (idomain!=i+1)
139             {
140               throw INTERP_KERNEL::Exception("domain must be written from 1 to N in ASCII file descriptor");
141             }
142           if ( !domainSelector || domainSelector->isMyDomain(i))
143             readSubdomain(i);
144
145         } //loop on domains
146     } //of try
147   catch(...)
148     {
149       throw INTERP_KERNEL::Exception("I/O error reading parallel MED file");
150     }
151
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);
155
156   for (int i=0; i<nbdomain; i++)
157     {
158       delete [] cellglobal[i];
159       delete [] nodeglobal[i];
160       delete [] faceglobal[i];
161     }
162   return 0;
163 }
164
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
168  */
169 void MeshCollectionMedAsciiDriver::write(const char* filename, ParaDomainSelector* domainSelector) const
170 {
171   int nbdomains=_collection->getMesh().size();
172   std::vector<std::string> filenames;
173   filenames.resize(nbdomains);
174
175   //loop on the domains
176   for (int idomain=0; idomain<nbdomains; idomain++)
177     {
178       std::string distfilename;
179       std::ostringstream suffix;
180       suffix << filename << idomain+1 << ".med";
181       distfilename=suffix.str();
182       filenames[idomain]=distfilename;
183
184       if ( !domainSelector || domainSelector->isMyDomain( idomain ) )
185         {
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);
190         }
191     }
192
193   //write master file
194   if ( !domainSelector || domainSelector->rank() == 0 )
195     {
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;
200
201       for (int idomain=0; idomain<nbdomains; idomain++)
202         file << _collection->getName() <<" "<< idomain+1 << " "
203              << (_collection->getMesh())[idomain]->getName() << " localhost "
204              << filenames[idomain] << " "<< std::endl;
205     }
206
207 }