libMesh
solution_function.h
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2025 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License, or (at your option) any later version.
8 
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
13 
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 
18 #ifndef SOLUTION_FUNCTION_H
19 #define SOLUTION_FUNCTION_H
20 
21 // libMesh includes
22 #include "libmesh/function_base.h"
23 
24 // Example includes
25 #include "mixed_exact_solution.h"
26 
27 // C++ includes
28 #include <memory>
29 
30 using namespace libMesh;
31 
32 template <unsigned int dim>
33 class SolutionFunction : public FunctionBase<Number>
34 {
35 public:
36  SolutionFunction() = default;
37  ~SolutionFunction() = default;
38 
39  virtual Number operator()(const Point &, const Real = 0) override { libmesh_not_implemented(); }
40 
41  virtual void operator()(const Point & p, const Real, DenseVector<Number> & output) override;
42 
43  virtual std::unique_ptr<FunctionBase<Number>> clone() const override
44  {
45  return std::make_unique<SolutionFunction>();
46  }
47 
48  virtual Number component(unsigned int i, const Point & p, Real time = 0.) override
49  {
50  const auto size = dim == 2 ? 4 : 5;
51  DenseVector<Number> outvec(size);
52  (*this)(p, time, outvec);
53  return outvec(i);
54  }
55 
56 private:
58 };
59 
60 template <>
61 void
63 {
64  // We should have our vector variable, our scalar variable, and our higher order scalar variable
65  libmesh_assert(output.size() <= 4);
66  output.zero();
67  const Real x = p(0), y = p(1);
68  // libMesh assumes each component of a vector-valued variable is stored
69  // contiguously.
70  const auto vector = soln(x, y);
71  output(0) = vector(0);
72  output(1) = vector(1);
73  const auto scalar = soln.scalar(x, y);
74  output(2) = scalar;
75  output(3) = scalar;
76 }
77 
78 template <>
79 void
81 {
82  // We should have our vector variable, our scalar variable, and our higher order scalar variable
83  libmesh_assert(output.size() <= 5);
84  output.zero();
85  const Real x = p(0), y = p(1), z = p(2);
86  // libMesh assumes each component of the vector-valued variable is stored
87  // contiguously.
88  const auto vector = soln(x, y, z);
89  output(0) = vector(0);
90  output(1) = vector(1);
91  output(2) = vector(2);
92  const auto scalar = soln.scalar(x, y, z);
93  output(3) = scalar;
94  output(4) = scalar;
95 }
96 
97 template <unsigned int dim>
98 class SolutionGradient : public FunctionBase<Gradient>
99 {
100 public:
101  SolutionGradient() = default;
102  ~SolutionGradient() = default;
103 
104  virtual Gradient operator()(const Point &, const Real = 0) override { libmesh_not_implemented(); }
105 
106  virtual void operator()(const Point & p, const Real, DenseVector<Gradient> & output) override;
107 
108  virtual std::unique_ptr<FunctionBase<Gradient>> clone() const override
109  {
110  return std::make_unique<SolutionGradient>();
111  }
112 
113  virtual Gradient component(unsigned int i, const Point & p, Real time = 0.) override
114  {
115  const auto size = dim == 2 ? 4 : 5;
116  DenseVector<Gradient> outvec(size);
117  (*this)(p, time, outvec);
118  return outvec(i);
119  }
120 
121 private:
123 };
124 
125 template <>
126 void
128 {
129  output.zero();
130  const Real x = p(0), y = p(1);
131  output(0) = soln.grad(x, y).row(0);
132  output(1) = soln.grad(x, y).row(1);
133 }
134 
135 template <>
136 void
138 {
139  output.zero();
140  const Real x = p(0), y = p(1), z = p(2);
141  output(0) = soln.grad(x, y, z).row(0);
142  output(1) = soln.grad(x, y, z).row(1);
143  output(2) = soln.grad(x, y, z).row(2);
144 }
145 
146 #endif // SOLUTION_FUNCTION_H
virtual Number operator()(const Point &, const Real=0)
virtual void zero() override final
Set every element in the vector to 0.
Definition: dense_vector.h:420
virtual Gradient operator()(const Point &, const Real=0)
unsigned int dim
This class defines a vector in LIBMESH_DIM dimensional Real or Complex space.
The libMesh namespace provides an interface to certain functionality in the library.
virtual std::unique_ptr< FunctionBase< Number > > clone() const override
libmesh_assert(ctx)
virtual std::unique_ptr< FunctionBase< Gradient > > clone() const override
virtual Gradient component(unsigned int i, const Point &p, Real time=0.) override
virtual Gradient operator()(const Point &, const Real=0) override
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
MixedExactSolution soln
virtual Number operator()(const Point &, const Real=0) override
virtual unsigned int size() const override final
Definition: dense_vector.h:104
virtual Number component(unsigned int i, const Point &p, Real time=0.) override
Base class for functors that can be evaluated at a point and (optionally) time.
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition: point.h:39
MixedExactSolution soln