Back to index

salome-med  6.5.0
MEDSPLITTER_MESHCollectionMedXMLDriver.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D
00002 //
00003 // This library is free software; you can redistribute it and/or
00004 // modify it under the terms of the GNU Lesser General Public
00005 // License as published by the Free Software Foundation; either
00006 // version 2.1 of the License.
00007 //
00008 // This library is distributed in the hope that it will be useful,
00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011 // Lesser General Public License for more details.
00012 //
00013 // You should have received a copy of the GNU Lesser General Public
00014 // License along with this library; if not, write to the Free Software
00015 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00016 //
00017 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00018 //
00019 #include <vector>
00020 #include <string>
00021 #include <map>
00022 #include <set>
00023 
00024 #include <iostream>
00025 #include <fstream>
00026 
00027 #include <libxml/tree.h>
00028 #include <libxml/parser.h>
00029 #include <libxml/xpath.h>
00030 #include <libxml/xpathInternals.h>
00031 
00032 #ifndef WIN32
00033 #include <sys/time.h>
00034 #else
00035 #include <time.h>
00036 #include <windows.h>
00037 #endif
00038 //Debug macros
00039 #include "MEDMEM_Utilities.hxx"
00040 
00041 //MEDMEM includes
00042 #include "MEDMEM_DriversDef.hxx"
00043 #include "MEDMEM_Mesh.hxx"
00044 #include "MEDMEM_Field.hxx"
00045 #include "MEDMEM_Meshing.hxx"
00046 #include "MEDMEM_CellModel.hxx"
00047 #include "MEDMEM_SkyLineArray.hxx"
00048 #include "MEDMEM_ConnectZone.hxx"
00049 
00050 //MEDSPLITTER includes
00051 #include "MEDSPLITTER_Topology.hxx"
00052 #include "MEDSPLITTER_ParallelTopology.hxx"
00053 #include "MEDSPLITTER_SequentialTopology.hxx"
00054 #include "MEDSPLITTER_MESHCollectionDriver.hxx"
00055 #include "MEDSPLITTER_MESHCollection.hxx"
00056 #include "MEDSPLITTER_MESHCollectionMedXMLDriver.hxx"
00057 #include "MEDSPLITTER_ParaDomainSelector.hxx"
00058 
00059 using namespace MEDSPLITTER;
00060 
00061 //template inclusion
00062 #include "MEDSPLITTER_MESHCollectionMedXMLDriver.H"
00063 
00078 MESHCollectionMedXMLDriver::MESHCollectionMedXMLDriver(MESHCollection* collection):MESHCollectionDriver(collection)
00079 {
00080 }
00081 
00089 int MESHCollectionMedXMLDriver::read(char* filename, ParaDomainSelector* domainSelector)
00090 {
00091   const char* LOC = "MEDSPLITTER::MESHCollectionDriver::read()";
00092   BEGIN_OF_MED(LOC);
00093 
00094   //ditributed meshes
00095   vector<int*> cellglobal;
00096   vector<int*> nodeglobal;
00097   vector<int*> faceglobal;
00098 
00099   int nbdomain;
00100 
00101   _master_filename=filename;
00102 
00103   // reading ascii master file
00104   try
00105     {
00106       MESSAGE_MED("Start reading");
00107 
00108       // Setting up the XML tree corresponding to filename
00109       xmlDocPtr master_doc=xmlParseFile(filename);
00110 
00111       if (!master_doc)    
00112         throw MEDEXCEPTION("MEDSPLITTER XML read - Master File does not exist o r is not compliant with XML scheme");
00113 
00115       //number of domains
00117       xmlXPathContextPtr xpathCtx = xmlXPathNewContext(master_doc);
00118       xmlXPathObjectPtr xpathObj = xmlXPathEvalExpression(BAD_CAST "//splitting/subdomain", xpathCtx);
00119       if (xpathObj==0 || xpathObj->nodesetval->nodeNr ==0)
00120         {
00121           xmlXPathFreeObject(xpathObj);
00122           throw MEDEXCEPTION("MEDSPLITTER read - XML Master File does not contain /MED/splitting/subdomain node");
00123         }
00124       /* as subdomain has only one property which is "number"
00125        * it suffices to take the content of its first child */
00126       const char* mystring = (const char*)xpathObj->nodesetval->nodeTab[0]->properties->children->content;
00127       sscanf(mystring, "%d", &nbdomain);
00128 
00130       //mesh name
00132       xmlXPathFreeObject(xpathObj);
00133       xpathObj = xmlXPathEvalExpression(BAD_CAST "//content/mesh", xpathCtx);
00134       if (xpathObj==0 || xpathObj->nodesetval->nodeNr ==0)
00135         {
00136           xmlXPathFreeObject(xpathObj);
00137           throw MEDEXCEPTION("MEDSPLITTER read - XML Master File does not contain /MED/content/mesh node");
00138         }
00139       _collection->setName( (const char*)xpathObj->nodesetval->nodeTab[0]->properties->children->content);
00140 
00141       cout << "nb domain " << nbdomain << endl;
00142       _filename.resize(nbdomain);
00143       _meshname.resize(nbdomain);
00144       (_collection->getMesh()).resize(nbdomain);
00145       cellglobal.resize(nbdomain);
00146       nodeglobal.resize(nbdomain);
00147       faceglobal.resize(nbdomain);
00148 
00149 
00150       // retrieving the node which contains the file names
00151       const char filechar[]="//files/subfile";
00152       xmlXPathFreeObject(xpathObj);
00153       xpathObj = xmlXPathEvalExpression(BAD_CAST filechar, xpathCtx);
00154       if (xpathObj==0 || xpathObj->nodesetval->nodeNr ==0)
00155         {
00156           xmlXPathFreeObject(xpathObj);
00157           throw MEDEXCEPTION("MEDSPLITTER read - XML Master File does not contain /MED/files/subfile nodes");
00158         }
00159       int nbfiles = xpathObj->nodesetval ->nodeNr;
00160 
00161       for (int i=0; i<nbfiles;i++)
00162         {
00163           //reading information about the domain
00164 
00165           string host;
00166 
00167           cellglobal[i]=0;
00168           faceglobal[i]=0;
00169           nodeglobal[i]=0;
00170 
00172           //reading file names 
00174           ostringstream name_search_string;
00175           name_search_string<<"//files/subfile[@id=\""<<i+1<<"\"]/name";
00176           //cout <<name_search_string.str()<<endl;
00177           xmlXPathObjectPtr xpathObjfilename =
00178             xmlXPathEvalExpression(BAD_CAST name_search_string.str().c_str(),xpathCtx);
00179           if (xpathObjfilename->nodesetval ==0)
00180             throw MEDEXCEPTION("MED XML reader : Error retrieving file name ");
00181           _filename[i]=(const char*)xpathObjfilename->nodesetval->nodeTab[0]->children->content;
00182 
00184           //reading the local mesh names
00186           ostringstream mesh_search_string;
00187           mesh_search_string<<"//mapping/mesh/chunk[@subdomain=\""<<i+1<<"\"]/name";
00188 
00189           xmlXPathObjectPtr xpathMeshObj = xmlXPathEvalExpression(BAD_CAST mesh_search_string.str().c_str(),xpathCtx);
00190           if (xpathMeshObj->nodesetval ==0)
00191             throw MEDEXCEPTION("MED XML reader : Error retrieving mesh name ");
00192           _meshname[i]=(const char*)xpathMeshObj->nodesetval->nodeTab[0]->children->content;
00193 
00194           if ( !domainSelector || domainSelector->isMyDomain(i))
00195             readSubdomain(cellglobal, faceglobal, nodeglobal, i);
00196           xmlXPathFreeObject(xpathObjfilename);
00197 
00198           xmlXPathFreeObject(xpathMeshObj);
00199         }//loop on domains
00200 
00201       // LIBXML cleanup
00202       xmlXPathFreeObject(xpathObj);
00203       xmlXPathFreeContext(xpathCtx);
00204       xmlFreeDoc(master_doc);
00205 
00206       MESSAGE_MED("end of read");
00207     }//of try
00208   catch(...)
00209     {
00210       throw MEDEXCEPTION("I/O error reading parallel MED file");
00211     }
00212 
00213   //creation of topology from mesh and connect zones
00214   ParallelTopology* aPT = new ParallelTopology
00215     ((_collection->getMesh()), (_collection->getCZ()), cellglobal, nodeglobal, faceglobal);
00216   _collection->setTopology(aPT);
00217 
00218   for (int i=0; i<nbdomain; i++)
00219     {
00220       if (cellglobal[i]!=0) delete[] cellglobal[i];
00221       if (nodeglobal[i]!=0) delete[] nodeglobal[i];
00222       if (faceglobal[i]!=0) delete[] faceglobal[i];
00223     }
00224 
00225   END_OF_MED(LOC);
00226   return 0;
00227 }
00228 
00229 
00235 void MESHCollectionMedXMLDriver::write(char* filename, ParaDomainSelector* domainSelector)
00236 {
00237   const char* LOC = "MEDSPLITTER::MESHCollectionDriver::writeXML()";
00238   BEGIN_OF_MED(LOC);
00239 
00240   xmlDocPtr master_doc = 0;
00241   xmlNodePtr root_node = 0, node, node2;
00242   //  xmlDTDPtr dtd = 0;
00243 
00244   char buff[256];
00245 
00246   //Creating the XML document
00247 
00248   master_doc = xmlNewDoc(BAD_CAST "1.0");
00249   root_node = xmlNewNode(0, BAD_CAST "root");
00250   xmlDocSetRootElement(master_doc,root_node);
00251 
00252   //Creating child nodes
00253 
00254   // Version tag
00255   node = xmlNewChild(root_node, 0, BAD_CAST "version",0);
00256   xmlNewProp(node, BAD_CAST "maj", BAD_CAST "2");
00257   xmlNewProp(node, BAD_CAST "min", BAD_CAST "3");
00258   xmlNewProp(node, BAD_CAST "ver", BAD_CAST "1");
00259 
00260   //Description tag
00261   char date[1024];
00262 #ifndef WIN32
00263   time_t present;
00264   time( &present);
00265   struct tm *time_asc = localtime(&present);
00266   sprintf(date,"%02d%02d%02d",time_asc->tm_year
00267           ,time_asc->tm_mon+1
00268           ,time_asc->tm_mday);
00269 #else
00270   SYSTEMTIME    st;
00271   GetLocalTime ( &st );
00272   sprintf(date,"%02d%02d%02d",
00273           st.wYear
00274           ,st.wMonth
00275           ,st.wDay);
00276 #endif
00277 
00278   node = xmlNewChild(root_node,0, BAD_CAST "description",0);
00279 
00280   xmlNewProp(node, BAD_CAST "what", BAD_CAST _collection->getDescription().c_str());
00281   xmlNewProp(node, BAD_CAST "when", BAD_CAST date);
00282 
00283   //Content tag
00284   node =xmlNewChild(root_node,0, BAD_CAST "content",0);
00285   node2 = xmlNewChild(node, 0, BAD_CAST "mesh",0);
00286   xmlNewProp(node2, BAD_CAST "name", BAD_CAST _collection->getName().c_str());
00287 
00288   //Splitting tag
00289   node=xmlNewChild(root_node,0,BAD_CAST "splitting",0);
00290   node2=xmlNewChild(node,0,BAD_CAST "subdomain",0);
00291   sprintf(buff, "%d", (int)_collection->getMesh().size());
00292   xmlNewProp(node2, BAD_CAST "number", BAD_CAST buff);
00293   node2=xmlNewChild(node,0,BAD_CAST "global_numbering",0);
00294   xmlNewProp(node2, BAD_CAST "present", BAD_CAST "yes");
00295 
00296   //Files tag
00297   xmlNodePtr file_node=xmlNewChild(root_node,0,BAD_CAST "files",0);
00298 
00299   //Mapping tag
00300   node = xmlNewChild(root_node,0,BAD_CAST "mapping",0);
00301   xmlNodePtr mesh_node = xmlNewChild(node, 0, BAD_CAST "mesh",0);
00302   xmlNewProp(mesh_node, BAD_CAST "name", BAD_CAST _collection->getName().c_str());
00303 
00304   int nbdomains= _collection->getMesh().size();
00305   _filename.resize(nbdomains);
00306 
00307   //loop on the domains
00308   for (int idomain=nbdomains-1; idomain>=0;idomain--)
00309     {
00310       char distfilename[256];
00311 
00312       ostringstream suffix;
00313       suffix << filename<< idomain+1 <<".med";
00314 
00315       strcpy(distfilename,suffix.str().c_str());
00316 
00317       _filename[idomain]=string(distfilename);
00318 
00319       MESSAGE_MED("File name "<<string(distfilename));
00320 
00321       if ( !domainSelector || domainSelector->isMyDomain( idomain ) )
00322         {
00323           if ( !_collection->getMesh()[idomain]->getConnectivityptr() ) continue;//empty domain
00324 
00325           int id=(_collection->getMesh())[idomain]->addDriver(MEDMEM::MED_DRIVER,distfilename,(_collection->getMesh())[idomain]->getName(),MED_EN::WRONLY);
00326 
00327           MESSAGE_MED("Start writing");
00328           (_collection->getMesh())[idomain]->write(id);
00329           (_collection->getMesh())[idomain]->rmDriver(id);
00330 
00331           writeSubdomain(idomain, nbdomains, distfilename, domainSelector);
00332         }
00333       //updating the ascii description file
00334       node = xmlNewChild(file_node, 0, BAD_CAST "subfile",0);
00335       sprintf (buff,"%d",idomain+1);
00336       xmlNewProp(node, BAD_CAST "id", BAD_CAST buff);
00337       xmlNewChild(node,0,BAD_CAST "name",BAD_CAST distfilename);
00338       xmlNewChild(node,0,BAD_CAST "machine",BAD_CAST "localhost");
00339 
00340       node = xmlNewChild(mesh_node,0, BAD_CAST "chunk",0);
00341       xmlNewProp(node, BAD_CAST "subdomain", BAD_CAST buff);
00342       xmlNewChild(node,0,BAD_CAST "name", BAD_CAST (_collection->getMesh())[idomain]->getName().c_str());
00343     }
00344   strcat(filename,".xml");
00345   _master_filename=filename;
00346   if ( !domainSelector || domainSelector->rank() == 0 )
00347     xmlSaveFormatFileEnc(filename, master_doc, "UTF-8", 1);
00348   xmlFreeDoc(master_doc);
00349   //xmlCleanupParser();
00350 
00351   END_OF_MED(LOC);
00352 }