Loading Unstructured_mesh/MeshFunctions.h +72 −5 Original line number Original line Diff line number Diff line Loading @@ -570,12 +570,12 @@ struct MeshApply { enum Ordering{ enum Order{ ORDER_ASCEND, ORDER_ASCEND, ORDER_ORIGINAL ORDER_ORIGINAL }; }; template<unsigned int StartDim, unsigned int TargetDim, Ordering order = Ordering::ORDER_ASCEND> template<unsigned int StartDim, unsigned int TargetDim, Order order = Order::ORDER_ASCEND> struct MeshConnections { struct MeshConnections { /** /** * @brief connections<HR> * @brief connections<HR> Loading @@ -600,7 +600,7 @@ struct MeshConnections { template<unsigned int StartDim, unsigned int TargetDim> template<unsigned int StartDim, unsigned int TargetDim> struct MeshConnections<StartDim, TargetDim, Ordering::ORDER_ORIGINAL> { struct MeshConnections<StartDim, TargetDim, Order::ORDER_ORIGINAL> { /** /** * @brief orderedConnections<HR> * @brief orderedConnections<HR> Loading Loading @@ -640,14 +640,81 @@ struct MeshConnections<StartDim, TargetDim, Ordering::ORDER_ORIGINAL> { template <unsigned int StartDim, unsigned int ConnectingDim, unsigned int ConnectedDim = StartDim, Ordering order = Ordering::ORDER_ASCEND> template <unsigned int StartDim, unsigned int ConnectingDim, unsigned int ConnectedDim = StartDim, Order order = Order::ORDER_ASCEND> class MeshNegborhood{ class MeshNegborhood{ template<unsigned int MeshDimension, typename IndexType, typename Real, unsigned int ...Reserve> template<unsigned int MeshDimension, typename IndexType, typename Real, unsigned int ...Reserve> static MeshDataContainer<std::vector<IndexType>, StartDim> connections(); static MeshDataContainer<std::set<IndexType>, StartDim> neighbors( MeshElements<MeshDimension, IndexType, Real, Reserve...>& mesh ) { MeshDataContainer<std::set<IndexType>, StartDim> result; MeshDataContainer<std::set<IndexType>, StartDim> firstConnections = MeshConnections<StartDim, ConnectingDim, order>::connections(mesh); MeshDataContainer<std::set<IndexType>, StartDim> secondConnections = MeshConnections<ConnectingDim, ConnectedDim, order>::connections(mesh); for (IndexType elementIndex = 0; elementIndex < mesh.template getElements<StartDim>().size(); elementIndex++) { for (IndexType& firstConectedElem : firstConnections.template getDataByPos<0>().at(elementIndex)){ for (IndexType& neighborIndex : secondConnections.template getDataByPos<0>().at(firstConectedElem)){ if (StartDim == ConnectedDim && elementIndex == neighborIndex) { continue; } else { result.template getDataByPos<0>().at(elementIndex).insert(neighborIndex); } } } } return result; } }; }; template <unsigned int StartDim, unsigned int ConnectingDim, unsigned int ConnectedDim> class MeshNegborhood<StartDim, ConnectingDim, ConnectedDim, Order::ORDER_ORIGINAL>{ template<unsigned int MeshDimension, typename IndexType, typename Real, unsigned int ...Reserve> static MeshDataContainer<std::set<IndexType>, StartDim> neighbors( MeshElements<MeshDimension, IndexType, Real, Reserve...>& mesh ) { MeshDataContainer<std::map<IndexType, IndexType>, StartDim> tempResultMap(mesh); MeshDataContainer<std::vector<IndexType>, StartDim> firstConnections = MeshConnections<StartDim, ConnectingDim, Order::ORDER_ORIGINAL>::connections(mesh); MeshDataContainer<std::vector<IndexType>, StartDim> secondConnections = MeshConnections<ConnectingDim, ConnectedDim, Order::ORDER_ORIGINAL>::connections(mesh); for (IndexType elementIndex = 0; elementIndex < mesh.template getElements<StartDim>().size(); elementIndex++) { for (IndexType& firstConectedElem : firstConnections.template getDataByPos<0>().at(elementIndex)){ for (IndexType& neighborIndex : secondConnections.template getDataByPos<0>().at(firstConectedElem)){ if (StartDim == ConnectedDim && elementIndex == neighborIndex) { continue; } else { IndexType pos = tempResultMap.template getDataByPos<0>().at(elementIndex).size(); tempResultMap.template getDataByPos<0>().at(elementIndex).insert({neighborIndex, pos}); } } } } MeshDataContainer<std::vector<IndexType>, StartDim> result; for (IndexType i = 0; i < mesh.template getElements<StartDim>().size(); i++){ //resize the vector at the position result.template getDataByPos<0>().at(i).resize( tempResultMap.template getDataByPos<0>().at(i).size() ); for(std::pair<IndexType, IndexType>& mapElem : tempResultMap) { result.template getDataByPos<0>().at(i).at(mapElem.second) = mapElem.first; } } return result; } }; Loading Unstructured_mesh/MeshWriter.h +16 −1 Original line number Original line Diff line number Diff line Loading @@ -26,6 +26,18 @@ private: return mesh.template getElements<0>().size(); return mesh.template getElements<0>().size(); } } }; }; template<typename IndexType, typename Real> struct HashData{ IndexType nElem; Real totCoord; }; template<typename IndexType, typename Real> union HashUni { HashData<IndexType, Real> data; char bytes[sizeof (HashData<IndexType, Real>) + 1] = {}; }; public: public: using type = MeshNativeType<MeshDimension>; using type = MeshNativeType<MeshDimension>; Loading @@ -52,8 +64,11 @@ public: IndexType numberOfElements = sumOfMeshElements<MeshDimension>::sum(mesh); IndexType numberOfElements = sumOfMeshElements<MeshDimension>::sum(mesh); HashUni<IndexType, Real> uni; uni.data = {numberOfElements, totalVert}; std::hash<std::string> hasher; std::hash<std::string> hasher; return hasher(std::to_string(totalVert)+";"+std::to_string(numberOfElements)); return hasher(uni.bytes); //return hasher(std::to_string(totalVert)+";"+std::to_string(numberOfElements)); } } }; }; Loading Unstructured_mesh/Unstructured_mesh.pro.user +1 −1 Original line number Original line Diff line number Diff line <?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE QtCreatorProject> <!DOCTYPE QtCreatorProject> <!-- Written by QtCreator 4.10.0, 2019-10-15T12:09:44. --> <!-- Written by QtCreator 4.10.0, 2019-10-16T23:26:43. --> <qtcreator> <qtcreator> <data> <data> <variable>EnvironmentId</variable> <variable>EnvironmentId</variable> Loading Unstructured_mesh/VTKMeshWriter.h +136 −105 Original line number Original line Diff line number Diff line Loading @@ -272,6 +272,110 @@ public: private: /** * @brief indexPyramid<HR> * Stores indexes of vertices in output container vertWrit * @param mesh * @param cell the current proceeded cell * @param face the base face of the pyramid * @param faceEdgeOri orientation of edges to faces * @param vertWrit [out] */ template<unsigned int ... Reserve> void indexPyramid( MeshElements<3, IndexType, Real, Reserve...>& mesh, typename MeshElements<3, IndexType, Real, Reserve...>::Cell& cell, typename MeshElements<3, IndexType, Real, Reserve...>::Face& face, MeshDataContainer<std::vector<bool>,2>& faceEdgeOri, std::vector<IndexType>& vertWrit ){ indexFace(mesh,face, cell, faceEdgeOri, vertWrit); for (IndexType index : cellVert[cell]) { bool vertOK = true; for (IndexType i : vertWrit){ if (i == index){ vertOK = false; } } if (vertOK){ vertWrit.push_back(index); } } } /** * @brief indexLinearObject<HR> * This function stores indexes of vertices of cells which are made by cartesian product of * a line and the base face in output container vertWrit. * @param mesh * @param cell the current proceeded cell * @param face the base face of the pyramid * @param faceEdgeOri orientation of edges to faces * @param vertWrit [out] */ template<unsigned int ... Reserve> void indexLinearObject( MeshElements<3, IndexType, Real, Reserve...>& mesh, typename MeshElements<3, IndexType, Real, Reserve...>::Cell& cell, typename MeshElements<3, IndexType, Real, Reserve...>::Face& face, MeshDataContainer<std::vector<bool>,2>& faceEdgeOri, std::vector<IndexType>& vertWrit ){ indexFace(mesh, face, cell, faceEdgeOri, vertWrit); // write vertices of the oposite triangular side IndexType numVertBaseFace = vertWrit.size(); IndexType index = 0; auto lambdaProc = [&mesh,&index,&vertWrit](IndexType, IndexType edgeIndex){ auto& edge = mesh.getEdges().at(edgeIndex); if (edge.getVertexAIndex() == index){ bool edgeOK = true; for (IndexType i : vertWrit){ if (edge.getVertexBIndex() == i){ edgeOK = false; } } if(edgeOK){ vertWrit.push_back(edge.getVertexBIndex()); } } if (edge.getVertexBIndex() == index){ bool edgeOK = true; for (IndexType i : vertWrit){ if (edge.getVertexAIndex() == i){ edgeOK = false; } } if(edgeOK){ vertWrit.push_back(edge.getVertexAIndex()); } } }; for (IndexType i = 0; i < numVertBaseFace; i++) { index = vertWrit[i]; MeshRun<3,3,1,3,false, true>::run( mesh, cell.getIndex(), cell.getIndex(), lambdaProc ); } } public: /** /** * @brief indexMesh<HR> * @brief indexMesh<HR> Loading Loading @@ -311,56 +415,42 @@ DBGMSG("indexing mesh"); vertWrit.reserve(cellVert[cell].size()); vertWrit.reserve(cellVert[cell].size()); // switch the writing procedure according to cell type switch (cellTypes.template getDataByPos<0>().at(cell.getIndex())) { switch (cellTypes.template getDataByPos<0>().at(cell.getIndex())) { // Cell type TETRA case writer::type::ElementType::TETRA :{ case writer::type::ElementType::TETRA :{ // write vertices of one face // every face is base face for TETRAHEDRON auto& face = mesh.getFaces().at(cell.getBoundaryElementIndex()); auto& face = mesh.getFaces().at(cell.getBoundaryElementIndex()); indexFace(mesh,face, cell, faceEdgeOri, vertWrit); indexPyramid(mesh, cell, face, faceEdgeOri, vertWrit); for (IndexType index : cellVert[cell]) { bool vertOK = true; for (IndexType i : vertWrit){ if (i == index){ vertOK = false; } } if (vertOK){ vertWrit.push_back(index); } } this->cellVert.template getDataByPos<0>().push_back(vertWrit); this->cellVert.template getDataByPos<0>().push_back(vertWrit); this->cellTypes.template getDataByPos<0>().push_back(cellTypes.at(cell)); this->cellTypes.template getDataByPos<0>().push_back(cellTypes.at(cell)); }break; }break; // Cell type PYRAMID case writer::type::ElementType::PYRAMID :{ case writer::type::ElementType::PYRAMID :{ // write vertices of one face typename MeshElements<3, IndexType, Real, Reserve...>::Face* face = nullptr; // search for the base face // search for the base face typename MeshElements<3, IndexType, Real, Reserve...>::Face* face = nullptr; for (IndexType faceIndex : mesh.template getElement<3>(cell.getIndex()).getSubelements()){ for (IndexType faceIndex : mesh.template getElement<3>(cell.getIndex()).getSubelements()){ if (mesh.template getElements<2>().at(faceIndex).getSubelements().getNumberOfSubElements() > 3){ if (mesh.template getElements<2>().at(faceIndex).getSubelements().getNumberOfSubElements() > 3){ face = &mesh.getFaces().at(faceIndex); face = &mesh.getFaces().at(faceIndex); } } } } // index the pyramid object indexPyramid(mesh, cell, *face, faceEdgeOri, vertWrit); indexFace(mesh, *face, cell, faceEdgeOri, vertWrit); // write the last vertex for (IndexType index : cellVert.at(cell)) { bool vertOK = true; for (IndexType i : vertWrit){ if (i == index){ vertOK = false; } } if (vertOK){ vertWrit.push_back(index); } } this->cellVert.template getDataByPos<0>().push_back(vertWrit); this->cellVert.template getDataByPos<0>().push_back(vertWrit); this->cellTypes.template getDataByPos<0>().push_back(cellTypes.at(cell)); this->cellTypes.template getDataByPos<0>().push_back(cellTypes.at(cell)); }break; }break; // Cell type WEDGE case writer::type::ElementType::WEDGE :{ case writer::type::ElementType::WEDGE :{ // write vertices of one face // write vertices of one face typename MeshElements<3, IndexType, Real, Reserve...>::Face* face = nullptr; typename MeshElements<3, IndexType, Real, Reserve...>::Face* face = nullptr; Loading @@ -373,93 +463,25 @@ DBGMSG("indexing mesh"); } } } } indexFace(mesh, *face, cell, faceEdgeOri, vertWrit); indexLinearObject(mesh, cell, *face, faceEdgeOri, vertWrit); // write vertices of the oposite triangular side for (IndexType i = 0; i < vertWrit.size(); i++) { IndexType index = vertWrit[i]; MeshRun<3,3,1,3,false, true>::run(mesh, cell.getIndex(),cell.getIndex(), [&mesh,&index,&vertWrit](IndexType, IndexType edgeIndex){ auto& edge = mesh.getEdges().at(edgeIndex); if (edge.getVertexAIndex() == index){ bool edgeOK = true; for (IndexType i : vertWrit){ if (edge.getVertexBIndex() == i){ edgeOK = false; } } if(edgeOK){ vertWrit.push_back(edge.getVertexBIndex()); } } if (edge.getVertexBIndex() == index){ bool edgeOK = true; for (IndexType i : vertWrit){ if (edge.getVertexAIndex() == i){ edgeOK = false; } } if(edgeOK){ vertWrit.push_back(edge.getVertexAIndex()); } } } ); if (vertWrit.size() == 6) { break; } } this->cellVert.template getDataByPos<0>().push_back(vertWrit); this->cellVert.template getDataByPos<0>().push_back(vertWrit); this->cellTypes.template getDataByPos<0>().push_back(cellTypes.at(cell)); this->cellTypes.template getDataByPos<0>().push_back(cellTypes.at(cell)); }break; }break; // Cell type HEXAHEDRON case writer::type::ElementType::HEXAHEDRON :{ case writer::type::ElementType::HEXAHEDRON :{ // write vertices of one face // write vertices of one face auto& face = mesh.getFaces().at(cell.getBoundaryElementIndex()); auto& face = mesh.getFaces().at(cell.getBoundaryElementIndex()); indexFace(mesh, face, cell, faceEdgeOri, vertWrit); indexLinearObject(mesh, cell, face, faceEdgeOri, vertWrit); // write vertices of the oposite triangular side for (IndexType i = 0; i < vertWrit.size(); i++) { IndexType index = vertWrit[i]; MeshRun<3,3,1,3,false, true>::run(mesh, cell.getIndex(),cell.getIndex(), [&mesh,&index,&vertWrit](IndexType, IndexType edgeIndex){ auto& edge = mesh.getEdges().at(edgeIndex); if (edge.getVertexAIndex() == index){ bool edgeOK = true; for (IndexType i : vertWrit){ if (edge.getVertexBIndex() == i){ edgeOK = false; } } if(edgeOK){ vertWrit.push_back(edge.getVertexBIndex()); } } if (edge.getVertexBIndex() == index){ bool edgeOK = true; for (IndexType i : vertWrit){ if (edge.getVertexAIndex() == i){ edgeOK = false; } } if(edgeOK){ vertWrit.push_back(edge.getVertexAIndex()); } } } ); if (vertWrit.size() == 8) { break; } } this->cellVert.template getDataByPos<0>().push_back(vertWrit); this->cellVert.template getDataByPos<0>().push_back(vertWrit); this->cellTypes.template getDataByPos<0>().push_back(cellTypes.at(cell)); this->cellTypes.template getDataByPos<0>().push_back(cellTypes.at(cell)); }break; }break; // Defalt splitting of the volume default: { default: { //throw std::runtime_error("it is not possible yet to write generic object into VTK"); //throw std::runtime_error("it is not possible yet to write generic object into VTK"); Loading Loading @@ -522,6 +544,15 @@ DBGMSG("indexing mesh"); } } /** * @brief writeToStream * Exports the mesh to the output stream in VTK format. * If the mesh is written for the first time, it is indexed. * @see indexMesh * @param ost * @param mesh * @param cellTypes the types of cells in NativeType format */ template<unsigned int ...Reserve> template<unsigned int ...Reserve> void writeToStream(std::ostream& ost, void writeToStream(std::ostream& ost, MeshElements<3, IndexType, Real, Reserve...>& mesh, MeshElements<3, IndexType, Real, Reserve...>& mesh, Loading Loading
Unstructured_mesh/MeshFunctions.h +72 −5 Original line number Original line Diff line number Diff line Loading @@ -570,12 +570,12 @@ struct MeshApply { enum Ordering{ enum Order{ ORDER_ASCEND, ORDER_ASCEND, ORDER_ORIGINAL ORDER_ORIGINAL }; }; template<unsigned int StartDim, unsigned int TargetDim, Ordering order = Ordering::ORDER_ASCEND> template<unsigned int StartDim, unsigned int TargetDim, Order order = Order::ORDER_ASCEND> struct MeshConnections { struct MeshConnections { /** /** * @brief connections<HR> * @brief connections<HR> Loading @@ -600,7 +600,7 @@ struct MeshConnections { template<unsigned int StartDim, unsigned int TargetDim> template<unsigned int StartDim, unsigned int TargetDim> struct MeshConnections<StartDim, TargetDim, Ordering::ORDER_ORIGINAL> { struct MeshConnections<StartDim, TargetDim, Order::ORDER_ORIGINAL> { /** /** * @brief orderedConnections<HR> * @brief orderedConnections<HR> Loading Loading @@ -640,14 +640,81 @@ struct MeshConnections<StartDim, TargetDim, Ordering::ORDER_ORIGINAL> { template <unsigned int StartDim, unsigned int ConnectingDim, unsigned int ConnectedDim = StartDim, Ordering order = Ordering::ORDER_ASCEND> template <unsigned int StartDim, unsigned int ConnectingDim, unsigned int ConnectedDim = StartDim, Order order = Order::ORDER_ASCEND> class MeshNegborhood{ class MeshNegborhood{ template<unsigned int MeshDimension, typename IndexType, typename Real, unsigned int ...Reserve> template<unsigned int MeshDimension, typename IndexType, typename Real, unsigned int ...Reserve> static MeshDataContainer<std::vector<IndexType>, StartDim> connections(); static MeshDataContainer<std::set<IndexType>, StartDim> neighbors( MeshElements<MeshDimension, IndexType, Real, Reserve...>& mesh ) { MeshDataContainer<std::set<IndexType>, StartDim> result; MeshDataContainer<std::set<IndexType>, StartDim> firstConnections = MeshConnections<StartDim, ConnectingDim, order>::connections(mesh); MeshDataContainer<std::set<IndexType>, StartDim> secondConnections = MeshConnections<ConnectingDim, ConnectedDim, order>::connections(mesh); for (IndexType elementIndex = 0; elementIndex < mesh.template getElements<StartDim>().size(); elementIndex++) { for (IndexType& firstConectedElem : firstConnections.template getDataByPos<0>().at(elementIndex)){ for (IndexType& neighborIndex : secondConnections.template getDataByPos<0>().at(firstConectedElem)){ if (StartDim == ConnectedDim && elementIndex == neighborIndex) { continue; } else { result.template getDataByPos<0>().at(elementIndex).insert(neighborIndex); } } } } return result; } }; }; template <unsigned int StartDim, unsigned int ConnectingDim, unsigned int ConnectedDim> class MeshNegborhood<StartDim, ConnectingDim, ConnectedDim, Order::ORDER_ORIGINAL>{ template<unsigned int MeshDimension, typename IndexType, typename Real, unsigned int ...Reserve> static MeshDataContainer<std::set<IndexType>, StartDim> neighbors( MeshElements<MeshDimension, IndexType, Real, Reserve...>& mesh ) { MeshDataContainer<std::map<IndexType, IndexType>, StartDim> tempResultMap(mesh); MeshDataContainer<std::vector<IndexType>, StartDim> firstConnections = MeshConnections<StartDim, ConnectingDim, Order::ORDER_ORIGINAL>::connections(mesh); MeshDataContainer<std::vector<IndexType>, StartDim> secondConnections = MeshConnections<ConnectingDim, ConnectedDim, Order::ORDER_ORIGINAL>::connections(mesh); for (IndexType elementIndex = 0; elementIndex < mesh.template getElements<StartDim>().size(); elementIndex++) { for (IndexType& firstConectedElem : firstConnections.template getDataByPos<0>().at(elementIndex)){ for (IndexType& neighborIndex : secondConnections.template getDataByPos<0>().at(firstConectedElem)){ if (StartDim == ConnectedDim && elementIndex == neighborIndex) { continue; } else { IndexType pos = tempResultMap.template getDataByPos<0>().at(elementIndex).size(); tempResultMap.template getDataByPos<0>().at(elementIndex).insert({neighborIndex, pos}); } } } } MeshDataContainer<std::vector<IndexType>, StartDim> result; for (IndexType i = 0; i < mesh.template getElements<StartDim>().size(); i++){ //resize the vector at the position result.template getDataByPos<0>().at(i).resize( tempResultMap.template getDataByPos<0>().at(i).size() ); for(std::pair<IndexType, IndexType>& mapElem : tempResultMap) { result.template getDataByPos<0>().at(i).at(mapElem.second) = mapElem.first; } } return result; } }; Loading
Unstructured_mesh/MeshWriter.h +16 −1 Original line number Original line Diff line number Diff line Loading @@ -26,6 +26,18 @@ private: return mesh.template getElements<0>().size(); return mesh.template getElements<0>().size(); } } }; }; template<typename IndexType, typename Real> struct HashData{ IndexType nElem; Real totCoord; }; template<typename IndexType, typename Real> union HashUni { HashData<IndexType, Real> data; char bytes[sizeof (HashData<IndexType, Real>) + 1] = {}; }; public: public: using type = MeshNativeType<MeshDimension>; using type = MeshNativeType<MeshDimension>; Loading @@ -52,8 +64,11 @@ public: IndexType numberOfElements = sumOfMeshElements<MeshDimension>::sum(mesh); IndexType numberOfElements = sumOfMeshElements<MeshDimension>::sum(mesh); HashUni<IndexType, Real> uni; uni.data = {numberOfElements, totalVert}; std::hash<std::string> hasher; std::hash<std::string> hasher; return hasher(std::to_string(totalVert)+";"+std::to_string(numberOfElements)); return hasher(uni.bytes); //return hasher(std::to_string(totalVert)+";"+std::to_string(numberOfElements)); } } }; }; Loading
Unstructured_mesh/Unstructured_mesh.pro.user +1 −1 Original line number Original line Diff line number Diff line <?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE QtCreatorProject> <!DOCTYPE QtCreatorProject> <!-- Written by QtCreator 4.10.0, 2019-10-15T12:09:44. --> <!-- Written by QtCreator 4.10.0, 2019-10-16T23:26:43. --> <qtcreator> <qtcreator> <data> <data> <variable>EnvironmentId</variable> <variable>EnvironmentId</variable> Loading
Unstructured_mesh/VTKMeshWriter.h +136 −105 Original line number Original line Diff line number Diff line Loading @@ -272,6 +272,110 @@ public: private: /** * @brief indexPyramid<HR> * Stores indexes of vertices in output container vertWrit * @param mesh * @param cell the current proceeded cell * @param face the base face of the pyramid * @param faceEdgeOri orientation of edges to faces * @param vertWrit [out] */ template<unsigned int ... Reserve> void indexPyramid( MeshElements<3, IndexType, Real, Reserve...>& mesh, typename MeshElements<3, IndexType, Real, Reserve...>::Cell& cell, typename MeshElements<3, IndexType, Real, Reserve...>::Face& face, MeshDataContainer<std::vector<bool>,2>& faceEdgeOri, std::vector<IndexType>& vertWrit ){ indexFace(mesh,face, cell, faceEdgeOri, vertWrit); for (IndexType index : cellVert[cell]) { bool vertOK = true; for (IndexType i : vertWrit){ if (i == index){ vertOK = false; } } if (vertOK){ vertWrit.push_back(index); } } } /** * @brief indexLinearObject<HR> * This function stores indexes of vertices of cells which are made by cartesian product of * a line and the base face in output container vertWrit. * @param mesh * @param cell the current proceeded cell * @param face the base face of the pyramid * @param faceEdgeOri orientation of edges to faces * @param vertWrit [out] */ template<unsigned int ... Reserve> void indexLinearObject( MeshElements<3, IndexType, Real, Reserve...>& mesh, typename MeshElements<3, IndexType, Real, Reserve...>::Cell& cell, typename MeshElements<3, IndexType, Real, Reserve...>::Face& face, MeshDataContainer<std::vector<bool>,2>& faceEdgeOri, std::vector<IndexType>& vertWrit ){ indexFace(mesh, face, cell, faceEdgeOri, vertWrit); // write vertices of the oposite triangular side IndexType numVertBaseFace = vertWrit.size(); IndexType index = 0; auto lambdaProc = [&mesh,&index,&vertWrit](IndexType, IndexType edgeIndex){ auto& edge = mesh.getEdges().at(edgeIndex); if (edge.getVertexAIndex() == index){ bool edgeOK = true; for (IndexType i : vertWrit){ if (edge.getVertexBIndex() == i){ edgeOK = false; } } if(edgeOK){ vertWrit.push_back(edge.getVertexBIndex()); } } if (edge.getVertexBIndex() == index){ bool edgeOK = true; for (IndexType i : vertWrit){ if (edge.getVertexAIndex() == i){ edgeOK = false; } } if(edgeOK){ vertWrit.push_back(edge.getVertexAIndex()); } } }; for (IndexType i = 0; i < numVertBaseFace; i++) { index = vertWrit[i]; MeshRun<3,3,1,3,false, true>::run( mesh, cell.getIndex(), cell.getIndex(), lambdaProc ); } } public: /** /** * @brief indexMesh<HR> * @brief indexMesh<HR> Loading Loading @@ -311,56 +415,42 @@ DBGMSG("indexing mesh"); vertWrit.reserve(cellVert[cell].size()); vertWrit.reserve(cellVert[cell].size()); // switch the writing procedure according to cell type switch (cellTypes.template getDataByPos<0>().at(cell.getIndex())) { switch (cellTypes.template getDataByPos<0>().at(cell.getIndex())) { // Cell type TETRA case writer::type::ElementType::TETRA :{ case writer::type::ElementType::TETRA :{ // write vertices of one face // every face is base face for TETRAHEDRON auto& face = mesh.getFaces().at(cell.getBoundaryElementIndex()); auto& face = mesh.getFaces().at(cell.getBoundaryElementIndex()); indexFace(mesh,face, cell, faceEdgeOri, vertWrit); indexPyramid(mesh, cell, face, faceEdgeOri, vertWrit); for (IndexType index : cellVert[cell]) { bool vertOK = true; for (IndexType i : vertWrit){ if (i == index){ vertOK = false; } } if (vertOK){ vertWrit.push_back(index); } } this->cellVert.template getDataByPos<0>().push_back(vertWrit); this->cellVert.template getDataByPos<0>().push_back(vertWrit); this->cellTypes.template getDataByPos<0>().push_back(cellTypes.at(cell)); this->cellTypes.template getDataByPos<0>().push_back(cellTypes.at(cell)); }break; }break; // Cell type PYRAMID case writer::type::ElementType::PYRAMID :{ case writer::type::ElementType::PYRAMID :{ // write vertices of one face typename MeshElements<3, IndexType, Real, Reserve...>::Face* face = nullptr; // search for the base face // search for the base face typename MeshElements<3, IndexType, Real, Reserve...>::Face* face = nullptr; for (IndexType faceIndex : mesh.template getElement<3>(cell.getIndex()).getSubelements()){ for (IndexType faceIndex : mesh.template getElement<3>(cell.getIndex()).getSubelements()){ if (mesh.template getElements<2>().at(faceIndex).getSubelements().getNumberOfSubElements() > 3){ if (mesh.template getElements<2>().at(faceIndex).getSubelements().getNumberOfSubElements() > 3){ face = &mesh.getFaces().at(faceIndex); face = &mesh.getFaces().at(faceIndex); } } } } // index the pyramid object indexPyramid(mesh, cell, *face, faceEdgeOri, vertWrit); indexFace(mesh, *face, cell, faceEdgeOri, vertWrit); // write the last vertex for (IndexType index : cellVert.at(cell)) { bool vertOK = true; for (IndexType i : vertWrit){ if (i == index){ vertOK = false; } } if (vertOK){ vertWrit.push_back(index); } } this->cellVert.template getDataByPos<0>().push_back(vertWrit); this->cellVert.template getDataByPos<0>().push_back(vertWrit); this->cellTypes.template getDataByPos<0>().push_back(cellTypes.at(cell)); this->cellTypes.template getDataByPos<0>().push_back(cellTypes.at(cell)); }break; }break; // Cell type WEDGE case writer::type::ElementType::WEDGE :{ case writer::type::ElementType::WEDGE :{ // write vertices of one face // write vertices of one face typename MeshElements<3, IndexType, Real, Reserve...>::Face* face = nullptr; typename MeshElements<3, IndexType, Real, Reserve...>::Face* face = nullptr; Loading @@ -373,93 +463,25 @@ DBGMSG("indexing mesh"); } } } } indexFace(mesh, *face, cell, faceEdgeOri, vertWrit); indexLinearObject(mesh, cell, *face, faceEdgeOri, vertWrit); // write vertices of the oposite triangular side for (IndexType i = 0; i < vertWrit.size(); i++) { IndexType index = vertWrit[i]; MeshRun<3,3,1,3,false, true>::run(mesh, cell.getIndex(),cell.getIndex(), [&mesh,&index,&vertWrit](IndexType, IndexType edgeIndex){ auto& edge = mesh.getEdges().at(edgeIndex); if (edge.getVertexAIndex() == index){ bool edgeOK = true; for (IndexType i : vertWrit){ if (edge.getVertexBIndex() == i){ edgeOK = false; } } if(edgeOK){ vertWrit.push_back(edge.getVertexBIndex()); } } if (edge.getVertexBIndex() == index){ bool edgeOK = true; for (IndexType i : vertWrit){ if (edge.getVertexAIndex() == i){ edgeOK = false; } } if(edgeOK){ vertWrit.push_back(edge.getVertexAIndex()); } } } ); if (vertWrit.size() == 6) { break; } } this->cellVert.template getDataByPos<0>().push_back(vertWrit); this->cellVert.template getDataByPos<0>().push_back(vertWrit); this->cellTypes.template getDataByPos<0>().push_back(cellTypes.at(cell)); this->cellTypes.template getDataByPos<0>().push_back(cellTypes.at(cell)); }break; }break; // Cell type HEXAHEDRON case writer::type::ElementType::HEXAHEDRON :{ case writer::type::ElementType::HEXAHEDRON :{ // write vertices of one face // write vertices of one face auto& face = mesh.getFaces().at(cell.getBoundaryElementIndex()); auto& face = mesh.getFaces().at(cell.getBoundaryElementIndex()); indexFace(mesh, face, cell, faceEdgeOri, vertWrit); indexLinearObject(mesh, cell, face, faceEdgeOri, vertWrit); // write vertices of the oposite triangular side for (IndexType i = 0; i < vertWrit.size(); i++) { IndexType index = vertWrit[i]; MeshRun<3,3,1,3,false, true>::run(mesh, cell.getIndex(),cell.getIndex(), [&mesh,&index,&vertWrit](IndexType, IndexType edgeIndex){ auto& edge = mesh.getEdges().at(edgeIndex); if (edge.getVertexAIndex() == index){ bool edgeOK = true; for (IndexType i : vertWrit){ if (edge.getVertexBIndex() == i){ edgeOK = false; } } if(edgeOK){ vertWrit.push_back(edge.getVertexBIndex()); } } if (edge.getVertexBIndex() == index){ bool edgeOK = true; for (IndexType i : vertWrit){ if (edge.getVertexAIndex() == i){ edgeOK = false; } } if(edgeOK){ vertWrit.push_back(edge.getVertexAIndex()); } } } ); if (vertWrit.size() == 8) { break; } } this->cellVert.template getDataByPos<0>().push_back(vertWrit); this->cellVert.template getDataByPos<0>().push_back(vertWrit); this->cellTypes.template getDataByPos<0>().push_back(cellTypes.at(cell)); this->cellTypes.template getDataByPos<0>().push_back(cellTypes.at(cell)); }break; }break; // Defalt splitting of the volume default: { default: { //throw std::runtime_error("it is not possible yet to write generic object into VTK"); //throw std::runtime_error("it is not possible yet to write generic object into VTK"); Loading Loading @@ -522,6 +544,15 @@ DBGMSG("indexing mesh"); } } /** * @brief writeToStream * Exports the mesh to the output stream in VTK format. * If the mesh is written for the first time, it is indexed. * @see indexMesh * @param ost * @param mesh * @param cellTypes the types of cells in NativeType format */ template<unsigned int ...Reserve> template<unsigned int ...Reserve> void writeToStream(std::ostream& ost, void writeToStream(std::ostream& ost, MeshElements<3, IndexType, Real, Reserve...>& mesh, MeshElements<3, IndexType, Real, Reserve...>& mesh, Loading