From 37e6bf9abb791ecb12acb857f791fa34430ab682 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20H=C3=B6rl?= <maximilian.hoerl@mathematik.uni-stuttgart.de> Date: Fri, 12 Jun 2020 21:58:14 +0200 Subject: [PATCH] add enum SolverType, add parameters solver, dmin, dmax --- dune/mmdg/dg.hh | 33 +++++++++++++++++++++------ dune/mmdg/mmdg.hh | 24 +++++++++++++++----- dune/mmdg/solvertype.hh | 5 +++++ src/dg.cc | 43 +++++++++++++++++++++++++++++++++-- src/mmdg.cc | 50 +++++++++++++++++++++++++++++++---------- src/parameterDG.ini | 5 +++-- src/parameterMMDG.ini | 6 +++-- 7 files changed, 136 insertions(+), 30 deletions(-) create mode 100644 dune/mmdg/solvertype.hh diff --git a/dune/mmdg/dg.hh b/dune/mmdg/dg.hh index 623c825..cdc3287 100644 --- a/dune/mmdg/dg.hh +++ b/dune/mmdg/dg.hh @@ -14,9 +14,11 @@ #include <dune/istl/bcrsmatrix.hh> #include <dune/istl/solver.hh> #include <dune/istl/cholmod.hh> +#include <dune/istl/umfpack.hh> #include <dune/mmdg/nonconformingp1vtkfunction.hh> #include <dune/mmdg/eigenvaluehelper.hh> +#include <dune/mmdg/solvertype.hh> template<class GridView, class Mapper, class Problem> class DG @@ -40,9 +42,10 @@ public: using QRulesEdge = Dune::QuadratureRules<Scalar, dim-1>; //constructor - DG (const GridView& gridView, const Mapper& mapper, const Problem& problem) : + DG (const GridView& gridView, const Mapper& mapper, const Problem& problem, + const SolverType& solver) : gridView_(gridView), mapper_(mapper), problem_(problem), - dof_((1 + dim) * gridView.size(0)) + dof_((1 + dim) * gridView.size(0)), solver_(solver) { //initialize stiffness matrix A, load vector b and solution vector d A = std::make_shared<Matrix>(dof_, dof_, 10, 1, Matrix::implicit); //TODO @@ -57,9 +60,23 @@ public: A->compress(); Dune::InverseOperatorResult result; - Dune::Cholmod<Vector> solver; - solver.setMatrix(*A); - solver.apply(d, b, result); + + if (solver_ == SolverType::Cholmod) + { + Dune::Cholmod<Vector> solver; + solver.setMatrix(*A); + solver.apply(d, b, result); + } + else if (solver_ == SolverType::UMFPack) + { + Dune::UMFPack<Matrix> solver(*A); + solver.apply(d, b, result); + } + else + { + DUNE_THROW(Dune::Exception, "ERROR: Specified solver type not " + "implemented"); + } //write solution to a vtk file writeVTKoutput(); @@ -113,8 +130,9 @@ public: protected: DG (const GridView& gridView, const Mapper& mapper, const Problem& problem, - const int dof) : - gridView_(gridView), mapper_(mapper), problem_(problem), dof_(dof) + const SolverType solver, const int dof) : + gridView_(gridView), mapper_(mapper), problem_(problem), dof_(dof), + solver_(solver) { //initialize stiffness matrix A, load vector b and solution vector d A = std::make_shared<Matrix>(dof_, dof_, 10, 1, Matrix::implicit); //TODO @@ -561,6 +579,7 @@ protected: std::shared_ptr<Matrix> A; //stiffness matrix Vector b; //load vector Vector d; //solution vector + SolverType solver_; //solver type (Cholmod or UMFPack) private: //writes the solution to a vtk file diff --git a/dune/mmdg/mmdg.hh b/dune/mmdg/mmdg.hh index be04ec7..70d6a31 100644 --- a/dune/mmdg/mmdg.hh +++ b/dune/mmdg/mmdg.hh @@ -30,8 +30,8 @@ public: //constructor MMDG (const GridView& gridView, const Mapper& mapper, const InterfaceGridView& iGridView, const InterfaceMapper& iMapper, - const Problem& problem) : - Base(gridView, mapper, problem, + const Problem& problem, const SolverType& solver) : + Base(gridView, mapper, problem, solver, (1 + dim) * gridView.size(0) + dim * iGridView.size(0)), iGridView_(iGridView), iMapper_(iMapper) {} @@ -41,9 +41,23 @@ public: Base::A->compress(); Dune::InverseOperatorResult result; - Dune::Cholmod<Vector> solver; - solver.setMatrix(*Base::A); - solver.apply(Base::d, Base::b, result); + + if (Base::solver_ == SolverType::Cholmod) + { + Dune::Cholmod<Vector> solver; + solver.setMatrix(*Base::A); + solver.apply(Base::d, Base::b, result); + } + else if (Base::solver_ == SolverType::UMFPack) + { + Dune::UMFPack<Matrix> solver(*Base::A); + solver.apply(Base::d, Base::b, result); + } + else + { + DUNE_THROW(Dune::Exception, "ERROR: Specified solver type not " + "implemented"); + } //write solution to a vtk file writeVTKoutput(); diff --git a/dune/mmdg/solvertype.hh b/dune/mmdg/solvertype.hh new file mode 100644 index 0000000..560113e --- /dev/null +++ b/dune/mmdg/solvertype.hh @@ -0,0 +1,5 @@ +enum SolverType +{ + Cholmod, + UMFPack +}; diff --git a/src/dg.cc b/src/dg.cc index 5304bf3..2739fce 100644 --- a/src/dg.cc +++ b/src/dg.cc @@ -25,6 +25,7 @@ #include <dune/mmdg/problems/dgproblem2.hh> #include <dune/mmdg/problems/dgproblem3.hh> #include <dune/mmdg/problems/dgproblem4.hh> +#include <dune/mmdg/problems/dgproblem5.hh> int main(int argc, char** argv) { @@ -101,14 +102,52 @@ int main(int argc, char** argv) "file parameterDG.ini and make sure that they are specified."); } } + else if (pt["problem"] == "dg5") + { + if ( pt.hasKey("dmin") && pt.hasKey("dmax") ) + { + const double dmin = std::stod(pt["dmin"]); + const double dmax = std::stod(pt["dmax"]); + problem = new DGProblem5<Coordinate>(dmin, dmax); + + std::cout << "NOTE: You will not see convergence for problem dg5 as it " + "only fulfills continuity of the normal component of the Darcy " + "velocity with respect to the normal of the hyperplane Gamma = " + "{ x_1 = 0.5 } but not with respect to the normal of the actual " + "interfaces between the bulk and fracture domains. \n\n"; + } + else + { + DUNE_THROW(Dune::Exception, + "Problem dg4 requires the parameters 'dmin' and 'dmax'. Check the " + "file parameterDG.ini and make sure that they are specified."); + } + } else { DUNE_THROW(Dune::Exception, "Invalid problem type or parameter 'problem' not specified in file " - "parameterDG.ini (use 'dg1' to 'dg4')"); + "parameterDG.ini (use 'dg1' to 'dg5')"); + } + + //determine solver type + SolverType solver = SolverType::Cholmod; + + if (pt.hasKey("solver")) + { + if (pt["solver"] == "UMFPack") + { + solver = SolverType::UMFPack; + } + else if (pt["solver"] != "Cholmod") + { + DUNE_THROW(Dune::Exception, + "Invalid solver type (use 'Cholmod' or 'UMFPack' for the parameter " + "'solver' in the file parameterDG.ini)"); + } } - DG dg(gridView, mapper, *problem); + DG dg(gridView, mapper, *problem, solver); dg(mu0); diff --git a/src/mmdg.cc b/src/mmdg.cc index 244d92f..aa8d811 100644 --- a/src/mmdg.cc +++ b/src/mmdg.cc @@ -58,7 +58,7 @@ int main(int argc, char** argv) Dune::ParameterTreeParser::readINITree("parameterMMDG.ini", pt); const double mu0 = std::stod(pt["mu0"]); //penalty parameter (prefactor) - const double aperture = std::stod(pt["d"]); //aperture (prefactor) + const double dmax = std::stod(pt["dmax"]); //maximum aperture double xi; //coupling parameter Problem* problem; //problem to be solved @@ -68,51 +68,60 @@ int main(int argc, char** argv) //determine problem type if (pt["problem"] == "mmdg1") { - problem = new MMDGProblem1<Coordinate>(aperture); + problem = new MMDGProblem1<Coordinate>(dmax); gridType = "mmdg2_C"; xi = 0.75; } else if (pt["problem"] == "mmdg2") { - problem = new MMDGProblem2<Coordinate>(aperture); + problem = new MMDGProblem2<Coordinate>(dmax); gridType = "mmdg2_C"; xi = 0.75; } else if (pt["problem"] == "mmdg3") { - problem = new MMDGProblem3<Coordinate>(aperture); + problem = new MMDGProblem3<Coordinate>(dmax); gridType = "mmdg3_C"; xi = 1.0; } else if (pt["problem"] == "mmdg4") { - problem = new MMDGProblem4<Coordinate>(aperture); + problem = new MMDGProblem4<Coordinate>(dmax); gridType = "mmdg2_C"; xi = 0.75; } else if (pt["problem"] == "mmdg5") { - problem = new MMDGProblem5<Coordinate>(aperture); + problem = new MMDGProblem5<Coordinate>(dmax); gridType = "mmdg5_C"; xi = 0.75; } else if (pt["problem"] == "mmdg6") { xi = (pt.hasKey("xi")) ? std::stod(pt["xi"]) : 1.0; - problem = new MMDGProblem6<Coordinate>(aperture, xi); + problem = new MMDGProblem6<Coordinate>(dmax, xi); gridType = "mmdg2_C"; } else if (pt["problem"] == "mmdg7") { - xi = (pt.hasKey("xi")) ? std::stod(pt["xi"]) : 1.0; - problem = new MMDGProblem7<Coordinate>(aperture, xi); - gridType = "mmdg2_C"; + if (pt.hasKey("dmin")) + { + problem = new MMDGProblem7<Coordinate>(std::stod(pt["dmin"]), dmax); + gridType = "mmdg2_C"; + xi = 0.75; + } + else + { + DUNE_THROW(Dune::Exception, + "Problem dg4 requires the parameter 'dmin'. Check the " + "file parameterMMDG.ini and make sure that it is specified."); + } } else { DUNE_THROW(Dune::Exception, "Invalid problem type or parameter 'problem' not specified in file " - "parameterDG.ini (use 'mmdg1' to 'mmdg6')"); + "parameterDG.ini (use 'mmdg1' to 'mmdg7')"); } if (pt.hasKey("gridfile")) //non-default grid type @@ -125,6 +134,23 @@ int main(int argc, char** argv) xi = std::stod(pt["xi"]); } + //determine solver type + SolverType solver = SolverType::Cholmod; + + if (pt.hasKey("solver")) + { + if (pt["solver"] == "UMFPack") + { + solver = SolverType::UMFPack; + } + else if (pt["solver"] != "Cholmod") + { + DUNE_THROW(Dune::Exception, + "Invalid solver type (use 'Cholmod' or 'UMFPack' for the parameter " + "'solver' in the file parameterDG.ini)"); + } + } + //create a grid from .dgf file GridFactory gridFactory( "grids/" + gridType + "_" + std::to_string(dim) + "d.msh" ); @@ -137,7 +163,7 @@ int main(int argc, char** argv) const Mapper mapper(gridView, Dune::mcmgElementLayout()); const IMapper iMapper(iGridView, Dune::mcmgElementLayout()); - MMDG mmdg(gridView, mapper, iGridView, iMapper, *problem); + MMDG mmdg(gridView, mapper, iGridView, iMapper, *problem, solver); mmdg(mu0, xi); //errors and total run time diff --git a/src/parameterDG.ini b/src/parameterDG.ini index f6448b0..11dd074 100644 --- a/src/parameterDG.ini +++ b/src/parameterDG.ini @@ -1,5 +1,6 @@ mu0 = 1000 problem = dg4 +dmin = 1e-2 +dmax = 1e-1 +solver = Cholmod fastEOC = true -dmin = 1e-1 -dmax = 3e-1 diff --git a/src/parameterMMDG.ini b/src/parameterMMDG.ini index 257871d..f572d82 100644 --- a/src/parameterMMDG.ini +++ b/src/parameterMMDG.ini @@ -1,6 +1,8 @@ mu0 = 1000 -problem = mmdg2 -d = 1e-2 +problem = mmdg6 +dmax = 1e-3 +dmin = 1e-2 #xi = 0.75 gridfile = mmdg2_C +solver = Cholmod fastEOC = true -- GitLab