Salome HOME
Synchronize adm files
[modules/med.git] / src / MEDPartitioner / MEDPARTITIONER_MeshCollectionMedAsciiDriver.cxx
1 // Copyright (C) 2007-2014  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
37 #include <libxml/tree.h>
38 #include <libxml/parser.h>
39 #include <libxml/xpath.h>
40 #include <libxml/xpathInternals.h>
41
42 using namespace MEDPARTITIONER;
43
44 MeshCollectionMedAsciiDriver::MeshCollectionMedAsciiDriver(MeshCollection* collection):MeshCollectionDriver(collection)
45 {
46 }
47
48 /*!reads a MED File v>=2.3
49  * and mounts the corresponding meshes in memory
50  * the connect zones are created from the joints
51  * 
52  *\param filename ascii file containing the list of MED v2.3 files
53  * */
54
55 int MeshCollectionMedAsciiDriver::read(const char* filename, ParaDomainSelector* domainSelector)
56 {
57   //distributed meshes
58   std::vector<int*> cellglobal;
59   std::vector<int*> nodeglobal;
60   std::vector<int*> faceglobal;
61   int nbdomain;
62
63   //reading ascii master file
64   try
65     {
66       std::ifstream asciiinput(filename);
67       if (!asciiinput)
68         throw INTERP_KERNEL::Exception("Master ASCII File does not exist");
69       char charbuffer[512];
70       asciiinput.getline(charbuffer,512);
71
72       while (charbuffer[0]=='#')
73         {
74           asciiinput.getline(charbuffer,512);
75         }
76
77       //reading number of domains
78       nbdomain=atoi(charbuffer);
79       MyGlobals::_File_Names.resize(nbdomain);
80       MyGlobals::_Mesh_Names.resize(nbdomain);
81       (_collection->getMesh()).resize(nbdomain);
82       cellglobal.resize(nbdomain);
83       nodeglobal.resize(nbdomain);
84       faceglobal.resize(nbdomain);
85
86       if (nbdomain == 0)
87         throw INTERP_KERNEL::Exception("Empty ASCII master file");
88       for (int i=0; i<nbdomain;i++)
89         {
90           //reading information about the domain
91           std::string mesh,host;
92           int idomain;
93           cellglobal[i]=0;
94           faceglobal[i]=0;
95           nodeglobal[i]=0;
96
97           asciiinput >> mesh >> idomain >> MyGlobals::_Mesh_Names[i] >> host >> MyGlobals::_File_Names[i];
98
99           //Setting the name of the global mesh (which should be is the same for all the subdomains)
100           if (i==0)
101             _collection->setName(mesh);
102
103           if (idomain!=i+1)
104             {
105               throw INTERP_KERNEL::Exception("domain must be written from 1 to N in ASCII file descriptor");
106             }
107           if ( !domainSelector || domainSelector->isMyDomain(i))
108             readSubdomain(cellglobal,faceglobal,nodeglobal, i);
109
110         } //loop on domains
111     } //of try
112   catch(...)
113     {
114       throw INTERP_KERNEL::Exception("I/O error reading parallel MED file");
115     }
116
117   //creation of topology from mesh and connect zones
118   ParallelTopology* aPT = new ParallelTopology((_collection->getMesh()), (_collection->getCZ()), cellglobal, nodeglobal, faceglobal);
119   _collection->setTopology(aPT);
120
121   for (int i=0; i<nbdomain; i++)
122     {
123       delete [] cellglobal[i];
124       delete [] nodeglobal[i];
125       delete [] faceglobal[i];
126     }
127   return 0;
128 }
129
130
131 /*! writes the collection of meshes in a MED v2.3 file
132  * with the connect zones being written as joints
133  * \param filename name of the ascii file containing the meshes description
134  */
135 void MeshCollectionMedAsciiDriver::write(const char* filename, ParaDomainSelector* domainSelector) const
136 {
137   int nbdomains=_collection->getMesh().size();
138   std::vector<std::string> filenames;
139   filenames.resize(nbdomains);
140
141   //loop on the domains
142   for (int idomain=0; idomain<nbdomains; idomain++)
143     {
144       std::string distfilename;
145       std::ostringstream suffix;
146       suffix << filename << idomain+1 << ".med";
147       distfilename=suffix.str();
148       filenames[idomain]=distfilename;
149
150       if ( !domainSelector || domainSelector->isMyDomain( idomain ) )
151         {
152           if ( !_collection->getMesh()[idomain]->getNumberOfCells()==0 ) continue;//empty domain
153           MEDLoader::WriteUMesh(distfilename.c_str(),(_collection->getMesh())[idomain],true);
154           //writeSubdomain(idomain, nbdomains, distfilename.c_str(), domainSelector);
155         }
156     }
157
158   //write master file
159   if ( !domainSelector || domainSelector->rank() == 0 )
160     {
161       std::ofstream file(filename);
162       file << "#MED Fichier V 2.3"<<" " << std::endl;
163       file << "#" << " " << std::endl;
164       file << _collection->getMesh().size() << " " << std::endl;
165
166       for (int idomain=0; idomain<nbdomains; idomain++)
167         file << _collection->getName() <<" "<< idomain+1 << " "
168              << (_collection->getMesh())[idomain]->getName() << " localhost "
169              << filenames[idomain] << " "<< std::endl;
170     }
171
172 }