feat(quadrature): quadrature system brought over
Ported and dramatically cleaned up the quadrature system. This includes centralizing all field definitions
This commit is contained in:
10
src/include/serif/discretization/forms/concept.hpp
Normal file
10
src/include/serif/discretization/forms/concept.hpp
Normal file
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
#include "serif/discretization/forms/forms.hpp"
|
||||
|
||||
namespace serif::discretization::forms {
|
||||
template <typename FormCandidate>
|
||||
concept Form = std::derived_from<std::remove_cvref_t<FormCandidate>, form> && // A form must derive from form
|
||||
requires {
|
||||
typename std::remove_cvref_t<FormCandidate>::operand_types; // a form must define a type list of operand types for the trial and test terms
|
||||
}; // We could consider strengthening this to enforce that the type list (operand_types) contains only operand types and that there is an entry for TrialT and TestT
|
||||
}
|
||||
48
src/include/serif/discretization/forms/form_traits.hpp
Normal file
48
src/include/serif/discretization/forms/form_traits.hpp
Normal file
@@ -0,0 +1,48 @@
|
||||
#pragma once
|
||||
|
||||
#include "serif/discretization/forms/concept.hpp"
|
||||
#include "serif/discretization/forms/forms.hpp"
|
||||
|
||||
namespace serif::discretization::forms {
|
||||
template <Form FormT>
|
||||
struct FormTraits {
|
||||
static constexpr int trial_order_reduction = 0;
|
||||
static constexpr int test_order_reduction = 0;
|
||||
};
|
||||
|
||||
template <blocks::Term TrialT, blocks::Term TestT>
|
||||
struct FormTraits<mass<TrialT, TestT>> {
|
||||
static constexpr int trial_order_reduction = 0;
|
||||
static constexpr int test_order_reduction = 0;
|
||||
};
|
||||
|
||||
template <blocks::Term TrialT, blocks::Term TestT>
|
||||
struct FormTraits<divergence<TrialT, TestT>> {
|
||||
static constexpr int trial_order_reduction = 1;
|
||||
static constexpr int test_order_reduction = 0;
|
||||
};
|
||||
|
||||
template <blocks::Term TrialT, blocks::Term TestT>
|
||||
struct FormTraits<source<TrialT, TestT>> {
|
||||
static constexpr int trial_order_reduction = 0;
|
||||
static constexpr int test_order_reduction = 0;
|
||||
};
|
||||
|
||||
template <blocks::Term TrialT, blocks::Term TestT>
|
||||
struct FormTraits<force<TrialT, TestT>> {
|
||||
static constexpr int trial_order_reduction = 0;
|
||||
static constexpr int test_order_reduction = 0;
|
||||
};
|
||||
|
||||
template <blocks::Term TrialT, blocks::Term TestT>
|
||||
struct FormTraits<boundary_flux<TrialT, TestT>> {
|
||||
static constexpr int trial_order_reduction = 0;
|
||||
static constexpr int test_order_reduction = 0;
|
||||
};
|
||||
|
||||
template <blocks::Term TrialT, blocks::Term TestT>
|
||||
struct FormTraits<projection<TrialT, TestT>> {
|
||||
static constexpr int trial_order_reduction = 0;
|
||||
static constexpr int test_order_reduction = 0;
|
||||
};
|
||||
}
|
||||
73
src/include/serif/discretization/forms/forms.hpp
Normal file
73
src/include/serif/discretization/forms/forms.hpp
Normal file
@@ -0,0 +1,73 @@
|
||||
#pragma once
|
||||
|
||||
#include <concepts>
|
||||
#include <type_traits>
|
||||
|
||||
#include "serif/discretization/blocks/concepts.hpp"
|
||||
#include "serif/discretization/forms/operands.hpp"
|
||||
#include "serif/utils/types/type_list.hpp"
|
||||
#include "serif/meta/names.hpp"
|
||||
|
||||
namespace serif::discretization::forms {
|
||||
struct form {};
|
||||
|
||||
template <blocks::Term TrialT, blocks::Term TestT>
|
||||
struct mass final : form {
|
||||
static constexpr std::string_view name = meta::template_name<mass>();
|
||||
|
||||
using trial_type = TrialT;
|
||||
using test_type = TestT;
|
||||
|
||||
using operand_types = utils::types::TypeList<Operand<TrialT>, Operand<TestT>>;
|
||||
};
|
||||
|
||||
template <blocks::Term TrialT, blocks::Term TestT>
|
||||
struct divergence final : form {
|
||||
static constexpr std::string_view name = meta::template_name<divergence>();
|
||||
|
||||
using trial_type = TrialT;
|
||||
using test_type = TestT;
|
||||
|
||||
using operand_types = utils::types::TypeList<Operand<TrialT, Operation::Divergence>, Operand<TestT>>;
|
||||
};
|
||||
|
||||
template <blocks::Term TrialT, blocks::Term TestT>
|
||||
struct source final : form {
|
||||
static constexpr std::string_view name = meta::template_name<source>();
|
||||
|
||||
using trial_type = TrialT;
|
||||
using test_type = TestT;
|
||||
|
||||
using operand_types = utils::types::TypeList<Operand<TrialT>, Operand<TestT>>;
|
||||
};
|
||||
|
||||
template <blocks::Term TrialT, blocks::Term TestT>
|
||||
struct force final : form {
|
||||
static constexpr std::string_view name = meta::template_name<force>();
|
||||
|
||||
using trial_type = TrialT;
|
||||
using test_type = TestT;
|
||||
|
||||
using operand_types = utils::types::TypeList<Operand<TrialT>, Operand<TestT>>;
|
||||
};
|
||||
|
||||
template <blocks::Term TrialT, blocks::Term TestT>
|
||||
struct boundary_flux final : form {
|
||||
static constexpr std::string_view name = meta::template_name<boundary_flux>();
|
||||
|
||||
using trial_type = TrialT;
|
||||
using test_type = TestT;
|
||||
|
||||
using operand_types = utils::types::TypeList<Operand<TrialT, Operation::NormalTrace>, Operand<TestT, Operation::NormalTrace>>;
|
||||
};
|
||||
|
||||
template <blocks::Term TrialT, blocks::Term TestT>
|
||||
struct projection final : form {
|
||||
static constexpr std::string_view name = meta::template_name<projection>();
|
||||
|
||||
using trial_type = TrialT;
|
||||
using test_type = TestT;
|
||||
|
||||
using operand_types = utils::types::TypeList<Operand<TrialT>, Operand<TestT>>;
|
||||
};
|
||||
}
|
||||
38
src/include/serif/discretization/forms/operands.hpp
Normal file
38
src/include/serif/discretization/forms/operands.hpp
Normal file
@@ -0,0 +1,38 @@
|
||||
#pragma once
|
||||
|
||||
#include <concepts>
|
||||
#include <type_traits>
|
||||
|
||||
#include "serif/discretization/blocks/concepts.hpp"
|
||||
|
||||
namespace serif::discretization::forms {
|
||||
struct Operation {
|
||||
struct Value {};
|
||||
struct Gradient {};
|
||||
struct Divergence {};
|
||||
struct Curl {};
|
||||
struct NormalTrace {};
|
||||
};
|
||||
|
||||
template <typename OperationCandidate>
|
||||
concept IsOperation =
|
||||
std::same_as<std::remove_cvref_t<OperationCandidate>, Operation::Value> ||
|
||||
std::same_as<std::remove_cvref_t<OperationCandidate>, Operation::Gradient> ||
|
||||
std::same_as<std::remove_cvref_t<OperationCandidate>, Operation::Divergence> ||
|
||||
std::same_as<std::remove_cvref_t<OperationCandidate>, Operation::Curl> ||
|
||||
std::same_as<std::remove_cvref_t<OperationCandidate>, Operation::NormalTrace>;
|
||||
|
||||
template <blocks::Term TermT, IsOperation OperationT = Operation::Value> // We choose to default to the value operation because it is the most common.
|
||||
struct Operand final {
|
||||
using term_type = TermT;
|
||||
using operation_type = OperationT;
|
||||
};
|
||||
|
||||
template <typename OperandCandidate>
|
||||
concept IsOperand = requires { // Recall that requires expressions are not evaluated. What this checks is that it is valid syntax given the type to requires the term type and operation type. It does not check that the term type is a valid term or that the operation type is a valid operation.
|
||||
typename std::remove_cvref_t<OperandCandidate>::term_type;
|
||||
typename std::remove_cvref_t<OperandCandidate>::operation_type; } &&
|
||||
blocks::Term<typename std::remove_cvref_t<OperandCandidate>::term_type> && // Then here, now that we know we can safely ask for the term type we validate it is actually a valid term
|
||||
IsOperation<typename std::remove_cvref_t<OperandCandidate>::operation_type>; // And here we validate that the operation type is actually a valid operation
|
||||
|
||||
};
|
||||
34
src/include/serif/discretization/forms/runtime.hpp
Normal file
34
src/include/serif/discretization/forms/runtime.hpp
Normal file
@@ -0,0 +1,34 @@
|
||||
#pragma once
|
||||
|
||||
#include <string_view>
|
||||
#include <format>
|
||||
|
||||
#include "serif/discretization/blocks/runtime.hpp"
|
||||
#include "serif/discretization/forms/concept.hpp"
|
||||
|
||||
namespace serif::discretization::forms {
|
||||
struct FormDescriptor final {
|
||||
std::string_view name;
|
||||
|
||||
blocks::TermDescriptor trial;
|
||||
blocks::TermDescriptor test;
|
||||
|
||||
[[nodiscard]] friend constexpr bool operator==(const FormDescriptor&, const FormDescriptor&) noexcept = default;
|
||||
};
|
||||
|
||||
template <Form FormT>
|
||||
inline constexpr FormDescriptor form_descriptor{
|
||||
.name = FormT::name,
|
||||
.trial = blocks::term_descriptor<typename FormT::trial_type>,
|
||||
.test = blocks::term_descriptor<typename FormT::test_type>
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
template <>
|
||||
struct std::formatter<serif::discretization::forms::FormDescriptor> : std::formatter<std::string> {
|
||||
template <typename FormatContext>
|
||||
auto format(const serif::discretization::forms::FormDescriptor& fd, FormatContext& ctx) const {
|
||||
return std::formatter<std::string>::format(std::format("FormDescriptor(name={}, trial={}, test={})", fd.name, fd.trial, fd.test), ctx);
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user