39 #define PETSC_HAVE_BROKEN_RECURSIVE_MACRO
41 #include "AbstractTetrahedralMeshWriter.hpp"
42 #include "AbstractTetrahedralMesh.hpp"
43 #include "DistributedTetrahedralMesh.hpp"
44 #include "MixedDimensionMesh.hpp"
45 #include "Version.hpp"
50 const char*
MeshEventHandler::EventName[] = {
"Tri write",
"BinTri write",
"VTK write",
"PVTK write",
"node write",
"ele write",
"face write",
"ncl write",
"comm1",
"comm2",
"Total"};
55 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
71 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
73 const std::string& rBaseName,
74 const bool clearOutputDir)
77 mNodesPerElement(ELEMENT_DIM+1),
78 mNodesPerBoundaryElement(ELEMENT_DIM),
80 mpDistributedMesh(NULL),
83 mNodeCounterForParallelMesh(0),
84 mElementCounterForParallelMesh(0),
85 mBoundaryElementCounterForParallelMesh(0),
86 mCableElementCounterForParallelMesh(0),
87 mFilesAreBinary(false)
91 mpIters->pBoundaryElemIter = NULL;
94 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
97 if (mpIters->pNodeIter)
99 delete mpIters->pNodeIter;
101 if (mpIters->pElemIter)
103 delete mpIters->pElemIter;
105 if (mpIters->pBoundaryElemIter)
107 delete mpIters->pBoundaryElemIter;
119 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
126 std::vector<double> coords(SPACE_DIM);
129 if ( (*(mpIters->pNodeIter)) != mpMesh->GetNodeIteratorEnd())
133 for (
unsigned j=0; j<SPACE_DIM; j++)
135 coords[j] = (*(mpIters->pNodeIter))->GetPoint()[j];
138 mNodeCounterForParallelMesh=(*(mpIters->pNodeIter))->GetIndex() + 1;
140 ++(*(mpIters->pNodeIter));
147 assert( mpDistributedMesh != NULL );
150 status.MPI_ERROR = MPI_SUCCESS;
152 boost::scoped_array<double> raw_coords(
new double[SPACE_DIM]);
153 MPI_Recv(raw_coords.get(), SPACE_DIM, MPI_DOUBLE, MPI_ANY_SOURCE, mNodeCounterForParallelMesh, PETSC_COMM_WORLD, &status);
154 assert(status.MPI_ERROR == MPI_SUCCESS);
155 for (
unsigned j=0; j<coords.size(); j++)
157 coords[j] = raw_coords[j];
160 mNodeCounterForParallelMesh++;
169 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
179 if ( mpDistributedMesh == NULL )
182 assert(this->mNumElements==mpMesh->GetNumElements());
184 for (
unsigned j=0; j<elem_data.
NodeIndices.size(); j++)
186 unsigned old_index = (*(mpIters->pElemIter))->GetNodeGlobalIndex(j);
187 elem_data.
NodeIndices[j] = mpMesh->IsMeshChanging() ? mpNodeMap->GetNewIndex(old_index) : old_index;
190 elem_data.
AttributeValue = (*(mpIters->pElemIter))->GetAttribute();
192 ++(*(mpIters->pElemIter));
199 if ( mpDistributedMesh->CalculateDesignatedOwnershipOfElement( mElementCounterForParallelMesh ) == true )
203 assert(elem_data.
NodeIndices.size() == mNodesPerElement);
206 for (
unsigned j=0; j<mNodesPerElement; j++)
215 UnpackElement(elem_data, mElementCounterForParallelMesh, mNodesPerElement, this->mNumNodes + mElementCounterForParallelMesh);
218 mElementCounterForParallelMesh++;
229 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
237 boundary_elem_data.
NodeIndices.resize(mNodesPerBoundaryElement);
239 if ( mpDistributedMesh == NULL )
242 assert(this->mNumBoundaryElements==mpMesh->GetNumBoundaryElements());
244 for (
unsigned j=0; j<boundary_elem_data.
NodeIndices.size(); j++)
246 unsigned old_index = (*(*(mpIters->pBoundaryElemIter)))->GetNodeGlobalIndex(j);
247 boundary_elem_data.
NodeIndices[j] = mpMesh->IsMeshChanging() ? mpNodeMap->GetNewIndex(old_index) : old_index;
249 boundary_elem_data.
AttributeValue = (*(*(mpIters->pBoundaryElemIter)))->GetAttribute();
251 ++(*(mpIters->pBoundaryElemIter));
252 return boundary_elem_data;
257 if ( mpDistributedMesh->CalculateDesignatedOwnershipOfBoundaryElement( mBoundaryElementCounterForParallelMesh ) == true )
260 BoundaryElement<ELEMENT_DIM-1, SPACE_DIM>* p_boundary_element = mpDistributedMesh->GetBoundaryElement(mBoundaryElementCounterForParallelMesh);
261 assert(boundary_elem_data.
NodeIndices.size() == ELEMENT_DIM);
262 assert( ! p_boundary_element->IsDeleted() );
264 for (
unsigned j=0; j<ELEMENT_DIM; j++)
266 boundary_elem_data.
NodeIndices[j] = p_boundary_element->GetNodeGlobalIndex(j);
268 boundary_elem_data.
AttributeValue = p_boundary_element->GetAttribute();
273 UnpackElement(boundary_elem_data, mBoundaryElementCounterForParallelMesh, ELEMENT_DIM, this->mNumNodes + this->mNumElements + mBoundaryElementCounterForParallelMesh);
276 mBoundaryElementCounterForParallelMesh++;
278 return boundary_elem_data;
288 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
303 if ( mpMixedMesh->CalculateDesignatedOwnershipOfCableElement( mCableElementCounterForParallelMesh ) == true )
306 Element<1, SPACE_DIM>* p_element = mpMixedMesh->GetCableElement(mCableElementCounterForParallelMesh);
309 for (
unsigned j=0; j<2; j++)
318 UnpackElement(elem_data, mCableElementCounterForParallelMesh, 2, this->mNumNodes + this->mNumElements + this->mNumBoundaryElements + mCableElementCounterForParallelMesh);
321 mCableElementCounterForParallelMesh++;
331 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
334 bool invertMeshPermutation)
337 unsigned max_elements_all;
345 MPI_Allreduce(&max_elements_per_process, &max_elements_all, 1, MPI_UNSIGNED, MPI_MAX, PETSC_COMM_WORLD);
348 std::string node_connect_list_file_name = this->mBaseName +
".ncl";
351 node_connect_list_file_name +=
"-tmp";
356 out_stream p_ncl_file = out_stream(NULL);
361 p_ncl_file = this->mpOutputFileHandler->OpenOutputFile(node_connect_list_file_name, std::ios::binary | std::ios::trunc);
365 *p_ncl_file << max_elements_all <<
"\t";
366 *p_ncl_file <<
"\tBIN\n";
371 p_ncl_file = this->mpOutputFileHandler->OpenOutputFile(node_connect_list_file_name, std::ios::binary | std::ios::app);
375 unsigned default_marker = UINT_MAX;
383 std::set<unsigned>& r_elem_set = iter->rGetContainingElementIndices();
384 std::vector<unsigned> elem_vector(r_elem_set.begin(), r_elem_set.end());
385 std::sort(elem_vector.begin(), elem_vector.end());
387 for (
unsigned elem_index=elem_vector.size(); elem_index<max_elements_all; elem_index++)
389 elem_vector.push_back(default_marker);
391 assert(elem_vector.size() == max_elements_all);
393 if (max_elements_all > 0u)
395 p_ncl_file->write((
char*)&elem_vector[0], elem_vector.size()*
sizeof(
unsigned));
411 const std::string real_node_connect_list_file_name = this->mBaseName +
".ncl";
412 out_stream p_ncl_file = this->mpOutputFileHandler->OpenOutputFile(real_node_connect_list_file_name, std::ios::binary | std::ios::trunc);
413 FileFinder temp_ncl_path = this->mpOutputFileHandler->FindFile(node_connect_list_file_name);
414 std::ifstream temp_ncl_file(temp_ncl_path.
GetAbsolutePath().c_str(), std::ios::binary);
416 std::string header_line;
417 getline(temp_ncl_file, header_line,
'\n');
418 (*p_ncl_file) << header_line <<
"\n";
419 const std::streampos data_start = temp_ncl_file.tellg();
420 const std::streamoff item_width = max_elements_all *
sizeof(
unsigned);
422 std::vector<unsigned> elem_vector(max_elements_all);
423 for (
unsigned node_index=0; node_index<rMesh.
GetNumAllNodes(); node_index++)
426 temp_ncl_file.seekg(data_start + item_width * permuted_index, std::ios_base::beg);
427 temp_ncl_file.read((
char*)&elem_vector[0], max_elements_all*
sizeof(
unsigned));
428 p_ncl_file->write((
char*)&elem_vector[0], max_elements_all*
sizeof(
unsigned));
441 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
444 bool keepOriginalElementIndexing)
446 this->mpMeshReader = NULL;
450 this->mNumElements = mpMesh->GetNumElements();
451 this->mNumBoundaryElements = mpMesh->GetNumBoundaryElements();
452 this->mNumCableElements = mpMesh->GetNumCableElements();
455 mpIters->pNodeIter =
new NodeIterType(mpMesh->GetNodeIteratorBegin());
458 mpIters->pElemIter =
new ElemIterType(mpMesh->GetElementIteratorBegin());
461 mpIters->pBoundaryElemIter =
new BoundaryElemIterType(mpMesh->GetBoundaryElementIteratorBegin());
464 if ( (*(mpIters->pElemIter)) != mpMesh->GetElementIteratorEnd())
466 mNodesPerElement = (*(mpIters->pElemIter))->GetNumNodes();
470 if ( (*(mpIters->pBoundaryElemIter)) != mpMesh->GetBoundaryElementIteratorEnd())
472 mNodesPerBoundaryElement = (*(*(mpIters->pBoundaryElemIter)))->GetNumNodes();
476 if (this->mFilesAreBinary && keepOriginalElementIndexing)
478 WriteNclFile(*mpMesh);
489 if (mpDistributedMesh != NULL)
492 WriteFilesUsingParallelMesh(keepOriginalElementIndexing);
503 unsigned node_map_index = 0;
504 if (mpMesh->IsMeshChanging())
506 mpNodeMap =
new NodeMap(mpMesh->GetMaximumNodeIndex());
507 for (NodeIterType it = mpMesh->GetNodeIteratorBegin(); it != mpMesh->GetNodeIteratorEnd(); ++it)
509 mpNodeMap->
SetNewIndex(it->GetIndex(), node_map_index++);
515 delete mpIters->pNodeIter;
516 mpIters->pNodeIter = NULL;
517 delete mpIters->pElemIter;
518 mpIters->pElemIter = NULL;
519 delete mpIters->pBoundaryElemIter;
520 mpIters->pBoundaryElemIter = NULL;
523 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
528 WriteNclFile(rMesh,
true);
529 this->WriteFilesUsingMeshReader(rMeshReader);
532 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
535 if (keepOriginalElementIndexing)
546 boost::scoped_array<double> raw_coords(
new double[SPACE_DIM]);
549 for (NodeIterType it = mpMesh->GetNodeIteratorBegin(); it != mpMesh->GetNodeIteratorEnd(); ++it)
551 for (
unsigned j=0; j<SPACE_DIM; j++)
553 raw_coords[j] = it->GetPoint()[j];
555 MPI_Ssend(raw_coords.get(), SPACE_DIM, MPI_DOUBLE, 0, it->GetIndex(), PETSC_COMM_WORLD);
562 boost::scoped_array<unsigned> raw_indices(
new unsigned[mNodesPerElement]);
564 for (ElementIterType it = mpMesh->GetElementIteratorBegin(); it != mpMesh->GetElementIteratorEnd(); ++it)
566 unsigned index = it->GetIndex();
567 if ( mpDistributedMesh->CalculateDesignatedOwnershipOfElement( index ) == true )
569 for (
unsigned j=0; j<mNodesPerElement; j++)
571 raw_indices[j] = it->GetNodeGlobalIndex(j);
573 PostElement(index, raw_indices.get(), mNodesPerElement, this->mNumNodes + index, it->GetAttribute());
580 if (ELEMENT_DIM != 1)
582 boost::scoped_array<unsigned> raw_face_indices(
new unsigned[ELEMENT_DIM]);
584 for (BoundaryElementIterType it = mpMesh->GetBoundaryElementIteratorBegin(); it != mpMesh->GetBoundaryElementIteratorEnd(); ++it)
586 unsigned index = (*it)->GetIndex();
587 if ( mpDistributedMesh->CalculateDesignatedOwnershipOfBoundaryElement( index ) == true )
589 for (
unsigned j=0; j<ELEMENT_DIM; j++)
591 raw_face_indices[j] = (*it)->GetNodeGlobalIndex(j);
593 PostElement(index, raw_face_indices.get(), ELEMENT_DIM, this->mNumNodes + this->mNumElements + index, (*it)->GetAttribute());
604 for (CableElementIterType it = mpMixedMesh->GetCableElementIteratorBegin(); it != mpMixedMesh->GetCableElementIteratorEnd(); ++it)
606 unsigned index =(*it)->GetIndex();
607 if ( mpMixedMesh->CalculateDesignatedOwnershipOfCableElement( index ) == true )
609 unsigned raw_cable_element_indices[2];
610 for (
unsigned j=0; j<2; j++)
612 raw_cable_element_indices[j] = (*it)->GetNodeGlobalIndex(j);
614 PostElement(index, raw_cable_element_indices, 2, this->mNumNodes + this->mNumElements + this->mNumBoundaryElements + index, (*it)->GetAttribute());
629 CreateFilesWithHeaders();
632 AppendLocalDataToFiles();
645 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
653 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
661 template<
unsigned ELEMENT_DIM,
unsigned SPACE_DIM>
virtual ElementData GetNextCableElement()
ElementData GetNextCableElement()
unsigned GetNodeGlobalIndex(unsigned localIndex) const
const std::vector< unsigned > & rGetNodePermutation() const
std::string GetAbsolutePath() const
ElementData GetNextBoundaryElement()
static void BeginEvent(unsigned event)
AbstractTetrahedralMeshWriter(const std::string &rDirectory, const std::string &rBaseName, const bool clearOutputDir=true)
NodeIterator GetNodeIteratorEnd()
virtual void CreateFilesWithHeaders()
unsigned CalculateMaximumContainingElementsPerProcess() const
virtual unsigned GetNumNodes() const
AbstractMesh< ELEMENT_DIM, SPACE_DIM >::NodeIterator * pNodeIter
AbstractTetrahedralMesh< ELEMENT_DIM, SPACE_DIM >::BoundaryElementIterator * pBoundaryElemIter
virtual unsigned GetNumAllNodes() const
virtual std::vector< double > GetNextNode()
AbstractTetrahedralMesh< ELEMENT_DIM, SPACE_DIM >::ElementIterator * pElemIter
MeshWriterIterators< ELEMENT_DIM, SPACE_DIM > * mpIters
std::vector< unsigned > NodeIndices
void SetNewIndex(unsigned oldIndex, unsigned newIndex)
void WriteNclFile(AbstractTetrahedralMesh< ELEMENT_DIM, SPACE_DIM > &rMesh, bool invertMeshPermutation=false)
std::vector< double > GetNextNode()
static const char * EventName[11]
virtual void WriteFilesUsingParallelMesh(bool keepOriginalElementIndexing=true)
ElementData GetNextElement()
virtual ~AbstractTetrahedralMeshWriter()
NodeIterator GetNodeIteratorBegin(bool skipDeletedNodes=true)
virtual void WriteFilesFooter()
virtual ElementData GetNextBoundaryElement()
static std::string GetProvenanceString()
static void EndEvent(unsigned event)
std::vector< BoundaryElement< ELEMENT_DIM-1, SPACE_DIM > * >::const_iterator BoundaryElementIterator
virtual ElementData GetNextElement()
virtual void WriteFilesUsingMesh(AbstractTetrahedralMesh< ELEMENT_DIM, SPACE_DIM > &rMesh, bool keepOriginalElementIndexing=true)
virtual void AppendLocalDataToFiles()
void WriteFilesUsingMeshReaderAndMesh(AbstractMeshReader< ELEMENT_DIM, SPACE_DIM > &rMeshReader, AbstractTetrahedralMesh< ELEMENT_DIM, SPACE_DIM > &rMesh)
std::vector< Element< 1, SPACE_DIM > * >::const_iterator CableElementIterator