From afe38dd3c364d17e85fe4c715ebaf729e15cdce2 Mon Sep 17 00:00:00 2001 From: Felix Schindler <felix.schindler@wwu.de> Date: Thu, 23 Jul 2015 08:38:10 +0200 Subject: [PATCH] [functions.indicator] And that one too... --- dune/stuff/functions/indicator.hh | 193 ++++++++++++++++++++++++++++++ 1 file changed, 193 insertions(+) create mode 100644 dune/stuff/functions/indicator.hh diff --git a/dune/stuff/functions/indicator.hh b/dune/stuff/functions/indicator.hh new file mode 100644 index 000000000..5fe128ba4 --- /dev/null +++ b/dune/stuff/functions/indicator.hh @@ -0,0 +1,193 @@ +// 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) + +#ifndef DUNE_STUFF_FUNCTIONS_INDICATOR_HH +#define DUNE_STUFF_FUNCTIONS_INDICATOR_HH + +#include <memory> +#include <vector> +#include <utility> + +#include <dune/stuff/common/type_utils.hh> + +#include <dune/stuff/common/fvector.hh> +#include <dune/stuff/common/string.hh> +#include <dune/stuff/common/memory.hh> +#include <dune/stuff/common/configuration.hh> + +#include "interfaces.hh" + +namespace Dune { +namespace Stuff { +namespace Functions { + + +template <class E, class D, size_t d, class R, size_t r, size_t rC = 1> +class Indicator : public LocalizableFunctionInterface<E, D, d, R, r, rC> +{ + Indicator() + { + static_assert(AlwaysFalse<E>::value, "Not available for these dimensions!"); + } +}; + + +template <class E, class D, size_t d, class R> +class Indicator<E, D, d, R, 1> : public LocalizableFunctionInterface<E, D, d, R, 1> +{ + typedef LocalizableFunctionInterface<E, D, d, R, 1> BaseType; + typedef Indicator<E, D, d, R, 1> ThisType; + + class Localfunction : public LocalfunctionInterface<E, D, d, R, 1> + { + typedef LocalfunctionInterface<E, D, d, R, 1> InterfaceType; + + public: + using typename InterfaceType::EntityType; + using typename InterfaceType::DomainType; + using typename InterfaceType::RangeType; + using typename InterfaceType::JacobianRangeType; + + Localfunction(const EntityType& entity, const RangeType& value) + : InterfaceType(entity) + , value_(value) + { + } + + virtual size_t order() const override final + { + return 0; + } + + virtual void evaluate(const DomainType& xx, RangeType& ret) const override final + { + assert(this->is_a_valid_point(xx)); + ret = value_; + } + + virtual void jacobian(const DomainType& xx, JacobianRangeType& ret) const override final + { + assert(this->is_a_valid_point(xx)); + ret *= 0.0; + } + + private: + const RangeType value_; + }; // class Localfunction + +public: + using typename BaseType::EntityType; + using typename BaseType::DomainFieldType; + using typename BaseType::DomainType; + using typename BaseType::RangeType; + using typename BaseType::RangeFieldType; + using typename BaseType::LocalfunctionType; + + static const bool available = true; + + static std::string static_id() + { + return BaseType::static_id() + ".indicator"; + } + + static Common::Configuration default_config(const std::string sub_name = "") + { + Common::Configuration cfg; + cfg["name"] = static_id(); + if (d == 1) + cfg["0.domain"] = "[0.25 0.75]"; + else if (d == 2) + cfg["0.domain"] = "[0.25 0.75; 0.25 0.75]"; + else if (d == 3) + cfg["0.domain"] = "[0.25 0.75; 0.25 0.75; 0.25 0.75]"; + else + DUNE_THROW(NotImplemented, "Indeed!"); + cfg["0.value"] = "1"; + if (sub_name.empty()) + return cfg; + else { + Common::Configuration tmp; + tmp.add(cfg, 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()) + { + const Common::Configuration cfg = config.has_sub(sub_name) ? config.sub(sub_name) : config; + const Common::Configuration def_cfg = default_config(); + std::vector<std::tuple<DomainType, DomainType, RangeFieldType>> values; + DomainType tmp_lower; + DomainType tmp_upper; + size_t cc = 0; + while (cfg.has_sub(DSC::toString(cc))) { + const Stuff::Common::Configuration local_cfg = cfg.sub(DSC::toString(cc)); + if (local_cfg.has_key("domain") && local_cfg.has_key("value")) { + auto domains = local_cfg.get<FieldMatrix<DomainFieldType, d, 2>>("domain"); + for (size_t dd = 0; dd < d; ++dd) { + tmp_lower[dd] = domains[dd][0]; + tmp_upper[dd] = domains[dd][1]; + } + auto val = local_cfg.get<RangeFieldType>("value"); + values.emplace_back(tmp_lower, tmp_upper, val); + } else + break; + ++cc; + } + return Common::make_unique<ThisType>(values, cfg.get("name", def_cfg.get<std::string>("name"))); + } // ... create(...) + + Indicator(const std::vector<std::tuple<DomainType, DomainType, R>>& values, const std::string name_in = "indicator") + : values_(values) + , name_(name_in) + { + } + + Indicator(const std::vector<std::pair<std::pair<Common::FieldVector<D, d>, Common::FieldVector<D, d>>, R>>& values, + const std::string name_in = "indicator") + : values_(convert(values)) + , name_(name_in) + { + } + + virtual ~Indicator() + { + } + + virtual std::string name() const override final + { + return name_; + } + + virtual std::unique_ptr<LocalfunctionType> local_function(const EntityType& entity) const override final + { + const auto center = entity.geometry().center(); + for (const auto& element : values_) + if (Common::FloatCmp::le(std::get<0>(element), center) && Common::FloatCmp::lt(center, std::get<1>(element))) + return Common::make_unique<Localfunction>(entity, std::get<2>(element)); + return Common::make_unique<Localfunction>(entity, 0.0); + } // ... local_function(...) + +private: + static std::vector<std::tuple<DomainType, DomainType, R>> + convert(const std::vector<std::pair<std::pair<Common::FieldVector<D, d>, Common::FieldVector<D, d>>, R>>& values) + { + std::vector<std::tuple<DomainType, DomainType, R>> ret; + for (const auto& element : values) + ret.emplace_back(element.first.first, element.first.second, element.second); + return ret; + } // convert(...) + + const std::vector<std::tuple<DomainType, DomainType, R>> values_; + const std::string name_; +}; // class Indicator + + +} // namespace Functions +} // namespace Stuff +} // namespace Dune + +#endif // DUNE_STUFF_FUNCTIONS_INDICATOR_HH -- GitLab