Commit 6ab9e153 authored by Tomáš Jakubec's avatar Tomáš Jakubec
Browse files

Final commit of Writer refactor

parent 85b70645
Loading
Loading
Loading
Loading
+72 −5
Original line number Original line Diff line number Diff line
@@ -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>
@@ -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>
@@ -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;
    }

};






+16 −1
Original line number Original line Diff line number Diff line
@@ -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>;


@@ -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));
    }
    }
};
};


+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>
+136 −105
Original line number Original line Diff line number Diff line
@@ -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>
@@ -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;
@@ -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");


@@ -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,