From b0c4be5c9fbd6572c5c048173d1cb5c68740d0ef Mon Sep 17 00:00:00 2001 From: podlesny <podlesny@zedat.fu-berlin.de> Date: Sun, 14 Jun 2020 17:36:46 +0200 Subject: [PATCH] . --- .../faultfactories/rockfaultfactory.hh | 118 ++++++++++-------- .../results/sparse/plot.tex | 39 +++--- .../sparsecantorfaultnetwork.cc | 8 +- 3 files changed, 91 insertions(+), 74 deletions(-) diff --git a/dune/faultnetworks/faultfactories/rockfaultfactory.hh b/dune/faultnetworks/faultfactories/rockfaultfactory.hh index 7f5bdef..31e0f13 100644 --- a/dune/faultnetworks/faultfactories/rockfaultfactory.hh +++ b/dune/faultnetworks/faultfactories/rockfaultfactory.hh @@ -91,22 +91,20 @@ protected: std::vector<ID> vertexIDs_; std::map<ID, size_t> IDsToDof_; + std::set<size_t> boundaryDofs_; + std::vector<std::vector<size_t>> vertexToFaces_; std::vector<int> coarseToLevelVertex_; const LevelRockFaultFactory& coarseLevelFactory_; std::vector<MyRock> rocks_; - std::vector<std::shared_ptr<FaultInterface<GV>>>& faults_; - -private: - template <typename T> int sgn(T val) { - return (T(0) < val) - (val < T(0)); - } + std::vector<std::shared_ptr<FaultInterface<GV>>> faults_; +protected: bool intersectionAllowed(const size_t faceID, const size_t vertexID, const std::array<size_t, 2>& centerIDs, const std::set<size_t>& deadendDofs, - const std::set<int>& separatingIDs, const std::set<size_t>& faultDofs, + const std::set<size_t>& separatingIDs, const std::set<size_t>& faultDofs, const Coords& direction, size_t dim) const { const auto& intersection = faces_[faceID]; @@ -127,9 +125,10 @@ private: const size_t otherDim = (dim + 1) % 2; for (const auto& isDof : intersectionDofs) { const auto& vertex = vertexPositions_[isDof]; - std::array<size_t, 2> IDs = {computeID(vertex, 0), computeID(vertex, 1)}; + ID IDs = {computeID(vertex, 0), computeID(vertex, 1)}; - bool centerPassed = (sgn(direction[dim])>0) ? (centerIDs[dim]<IDs[dim]) : (centerIDs[dim]>IDs[dim]); + auto val = direction[dim]; + bool centerPassed = ((0 < val) - (val < 0)>0) ? (centerIDs[dim]<IDs[dim]) : (centerIDs[dim]>IDs[dim]); if (faultDofs.count(isDof) or separatingIDs.count(IDs[otherDim]) or centerPassed or deadendDofs.count(isDof)) { return false; } @@ -250,17 +249,19 @@ private: if (std::abs(direction[0]) < std::abs(direction[1])) { dim = 1; } - + auto otherDim = (dim+1) % 2; const ID centerIDs = {computeID(center, 0), computeID(center, 1)}; std::set<size_t> separatingIDs; - auto faultSeedID = vertexIDs_[faultSeedIdx][dim]; + auto faultSeedID = vertexIDs_[faultSeedIdx][otherDim]; separatingIDs.insert(faultSeedID + corridor); separatingIDs.insert(faultSeedID - corridor); std::vector<size_t> faultDofs(0); + std::set<size_t> faultDofSet; faultDofs.push_back(faultSeedIdx); + faultDofSet.insert(faultSeedIdx); std::vector<size_t> faultFaces; @@ -283,7 +284,7 @@ private: std::vector<size_t> admissibleFaces; for (size_t i=0; i<faces.size(); i++) { - if (intersectionAllowed(faces[i], vertexID, centerIDs, deadendDofs, separatingIDs, faultDofs, direction, dim)) { + if (intersectionAllowed(faces[i], vertexID, centerIDs, deadendDofs, separatingIDs, faultDofSet, direction, dim)) { admissibleFaces.push_back(faces[i]); } } @@ -302,6 +303,7 @@ private: std::vector<size_t>& suitableFaces = vertexToAdmissibleFaces[vertexID]; if (suitableFaces.size()==0) { + faultDofSet.erase(faultDofs.back()); faultDofs.pop_back(); faultFaces.pop_back(); vertexToAdmissibleFaces.erase(vertexID); @@ -327,6 +329,7 @@ private: nextFaceDofs.erase(vertexID); faultDofs.push_back(*nextFaceDofs.begin()); + faultDofSet.insert(*nextFaceDofs.begin()); faultFaces.push_back(nextFaceID); size_t nextVertexID = *(nextFaceDofs.begin()); @@ -352,19 +355,19 @@ private: if (dir>0) { while (lastDof<0) { - candidatIDs[dim]++; auto dof = IDsToDof_[candidatIDs]; - if (separatingDofs.count(dof)) { + if (separatingDofs.count(dof) or boundaryDofs_.count(dof)) { lastDof = dof; } + candidatIDs[dim]++; } } else { while (lastDof<0) { - candidatIDs[dim]--; auto dof = IDsToDof_[candidatIDs]; - if (separatingDofs.count(dof)) { + if (separatingDofs.count(dof) or boundaryDofs_.count(dof)) { lastDof = dof; } + candidatIDs[dim]--; } } @@ -404,16 +407,16 @@ private: void prolong(const MyRock& rock, MyRock& newRock) { newRock.level = rock.level; - auto newLeft = coarseToLevelVertex_[rock.left()]; - auto newRight = coarseToLevelVertex_[rock.right()]; - auto newTop = coarseToLevelVertex_[rock.top()]; - auto newBottom = coarseToLevelVertex_[rock.bottom()]; + auto newLeft = coarseToLevelVertex_[rock.left]; + auto newRight = coarseToLevelVertex_[rock.right]; + auto newTop = coarseToLevelVertex_[rock.top]; + auto newBottom = coarseToLevelVertex_[rock.bottom]; - newRock.set(newLeft, newRight, newTop, newBottom, rock.center()); + newRock.set(newLeft, newRight, newTop, newBottom, rock.center); } bool randomSplit(const MyRock& rock) { - const auto& center = rock.center(); + const auto& center = rock.center; double res = 0.0; if (center[0] < center[1]) { @@ -433,16 +436,16 @@ private: Rock newRock; prolong(rock, newRock); - bool toBeSplit = (rock.level() == coarseLevelFactory_.level()) and randomSplit(rock); + bool toBeSplit = (rock.level == coarseLevelFactory_.level()) and randomSplit(rock); if (!toBeSplit) { rocks_.push_back(newRock); } else { const ID centerIDs = {computeID(newRock.center, 0), computeID(newRock.center, 1)}; - size_t xCorridor = 1.0/2 * std::min(centerIDs[0] - vertexIDs_[newRock.left][0], - vertexIDs_[newRock.right][0] - centerIDs[0]) + 1; - size_t yCorridor = 1.0/2 * std::min(centerIDs[1] - vertexIDs_[newRock.bottom][1], - vertexIDs_[newRock.top][1] - centerIDs[1]) + 1; + size_t xCorridor = 1.0/4 * std::min(centerIDs[0] - vertexIDs_[newRock.left][0], + vertexIDs_[newRock.right][0] - centerIDs[0]); + size_t yCorridor = 1.0/4 * std::min(centerIDs[1] - vertexIDs_[newRock.bottom][1], + vertexIDs_[newRock.top][1] - centerIDs[1]); // split rock into 4 subparts by 4 new faults intersecting at center of rock std::shared_ptr<FaultInterface<GV>> x1Fault = std::make_shared<FaultInterface<GV>>(gridView_, level_); @@ -468,30 +471,30 @@ private: MyRock rock00; auto center00 = 1.0/2*(right + bottom); - createRock(rock00, center00, separatingDofs, x2Fault.getInterfaceDofs(), 0, y1Fault.getInterfaceDofs(), 0); + createRock(rock00, center00, separatingDofs, x2Fault->getInterfaceDofs(), 0, y1Fault->getInterfaceDofs(), 0); rocks_.push_back(rock00); MyRock rock01; auto center01 = 1.0/2*(left + bottom); - createRock(rock01, center01, separatingDofs, x1Fault.getInterfaceDofs(), 0, y1Fault.getInterfaceDofs(), 1); + createRock(rock01, center01, separatingDofs, x1Fault->getInterfaceDofs(), 0, y1Fault->getInterfaceDofs(), 1); rocks_.push_back(rock01); MyRock rock10; auto center10 = 1.0/2*(right + top); - createRock(rock10, center10, separatingDofs, x2Fault.getInterfaceDofs(), 1, y2Fault.getInterfaceDofs(), 0); + createRock(rock10, center10, separatingDofs, x2Fault->getInterfaceDofs(), 1, y2Fault->getInterfaceDofs(), 0); rocks_.push_back(rock10); MyRock rock11; auto center11 = 1.0/2*(left + top); - createRock(rock11, center11, separatingDofs, x1Fault.getInterfaceDofs(), 1, y2Fault.getInterfaceDofs(), 1); + createRock(rock11, center11, separatingDofs, x1Fault->getInterfaceDofs(), 1, y2Fault->getInterfaceDofs(), 1); rocks_.push_back(rock11); } } public: LevelRockFaultFactory(const std::shared_ptr<GridType> grid, const int level, const ctype resolution, - const LevelRockFaultFactory& coarseLevelFactory, - const double splittingThreshold = 0.0, const double maxAngle = 2) : + const LevelRockFaultFactory* coarseLevelFactory, + const double splittingThreshold = 1.0, const double maxAngle = 2) : grid_(grid), level_(level), resolution_(resolution), @@ -500,14 +503,13 @@ private: maxAngle_(maxAngle), indexSet_(gridView_.indexSet()), faceMapper_(gridView_), - coarseLevelFactory_(coarseLevelFactory) + coarseLevelFactory_(*coarseLevelFactory) { // init faces_, vertexPositions_, vertexToFaces_ faces_.resize(faceMapper_.size()); vertexPositions_.resize(gridView_.size(dim)); vertexToFaces_.resize(gridView_.size(dim)); vertexIDs_.resize(gridView_.size(dim)); - coarseToLevelVertex_.resize(coarseLevelFactory_.gridView().size(dim)); std::vector<bool> faceHandled(faceMapper_.size(), false); @@ -517,8 +519,11 @@ private: const int faceID = faceMapper_.subIndex(elem, isect.indexInInside(), 1); - if (isect.boundary()) - continue; + if (isect.boundary()) { + std::set<size_t> intersectionDofs; + computeIntersectionDofs(isect, intersectionDofs); + boundaryDofs_.insert(intersectionDofs.begin(), intersectionDofs.end()); + } if (faceHandled[faceID]) continue; @@ -545,15 +550,18 @@ private: } } - for (const auto& vertex : vertices(gridView_)) { - size_t coarseVertexID; - bool isCoarseVertex = coarseLevelFactory_.indexSet().index(vertex, coarseVertexID); + if (coarseLevelFactory!=nullptr) { + const auto& coarseVertexCoords = coarseLevelFactory_.vertexCoords(); + coarseToLevelVertex_.resize(coarseVertexCoords.size()); - if (isCoarseVertex) { - coarseToLevelVertex_[coarseVertexID] = indexSet_.index(vertex); + for (size_t i=0; i<coarseVertexCoords.size(); i++) { + const auto& vertex = coarseVertexCoords[i]; + ID id = {computeID(vertex, 0), computeID(vertex, 1)}; + + coarseToLevelVertex_[i] = IDsToDof_[id]; } } - } + } void build(const std::set<size_t>& separatingDofs) { faults_.resize(0); @@ -598,12 +606,17 @@ private: const auto& faults() const { return faults_; } + + const auto& vertexCoords() const { + return vertexPositions_; + } }; template <class GridType> class InitLevelRockFaultFactory : public LevelRockFaultFactory<GridType> { -private: +protected: using Base = LevelRockFaultFactory<GridType>; + public: InitLevelRockFaultFactory(const std::shared_ptr<GridType> grid, const int level, const typename Base::ctype resolution) : Base(grid, level, resolution, nullptr) {} @@ -634,6 +647,8 @@ template <class GridType> class RockFaultFactory { private: + using GV = typename GridType::LevelGridView; + const int coarseResolution_; const size_t maxLevel_; const int coarseGridN_; @@ -696,22 +711,23 @@ public: // init level 0 rockFaultFactory levelResolutions_[0] = std::pow(2, coarseResolution_); + InitLevelRockFaultFactory<GridType> initFactory(grid_, 0, levelResolutions_[0]); + std::set<size_t> boundaryDofs; - BoundaryIterator<GV> bIt(levelRockFaultFactories_[0].gridView(), BoundaryIterator<GV>::begin); - BoundaryIterator<GV> bEnd(levelRockFaultFactories_[0].gridView(), BoundaryIterator<GV>::end); + BoundaryIterator<GV> bIt(initFactory.gridView(), BoundaryIterator<GV>::begin); + BoundaryIterator<GV> bEnd(initFactory.gridView(), BoundaryIterator<GV>::end); for(; bIt!=bEnd; ++bIt) { std::set<size_t> intersectionDofs; - levelRockFaultFactories_[0].computeIntersectionDofs(*bIt, intersectionDofs); + initFactory.computeIntersectionDofs(*bIt, intersectionDofs); boundaryDofs.insert(intersectionDofs.begin(), intersectionDofs.end()); } - InitLevelRockFaultFactory initFactory(grid_, 0, levelResolutions_[0]); initFactory.build(boundaryDofs); - levelRockFaultFactories_[0] = std::make_shared<LevelRockFaultFactory<GridType>>(grid_, 0, levelResolutions_[0], initFactory, 1.0); + levelRockFaultFactories_[0] = std::make_shared<LevelRockFaultFactory<GridType>>(grid_, 0, levelResolutions_[0], &initFactory, 0.0); levelRockFaultFactories_[0]->build(boundaryDofs); - const auto& faults = levelRockFaultFactories_[0]->faults(); + auto faults = levelRockFaultFactories_[0]->faults(); for (size_t j=0; j<faults.size(); j++) { interfaceNetwork_->addInterface(faults[j]); } @@ -721,7 +737,7 @@ public: levelResolutions_[i] = std::pow(2, coarseResolution_+i); //generate faults on level - levelRockFaultFactories_[i] = std::make_shared<LevelRockFaultFactory<GridType>>(grid_, i, levelResolutions_[i], *levelRockFaultFactories_[i-1], (i==1)*0.5); + levelRockFaultFactories_[i] = std::make_shared<LevelRockFaultFactory<GridType>>(grid_, i, levelResolutions_[i], levelRockFaultFactories_[i-1].get(), (i==1)*0.5 + (i>1)*1.0); levelRockFaultFactories_[i]->build(interfaceNetwork_->getInterfaceNetworkDofs(i)); faults = levelRockFaultFactories_[i]->faults(); diff --git a/src/cantorfaultnetworks/results/sparse/plot.tex b/src/cantorfaultnetworks/results/sparse/plot.tex index 5c038a7..6633d7c 100644 --- a/src/cantorfaultnetworks/results/sparse/plot.tex +++ b/src/cantorfaultnetworks/results/sparse/plot.tex @@ -4,25 +4,22 @@ \begin{document} - - \begin{figure} - \def\scale{5} - \input{levelinterfacenetwork_0.tikz} - \end{figure} - - \begin{figure} - \def\scale{5} - \input{levelinterfacenetwork_2.tikz} - \end{figure} - - \begin{figure} - \def\scale{5} - \input{levelinterfacenetwork_4.tikz} - \end{figure} - -% \begin{figure} -% \def\scale{5} -% \input{levelinterfacenetwork_6.tikz} -% \end{figure} - + \def\scale{6} + \begin{minipage}[t]{0.45\linewidth} + \flushleft + \input{levelinterfacenetwork_0.tikz}\\ + \vspace{2em} + \input{levelinterfacenetwork_1.tikz}\\ + \vspace{2em} + \input{levelinterfacenetwork_2.tikz}\\ + \vfill + \end{minipage} + \hspace{3em} + \begin{minipage}[t]{0.45\linewidth} + \flushright + \input{levelinterfacenetwork_3.tikz}\\ + \vspace{2em} + %\input{levelinterfacenetwork_4.tikz} + \vfill + \end{minipage} \end{document} \ No newline at end of file diff --git a/src/cantorfaultnetworks/sparsecantorfaultnetwork.cc b/src/cantorfaultnetworks/sparsecantorfaultnetwork.cc index e32efc7..9297708 100644 --- a/src/cantorfaultnetworks/sparsecantorfaultnetwork.cc +++ b/src/cantorfaultnetworks/sparsecantorfaultnetwork.cc @@ -152,11 +152,15 @@ int main(int argc, char** argv) { try const int exactLevelIdx = 2*(maxCantorLevel - minCantorLevel); // build multilevel cantor fault network - SparseCantorFaultFactory<GridType> faultFactory(minCantorLevel, maxCantorLevel); + //SparseCantorFaultFactory<GridType> faultFactory(minCantorLevel, maxCantorLevel); + //const auto& interfaceNetwork = faultFactory.interfaceNetwork(); + + std::srand(5); + RockFaultFactory<GridType> faultFactory(5, 1); const auto& interfaceNetwork = faultFactory.interfaceNetwork(); if (problemCount==0) { - std::vector<int> writeLevels {0, 2}; + std::vector<int> writeLevels {0, 1, 2}; for (size_t i=0; i<writeLevels.size(); i++) { int writeLevel = writeLevels[i]; bool writeGrid = !(writeLevel==8); -- GitLab