Skip to content
Snippets Groups Projects
Commit d2d3d1b0 authored by Dr. Felix Tobias Schindler's avatar Dr. Felix Tobias Schindler
Browse files

[tools] add LocalMassMatrixProvider

parent 88d7c7d3
No related branches found
No related tags found
No related merge requests found
// This file is part of the dune-gdt project:
// https://github.com/dune-community/dune-gdt
// Copyright 2010-2018 dune-gdt developers and contributors. All rights reserved.
// License: Dual licensed as BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)
// or GPL-2.0+ (http://opensource.org/licenses/gpl-license)
// with "runtime exception" (http://www.dune-project.org/license.html)
// Authors:
// Felix Schindler (2019)
#ifndef DUNE_GDT_TOOLS_local_mass_matrices_HH
#define DUNE_GDT_TOOLS_local_mass_matrices_HH
#include <mutex>
#include <vector>
#include <dune/xt/common/parallel/threadstorage.hh>
#include <dune/xt/la/container/common.hh>
#include <dune/xt/la/container/conversion.hh>
#include <dune/xt/la/matrix-inverter.hh>
#include <dune/xt/grid/functors/interfaces.hh>
#include <dune/xt/grid/type_traits.hh>
#include <dune/gdt/exceptions.hh>
#include <dune/gdt/local/bilinear-forms/integrals.hh>
#include <dune/gdt/local/integrands/product.hh>
#include <dune/gdt/spaces/interface.hh>
#include <dune/gdt/spaces/mapper/finite-volume.hh>
namespace Dune {
namespace GDT {
template <class GV, size_t r = 1, size_t rC = 1, class F = double, class AGV = GV>
class LocalMassMatrixProvider
: public XT::Grid::ElementFunctor<GV>
, public XT::Common::ThreadResultPropagator<
LocalMassMatrixProvider<GV, r, rC, F>,
std::map<size_t, std::pair<XT::LA::CommonDenseMatrix<F>, XT::LA::CommonDenseMatrix<F>>>,
XT::Common::merge_container<
std::map<size_t, std::pair<XT::LA::CommonDenseMatrix<F>, XT::LA::CommonDenseMatrix<F>>>>>
{
static_assert(XT::Grid::is_view<AGV>::value, "");
using ThisType = LocalMassMatrixProvider<GV, r, rC, F>;
using BaseType = XT::Grid::ElementFunctor<GV>;
using Propagator = XT::Common::ThreadResultPropagator<
LocalMassMatrixProvider<GV, r, rC, F>,
std::map<size_t, std::pair<XT::LA::CommonDenseMatrix<F>, XT::LA::CommonDenseMatrix<F>>>,
XT::Common::merge_container<
std::map<size_t, std::pair<XT::LA::CommonDenseMatrix<F>, XT::LA::CommonDenseMatrix<F>>>>>;
friend Propagator;
public:
using AssemblyGridView = AGV;
using SpaceType = SpaceInterface<GV, r, rC, F>;
using typename BaseType::E;
using typename BaseType::ElementType;
LocalMassMatrixProvider(const AssemblyGridView& grid_view, const SpaceType& space)
: Propagator(this)
, grid_view_(grid_view)
, space_(space)
, element_mapper_(grid_view_)
, instance_counter_(0)
, local_basis_(space_.basis().localize())
{}
LocalMassMatrixProvider(const ThisType& other)
: Propagator(this)
, grid_view_(other.grid_view_)
, space_(other.space_)
, element_mapper_(grid_view_)
, instance_counter_(other.instance_counter_ + 1)
, local_basis_(space_.basis().localize())
{}
void apply_local(const ElementType& element)
{
local_basis_->bind(element);
const size_t id = element_mapper_.global_index(element, 0);
const LocalElementIntegralBilinearForm<E, r, rC, F, F> local_l2_bilinear_form(
LocalElementProductIntegrand<E, r, rC, F, F>(1.));
auto matrix =
XT::LA::convert_to<XT::LA::CommonDenseMatrix<F>>(local_l2_bilinear_form.apply2(*local_basis_, *local_basis_));
auto inverse = XT::LA::invert_matrix(matrix);
local_mass_matrices_.insert(std::make_pair(id, std::make_pair(std::move(matrix), std::move(inverse))));
} // ... apply_local(...)
BaseType* copy() override final
{
return Propagator::copy_imp();
}
void finalize() override final
{
this->finalize_imp();
}
/**
* \note This is only used to merge the thread-local results after the grid walk, you are probably interested in
* local_mass_matrix() and local_mass_matrix_inverse().
*/
std::map<size_t, std::pair<XT::LA::CommonDenseMatrix<F>, XT::LA::CommonDenseMatrix<F>>> result() const
{
return local_mass_matrices_;
}
void set_result(std::map<size_t, std::pair<XT::LA::CommonDenseMatrix<F>, XT::LA::CommonDenseMatrix<F>>> res)
{
local_mass_matrices_ = res;
}
const XT::LA::CommonDenseMatrix<F>& local_mass_matrix(const ElementType& element) const
{
const size_t id = element_mapper_.global_index(element, 0);
DUNE_THROW_IF(local_mass_matrices_.count(id) == 0,
XT::Common::Exceptions::this_should_not_happen,
"Missing local mass matrix for id " << id << "!");
return local_mass_matrices_.at(id).first;
}
const XT::LA::CommonDenseMatrix<F>& local_mass_matrix_inverse(const ElementType& element) const
{
const size_t id = element_mapper_.global_index(element, 0);
DUNE_THROW_IF(local_mass_matrices_.count(id) == 0,
XT::Common::Exceptions::this_should_not_happen,
"Missing local mass matrix for id " << id << "!");
return local_mass_matrices_.at(id).second;
}
private:
const AssemblyGridView& grid_view_;
const SpaceType& space_;
const FiniteVolumeMapper<GV> element_mapper_;
size_t instance_counter_;
std::unique_ptr<typename SpaceType::GlobalBasisType::LocalizedBasisType> local_basis_;
std::map<size_t, std::pair<XT::LA::CommonDenseMatrix<F>, XT::LA::CommonDenseMatrix<F>>> local_mass_matrices_;
}; // class LocalMassMatrixProvider
} // namespace GDT
} // namespace Dune
#endif // DUNE_GDT_TOOLS_local_mass_matrices_HH
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment