From 5d525c212cb8b90002f5380dc85b4254770c46d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maximilian=20H=C3=B6rl?= <maximilian.hoerl@mathematik.uni-stuttgart.de> Date: Tue, 7 Jan 2020 18:19:43 +0100 Subject: [PATCH] [WIP] begin implementation of dg --- dune/mmdg/clockhelper.hh | 20 +++++ src/CMakeLists.txt | 2 + src/dg.cc | 170 ++++++++++++++++++++++++++++++++++----- src/grids/cube1d.dgf | 10 +++ src/grids/cube2d.dgf | 10 +++ src/grids/cube3d.dgf | 10 +++ src/parameterDG.ini | 2 + src/parameterMMDG.ini | 0 8 files changed, 206 insertions(+), 18 deletions(-) create mode 100644 dune/mmdg/clockhelper.hh create mode 100644 src/grids/cube1d.dgf create mode 100644 src/grids/cube2d.dgf create mode 100644 src/grids/cube3d.dgf create mode 100644 src/parameterDG.ini create mode 100644 src/parameterMMDG.ini diff --git a/dune/mmdg/clockhelper.hh b/dune/mmdg/clockhelper.hh new file mode 100644 index 0000000..05c3ddc --- /dev/null +++ b/dune/mmdg/clockhelper.hh @@ -0,0 +1,20 @@ +#ifndef __DUNE_MMDG_CLOCKHELPER_HH__ +#define __DUNE_MMDG_CLOCKHELPER_HH__ + +#include <chrono> + +class ClockHelper +{ + public: + using Clock = std::chrono::steady_clock; + + //returns the elapsed run time since the time point begin in seconds with a + //precision of a microsecond + static double elapsedRuntime(const Clock::time_point begin) + { + return 1e-6*std::chrono::duration_cast<std::chrono::microseconds> + (Clock::now() - begin).count();; + } +}; + +#endif diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index a8348fd..5088d17 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -9,3 +9,5 @@ target_link_dune_default_libraries("dg-2d") add_executable("mmdg-2d" mmdg.cc) target_compile_definitions("mmdg-2d" PRIVATE GRIDDIM=2) target_link_dune_default_libraries("mmdg-2d") + +dune_symlink_to_source_files(FILES grids parameterMMDG.ini parameterDG.ini) diff --git a/src/dg.cc b/src/dg.cc index 61ea9c4..559b344 100644 --- a/src/dg.cc +++ b/src/dg.cc @@ -1,30 +1,164 @@ -// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- -// vi: set et ts=4 sw=2 sts=2: - #ifdef HAVE_CONFIG_H # include "config.h" #endif -#include <iostream> -#include <dune/common/parallel/mpihelper.hh> // An initializer of MPI -#include <dune/common/exceptions.hh> // We use exceptions + +#include <dune/common/parallel/mpihelper.hh> +#include <dune/common/exceptions.hh> +#include <dune/common/parametertree.hh> +#include <dune/common/parametertreeparser.hh> +#include <dune/common/dynmatrix.hh> +#include <dune/common/dynvector.hh> + +#include <dune/grid/yaspgrid.hh> +#include <dune/grid/common/mcmgmapper.hh> +#include <dune/grid/io/file/dgfparser/dgfyasp.hh> +#include <dune/grid/io/file/dgfparser/dgfug.hh> + +#include <dune/geometry/quadraturerules.hh> + +#include <dune/mmdg/clockhelper.hh> int main(int argc, char** argv) { - try{ - // Maybe initialize MPI - Dune::MPIHelper& helper = Dune::MPIHelper::instance(argc, argv); - std::cout << "Hello World! This is dune-mmdg." << std::endl; - if(Dune::MPIHelper::isFake) - std::cout<< "This is a sequential program." << std::endl; - else - std::cout<<"I am rank "<<helper.rank()<<" of "<<helper.size() - <<" processes!"<<std::endl; + try + { + using Clock = std::chrono::steady_clock; + + //start run time measurement + const Clock::time_point timeInitial = Clock::now(); + + static constexpr int dim = GRIDDIM; + + using Grid = Dune::YaspGrid<dim>; + using GridFactory = Dune::DGFGridFactory<Grid>; + using GridView = typename Grid::LeafGridView; + using Mapper = typename Dune::MultipleCodimMultipleGeomTypeMapper<GridView>; + using Coordinate = Dune::FieldVector<double, dim>; + + //Message Passing Interface (MPI) for parallel computation + Dune::MPIHelper::instance(argc, argv); + + //get parameters from file "parameterDG.ini" + Dune::ParameterTree pt; + Dune::ParameterTreeParser::readINITree("parameterDG.ini", pt); + + //assume isotropic medium such that permeability tensor reduces to a scalar + const double K = std::stod(pt["K"]); + + //assume constant penalty parameter + const double mu = std::stod(pt["mu"]); + + //create a grid from .dgf file + GridFactory gridFactory( "grids/cube" + std::to_string(dim) + + "d.dgf" ); + const Grid& grid = *gridFactory.grid(); + const GridView& gridView = grid.leafGridView(); + + //element mapper for the leaf grid view + const Mapper mapper(gridView, Dune::mcmgElementLayout()); + + const int dof = (1 + dim)*gridView.size(0); //degrees of freedom + using Matrix = Dune::DynamicMatrix<double>; //Dune::FieldMatrix<double, dof, dof>; + using Vector = Dune::DynamicVector<double>; //Dune::FieldVector<double, dof>; + Matrix A(dof, dof, 0.0); //stiffness matrix + Vector b(dof, 0.0); + Vector d; + + const auto q = [](const Coordinate& x) {return x.two_norm();}; //source term + + const int order = 3; //order of the quadrature rule + for (const auto& elem : elements(gridView)) + { + const auto& geo = elem.geometry(); + const int elemIdx = mapper.index(elem); + //TODO: can be done outside of the loop? + const Dune::QuadratureRule<double,dim>& rule = + Dune::QuadratureRules<double,dim>::rule(geo.type(),order); + + for (const auto& ip : rule) + { + const auto qp = ip.position(); + //NOTE: is the volume of the element taken into account automatically? + const auto weight = ip.weight(); + + //basis function phi_{elem,0}(x) = indicator(elem); + b[(1 + dim)*elemIdx] += weight * q(qp); + for (int i = 0; i < dim; i++) + { + //basis function phi_{elem,i}(x) = x[i]*indicator(elem); + b[(1 + dim)*elemIdx + i + 1] += weight * qp[i] * q(qp); + } + } + + for (int i = 0; i < dim; i++) + { + //basis function phi_{elem,i}(x) = x[i]*indicator(elem); + A[(1 + dim)*elemIdx + i + 1][(1 + dim)*elemIdx + i + 1] = + K * geo.volume(); // \int_elem K\nabla\phi_i\cdot\nabla\phi_i dV + } + + //NOTE: Is there a neat way to evaluate the jump and average operators? + // (loop over facets?) + //NOTE: jump / average operators disappear as basis function are supported + //on a single element? + + //iterate over all intersection with the boundary of elem + for (const auto& intersct : intersections(gridView, elem)) + { + const auto& outerNormal = intersct.centerUnitOuterNormal(); + const auto& intersctGeo = intersct.geometry(); + + const Dune::QuadratureRule<double,dim-1>& rule = + Dune::QuadratureRules<double,dim-1>::rule(intersct.type(),order); + + A[(1 + dim)*elemIdx][(1 + dim)*elemIdx] += mu * intersctGeo.volume(); + + for (const auto& ip : rule) + { + const auto qp = ip.position(); + const auto weight = ip.weight(); + + //TODO + } + + + + if (intersct.neighbor()) //intersct has neighboring element + { + //index of the neighboring element + const int neighborIndex = mapper.index(intersct.outside()); + + // A[][] = 0.5* ...; //note that interior facets are considered twice + + //TODO + } + else //boundary element + { + //TODO + } + } + } + + A.solve(d, b); + + //NOTE: what is a suitable way to create the output? + + //print total run time + const double timeTotal = ClockHelper::elapsedRuntime(timeInitial); + std::cout << "Finished with a total run time of " << timeTotal << ".\n"; + return 0; } - catch (Dune::Exception &e){ - std::cerr << "Dune reported error: " << e << std::endl; + catch (Dune::Exception& e) + { + std::cerr << "Dune reported error: " << e.what() << std::endl; + } + catch (std::exception& e) + { + std::cerr << "Error: " << e.what() << std::endl; } - catch (...){ + catch (...) + { std::cerr << "Unknown exception thrown!" << std::endl; } } diff --git a/src/grids/cube1d.dgf b/src/grids/cube1d.dgf new file mode 100644 index 0000000..10e02bb --- /dev/null +++ b/src/grids/cube1d.dgf @@ -0,0 +1,10 @@ +DGF + +Interval +0 +1 +5 +# + +Simplex +# diff --git a/src/grids/cube2d.dgf b/src/grids/cube2d.dgf new file mode 100644 index 0000000..f1c490a --- /dev/null +++ b/src/grids/cube2d.dgf @@ -0,0 +1,10 @@ +DGF + +Interval +0 0 +1 1 +2 2 +# + +Simplex +# diff --git a/src/grids/cube3d.dgf b/src/grids/cube3d.dgf new file mode 100644 index 0000000..d201d0a --- /dev/null +++ b/src/grids/cube3d.dgf @@ -0,0 +1,10 @@ +DGF + +Interval +0 0 0 +1 1 1 +20 20 20 +# + +Simplex +# diff --git a/src/parameterDG.ini b/src/parameterDG.ini new file mode 100644 index 0000000..4ec0b2d --- /dev/null +++ b/src/parameterDG.ini @@ -0,0 +1,2 @@ +K = 1 +mu = 3 diff --git a/src/parameterMMDG.ini b/src/parameterMMDG.ini new file mode 100644 index 0000000..e69de29 -- GitLab