diff --git a/dune/faultnetworks/faultfactories/CMakeLists.txt b/dune/faultnetworks/faultfactories/CMakeLists.txt index b1baf5e789515893ec4ae134d84a4ca65d83911e..998ed92d5aba3ad6cd6d299bdabc29cc1be55150 100644 --- a/dune/faultnetworks/faultfactories/CMakeLists.txt +++ b/dune/faultnetworks/faultfactories/CMakeLists.txt @@ -4,6 +4,7 @@ add_custom_target(faultnetworks_faultfactories_src SOURCES geofaultfactory.hh cantorconvergencefaultfactory.hh cantorfaultfactory.hh + rockfaultfactory.hh sparsecantorfaultfactory.hh ) @@ -12,5 +13,6 @@ install(FILES geofaultfactory.hh cantorconvergencefaultfactory.hh cantorfaultfactory.hh + rockfaultfactory.hh sparsecantorfaultfactory.hh DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/dune/faultnetworks/faultfactories) diff --git a/dune/faultnetworks/faultfactories/rockfaultfactory.hh b/dune/faultnetworks/faultfactories/rockfaultfactory.hh new file mode 100644 index 0000000000000000000000000000000000000000..e8f216e60b7295bc40f132fe125c9f5a7d3efcad --- /dev/null +++ b/dune/faultnetworks/faultfactories/rockfaultfactory.hh @@ -0,0 +1,617 @@ +#ifndef ROCK_FAULT_FACTORY_HH +#define ROCK_FAULT_FACTORY_HH + +#include <math.h> +#include <queue> + +#include <dune/faultnetworks/facehierarchy.hh> +#include <dune/faultnetworks/utils/debugutils.hh> +#include <dune/faultnetworks/faultfactories/oscunitcube.hh> +#include <dune/faultnetworks/levelinterfacenetwork.hh> +#include <dune/faultnetworks/interfacenetwork.hh> +#include <dune/faultnetworks/faultinterface.hh> +#include <dune/faultnetworks/hierarchicleveliterator.hh> + +#include <dune/grid/common/mcmgmapper.hh> +#include <dune/grid/io/file/vtk/vtkwriter.hh> +#include <dune/grid/uggrid.hh> + +#include <dune/fufem/boundarypatch.hh> +#include <dune/fufem/boundaryiterator.hh> + +template<class ctype = double> class Rock { +protected: + int level_; + + // vertex IDs + int left_; + int right_; + int top_; + int bottom_; + + Dune::FieldVector<ctype, 2> center_; +public: + void set(int level, int left, int right, int top, int bottom, const Dune::FieldVector<ctype, 2>& center) { + level_ = level; + + left_ = left; + right_ = right; + top_ = top; + bottom_ = bottom; + + center_ = center; + } + + auto level() const { + return level_; + } + + auto left() const { + return left_; + } + + auto right() const { + return right_; + } + + auto top() const { + return top_; + } + + auto bottom() const { + return bottom_; + } + + const auto& center() { + return center_; + } +}; + + +template <class GridType> +class LevelRockFaultFactory +{ + //! Parameter for mapper class + template<int dim> + struct FaceMapperLayout + { + bool contains (Dune::GeometryType gt) + { + return gt.dim() == dim-1; + } + }; + +protected: + static const int dimworld = GridType::dimensionworld; + static const int dim = GridType::dimension; + using ctype = typename GridType::ctype; + + using Coords = typename Dune::FieldVector<ctype, dimworld>; + using GV = typename GridType::LevelGridView; + using Intersection = typename GridType::LevelIntersection; + + using Element = typename GridType::template Codim<0>::Entity; + static const int dimElement = Element::dimension; + + using FaceMapper = typename Dune::MultipleCodimMultipleGeomTypeMapper<GV, FaceMapperLayout >; + + + using Rock = Rock<ctype>; + + const std::shared_ptr<GridType> grid_; + const int level_; + const ctype resolution_; + const GV gridView_; + const double maxAngle_; + + const typename GV::IndexSet& indexSet_; + + FaceMapper faceMapper_; + + std::vector<Intersection> faces_; + std::vector<Coords> vertexPositions_; + std::vector<std::vector<size_t>> vertexToFaces_; + std::vector<int> coarseToLevelVertex_; + + const LevelRockFaultFactory& coarseLevelFactory_; + std::vector<Rock> rocks_; + std::vector<std::shared_ptr<FaultInterface<GV>>>& faults_; + +private: + template <typename T> int sgn(T val) { + return (T(0) < val) - (val < T(0)); + } + + bool intersectionAllowed(const size_t faceID, const size_t vertexID, + const std::array<size_t, 2>& centerIDs, + const std::set<int>& separatingIDs, const std::set<size_t>& faultDofs, + const Coords& direction, size_t dim) const { + + const auto& intersection = faces_[faceID]; + + //check if "back" edge, cannot deviate from desiredOrientation more than maxAngle degrees (radian) + auto orientation = intersection.geometry().center(); + orientation -= vertexPositions_[vertexID]; + orientation /= orientation.two_norm(); + + if (std::acos(direction*orientation) > maxAngle_) + return false; + + // check if intersection has separating dofs or other fault dofs + std::set<size_t> intersectionDofs; + computeIntersectionDofs(indexSet_, intersection, intersectionDofs); + intersectionDofs.erase(vertexID); + + 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)}; + + bool centerPassed = (sgn(direction[dim])>0) ? (centerIDs[dim]<IDs[dim]) : (centerIDs[dim]>IDs[dim]); + if (faultDofs.count(isDof) or separatingIDs.count(IDs[otherDim]) or centerPassed) { + return false; + } + } + + return true; + } + + /* + ctype distance(const Intersection& isec, const Dune::FieldVector<ctype, dimworld> & vertex) const { + Dune::FieldVector<ctype, dimworld> vec(vertex); + vec += isec.center(); + + return isec.unitOuterNormal()*vec; + }*/ + + //works only in 2D, vertex(1) = vertex(0) - yid, intersection of line (given by vertex and derivative 1) with y axis + int computeID(const Coords& vertex, int dim) const { + return (int) (vertex[dim]*resolution_); + } + + void computeIntersectionDofs(const Intersection& intersection, std::set<size_t>& intersectionDofs) const { + intersectionDofs.clear(); + + // loop over all vertices of the intersection + const auto& insideElement = intersection.inside(); + const auto& refElement = Dune::ReferenceElements<double,dimElement>::general(insideElement.type()); + + for (int i=0; i<refElement.size(intersection.indexInInside(), 1, dimElement); i++) { + size_t idxInElement = refElement.subEntity(intersection.indexInInside(), 1, i, dimElement); + size_t globalIdx = indexSet_.subIndex(insideElement, idxInElement, dimElement); + + intersectionDofs.insert(globalIdx); + } + } + + bool isTargetBoundaryVertex(size_t vertexIdx, const std::array<size_t, 2>& targetIDs) const { + const auto& vertex = vertexPositions_[vertexIdx]; + const std::array<size_t, 2> vertexIDs = {computeID(vertex, 0), computeID(vertex, 1)}; + return (vertexIDs[0] == targetIDs[0]) and (vertexIDs[1] == targetIDs[1]); + } + + typedef std::vector<double>::const_iterator ConstVectorIterator; + + struct ordering { + bool operator ()(std::pair<size_t, ConstVectorIterator> const& a, std::pair<size_t, ConstVectorIterator> const& b) { + return *(a.second) < *(b.second); + } + }; + + void distanceSort(std::vector<size_t>& admissibleFaces, std::vector<double>& distances) const { + std::vector<std::pair<size_t, ConstVectorIterator>> order(distances.size()); + + size_t j = 0; + ConstVectorIterator it = distances.begin(); + ConstVectorIterator itEnd = distances.end(); + for (; it != itEnd; ++it, ++j) + order[j] = std::make_pair(j, it); + + sort(order.begin(), order.end(), ordering()); + + std::vector<size_t> initialAdmissibleFaces(admissibleFaces); + for (size_t i=0; i<admissibleFaces.size(); i++) + admissibleFaces[i] = initialAdmissibleFaces[order[i].first]; + } + + /* void generateFaultSeeds(std::vector<FaultCorridor>& faultCorridors, std::vector<std::vector<size_t>>& faultSeeds) { + + //std::cout << "LevelGeoFaultFactory::generateFaultSeeds() " << std::endl; + //std::cout << "------------------------------------- " << std::endl << std::endl; + + faultSeeds.resize(faultCorridors.size()); + + std::map<int, std::pair<size_t,size_t>> yIDtoFaultCorridor; + for (size_t i=0; i<faultCorridors.size(); i++){ + FaultCorridor& faultCorridor = faultCorridors[i]; + const std::vector<int> & faultYs = faultCorridor.faultYs(); + + faultSeeds[i].resize(faultYs.size()); + for (size_t j=0; j<faultYs.size(); j++) { + yIDtoFaultCorridor[faultYs[j]] = std::make_pair(i, j); + } + } + + BoundaryIterator<GV> bIt(gridView_, BoundaryIterator<GV>::begin); + BoundaryIterator<GV> bEnd(gridView_, BoundaryIterator<GV>::end); + for(; bIt!=bEnd; ++bIt) { + + const Element& insideElement = bIt->inside(); + const auto& geometry = insideElement.geometry(); + + // neglect "upper" part of boundary, where (y==1 and x>0) or (y>0 and x==1) + const auto& center = bIt->geometry().center(); + if (center[0] + center[1] >1) + continue; + + const auto& refElement = Dune::ReferenceElements<double,dimElement>::general(insideElement.type()); + + for (int i=0; i<refElement.size(bIt->indexInInside(), 1, dimElement); i++) { + size_t idxInElement = refElement.subEntity(bIt->indexInInside(), 1, i, dimElement); + size_t globalIdx = indexSet_.subIndex(insideElement, idxInElement, dimElement); + + const auto& vertex = geometry.corner(idxInElement); + + const int yID = computeYID(vertex); + + if (yIDtoFaultCorridor.count(yID)) { + const std::pair<size_t, size_t>& indices = yIDtoFaultCorridor[yID]; + faultSeeds[indices.first][indices.second] = globalIdx; + } + } + } + + //std::cout << "------------------------------------- " << std::endl << std::endl; + }*/ + + + void generateFault(std::shared_ptr<FaultInterface<GV>> fault, const size_t faultSeedIdx, const Coords& center, + const size_t corridor, + const std::set<size_t>& constSeparatingDofs) { + //std::cout << "LevelGeoFaultFactory::generateFault() " << std::endl; + //std::cout << "------------------------------------- " << std::endl << std::endl; + + bool success = false; + + std::set<size_t> separatingDofs = constSeparatingDofs; + + auto direction = center; + direction -= vertexPositions_[faultSeedIdx]; + direction /= direction.two_norm(); + + size_t dim = 0; + if (std::abs(direction[0]) < std::abs(direction[1])) { + dim = 1; + } + + const std::array<size_t, 2> centerIDs = {computeID(center, 0), computeID(center, 1)}; + + std::set<size_t> separatingIDs; + + auto faultSeedID = computeID(vertexPositions_[faultSeedIdx], dim); + separatingIDs.insert(faultSeedID + corridor); + separatingIDs.insert(faultSeedID - corridor); + + std::vector<size_t> faultDofs(0); + faultDofs.push_back(faultSeedIdx); + + std::vector<size_t> faultFaces; + + std::map<size_t, std::vector<size_t>> vertexToAdmissibleFaces; + + std::queue<size_t> vertexQueue; + vertexQueue.push(faultSeedIdx); + + while (!vertexQueue.empty()) { + const size_t vertexID = vertexQueue.front(); + vertexQueue.pop(); + + if (isTargetBoundaryVertex(vertexID, centerIDs)) { + success = true; + break; + } + + if (vertexToAdmissibleFaces.count(vertexID)==0) { + const std::vector<size_t>& faces = vertexToFaces_[vertexID]; + std::vector<size_t> admissibleFaces; + + for (size_t i=0; i<faces.size(); i++) { + if (intersectionAllowed(faces[i], vertexID, centerIDs, separatingDofs, separatingIDs, faultDofs, direction, dim)) { + admissibleFaces.push_back(faces[i]); + } + } + + std::vector<double> distances(admissibleFaces.size(), 0); + for (size_t i=0; i<admissibleFaces.size(); i++) { + Coords vec(center); + vec -= faces_[admissibleFaces[i]].geometry().center(); + distances[i] = vec.two_norm(); + } + distanceSort(admissibleFaces, distances); + + vertexToAdmissibleFaces[vertexID] = admissibleFaces; + } + + std::vector<size_t>& suitableFaces = vertexToAdmissibleFaces[vertexID]; + + if (suitableFaces.size()==0) { + faultDofs.pop_back(); + faultFaces.pop_back(); + vertexToAdmissibleFaces.erase(vertexID); + + separatingDofs.insert(vertexID); + vertexQueue.push(faultDofs.back()); + } else { + + // generate random number from (0,1) + double randomNumber = ((double) std::rand() / (RAND_MAX)); + + size_t randSelector = (size_t) std::abs(std::log2(randomNumber)); + if (randSelector >= suitableFaces.size()) { + randSelector = suitableFaces.size() -1; + } + + size_t nextFaceID = suitableFaces[randSelector]; + + suitableFaces.erase(suitableFaces.begin()+randSelector); + + std::set<size_t> nextFaceDofs; + computeIntersectionDofs(indexSet_, faces_[nextFaceID], nextFaceDofs); + nextFaceDofs.erase(vertexID); + + faultDofs.push_back(*nextFaceDofs.begin()); + faultFaces.push_back(nextFaceID); + + size_t nextVertexID = *(nextFaceDofs.begin()); + vertexQueue.push(nextVertexID); + } + } + + if (!success) { + std::cout << "Generating a fault failed: Unable to reach target boundary! This should not happend!" << std::endl; + DUNE_THROW(Dune::Exception, "Generating a fault failed: Unable to reach target boundary!"); + } + + for (size_t i=0; i<faultFaces.size(); i++) { + fault->addFace(faces_[faultFaces[i]]); + } + + //std::cout << "------------------------------------- " << std::endl << std::endl; + } + + void prolong(const Rock& rock, Rock& newRock) { + auto newLeft = coarseToLevelVertex_[rock.left()]; + auto newRight = coarseToLevelVertex_[rock.right()]; + auto newTop = coarseToLevelVertex_[rock.top()]; + auto newBottom = coarseToLevelVertex_[rock.bottom()]; + + newRock.set(rock.level(), newLeft, newRight, newTop, newBottom, rock.center()); + } + + bool randomSplit(const Rock& rock) { + const auto& center = rock.center(); + + double res = 0.0; + if (center[0] < center[1]) { + res = 100.0*(1.0 - center[0]); + } else { + res = 100.0*(1.0 - center[1]); + } + + double prob = (100.0 * std::rand() / (RAND_MAX + 1.0)) + 1; + return res > prob; + } + + void split(const Rock& rock, const std::set<size_t>& separatingDofs) { + Rock newRock; + prolong(rock, newRock); + + bool toBeSplit = (rock.level() == level_-1) and randomSplit(rock); + if (!toBeSplit) { + rocks_.push_back(newRock); + } else { + // split rock into 4 subparts by two new intersecting faults + std::shared_ptr<FaultInterface<GV>> xFault = std::make_shared<FaultInterface<GV>>(gridView_, level_); + generateFault(xFault, newRock, separatingDofs, 0); + faults_.push_back(xFault); + + std::shared_ptr<FaultInterface<GV>> yFault = std::make_shared<FaultInterface<GV>>(gridView_, level_); + generateFault(yFault, newRock, separatingDofs, 1); + faults_.push_back(yFault); + } + } + + public: + LevelRockFaultFactory(const std::shared_ptr<GridType> grid, const int level, const ctype resolution) : + grid_(grid), + level_(level), + resolution_(resolution), + gridView_(grid_->levelGridView(level_)), + indexSet_(gridView_.indexSet()), + faceMapper_(gridView_) + { + // init faces_, vertexPositions_, vertexToFaces_ + faces_.resize(faceMapper_.size()); + vertexPositions_.resize(gridView_.size(dim)); + vertexToFaces_.resize(gridView_.size(dim)); + coarseToLevelVertex_.resize(coarseLevelFactory_.gridView().size(dim)); + + std::vector<bool> faceHandled(faceMapper_.size(), false); + + for (const auto& elem:elements(gridView_)) { + for (const auto& isect:intersections(gridView_, elem)) { + //const size_t faceID = faceMapper_.index(isect); + + const int faceID = faceMapper_.subIndex(elem, isect.indexInInside(), 1); + + if (isect.boundary()) + continue; + + if (faceHandled[faceID]) + continue; + + faceHandled[faceID] = true; + faces_[faceID] = isect; + + const auto& refElement = Dune::ReferenceElements<double,dimElement>::general(elem.type()); + + for (int i=0; i<refElement.size(isect.indexInInside(), 1, dimElement); i++) { + //size_t vertexID = idxSet.subIndex(elem.subEntity<1>(isect), i, dimElement); + + size_t idxInElement = refElement.subEntity(isect.indexInInside(), 1, i, dimElement); + const size_t vertexID = indexSet_.subIndex(elem, idxInElement, dimElement); + + vertexPositions_[vertexID] = elem.geometry().corner(idxInElement); + vertexToFaces_[vertexID].push_back(faceID); + } + } + } + + for (const auto& vertex : vertices(gridView_)) { + size_t coarseVertexID; + bool isCoarseVertex = coarseLevelFactory_.indexSet().index(vertex, coarseVertexID); + + if (isCoarseVertex) { + coarseToLevelVertex_[coarseVertexID] = indexSet_.index(vertex); + } + } + } + + void build(const std::set<size_t>& separatingDofs) { + faults_.resize(0); + const auto& coarseRocks = coarseLevelFactory_.rocks(); + + for (size_t i=0; i<coarseRocks.size(); i++) { + split(coarseRocks[i], separatingDofs); + } + } + + const auto& indexSet() const { + return indexSet_; + } + + const auto& rocks() const { + return rocks_; + } +}; + +template <class GridType> +class RockFaultFactory { + +private: + const int coarseResolution_; + const size_t maxLevel_; + const int coarseGridN_; + + std::vector<double> levelResolutions_; + + std::shared_ptr<GridType> grid_; + std::shared_ptr<InterfaceNetwork<GridType>> interfaceNetwork_; + + std::vector<std::shared_ptr<LevelRockFaultFactory<GridType>>> levelRockFaultFactories_; + +/*typename std::enable_if<!std::numeric_limits<ctype>::is_integer, bool>::type + almost_equal(ctype x, ctype y, int ulp) const + { + return std::abs(x-y) < std::numeric_limits<ctype>::epsilon() * std::abs(x+y) * ulp + || std::abs(x-y) < std::numeric_limits<ctype>::min(); + } + + + +bool isSeparatingIntersection(const Intersection& intersection, const std::set<int>& separatingYIDs) const { + Dune::FieldVector<ctype, dimworld> faceCenter = intersection.geometry().center(); + + ctype yID = faceCenter[1]*coarseGridN_; + ctype intpart; + + if (almost_equal(std::modf(yID, &intpart), 0.0, 2)) { + std::set<int>::iterator it = separatingYIDs.find((int) intpart); + if (it!=separatingYIDs.end()) + return true; + else + return false; + } else + return false; +}*/ + + +public: + //setup + RockFaultFactory(const int coarseResolution, const size_t maxLevel, const double maxAngle = 2) : + coarseResolution_(coarseResolution), + maxLevel_(maxLevel), + coarseGridN_(std::pow(2, coarseResolution_)), + interfaceNetwork_(nullptr) + { + using GridOb = OscUnitCube<GridType, 2>; + using GV = typename GridType::LevelGridView; + + Dune::UGGrid<GridType::dimension>::setDefaultHeapSize(4000); + GridOb unitCube(coarseGridN_); + grid_ = unitCube.grid(); + grid_->globalRefine(maxLevel_); + + levelResolutions_.resize(maxLevel_+1); + levelRockFaultFactories_.resize(maxLevel_+1); + + // init interface network + interfaceNetwork_ = std::make_shared<InterfaceNetwork<GridType>>(*grid_); + + for (size_t i=0; i<=maxLevel_; i++) { + std::vector<std::shared_ptr<FaultInterface<GV>>> faults; + + levelResolutions_[i] = std::pow(2, coarseResolution_+i); + + //generate faults on level + levelRockFaultFactories_[i] = std::make_shared<LevelRockFaultFactory<GridType>>(grid_, i, levelResolutions_[i]); + levelRockFaultFactories_[i]->build(faults, maxAngle); + + for (size_t j=0; j<faults.size(); j++) { + interfaceNetwork_->addInterface(faults[j]); + } + + if (i==maxLevel_) + continue; + + interfaceNetwork_->prolongLevel(i, i+1); + } + } + + /* + void prolongToAll() { + // prolong all faults to all subsequent levels + for (int i=maxLevel_-1; i>=0; i--) { + if (interfaceNetwork_->size(i)>0) { + std::set<int> toLevels; + for (size_t j=i+1; j<=maxLevel_; j++) { + toLevels.insert(j); + } + + interfaceNetwork_->prolongLevelInterfaces(i, toLevels); + } + } + interfaceNetwork_->build(); + }*/ + + /*void prolongToAll() { + // prolong all faults to all subsequent levels + for (int i=interfaceNetwork_->size()-1; i>=0; i--) { + interfaceNetwork_->prolongLevelInterfaces(i, maxLevel_); + } + interfaceNetwork_->build(); + }*/ + + const GridType& grid() const { + return *grid_; + } + + /*const InterfaceNetwork<GridType>& interfaceNetwork() { + return *interfaceNetwork_; + }*/ + + InterfaceNetwork<GridType>& interfaceNetwork() { + return *interfaceNetwork_; + } +}; +#endif diff --git a/dune/faultnetworks/localproblem.hh b/dune/faultnetworks/localproblem.hh index 5f115f88ad1ef2f3491def2eaf5d653b24c9c984..b4af08e91fa2108a7d5c62109b816465570a81a1 100644 --- a/dune/faultnetworks/localproblem.hh +++ b/dune/faultnetworks/localproblem.hh @@ -147,6 +147,10 @@ public: void updateLocalRhs(const RangeType& rhs){ localRhs = rhs; + /*for (size_t i=0; i<localRhs.size(); i++) { + if (!boundaryDofs_[i][0]) + localRhs[i] = rhs[i]; + }*/ } void updateRhsAndBoundary(const RangeType& rhs, const RangeType& boundary) { @@ -160,6 +164,8 @@ public: } void solve(DomainType& x){ + //print(boundaryDofs_, "boundaryDofs:"); + #if HAVE_UMFPACK RangeType localRhsCopy(localRhs); Dune::InverseOperatorResult res; diff --git a/dune/faultnetworks/preconditioners/levelpatchpreconditioner.hh b/dune/faultnetworks/preconditioners/levelpatchpreconditioner.hh index c43f777356a033483741e47b55076aeef54081d8..c9fb33fdb8fce847ece8f595310aa741c60733e6 100644 --- a/dune/faultnetworks/preconditioners/levelpatchpreconditioner.hh +++ b/dune/faultnetworks/preconditioners/levelpatchpreconditioner.hh @@ -182,19 +182,46 @@ private: auto& localProblem = *localProblems_[i]; - VectorType v; + VectorType v, v1, v2, v3; localProblem.restrict(*(this->x_), v); - VectorType r; - localProblem.restrict(*(this->rhs_), r); - Dune::MatrixVector::subtractProduct(r, localProblem.getLocalMat(), v); - localProblem.updateLocalRhs(r); + v1.resize(localProblem.getLocalMat().N()); + localProblem.getLocalMat().mv(v, v1); + v3.resize(matrix_.N()); + matrix_.mv(*(this->x_), v3); + localProblem.restrict(v3, v2); + + //print(v1, "v1"); + //print(v2, "v2"); + + VectorType r1; + localProblem.restrict(*(this->rhs_), r1); + Dune::MatrixVector::subtractProduct(r1, localProblem.getLocalMat(), v); + + /*localProblem.updateLocalRhs(r); VectorType x; localProblem.solve(x); v += x; - localProblem.updateVector(v, *(this->x_)); + localProblem.updateVector(v, *(this->x_));*/ + + VectorType localR; + VectorType r = *(this->rhs_); + Dune::MatrixVector::subtractProduct(r, matrix_, *(this->x_)); + localProblem.restrict(r, localR); + + // print(r1, "r1"); + // print(localR, "localR"); + + localProblem.updateLocalRhs(localR); + + VectorType x; + localProblem.solve(x); + + //VectorType v; + localProblem.prolong(x, v); + *(this->x_) += v; } }; diff --git a/src/cantorfaultnetworks/cantorfaultnetwork.cc b/src/cantorfaultnetworks/cantorfaultnetwork.cc index 1dd5701b135cfe3df444a169319826a0a22c9ef7..e2ed377d029c7229d6f8ff5125a8c3b088b26ecf 100644 --- a/src/cantorfaultnetworks/cantorfaultnetwork.cc +++ b/src/cantorfaultnetworks/cantorfaultnetwork.cc @@ -60,6 +60,8 @@ #include <dune/faultnetworks/faultfactories/cantorfaultfactory.hh> +#include <dune/solvers/solvers/loopsolver.hh> + int main(int argc, char** argv) { try { MPIHelper::instance(argc, argv); @@ -86,7 +88,7 @@ int main(int argc, char** argv) { try typedef OscLocalAssembler<GridType, DGFE, DGFE> LocalOscAssembler; typedef IntersectionJumpMassAssembler<GV, DGFE, DGFE> LocalInterfaceAssembler; - + // parse parameter file ParameterTree parameterSet; if (argc==2) @@ -110,7 +112,6 @@ int main(int argc, char** argv) { try const int minCantorResolution = problemParameters.get<int>("minCantorResolution"); const double c = problemParameters.get<double>("penaltyFactor"); - const int patchDepth = problemParameters.get<int>("patchDepth"); const int maxIterations = problemParameters.get<int>("maxIterations"); const double solverTolerance = problemParameters.get<double>("tol"); @@ -331,13 +332,23 @@ int main(int argc, char** argv) { try DGMGTransfer<DGBasis> discMGTransfer(*fineBasis, *exactBasis); // solve - OscCGSolver<MatrixType, VectorType, DGBasis> + /*OscCGSolver<MatrixType, VectorType, DGBasis> solver(*fineBasis, &fineGlobalAssembler.matrix(), &initialX, &rhs, &preconditioner, maxIterations, solverTolerance, &exactEnergyNorm, - Solver::FULL, &exactSol, &fineSol, discMGTransfer, 1.0, true); //((oscGridN+0.0)/fineGridN) + Solver::FULL, &exactSol, &fineSol, discMGTransfer, 1.0, true); //((oscGridN+0.0)/fineGridN) */ + + + //solver.historyBuffer_ = resultPath + "solutions/level_" + std::to_string(fineResolution) + ".vec"; + + VectorType x = initialX; + preconditioner.setProblem(fineGlobalAssembler.matrix(), x, rhs); - solver.historyBuffer_ = resultPath + "solutions/level_" + std::to_string(fineResolution) + ".vec"; + Dune::Solvers::LoopSolver<VectorType> + solver (preconditioner, maxIterations, solverTolerance, + fineEnergyNorm, + Solver::FULL, + true, &fineSol); solver.check(); solver.preprocess(); diff --git a/src/cantorfaultnetworks/cantorfaultnetwork.parset b/src/cantorfaultnetworks/cantorfaultnetwork.parset index 0d8411bb631bf9e36af423302f000bd1d9312dc8..fe8182cf83ad0868dc2354c936de20b271a04bac 100644 --- a/src/cantorfaultnetworks/cantorfaultnetwork.parset +++ b/src/cantorfaultnetworks/cantorfaultnetwork.parset @@ -1,6 +1,11 @@ path = ../data/ resultPath = ../cantorfaultnetworks/results/ +[preconditioner] +patch = SUPPORT # CELL , SUPPORT +mode = MULTIPLICATIVE # ADDITIVE , MULTIPLICATIVE +multDirection = SYMMETRIC # SYMMETRIC , FORWARD , BACKWARD +patchDepth = 1 ########################################### @@ -10,88 +15,10 @@ oscDataFile = oscDataLaplace32.mat # level resolution in 2^(-...) coarseResolution = 0 fineResolution = 5 -exactResolution = 10 -minCantorResolution = 0 - -penaltyFactor = 1 -patchDepth = 1 - -# cg solver -nestedIteration = 0 -tol = 1e-12 -maxIterations = 8 - -########################################### - -[problem1] -oscDataFile = oscDataLaplace32.mat - -# level resolution in 2^(-...) -coarseResolution = 0 -fineResolution = 6 -exactResolution = 10 +exactResolution = 8 minCantorResolution = 0 penaltyFactor = 1 -patchDepth = 1 - -# cg solver -nestedIteration = 0 -tol = 1e-12 -maxIterations = 8 - -########################################### - -[problem2] -oscDataFile = oscDataLaplace32.mat - -# level resolution in 2^(-...) -coarseResolution = 0 -fineResolution = 7 -exactResolution = 10 -minCantorResolution = 0 - -penaltyFactor = 1 -patchDepth = 1 - -# cg solver -nestedIteration = 0 -tol = 1e-12 -maxIterations = 8 - -########################################### - -[problem3] -oscDataFile = oscDataLaplace32.mat - -# level resolution in 2^(-...) -coarseResolution = 0 -fineResolution = 8 -exactResolution = 10 -minCantorResolution = 0 - -penaltyFactor = 1 -patchDepth = 1 - -# cg solver -nestedIteration = 0 -tol = 1e-12 -maxIterations = 8 - -########################################### - - -[problem4] -oscDataFile = oscDataLaplace32.mat - -# level resolution in 2^(-...) -coarseResolution = 0 -fineResolution = 9 -exactResolution = 10 -minCantorResolution = 0 - -penaltyFactor = 1 -patchDepth = 1 # cg solver nestedIteration = 0 diff --git a/src/cantorfaultnetworks/sparsecantorfaultnetwork.cc b/src/cantorfaultnetworks/sparsecantorfaultnetwork.cc index c0918ab598da0701b34eb5ef4f91a428f0692685..e32efc7b023c37e50fd6ea495fb2872c0a37d500 100644 --- a/src/cantorfaultnetworks/sparsecantorfaultnetwork.cc +++ b/src/cantorfaultnetworks/sparsecantorfaultnetwork.cc @@ -59,6 +59,9 @@ #include <dune/faultnetworks/dgmgtransfer.hh> #include <dune/faultnetworks/faultfactories/sparsecantorfaultfactory.hh> +#include <dune/faultnetworks/faultfactories/rockfaultfactory.hh> + +#include <dune/solvers/solvers/loopsolver.hh> int main(int argc, char** argv) { try { @@ -332,6 +335,15 @@ int main(int argc, char** argv) { try maxIterations, solverTolerance, &exactEnergyNorm, Solver::FULL, &exactSol, &fineSol, discMGTransfer, 1.0, true); //((oscGridN+0.0)/fineGridN) + /* VectorType x = initialX; + preconditioner.setProblem(fineGlobalAssembler.matrix(), x, rhs); + + Dune::Solvers::LoopSolver<VectorType> + solver (preconditioner, maxIterations, solverTolerance, + fineEnergyNorm, + Solver::FULL, + true, &fineSol);*/ + //solver.historyBuffer_ = resultPath + "solutions/level_" + std::to_string(fineCantorLevel) + ".vec"; diff --git a/src/cantorfaultnetworks/sparsecantorfaultnetwork.parset b/src/cantorfaultnetworks/sparsecantorfaultnetwork.parset index 3b3ea31b5fe0c7cd57ccaad38502e50f9d5090bb..456c5bfc2935601ddc4e07e80fd4070fd2f9aff7 100644 --- a/src/cantorfaultnetworks/sparsecantorfaultnetwork.parset +++ b/src/cantorfaultnetworks/sparsecantorfaultnetwork.parset @@ -2,7 +2,7 @@ path = ../data/ resultPath = ../cantorfaultnetworks/results/sparse/ [preconditioner] -patch = CELL # CELL , SUPPORT +patch = SUPPORT # CELL , SUPPORT mode = MULTIPLICATIVE # ADDITIVE , MULTIPLICATIVE multDirection = SYMMETRIC # SYMMETRIC , FORWARD , BACKWARD patchDepth = 1 @@ -13,9 +13,9 @@ patchDepth = 1 oscDataFile = oscDataLaplace4.mat # level resolution in 2^(-...) -coarseCantorLevel = 2 -fineCantorLevel = 3 -maxCantorLevel = 4 +coarseCantorLevel = 1 +fineCantorLevel = 2 +maxCantorLevel = 3 penaltyFactor = 1