Commit 301640ea authored by Praetorius, Simon's avatar Praetorius, Simon

some examples modified to make it running

parent 5c70d545
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include <dune/common/fmatrix.hh> #include <dune/common/fmatrix.hh>
#include <dune/common/fvector.hh> #include <dune/common/fvector.hh>
#include <dune/amdis/DirichletBC.hpp>
#include <dune/amdis/LinearAlgebra.hpp> #include <dune/amdis/LinearAlgebra.hpp>
#include <dune/amdis/Operator.hpp> #include <dune/amdis/Operator.hpp>
#include <dune/amdis/common/Mpl.hpp> #include <dune/amdis/common/Mpl.hpp>
...@@ -23,10 +24,12 @@ namespace AMDiS ...@@ -23,10 +24,12 @@ namespace AMDiS
/// Constructor, stores a shared-pointer to the feSpaces /// Constructor, stores a shared-pointer to the feSpaces
Assembler(GlobalBasis& globalBasis, Assembler(GlobalBasis& globalBasis,
MatrixOperators<GlobalBasis>& matrixOperators, MatrixOperators<GlobalBasis>& matrixOperators,
VectorOperators<GlobalBasis>& rhsOperators) VectorOperators<GlobalBasis>& rhsOperators,
Constraints<GlobalBasis>& constraints)
: globalBasis_(globalBasis) : globalBasis_(globalBasis)
, matrixOperators_(matrixOperators) , matrixOperators_(matrixOperators)
, rhsOperators_(rhsOperators) , rhsOperators_(rhsOperators)
, constraints_(constraints)
{} {}
void update(GridView const& gv) void update(GridView const& gv)
...@@ -88,6 +91,7 @@ namespace AMDiS ...@@ -88,6 +91,7 @@ namespace AMDiS
GlobalBasis& globalBasis_; GlobalBasis& globalBasis_;
MatrixOperators<GlobalBasis>& matrixOperators_; MatrixOperators<GlobalBasis>& matrixOperators_;
VectorOperators<GlobalBasis>& rhsOperators_; VectorOperators<GlobalBasis>& rhsOperators_;
Constraints<GlobalBasis>& constraints_;
}; };
} // end namespace AMDiS } // end namespace AMDiS
......
#pragma once #pragma once
#include <dune/functions/functionspacebases/subspacebasis.hh> #include <dune/functions/functionspacebases/subspacebasis.hh>
#include <dune/typetree/treepath.hh> #include <dune/amdis/utility/TreePath.hpp>
#include <dune/amdis/utility/Visitor.hpp> #include <dune/amdis/utility/Visitor.hpp>
namespace AMDiS { namespace AMDiS {
...@@ -64,15 +64,19 @@ void Assembler<GlobalBasis>::assemble( ...@@ -64,15 +64,19 @@ void Assembler<GlobalBasis>::assemble(
for (std::size_t i = 0; i < localView.size(); ++i) { for (std::size_t i = 0; i < localView.size(); ++i) {
auto const row = localIndexSet.index(i); auto const row = localIndexSet.index(i);
for (std::size_t j = 0; j < localView.size(); ++j) { for (std::size_t j = 0; j < localView.size(); ++j) {
auto const col = localIndexSet.index(j); if (elementMatrix(i,j) != 0.0) {
matrix(row,col) += elementMatrix(i,j); auto const col = localIndexSet.index(j);
matrix(row,col) += elementMatrix(i,j);
}
} }
} }
// add element-vector to system-vector // add element-vector to system-vector
for (std::size_t i = 0; i < localView.size(); ++i) { for (std::size_t i = 0; i < localView.size(); ++i) {
auto const idx = localIndexSet.index(i); if (elementVector[i] != 0.0) {
rhs[idx] += elementVector[i]; auto const idx = localIndexSet.index(i);
rhs[idx] += elementVector[i];
}
} }
localIndexSet.unbind(); localIndexSet.unbind();
...@@ -86,43 +90,6 @@ void Assembler<GlobalBasis>::assemble( ...@@ -86,43 +90,6 @@ void Assembler<GlobalBasis>::assemble(
} }
template <class GlobalBasis>
template <class SystemMatrixType, class SystemVectorType>
void Assembler<GlobalBasis>::initMatrixVector(
SystemMatrixType& matrix,
SystemVectorType& solution,
SystemVectorType& rhs,
bool asmMatrix, bool asmVector) const
{
matrix.init(asmMatrix);
solution.compress();
rhs.compress();
auto localView = globalBasis_.localView();
forEachNode(localView.tree(), [&,this](auto const& rowNode, auto rowTreePath)
{
if (rowNode.isLeaf)
msg(0, " DOFs for Basis[", 1, "]"); // TODO: add right values
auto rowBasis = Dune::Functions::subspaceBasis(globalBasis_, rowTreePath);
if (rhsOperators_[rowNode].assemble(asmVector))
rhsOperators_[rowNode].init(rowBasis);
forEachNode(localView.tree(), [&,this](auto const& colNode, auto colTreePath)
{
auto colBasis = Dune::Functions::subspaceBasis(globalBasis_, colTreePath);
if (matrixOperators_[rowNode][colNode].assemble(asmMatrix))
matrixOperators_[rowNode][colNode].init(rowBasis, colBasis);
// init boundary condition
// for (int c = 0; c < nComponents; ++c)
// for (auto bc : matrixOperators[R][c].dirichlet)
// bc->init(c == C, matrix(_r, _c), solution[_c], rhs[_r]);
});
});
}
template <class GlobalBasis> template <class GlobalBasis>
template <class ElementContainer, class Container, class Operators, class... LocalViews> template <class ElementContainer, class Container, class Operators, class... LocalViews>
void Assembler<GlobalBasis>::assembleElementOperators( void Assembler<GlobalBasis>::assembleElementOperators(
...@@ -160,6 +127,44 @@ void Assembler<GlobalBasis>::assembleElementOperators( ...@@ -160,6 +127,44 @@ void Assembler<GlobalBasis>::assembleElementOperators(
} }
template <class GlobalBasis>
template <class SystemMatrixType, class SystemVectorType>
void Assembler<GlobalBasis>::initMatrixVector(
SystemMatrixType& matrix,
SystemVectorType& solution,
SystemVectorType& rhs,
bool asmMatrix, bool asmVector) const
{
matrix.init(asmMatrix);
solution.compress();
rhs.compress();
auto localView = globalBasis_.localView();
forEachNode(localView.tree(), [&,this](auto const& rowNode, auto rowTreePath)
{
if (rowNode.isLeaf)
msg(0, " DOFs for Basis[", to_string(rowTreePath), "]"); // TODO: add right values
auto rowBasis = Dune::Functions::subspaceBasis(globalBasis_, rowTreePath);
if (rhsOperators_[rowNode].assemble(asmVector))
rhsOperators_[rowNode].init(rowBasis);
forEachNode(localView.tree(), [&,this](auto const& colNode, auto colTreePath)
{
auto colBasis = Dune::Functions::subspaceBasis(globalBasis_, colTreePath);
if (matrixOperators_[rowNode][colNode].assemble(asmMatrix))
matrixOperators_[rowNode][colNode].init(rowBasis, colBasis);
for (auto bc : constraints_[rowNode][colNode].scalar)
bc->init(matrix, solution, rhs, rowBasis, colBasis);
for (auto bc : constraints_[rowNode][colNode].vector)
bc->init(matrix, solution, rhs, rowBasis, colBasis);
});
});
msg(globalBasis_.dimension(), " total DOFs");
}
template <class GlobalBasis> template <class GlobalBasis>
template <class SystemMatrixType, class SystemVectorType> template <class SystemMatrixType, class SystemVectorType>
std::size_t Assembler<GlobalBasis>::finishMatrixVector( std::size_t Assembler<GlobalBasis>::finishMatrixVector(
...@@ -171,27 +176,25 @@ std::size_t Assembler<GlobalBasis>::finishMatrixVector( ...@@ -171,27 +176,25 @@ std::size_t Assembler<GlobalBasis>::finishMatrixVector(
matrix.finish(); matrix.finish();
auto localView = globalBasis_.localView(); auto localView = globalBasis_.localView();
forEachNode(localView.tree(), [&,this](auto const& rowNode, auto /*rowTreePath*/) forEachNode(localView.tree(), [&,this](auto const& rowNode, auto rowTreePath)
{ {
auto rowBasis = Dune::Functions::subspaceBasis(globalBasis_, rowTreePath);
auto& rhsOp = rhsOperators_[rowNode]; auto& rhsOp = rhsOperators_[rowNode];
if (rhsOp.assemble(asmVector)) if (rhsOp.assemble(asmVector))
rhsOp.assembled = true; rhsOp.assembled = true;
forEachNode(localView.tree(), [&,this](auto const& colNode, auto /*colTreePath*/) forEachNode(localView.tree(), [&,this](auto const& colNode, auto colTreePath)
{ {
auto colBasis = Dune::Functions::subspaceBasis(globalBasis_, colTreePath);
auto& matOp = matrixOperators_[rowNode][colNode]; auto& matOp = matrixOperators_[rowNode][colNode];
if (matOp.assemble(asmMatrix)) if (matOp.assemble(asmMatrix))
matOp.assembled = true; matOp.assembled = true;
// finish boundary condition // finish boundary condition
// for (int c = 0; c < nComponents; ++c) { for (auto bc : constraints_[rowNode][colNode].scalar)
// for (int r = 0; r < nComponents; ++r) { bc->finish(matrix, solution, rhs, rowBasis, colBasis);
// if (r != R && c != C) for (auto bc : constraints_[rowNode][colNode].vector)
// continue; bc->finish(matrix, solution, rhs, rowBasis, colBasis);
// for (auto bc : matrixOperators[r][c].dirichlet)
// bc->finish(r == R, c == C, matrix(_r, _c), solution[_c], rhs[_r]);
// }
// }
}); });
}); });
......
...@@ -4,9 +4,9 @@ ...@@ -4,9 +4,9 @@
#include <type_traits> #include <type_traits>
#include <vector> #include <vector>
#include <dune/amdis/common/Concepts.hpp>
#include <dune/amdis/Output.hpp> #include <dune/amdis/Output.hpp>
#include <dune/amdis/common/Concepts.hpp>
#include <dune/amdis/utility/TreeData.hpp>
namespace AMDiS namespace AMDiS
{ {
...@@ -25,13 +25,13 @@ namespace AMDiS ...@@ -25,13 +25,13 @@ namespace AMDiS
* support this symmetric modification. As a result, this method returns a list * support this symmetric modification. As a result, this method returns a list
* of columns values, that should be subtracted from the rhs. * of columns values, that should be subtracted from the rhs.
**/ **/
template <class WorldVector> template <class Domain, class Range = double>
class DirichletBC class DirichletBC
{ {
public: public:
template <class Predicate, class Values, template <class Predicate, class Values,
REQUIRES(Concepts::Functor<Predicate, bool(WorldVector)> && REQUIRES(Concepts::Functor<Predicate, bool(Domain)> &&
Concepts::Functor<Values, double(WorldVector)>) > Concepts::Functor<Values, Range(Domain)>) >
DirichletBC(Predicate&& predicate, Values&& values) DirichletBC(Predicate&& predicate, Values&& values)
: predicate(std::forward<Predicate>(predicate)) : predicate(std::forward<Predicate>(predicate))
, values(std::forward<Values>(values)) , values(std::forward<Values>(values))
...@@ -41,11 +41,15 @@ namespace AMDiS ...@@ -41,11 +41,15 @@ namespace AMDiS
/// Prepare the matrix, rhs and solution block for assembling dirichlet /// Prepare the matrix, rhs and solution block for assembling dirichlet
/// boundary conditions, e.g. collect the corresponding indices of boundary /// boundary conditions, e.g. collect the corresponding indices of boundary
/// DOFS for later elimination in \ref finish. /// DOFS for later elimination in \ref finish.
template <class Matrix, class VectorX, class VectorB> template <class Matrix, class VectorX, class VectorB, class RowBasis, class ColBasis>
void init(bool apply, void init(Matrix& /*matrix*/, VectorX& /*rhs*/, VectorB& /*solution*/,
Matrix& matrix, RowBasis const& rowBasis,
VectorX& rhs, ColBasis const& /*colBasis*/)
VectorB& solution); {
using RowNode = typename RowBasis::LocalView::Tree;
initImpl(rowBasis, typename RowNode::NodeTag{});
}
/// \brief Apply dirichlet BC to matrix and vector, i.e., add a unit-row /// \brief Apply dirichlet BC to matrix and vector, i.e., add a unit-row
...@@ -55,21 +59,51 @@ namespace AMDiS ...@@ -55,21 +59,51 @@ namespace AMDiS
* is assembled. The \p matrix, \p rhs, and \p solution correspond to the * is assembled. The \p matrix, \p rhs, and \p solution correspond to the
* currently visited blocks of system-matrix and system-vector. * currently visited blocks of system-matrix and system-vector.
**/ **/
template <class Matrix, class VectorX, class VectorB> template <class Matrix, class VectorX, class VectorB, class RowBasis, class ColBasis>
void finish(bool apply_row, void finish(Matrix& matrix,
bool apply_col,
Matrix& matrix,
VectorX& rhs, VectorX& rhs,
VectorB& solution); VectorB& solution,
RowBasis const& rowBasis,
ColBasis const& colBasis);
protected:
template <class RowBasis>
void initImpl(RowBasis const& rowBasis, Dune::TypeTree::LeafNodeTag);
template <class RowBasis>
void initImpl(RowBasis const& rowBasis, Dune::TypeTree::PowerNodeTag);
template <class RB, class RowNodeTag>
void initImpl(RB const&, RowNodeTag) {}
private: private:
std::function<bool(WorldVector)> predicate; std::function<bool(Domain)> predicate;
std::function<double(WorldVector)> values; std::function<Range(Domain)> values;
bool initialized = false; bool initialized = false;
std::vector<char> dirichletNodes; std::vector<char> dirichletNodes;
}; };
template <class GlobalBasis>
struct DirichletData
{
using WorldVector = typename GlobalBasis::GridView::template Codim<0>::Geometry::GlobalCoordinate;
template <class Node>
struct type
{
std::list<std::shared_ptr<DirichletBC<WorldVector, double>>> scalar;
std::list<std::shared_ptr<DirichletBC<WorldVector, WorldVector>>> vector;
void push_back(std::shared_ptr<DirichletBC<WorldVector, double>> const& bc) { scalar.push_back(bc); }
void push_back(std::shared_ptr<DirichletBC<WorldVector, WorldVector>> const& bc) { vector.push_back(bc); }
};
};
template <class GlobalBasis>
using Constraints = MatrixData<GlobalBasis, DirichletData<GlobalBasis>::template type>;
} // end namespace AMDiS } // end namespace AMDiS
#include "DirichletBC.inc.hpp" #include "DirichletBC.inc.hpp"
#pragma once #pragma once
#include <dune/functions/functionspacebases/interpolate.hh> #include <dune/functions/functionspacebases/interpolate.hh>
#include <dune/functions/functionspacebases/subspacebasis.hh>
#include <dune/amdis/LinearAlgebra.hpp> #include <dune/amdis/LinearAlgebra.hpp>
#include <dune/amdis/linear_algebra/HierarchicWrapper.hpp>
namespace AMDiS namespace AMDiS
{ {
template <class WorldVector> template <class WorldVector, class Range>
template <class Matrix, class VectorX, class VectorB> template <class RowBasis>
void DirichletBC<WorldVector>::init(bool /*apply*/, void DirichletBC<WorldVector, Range>::initImpl(
Matrix& matrix, RowBasis const& rowBasis, Dune::TypeTree::LeafNodeTag)
VectorX& /*solution*/,
VectorB& /*rhs*/)
{ {
using Dune::Functions::interpolate; using Dune::Functions::interpolate;
if (!initialized) { if (!initialized) {
interpolate(matrix.getRowFeSpace(), dirichletNodes, predicate); interpolate(rowBasis, hierarchicVectorWrapper(dirichletNodes), predicate);
initialized = true; initialized = true;
} }
} }
template <class WorldVector, class Range>
template <class RowBasis>
void DirichletBC<WorldVector, Range>::initImpl(
RowBasis const& rowBasis, Dune::TypeTree::PowerNodeTag)
{
using Dune::Functions::interpolate;
template <class WorldVector> if (!initialized) {
template <class Matrix, class VectorX, class VectorB> auto tp = rowBasis.prefixPath();
void DirichletBC<WorldVector>::finish(bool apply_row, auto const& basis = rowBasis.rootBasis();
bool apply_col, for (std::size_t i = 0; i < degree(rowBasis.localView().tree()); ++i)
Matrix& matrix, interpolate(Dune::Functions::subspaceBasis(basis, push_back(tp,i)),
VectorX& solution, hierarchicVectorWrapper(dirichletNodes), predicate);
VectorB& rhs) initialized = true;
}
}
template <class WorldVector, class Range>
template <class Matrix, class VectorX, class VectorB, class RowBasis, class ColBasis>
void DirichletBC<WorldVector, Range>::finish(
Matrix& matrix, VectorX& solution, VectorB& rhs,
RowBasis const& rowBasis, ColBasis const& colBasis)
// Dune::TypeTree::LeafNodeTag, Dune::TypeTree::LeafNodeTag)
{ {
using Dune::Functions::interpolate; using Dune::Functions::interpolate;
test_exit_dbg(initialized, "Boundary condition not initialized!"); test_exit_dbg(initialized, "Boundary condition not initialized!");
auto columns = matrix.applyDirichletBC(dirichletNodes, apply_row, apply_col); auto columns = matrix.applyDirichletBC(dirichletNodes);
if (apply_col) { interpolate(rowBasis, hierarchicVectorWrapper(rhs.getVector()), values, hierarchicVectorWrapper(dirichletNodes));
interpolate(matrix.getRowFeSpace(), wrapper(rhs.getVector()), values, dirichletNodes); interpolate(colBasis, hierarchicVectorWrapper(solution.getVector()), values, hierarchicVectorWrapper(dirichletNodes));
if (apply_row)
interpolate(matrix.getColFeSpace(), wrapper(solution.getVector()), values, dirichletNodes);
// subtract columns of dirichlet nodes from rhs // subtract columns of dirichlet nodes from rhs
for (auto const& triplet : columns) for (auto const& triplet : columns)
rhs[triplet.row] -= triplet.value * solution[triplet.col]; rhs[triplet.row] -= triplet.value * solution[triplet.col];
}
} }
......
This diff is collapsed.
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
#include <dune/amdis/common/Utility.hpp> #include <dune/amdis/common/Utility.hpp>
#include <dune/amdis/utility/RangeType.hpp> #include <dune/amdis/utility/RangeType.hpp>
#include <dune/amdis/utility/TreePath.hpp>
namespace AMDiS namespace AMDiS
{ {
...@@ -164,11 +165,19 @@ namespace AMDiS ...@@ -164,11 +165,19 @@ namespace AMDiS
/// Adds a Dirichlet boundary condition /// Adds a Dirichlet boundary condition
template <class Predicate, class Values> template <class Predicate, class RowTreePath, class ColTreePath, class Values>
void addDirichletBC(Predicate const& predicate, void addDirichletBC(Predicate const& predicate,
int row, int col, RowTreePath row, ColTreePath col,
Values const& values); Values const& values);
template <class Predicate, class RowTreePath, class ColTreePath>
void addDirichletBC(Predicate const& predicate,
RowTreePath row, ColTreePath col,
double constant)
{
addDirichletBC(predicate, row, col, [constant](auto const&) { return constant; });
}
/// Implementation of \ref ProblemStatBase::solve /// Implementation of \ref ProblemStatBase::solve
virtual void solve(AdaptInfo& adaptInfo, virtual void solve(AdaptInfo& adaptInfo,
...@@ -236,23 +245,27 @@ namespace AMDiS ...@@ -236,23 +245,27 @@ namespace AMDiS
/// Return a pointer to the solution, \ref solution /// Return a pointer to the solution, \ref solution
auto getSolution() { return solution; } std::shared_ptr<SystemVector> getSolution() { return solution; }
auto getSolution() const { return solution; } std::shared_ptr<SystemVector const> getSolution() const { return solution; }
/// Return the i'th \ref solution component /// Return a view to a solution component
template <class TreePath> template <class TreePath>
auto getSolution(TreePath path) auto getSolution(TreePath path)
{ {
using namespace Dune::Functions; using namespace Dune::Functions;
auto tp = makeTreePath(path); auto tp = makeTreePath(path);
using TP = decltype(tp);
using Node = typename GlobalBasis::NodeFactory::template Node<decltype(tp)>; using Tree = typename GlobalBasis::LocalView::Tree;
using Range = RangeType<Node, double>; using Node = typename Dune::TypeTree::ChildForTreePath<Tree, TP>;
using Range = RangeType<Node>;
using NTRM = Dune::Functions::DefaultNodeToRangeMap<Node>;
return makeDiscreteGlobalBasisFunction<Range>( using DiscreteFunction = Dune::Functions::DiscreteGlobalBasisFunction<GlobalBasis,TP,SystemVector,NTRM,Range>;
subspaceBasis(*globalBasis, tp),
*solution); auto nodeToRange = std::make_shared<NTRM>(makeDefaultNodeToRangeMap(*globalBasis, tp));
return std::make_shared<DiscreteFunction>(globalBasis, tp, solution, nodeToRange);
} }
...@@ -332,8 +345,10 @@ namespace AMDiS ...@@ -332,8 +345,10 @@ namespace AMDiS
void createGlobalBasis() void createGlobalBasis()
{ {
globalBasis = std::make_shared<GlobalBasis>(makeGlobalBasis<GlobalBasis>(leafGridView())); globalBasis = std::make_shared<GlobalBasis>(makeGlobalBasis<GlobalBasis>(leafGridView()));
matrixOperators.init(*globalBasis); globalTree = std::make_shared<typename GlobalBasis::LocalView::Tree>(globalBasis->localView().tree());
rhsOperators.init(*globalBasis); matrixOperators.init(*globalTree);
rhsOperators.init(*globalTree);
constraints.init(*globalTree);
} }
void createMatricesAndVectors() void createMatricesAndVectors()
...@@ -381,6 +396,7 @@ namespace AMDiS ...@@ -381,6 +396,7 @@ namespace AMDiS
/// FE spaces of this problem. /// FE spaces of this problem.
std::shared_ptr<GlobalBasis> globalBasis; // eventuell const std::shared_ptr<GlobalBasis> globalBasis; // eventuell const
std::shared_ptr<typename GlobalBasis::LocalView::Tree> globalTree;
/// A FileWriter object /// A FileWriter object
std::shared_ptr<FileWriter<GlobalBasis>> filewriter; std::shared_ptr<FileWriter<GlobalBasis>> filewriter;
...@@ -404,13 +420,7 @@ namespace AMDiS ...@@ -404,13 +420,7 @@ namespace AMDiS
MatrixOperators<GlobalBasis> matrixOperators; MatrixOperators<GlobalBasis> matrixOperators;
VectorOperators<GlobalBasis> rhsOperators; VectorOperators<GlobalBasis> rhsOperators;
template <class Node> Constraints<GlobalBasis> constraints;
struct DirichletData
{
std::list<std::shared_ptr<DirichletBC<WorldVector>>> bc;
};
MatrixData<GlobalBasis, DirichletData> matrixConstraints;
}; };
......
...@@ -7,7 +7,6 @@ ...@@ -7,7 +7,6 @@
#include <dune/amdis/common/Loops.hpp> #include <dune/amdis/common/Loops.hpp>
#include <dune/amdis/common/Timer.hpp> #include <dune/amdis/common/Timer.hpp>
#include <dune/amdis/linear_algebra/HierarchicWrapper.hpp> #include <dune/amdis/linear_algebra/HierarchicWrapper.hpp>
#include <dune/amdis/utility/TreePath.hpp>
namespace AMDiS { namespace AMDiS {
...@@ -241,9 +240,9 @@ addVectorOperator(std::map< int, std::pair<ElementOperator, bool> > ops) ...@@ -241,9 +240,9 @@ addVectorOperator(std::map< int, std::pair<ElementOperator, bool> > ops)
// Adds a Dirichlet boundary condition