00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include <sstream>
00037 #include <map>
00038
00039 #include "XdmfMeshWriter.hpp"
00040 #include "DistributedTetrahedralMesh.hpp"
00041 #include "Version.hpp"
00042
00043 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00044 XdmfMeshWriter<ELEMENT_DIM, SPACE_DIM>::XdmfMeshWriter(const std::string& rDirectory,
00045 const std::string& rBaseName,
00046 const bool clearOutputDir)
00047 : AbstractTetrahedralMeshWriter<ELEMENT_DIM, SPACE_DIM>(rDirectory, rBaseName, clearOutputDir),
00048 mNumberOfTimePoints(1u),
00049 mTimeStep(1.0)
00050 {
00051 }
00052
00053 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00054 void XdmfMeshWriter<ELEMENT_DIM, SPACE_DIM>::WriteFilesUsingMesh(AbstractTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>& rMesh,
00055 bool keepOriginalElementIndexing)
00056 {
00057 #ifdef _MSC_VER
00058 EXCEPTION("XDMF is not supported under Windows at present.");
00059 #else
00060 assert(keepOriginalElementIndexing);
00061 this->mpDistributedMesh = dynamic_cast<DistributedTetrahedralMesh<ELEMENT_DIM,SPACE_DIM>* >(&rMesh);
00062 bool mesh_is_distributed = (this->mpDistributedMesh != NULL) && PetscTools::IsParallel();
00063
00064 if (PetscTools::AmMaster())
00065 {
00066
00067
00068 unsigned num_chunks = 1;
00069 if (mesh_is_distributed)
00070 {
00071 num_chunks = PetscTools::GetNumProcs();
00072 }
00073 WriteXdmfMasterFile(num_chunks);
00074 }
00075 if (!mesh_is_distributed && !PetscTools::AmMaster())
00076 {
00077
00078 PetscTools::Barrier("XdmfMeshWriter wait for chunks to be written");
00079 return;
00080 }
00081
00082
00083 std::stringstream local_geometry_file_name;
00084 local_geometry_file_name << this->mBaseName << "_geometry_"<< PetscTools::GetMyRank() <<".xml";
00085 out_stream geometry_file = this->mpOutputFileHandler->OpenOutputFile(local_geometry_file_name.str());
00086 std::string geom_type = "XYZ";
00087 if (SPACE_DIM == 2)
00088 {
00089 geom_type = "XY";
00090 }
00091 (*geometry_file) << "<Geometry GeometryType=\""<< geom_type <<"\">\n";
00092 unsigned num_nodes = rMesh.GetNumNodes();
00093 if (this->mpDistributedMesh)
00094 {
00095 num_nodes = this->mpDistributedMesh->GetNumLocalNodes() + this->mpDistributedMesh->GetNumHaloNodes();
00096 }
00097
00098 (*geometry_file) << "\t<DataItem Format=\"XML\" Dimensions=\""<< num_nodes <<" "<< SPACE_DIM <<"\" DataType=\"Float\">";
00099
00100
00101 std::map<unsigned, unsigned> global_to_node_index_map;
00102
00103
00104 unsigned index = 0;
00105
00106
00107 for (typename AbstractMesh<ELEMENT_DIM,SPACE_DIM>::NodeIterator iter = rMesh.GetNodeIteratorBegin();
00108 iter != rMesh.GetNodeIteratorEnd();
00109 ++iter)
00110 {
00111 global_to_node_index_map[iter->GetIndex()] = index;
00112 index++;
00113 (*geometry_file) << "\n\t\t";
00114 c_vector<double, SPACE_DIM> current_item = (iter)->rGetLocation();
00115 for (unsigned j=0; j<SPACE_DIM; j++)
00116 {
00117 (*geometry_file) << current_item[j] << "\t";
00118 }
00119 }
00120
00121
00122 if (this->mpDistributedMesh)
00123 {
00124 for (typename DistributedTetrahedralMesh<ELEMENT_DIM, SPACE_DIM>::HaloNodeIterator halo_iter=this->mpDistributedMesh->GetHaloNodeIteratorBegin();
00125 halo_iter != this->mpDistributedMesh->GetHaloNodeIteratorEnd();
00126 ++halo_iter)
00127 {
00128 global_to_node_index_map[(*halo_iter)->GetIndex()] = index;
00129 index++;
00130 (*geometry_file) << "\n\t\t";
00131 c_vector<double, SPACE_DIM> current_item = (*halo_iter)->rGetLocation();
00132 for (unsigned j=0; j<SPACE_DIM; j++)
00133 {
00134 (*geometry_file) << current_item[j] << "\t";
00135 }
00136 }
00137 }
00138 (*geometry_file) << "\n";
00139
00140 (*geometry_file) << "\t</DataItem>\n";
00141 (*geometry_file) << "</Geometry>\n";
00142 (*geometry_file) << "<!-- " + ChasteBuildInfo::GetProvenanceString() + "-->\n";
00143 geometry_file->close();
00144
00145
00146 std::stringstream local_topology_file_name;
00147 local_topology_file_name << this->mBaseName << "_topology_"<< PetscTools::GetMyRank() <<".xml";
00148 out_stream topology_file = this->mpOutputFileHandler->OpenOutputFile(local_topology_file_name.str());
00149 std::string top_type = "Tetrahedron";
00150 if (SPACE_DIM == 2)
00151 {
00152 top_type = "Triangle";
00153 }
00154 unsigned num_elems = rMesh.GetNumElements();
00155 if (this->mpDistributedMesh)
00156 {
00157 num_elems = this->mpDistributedMesh->GetNumLocalElements();
00158 }
00159 (*topology_file) << "<Topology TopologyType=\""<< top_type <<"\" NumberOfElements=\""<< num_elems <<"\">\n";
00160 (*topology_file) << "\t<DataItem Format=\"XML\" Dimensions=\""<< num_elems <<" "<< ELEMENT_DIM+1 <<"\">";
00161 for (typename AbstractTetrahedralMesh<ELEMENT_DIM,SPACE_DIM>::ElementIterator elem_iter = rMesh.GetElementIteratorBegin();
00162 elem_iter != rMesh.GetElementIteratorEnd();
00163 ++elem_iter)
00164 {
00165 (*topology_file) << "\n\t\t";
00166 for (unsigned j=0; j<ELEMENT_DIM+1; j++)
00167 {
00168 unsigned local_index = global_to_node_index_map[ elem_iter->GetNodeGlobalIndex(j) ];
00169 (*topology_file) << local_index <<"\t";
00170 }
00171 }
00172 (*topology_file) << "\n";
00173
00174 (*topology_file) << "\t</DataItem>\n";
00175 (*topology_file) << "</Topology>\n";
00176 (*topology_file) << "<!-- " + ChasteBuildInfo::GetProvenanceString() + "-->\n";
00177 topology_file->close();
00178 PetscTools::Barrier("XdmfMeshWriter wait for chunks to be written");
00179 #endif
00180 }
00181
00182 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00183 void XdmfMeshWriter<ELEMENT_DIM, SPACE_DIM>::WriteFiles()
00184 {
00185 #ifdef _MSC_VER
00186 EXCEPTION("XDMF is not supported under Windows at present.");
00187 #else
00188
00189 if (PetscTools::AmMaster())
00190 {
00191 WriteXdmfMasterFile();
00192
00193
00194 out_stream geometry_file = this->mpOutputFileHandler->OpenOutputFile(this->mBaseName + "_geometry_0.xml");
00195 std::string geom_type = "XYZ";
00196 if (SPACE_DIM == 2)
00197 {
00198 geom_type = "XY";
00199 }
00200 (*geometry_file) << "<Geometry GeometryType=\""<< geom_type <<"\">\n";
00201 (*geometry_file) << "\t<DataItem Format=\"XML\" Dimensions=\""<< this->GetNumNodes() <<" "<< SPACE_DIM <<"\" DataType=\"Float\">";
00202 for (unsigned item_num=0; item_num<this->GetNumNodes(); item_num++)
00203 {
00204 (*geometry_file) << "\n\t\t";
00205 std::vector<double> current_item = this->GetNextNode();
00206 for (unsigned j=0; j<SPACE_DIM; j++)
00207 {
00208 (*geometry_file) << current_item[j]<<"\t";
00209 }
00210 }
00211 (*geometry_file) << "\n";
00212
00213 (*geometry_file) << "\t</DataItem>\n";
00214 (*geometry_file) << "</Geometry>\n";
00215 (*geometry_file) << "<!-- " + ChasteBuildInfo::GetProvenanceString() + "-->\n";
00216 geometry_file->close();
00217
00218
00219 out_stream topology_file = this->mpOutputFileHandler->OpenOutputFile(this->mBaseName + "_topology_0.xml");
00220 std::string top_type = "Tetrahedron";
00221 if (SPACE_DIM == 2)
00222 {
00223 top_type = "Triangle";
00224 }
00225 (*topology_file) << "<Topology TopologyType=\""<< top_type <<"\" NumberOfElements=\""<< this->GetNumElements() <<"\">\n";
00226 (*topology_file) << "\t<DataItem Format=\"XML\" Dimensions=\""<< this->GetNumElements() <<" "<< ELEMENT_DIM+1 <<"\">";
00227 for (unsigned item_num=0; item_num<this->GetNumElements(); item_num++)
00228 {
00229 (*topology_file) << "\n\t\t";
00230 std::vector<unsigned> current_item = this->GetNextElement().NodeIndices;
00231 for (unsigned j=0; j<ELEMENT_DIM+1; j++)
00232 {
00233 (*topology_file) << current_item[j]<<"\t";
00234 }
00235 }
00236 (*topology_file) << "\n";
00237
00238 (*topology_file) << "\t</DataItem>\n";
00239 (*topology_file) << "</Topology>\n";
00240 (*topology_file) << "<!-- " + ChasteBuildInfo::GetProvenanceString() + "-->\n";
00241 topology_file->close();
00242 }
00243 #endif
00244 }
00245
00246 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00247 void XdmfMeshWriter<ELEMENT_DIM, SPACE_DIM>::WriteXdmfMasterFile(unsigned numberOfChunks)
00248 {
00249 #ifndef _MSC_VER
00250 assert(PetscTools::AmMaster());
00251
00252 XERCES_CPP_NAMESPACE_USE
00253
00254
00255 XMLPlatformUtils::Initialize();
00256
00257 DOMImplementation* p_DOM_implementation = DOMImplementationRegistry::getDOMImplementation(X("core"));
00258
00259 DOMDocumentType* p_DOM_document_type = p_DOM_implementation->createDocumentType(X("Xdmf"),0,X("Xdmf.dtd"));
00260 DOMDocument* p_DOM_document = p_DOM_implementation->createDocument(0, X("Xdmf"), p_DOM_document_type);
00261 DOMElement* p_root_element = p_DOM_document->getDocumentElement();
00262 p_root_element->setAttribute(X("Version"), X("2.0"));
00263 p_root_element->setAttribute(X("xmlns:xi"), X("http://www.w3.org/2001/XInclude"));
00264
00265 DOMElement* p_domain_element = p_DOM_document->createElement(X("Domain"));
00266 p_root_element->appendChild(p_domain_element);
00267
00268
00269 DOMElement* p_grid_temp_collection_element = p_DOM_document->createElement(X("Grid"));
00270 p_grid_temp_collection_element->setAttribute(X("CollectionType"), X("Temporal"));
00271 p_grid_temp_collection_element->setAttribute(X("GridType"), X("Collection"));
00272 p_domain_element->appendChild(p_grid_temp_collection_element);
00273
00274
00275 DOMElement* p_time_element = p_DOM_document->createElement(X("Time"));
00276 p_time_element->setAttribute(X("TimeType"), X("HyperSlab"));
00277 p_grid_temp_collection_element->appendChild(p_time_element);
00278
00279 DOMElement* p_time_dataitem_element = p_DOM_document->createElement(X("DataItem"));
00280 p_time_dataitem_element->setAttribute(X("Format"),X("XML"));
00281 p_time_dataitem_element->setAttribute(X("NumberType"),X("Float"));
00282 p_time_dataitem_element->setAttribute(X("Dimensions"),X("3"));
00283 p_time_element->appendChild(p_time_dataitem_element);
00284
00285 std::stringstream time_stream;
00286 time_stream << "0.0 " << mTimeStep << " " << mNumberOfTimePoints;
00287 DOMText* p_time_text = p_DOM_document->createTextNode(X(time_stream.str()));
00288 p_time_dataitem_element->appendChild(p_time_text);
00289
00290 for(unsigned t=0; t<mNumberOfTimePoints; ++t)
00291 {
00292 DOMElement* p_grid_collection_element = p_DOM_document->createElement(X("Grid"));
00293 p_grid_collection_element->setAttribute(X("CollectionType"), X("Spatial"));
00294 p_grid_collection_element->setAttribute(X("GridType"), X("Collection"));
00295
00296 p_grid_temp_collection_element->appendChild(p_grid_collection_element);
00297
00298 if (t==0)
00299 {
00300 for (unsigned chunk=0; chunk<numberOfChunks; chunk++)
00301 {
00302 std::stringstream chunk_stream;
00303 chunk_stream << chunk;
00304
00305 DOMElement* p_grid_element = p_DOM_document->createElement(X("Grid"));
00306 p_grid_element->setAttribute(X("GridType"), X("Uniform"));
00307 p_grid_element->setAttribute(X("Name"), X("Chunk_" + chunk_stream.str()));
00308 p_grid_collection_element->appendChild(p_grid_element);
00309
00310
00311
00312 DOMElement* p_geom_element = p_DOM_document->createElement(X("xi:include"));
00313 p_geom_element->setAttribute(X("href"), X(this->mBaseName+"_geometry_"+chunk_stream.str()+".xml"));
00314 p_grid_element->appendChild(p_geom_element);
00315
00316
00317 DOMElement* p_topo_element = p_DOM_document->createElement(X("xi:include"));
00318 p_topo_element->setAttribute(X("href"), X(this->mBaseName+"_topology_"+chunk_stream.str()+".xml"));
00319 p_grid_element->appendChild(p_topo_element);
00320
00321
00322
00323
00324
00325 AddDataOnNodes(p_grid_element, p_DOM_document, t);
00326 }
00327 }
00328 else
00329 {
00330 for (unsigned chunk=0; chunk<numberOfChunks; chunk++)
00331 {
00332 std::stringstream chunk_stream;
00333 chunk_stream << chunk;
00334
00335 DOMElement* p_grid_element = p_DOM_document->createElement(X("Grid"));
00336 p_grid_element->setAttribute(X("GridType"), X("Subset"));
00337 p_grid_element->setAttribute(X("Section"), X("All"));
00338 p_grid_collection_element->appendChild(p_grid_element);
00339
00340
00341
00342
00343
00344 AddDataOnNodes(p_grid_element, p_DOM_document, t);
00345 DOMElement* p_grid_ref_element = p_DOM_document->createElement(X("Grid"));
00346 p_grid_ref_element->setAttribute(X("GridType"), X("Uniform"));
00347 p_grid_ref_element->setAttribute(X("Reference"), X("XML"));
00348
00349
00350 DOMText* p_ref_text = p_DOM_document->createTextNode(X("/Xdmf/Domain/Grid/Grid/Grid[@Name=\"Chunk_"+chunk_stream.str()+"\"]"));
00351 p_grid_ref_element->appendChild(p_ref_text);
00352 p_grid_element->appendChild(p_grid_ref_element);
00353 }
00354 }
00355 }
00356
00357 DOMComment* p_provenance_comment = p_DOM_document->createComment(X(" "+ChasteBuildInfo::GetProvenanceString()));
00358 p_DOM_document->appendChild(p_provenance_comment);
00359
00360 XMLFormatTarget* p_target = new LocalFileFormatTarget(X(this->mpOutputFileHandler->GetOutputDirectoryFullPath() + this->mBaseName+".xdmf"));
00361
00362 #if _XERCES_VERSION >= 30000
00363 DOMLSSerializer *p_serializer = ((DOMImplementationLS*)p_DOM_implementation)->createLSSerializer();
00364 p_serializer->getDomConfig()->setParameter(XMLUni::fgDOMWRTFormatPrettyPrint, true);
00365 DOMLSOutput *p_output = ((DOMImplementationLS*)p_DOM_implementation)->createLSOutput();
00366 p_output->setByteStream(p_target);
00367 p_serializer->write(p_DOM_document, p_output);
00368 #else
00369 DOMWriter* p_serializer = ((DOMImplementationLS*)p_DOM_implementation)->createDOMWriter();
00370 p_serializer->setFeature(XMLUni::fgDOMWRTFormatPrettyPrint, true);
00371 p_serializer->writeNode(p_target, *p_DOM_document);
00372 #endif
00373
00374
00375 p_serializer->release();
00376 p_DOM_document->release();
00377 delete p_target;
00378 XMLPlatformUtils::Terminate();
00379 #endif // _MSC_VER
00380 }
00381
00383
00385
00386 template class XdmfMeshWriter<1,1>;
00387 template class XdmfMeshWriter<1,2>;
00388 template class XdmfMeshWriter<1,3>;
00389 template class XdmfMeshWriter<2,2>;
00390 template class XdmfMeshWriter<2,3>;
00391 template class XdmfMeshWriter<3,3>;