12#ifndef HYBRIDADRSOLVER_PROBLEM_DEFINITION_H
13#define HYBRIDADRSOLVER_PROBLEM_DEFINITION_H
15#ifndef HYBRIDADRSOLVER_PROBLEM_BASE_H
16#define HYBRIDADRSOLVER_PROBLEM_BASE_H
19#include <deal.II/base/function.h>
20#include <deal.II/base/point.h>
21#include <deal.II/base/tensor.h>
26using namespace dealii;
68 [[nodiscard]]
virtual std::set<types::boundary_id>
75 [[nodiscard]]
virtual std::set<types::boundary_id>
82 virtual const Function<dim>&
89 virtual const Function<dim>&
112 [[nodiscard]]
virtual std::string
get_name()
const = 0;
131 double value(
const Point<dim>& p,
const unsigned int)
const override {
133 for (
unsigned int d = 0; d < dim; ++d)
134 val *= std::sin(PI * p[d]);
142 const unsigned int)
const override {
144 for (
unsigned int d = 0; d < dim; ++d) {
145 grad[d] = PI * std::cos(PI * p[d]);
146 for (
unsigned int other = 0; other < dim; ++other)
148 grad[d] *= std::sin(PI * p[other]);
162 double value(
const Point<dim>& p,
const unsigned int)
const override {
167 double val = -1.0 * PI;
168 for (
unsigned int d = 1; d < dim; ++d)
169 val *= std::sin(PI * p[d]);
185 ADRProblem() : zero_function(1), neumann_flux(), exact_solution() {}
220 const double u = exact_solution.value(p, 0);
221 Tensor<1, dim> grad = exact_solution.gradient(p, 0);
228 const double lap = -1.0 * dim * PI * PI * u;
230 return -mu * lap + beta * grad + gamma * u;
237 [[nodiscard]] std::set<types::boundary_id>
239 std::set<types::boundary_id> ids;
254 [[nodiscard]] std::set<types::boundary_id>
262 return zero_function;
270 Assert(
false, ExcMessage(
"Unknown Neumann ID requested"));
271 return zero_function;
276 return exact_solution;
282 [[nodiscard]] std::string
get_name()
const override {
283 return "Manufactured ADR (Dirichlet + Neumann)";
287 Functions::ZeroFunction<dim> zero_function;
Abstract interface for defining a physical problem.
Definition problem_definition.h:39
virtual const Function< dim > & get_exact_solution() const =0
Returns the exact solution function object (if available).
virtual std::set< types::boundary_id > get_dirichlet_ids() const =0
Returns the set of boundary IDs where Dirichlet conditions are applied.
virtual const Function< dim > & get_dirichlet_function(types::boundary_id id) const =0
Gets the function describing the Dirichlet boundary value for a specific boundary ID.
virtual ~ProblemInterface()=default
virtual double reaction_coefficient(const Point< dim > &p) const =0
Returns the reaction coefficient .
virtual const Function< dim > & get_neumann_function(types::boundary_id id) const =0
Gets the function describing the Neumann flux for a specific boundary ID.
virtual std::string get_name() const =0
Returns a descriptive name of the problem.
virtual double diffusion_coefficient(const Point< dim > &p) const =0
Returns the diffusion coefficient .
virtual bool has_exact_solution() const =0
Checks if an analytical exact solution is available.
virtual Tensor< 1, dim > advection_field(const Point< dim > &p) const =0
Returns the advection velocity field .
virtual double source_term(const Point< dim > &p) const =0
Returns the source term .
virtual bool is_symmetric() const =0
Checks if the problem system matrix is symmetric.
virtual std::set< types::boundary_id > get_neumann_ids() const =0
Returns the set of boundary IDs where Neumann conditions are applied.
const Function< dim > & get_neumann_function(const types::boundary_id id) const override
Returns analytic flux for Neumann BCs.
Definition problem_definition.h:267
bool is_symmetric() const override
Problem is non-symmetric due to advection term.
Definition problem_definition.h:280
bool has_exact_solution() const override
Checks if an analytical exact solution is available.
Definition problem_definition.h:274
double diffusion_coefficient(const Point< dim > &) const override
Constant diffusion coefficient .
Definition problem_definition.h:188
const Function< dim > & get_dirichlet_function(types::boundary_id) const override
Returns zero function for Dirichlet BCs.
Definition problem_definition.h:261
std::string get_name() const override
Returns a descriptive name of the problem.
Definition problem_definition.h:282
Tensor< 1, dim > advection_field(const Point< dim > &p) const override
Rotational advection field. 2D: 3D: .
Definition problem_definition.h:202
ADRProblem()
Definition problem_definition.h:185
std::set< types::boundary_id > get_dirichlet_ids() const override
Defines Dirichlet boundaries. All boundaries except Right (ID 1) are Dirichlet (0,...
Definition problem_definition.h:238
const Function< dim > & get_exact_solution() const override
Returns the exact solution function object (if available).
Definition problem_definition.h:275
std::set< types::boundary_id > get_neumann_ids() const override
Defines Neumann boundaries. Only the Right boundary (ID 1) is Neumann.
Definition problem_definition.h:255
double source_term(const Point< dim > &p) const override
Computes the source term using the Method of Manufactured Solutions.
Definition problem_definition.h:219
double reaction_coefficient(const Point< dim > &) const override
Constant reaction coefficient .
Definition problem_definition.h:193
Manufactured exact solution: .
Definition problem_definition.h:125
Tensor< 1, dim > gradient(const Point< dim > &p, const unsigned int) const override
Evaluates the gradient of the exact solution at point p.
Definition problem_definition.h:141
double value(const Point< dim > &p, const unsigned int) const override
Evaluates the exact solution at point p.
Definition problem_definition.h:131
Analytic Neumann flux for the Right boundary (x=1).
Definition problem_definition.h:160
double value(const Point< dim > &p, const unsigned int) const override
Definition problem_definition.h:162
Definition problem_definition.h:115
Definition problem_definition.h:25