Skip to content
Snippets Groups Projects
Commit e6d5dbb5 authored by Tobias Leibner's avatar Tobias Leibner
Browse files

[functions.linear] add (affine) linear global function

parent 50e5a6d7
No related branches found
No related tags found
No related merge requests found
// This file is part of the dune-stuff project:
// https://github.com/wwu-numerik/dune-stuff
// Copyright holders: Rene Milk, Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)
//
// Contributors: Tobias Leibner
#ifndef DUNE_STUFF_FUNCTIONS_LINEAR_HH
#define DUNE_STUFF_FUNCTIONS_LINEAR_HH
#include <memory>
#include <dune/stuff/common/configuration.hh>
#include "interfaces.hh"
namespace Dune {
namespace Stuff {
namespace Functions {
template <class EntityImp, class DomainFieldImp, size_t domainDim, class RangeFieldImp, size_t rangeDim,
size_t rangeDimCols = 1>
class Linear
{
Linear()
{
static_assert(AlwaysFalse<EntityImp>::value, "Not available for rangeDimCols > 1!");
}
};
template <class EntityImp, class DomainFieldImp, size_t domainDim, class RangeFieldImp, size_t rangeDim>
class Linear<EntityImp, DomainFieldType, domainDim, RangeFieldImp, rangeDim, 1>
: public GlobalFunctionInterface<EntityImp, DomainFieldImp, domainDim, RangeFieldImp, rangeDim, 1>
{
typedef GlobalFunctionInterface<EntityImp, DomainFieldImp, domainDim, RangeFieldImp, rangeDim, 1> BaseType;
typedef Linear<EntityImp, DomainFieldImp, domainDim, RangeFieldImp, rangeDim, 1> ThisType;
template <class R, size_t r, size_t rC>
struct Get
{
static std::string value_str()
{
std::string str = "[";
for (size_t rr = 0; rr < r; ++rr) {
if (rr > 0)
str += "; ";
for (size_t cc = 0; cc < rC; ++cc) {
if (cc > 0)
str += " ";
if (cc == rr)
str += "1";
else
str += "0";
}
}
str += "]";
return str;
}
};
template <class R, size_t rC>
struct Get<R, 1, rC>
{
static std::string value_str()
{
std::string str = "[";
for (size_t cc = 0; cc < rC; ++cc) {
if (cc > 0)
str += " ";
str += "0";
}
str += "]";
return str;
}
};
template <class R, size_t r>
struct Get<R, r, 1>
{
static std::string value_str()
{
return Get<R, 1, r>::value_str();
}
};
template <class R>
struct Get<R, 1, 1>
{
static std::string value_str()
{
return "1";
}
};
public:
typedef typename BaseType::DomainType DomainType;
typedef typename BaseType::RangeType RangeType;
typedef typename BaseType::JacobianRangeType JacobianRangeType;
typedef typename Dune::FieldMatrix<RangeFieldImp, rangeDim, domainDim> MatrixType;
using typename BaseType::LocalfunctionType;
static const bool available = true;
static std::string static_id()
{
return BaseType::static_id() + ".linear";
}
static Common::Configuration default_config(const std::string sub_name = "")
{
Common::Configuration config;
config["matrix"] = Get<RangeFieldImp, rangeDim, domainDim>::value_str();
config["vector"] = Get<RangeFieldImp, rangeDim, 1>::value_str();
config["name"] = static_id();
if (sub_name.empty())
return config;
else {
Common::Configuration tmp;
tmp.add(config, sub_name);
return tmp;
}
} // ... default_config(...)
static std::unique_ptr<ThisType> create(const Common::Configuration config = default_config(),
const std::string sub_name = static_id())
{
// get correct config
const Common::Configuration cfg = config.has_sub(sub_name) ? config.sub(sub_name) : config;
const Common::Configuration default_cfg = default_config();
return Common::make_unique<ThisType>(cfg.get("matrix", default_cfg.get<MatrixType>("matrix")),
cfg.get("vector", default_cfg.get<RangeType>("vector")),
cfg.get("name", default_cfg.get<std::string>("name")));
} // ... create(...)
explicit Linear(const MatrixType& matrix, const RangeType& vector, const std::string name_in = static_id())
: matrix_(matrix)
, vector_(vector)
, name_(name_in)
{
}
Linear(const ThisType& other) = default;
virtual std::string type() const override final
{
return BaseType::static_id() + ".linear";
}
virtual size_t order() const override final
{
return 1;
}
virtual void evaluate(const DomainType& x, RangeType& ret) const override final
{
matrix_.mv(x, ret);
ret += vector_;
return ret;
}
virtual void jacobian(const DomainType& /*x*/, JacobianRangeType& ret) const override final
{
ret = matrix_;
}
virtual std::string name() const override final
{
return name_;
}
private:
const MatrixType matrix_;
const RangeType vector_;
const std::string name_;
};
} // namespace Functions
} // namespace Stuff
} // namespace Dune
#endif // DUNE_STUFF_FUNCTIONS_LINEAR_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