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 #include "VertexMeshWriter.hpp"
00030 #include "Version.hpp"
00031
00035 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00036 struct MeshWriterIterators
00037 {
00039 typename AbstractMesh<ELEMENT_DIM,SPACE_DIM>::NodeIterator* pNodeIter;
00041 typename VertexMesh<ELEMENT_DIM,SPACE_DIM>::VertexElementIterator* pElemIter;
00042 };
00043
00045
00047
00048 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00049 VertexMeshWriter<ELEMENT_DIM, SPACE_DIM>::VertexMeshWriter(const std::string& rDirectory,
00050 const std::string& rBaseName,
00051 const bool clearOutputDir)
00052 : AbstractMeshWriter<ELEMENT_DIM, SPACE_DIM>(rDirectory, rBaseName, clearOutputDir),
00053 mpMesh(NULL),
00054 mpIters(new MeshWriterIterators<ELEMENT_DIM, SPACE_DIM>),
00055 mpNodeMap(NULL),
00056 mNodeMapCurrentIndex(0)
00057 {
00058 mpIters->pNodeIter = NULL;
00059 mpIters->pElemIter = NULL;
00060
00061 #ifdef CHASTE_VTK
00062
00063 mpVtkUnstructedMesh = vtkUnstructuredGrid::New();
00064 #endif //CHASTE_VTK
00065 }
00066
00067 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00068 VertexMeshWriter<ELEMENT_DIM, SPACE_DIM>::~VertexMeshWriter()
00069 {
00070 if (mpIters->pNodeIter)
00071 {
00072 delete mpIters->pNodeIter;
00073 delete mpIters->pElemIter;
00074 }
00075
00076 delete mpIters;
00077
00078 if (mpNodeMap)
00079 {
00080 delete mpNodeMap;
00081 }
00082
00083 #ifdef CHASTE_VTK
00084
00085 mpVtkUnstructedMesh->Delete();
00086 #endif //CHASTE_VTK
00087 }
00088
00089 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00090 std::vector<double> VertexMeshWriter<ELEMENT_DIM, SPACE_DIM>::GetNextNode()
00091 {
00092 if (mpMesh)
00093 {
00094
00095 assert(this->mNumNodes == mpMesh->GetNumNodes());
00096
00097 std::vector<double> coordinates(SPACE_DIM+1);
00098
00099
00100 for (unsigned j=0; j<SPACE_DIM; j++)
00101 {
00102 coordinates[j] = (*(mpIters->pNodeIter))->GetPoint()[j];
00103 }
00104 coordinates[SPACE_DIM] = (*(mpIters->pNodeIter))->IsBoundaryNode();
00105
00106 ++(*(mpIters->pNodeIter));
00107
00108 return coordinates;
00109 }
00110 else
00111 {
00112 return AbstractMeshWriter<ELEMENT_DIM,SPACE_DIM>::GetNextNode();
00113 }
00114 }
00115
00116 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00117 VertexElementData VertexMeshWriter<ELEMENT_DIM, SPACE_DIM>::GetNextElementWithFaces()
00118 {
00119
00120 assert(SPACE_DIM == 3);
00121 assert(mpMesh);
00122 assert(this->mNumElements == mpMesh->GetNumElements());
00123
00124
00125 VertexElementData elem_data;
00126
00127
00128 elem_data.NodeIndices.resize((*(mpIters->pElemIter))->GetNumNodes());
00129 for (unsigned j=0; j<elem_data.NodeIndices.size(); j++)
00130 {
00131 unsigned old_index = (*(mpIters->pElemIter))->GetNodeGlobalIndex(j);
00132 elem_data.NodeIndices[j] = mpMesh->IsMeshChanging() ? mpNodeMap->GetNewIndex(old_index) : old_index;
00133 }
00134
00135
00136 elem_data.Faces.resize((*(mpIters->pElemIter))->GetNumFaces());
00137 for (unsigned i=0; i<elem_data.Faces.size(); i++)
00138 {
00139
00140 VertexElement<ELEMENT_DIM-1, SPACE_DIM>* p_face = (*(mpIters->pElemIter))->GetFace(i);
00141
00142
00143 ElementData face_data;
00144
00145
00146 face_data.AttributeValue = p_face->GetIndex();
00147
00148
00149 face_data.NodeIndices.resize(p_face->GetNumNodes());
00150 for (unsigned j=0; j<face_data.NodeIndices.size(); j++)
00151 {
00152 unsigned old_index = p_face->GetNodeGlobalIndex(j);
00153 face_data.NodeIndices[j] = mpMesh->IsMeshChanging() ? mpNodeMap->GetNewIndex(old_index) : old_index;
00154 }
00155
00156
00157 elem_data.Faces[i] = face_data;
00158
00160 }
00161
00162
00163 elem_data.AttributeValue = (*(mpIters->pElemIter))->GetRegion();
00164 ++(*(mpIters->pElemIter));
00165
00166 return elem_data;
00167 }
00168
00169 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00170 ElementData VertexMeshWriter<ELEMENT_DIM, SPACE_DIM>::GetNextElement()
00171 {
00173
00174 if (mpMesh)
00175 {
00176 assert(this->mNumElements == mpMesh->GetNumElements());
00177
00178 ElementData elem_data;
00179 elem_data.NodeIndices.resize((*(mpIters->pElemIter))->GetNumNodes());
00180 for (unsigned j=0; j<elem_data.NodeIndices.size(); j++)
00181 {
00182 unsigned old_index = (*(mpIters->pElemIter))->GetNodeGlobalIndex(j);
00183 elem_data.NodeIndices[j] = mpMesh->IsMeshChanging() ? mpNodeMap->GetNewIndex(old_index) : old_index;
00184 }
00185
00186
00187 elem_data.AttributeValue = (*(mpIters->pElemIter))->GetRegion();
00188 ++(*(mpIters->pElemIter));
00189
00190 return elem_data;
00191 }
00192 else
00193 {
00194 return AbstractMeshWriter<ELEMENT_DIM, SPACE_DIM>::GetNextElement();
00195 }
00196 }
00197
00198 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00199 void VertexMeshWriter<ELEMENT_DIM, SPACE_DIM>::WriteVtkUsingMesh(VertexMesh<ELEMENT_DIM, SPACE_DIM>& rMesh, std::string stamp)
00200 {
00201 #ifdef CHASTE_VTK
00202
00203 assert(SPACE_DIM==3 || SPACE_DIM == 2);
00204 vtkPoints* p_pts = vtkPoints::New(VTK_DOUBLE);
00205 p_pts->GetData()->SetName("Vertex positions");
00206 for (unsigned node_num=0; node_num<rMesh.GetNumNodes(); node_num++)
00207 {
00208 c_vector<double, SPACE_DIM> position = rMesh.GetNode(node_num)->rGetLocation();
00209 if (SPACE_DIM==2)
00210 {
00211 p_pts->InsertPoint(node_num, position[0], position[1], 0.0);
00212 }
00213 else
00214 {
00215 p_pts->InsertPoint(node_num, position[0], position[1], position[2]);
00216 }
00217 }
00218
00219 mpVtkUnstructedMesh->SetPoints(p_pts);
00220 p_pts->Delete();
00221 for (typename VertexMesh<ELEMENT_DIM,SPACE_DIM>::VertexElementIterator iter = rMesh.GetElementIteratorBegin();
00222 iter != rMesh.GetElementIteratorEnd();
00223 ++iter)
00224 {
00225 vtkCell* p_cell;
00226 if (SPACE_DIM == 2)
00227 {
00228 p_cell = vtkPolygon::New();
00229 }
00230 else
00231 {
00232 p_cell = vtkConvexPointSet::New();
00233 }
00234 vtkIdList* p_cell_id_list = p_cell->GetPointIds();
00235 p_cell_id_list->SetNumberOfIds(iter->GetNumNodes());
00236 for (unsigned j = 0; j < iter->GetNumNodes(); ++j)
00237 {
00238 p_cell_id_list->SetId(j, iter->GetNodeGlobalIndex(j));
00239 }
00240 mpVtkUnstructedMesh->InsertNextCell(p_cell->GetCellType(), p_cell_id_list);
00241 p_cell->Delete();
00242 }
00243
00244
00245 assert(mpVtkUnstructedMesh->CheckAttributes() == 0);
00246 vtkXMLUnstructuredGridWriter* p_writer = vtkXMLUnstructuredGridWriter::New();
00247 p_writer->SetInput(mpVtkUnstructedMesh);
00248
00249
00250 p_writer->SetCompressor(NULL);
00251
00252
00253 std::string vtk_file_name = this->mpOutputFileHandler->GetOutputDirectoryFullPath() + this->mBaseName;
00254 if (stamp != "")
00255 {
00256 vtk_file_name += "_" + stamp;
00257 }
00258 vtk_file_name += ".vtu";
00259
00260 p_writer->SetFileName(vtk_file_name.c_str());
00261
00262 p_writer->Write();
00263 p_writer->Delete();
00264 #endif //CHASTE_VTK
00265 }
00266
00267 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00268 void VertexMeshWriter<ELEMENT_DIM, SPACE_DIM>::AddCellData(std::string dataName, std::vector<double> dataPayload)
00269 {
00270 #ifdef CHASTE_VTK
00271 vtkDoubleArray* p_scalars = vtkDoubleArray::New();
00272 p_scalars->SetName(dataName.c_str());
00273 for (unsigned i=0; i<dataPayload.size(); i++)
00274 {
00275 p_scalars->InsertNextValue(dataPayload[i]);
00276 }
00277
00278 vtkCellData* p_cell_data = mpVtkUnstructedMesh->GetCellData();
00279 p_cell_data->AddArray(p_scalars);
00280 p_scalars->Delete();
00281 #endif //CHASTE_VTK
00282 }
00283
00284 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00285 void VertexMeshWriter<ELEMENT_DIM, SPACE_DIM>::AddPointData(std::string dataName, std::vector<double> dataPayload)
00286 {
00287 #ifdef CHASTE_VTK
00288 vtkDoubleArray* p_scalars = vtkDoubleArray::New();
00289 p_scalars->SetName(dataName.c_str());
00290 for (unsigned i=0; i<dataPayload.size(); i++)
00291 {
00292 p_scalars->InsertNextValue(dataPayload[i]);
00293 }
00294
00295 vtkPointData* p_point_data = mpVtkUnstructedMesh->GetPointData();
00296 p_point_data->AddArray(p_scalars);
00297 p_scalars->Delete();
00298 #endif //CHASTE_VTK
00299 }
00300
00302 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00303 void VertexMeshWriter<ELEMENT_DIM, SPACE_DIM>::WriteFilesUsingMesh(VertexMesh<ELEMENT_DIM,SPACE_DIM>& rMesh)
00304 {
00305
00306 this->mpMeshReader = NULL;
00307 mpMesh = &rMesh;
00308
00309 this->mNumNodes = mpMesh->GetNumNodes();
00310 this->mNumElements = mpMesh->GetNumElements();
00311
00312 typedef typename AbstractMesh<ELEMENT_DIM,SPACE_DIM>::NodeIterator NodeIterType;
00313 mpIters->pNodeIter = new NodeIterType(mpMesh->GetNodeIteratorBegin());
00314
00315 typedef typename VertexMesh<ELEMENT_DIM,SPACE_DIM>::VertexElementIterator ElemIterType;
00316 mpIters->pElemIter = new ElemIterType(mpMesh->GetElementIteratorBegin());
00317
00318
00319 mNodeMapCurrentIndex = 0;
00320 if (mpMesh->IsMeshChanging())
00321 {
00322 mpNodeMap = new NodeMap(mpMesh->GetNumAllNodes());
00323 for (NodeIterType it = mpMesh->GetNodeIteratorBegin(); it != mpMesh->GetNodeIteratorEnd(); ++it)
00324 {
00325 mpNodeMap->SetNewIndex(it->GetIndex(), mNodeMapCurrentIndex++);
00326 }
00327 }
00328 WriteFiles();
00329 }
00330
00331 template<unsigned ELEMENT_DIM, unsigned SPACE_DIM>
00332 void VertexMeshWriter<ELEMENT_DIM, SPACE_DIM>::WriteFiles()
00333 {
00334 std::string comment = "# " + ChasteBuildInfo::GetProvenanceString();
00335
00336
00337 std::string node_file_name = this->mBaseName + ".node";
00338 out_stream p_node_file = this->mpOutputFileHandler->OpenOutputFile(node_file_name);
00339
00340
00341 unsigned num_attr = 0;
00342 unsigned max_bdy_marker = 1;
00343 unsigned num_nodes = this->GetNumNodes();
00344
00345 *p_node_file << num_nodes << "\t";
00346 *p_node_file << SPACE_DIM << "\t";
00347 *p_node_file << num_attr << "\t";
00348 *p_node_file << max_bdy_marker << "\n";
00349 *p_node_file << std::setprecision(6);
00350
00351
00352 for (unsigned item_num=0; item_num<num_nodes; item_num++)
00353 {
00354 std::vector<double> current_item = this->GetNextNode();
00355 *p_node_file << item_num;
00356 for (unsigned i=0; i<SPACE_DIM+1; i++)
00357 {
00358 *p_node_file << "\t" << current_item[i];
00359 }
00360 *p_node_file << "\n";
00361 }
00362 *p_node_file << comment << "\n";
00363 p_node_file->close();
00364
00365
00366 std::string element_file_name = this->mBaseName + ".cell";
00367 out_stream p_element_file = this->mpOutputFileHandler->OpenOutputFile(element_file_name);
00368
00369
00370 unsigned num_elements = this->GetNumElements();
00371
00372 unsigned first_elem_attribute_value = (*(mpIters->pElemIter))->GetRegion();
00373 if (first_elem_attribute_value != 0)
00374 {
00375 num_attr = 1;
00376 }
00377
00378 *p_element_file << num_elements << "\t";
00379 *p_element_file << num_attr << "\n";
00380
00381
00382 for (unsigned item_num=0; item_num<num_elements; item_num++)
00383 {
00384 if (SPACE_DIM == 2)
00385 {
00386
00387 ElementData elem_data = this->GetNextElement();
00388
00389
00390 std::vector<unsigned> node_indices = elem_data.NodeIndices;
00391
00392
00393 *p_element_file << item_num << "\t" << node_indices.size();
00394
00395
00396 for (unsigned i=0; i<node_indices.size(); i++)
00397 {
00398 *p_element_file << "\t" << node_indices[i];
00399 }
00400
00401
00402 if (elem_data.AttributeValue != 0)
00403 {
00404 *p_element_file << "\t" << elem_data.AttributeValue;
00405 }
00406
00407
00408 *p_element_file << "\n";
00409 }
00410 else
00411 {
00412 assert(SPACE_DIM == 3);
00413
00414
00415 VertexElementData elem_data_with_faces = this->GetNextElementWithFaces();
00416
00417
00418 std::vector<unsigned> node_indices = elem_data_with_faces.NodeIndices;
00419
00420
00421 *p_element_file << item_num << "\t" << node_indices.size();
00422
00423
00424 for (unsigned i=0; i<node_indices.size(); i++)
00425 {
00426 *p_element_file << "\t" << node_indices[i];
00427 }
00428
00429
00430 std::vector<ElementData> faces = elem_data_with_faces.Faces;
00431
00432
00433 *p_element_file << "\t" << faces.size();
00434
00435 for (unsigned j=0; j<faces.size(); j++)
00436 {
00437
00438 std::vector<unsigned> face_node_indices = faces[j].NodeIndices;
00439
00440
00441 *p_element_file << "\t" << faces[j].AttributeValue << "\t" << face_node_indices.size();
00442
00443
00444 for (unsigned i=0; i<face_node_indices.size(); i++)
00445 {
00446 *p_element_file << "\t" << face_node_indices[i];
00447 }
00448
00450 }
00451
00452
00453 if (elem_data_with_faces.AttributeValue != 0)
00454 {
00455 *p_element_file << "\t" << elem_data_with_faces.AttributeValue;
00456 }
00457
00458
00459 *p_element_file << "\n";
00460 }
00461 }
00462
00463 *p_element_file << comment << "\n";
00464 p_element_file->close();
00465 }
00466
00468
00470
00471 template class VertexMeshWriter<1,1>;
00472 template class VertexMeshWriter<1,2>;
00473 template class VertexMeshWriter<1,3>;
00474 template class VertexMeshWriter<2,2>;
00475 template class VertexMeshWriter<2,3>;
00476 template class VertexMeshWriter<3,3>;