libMesh
Loading...
Searching...
No Matches
composite_fem_function.h
Go to the documentation of this file.
1// The libMesh Finite Element Library.
2// Copyright (C) 2002-2026 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 LIBMESH_COMPOSITE_FEM_FUNCTION_H
19#define LIBMESH_COMPOSITE_FEM_FUNCTION_H
20
21// libMesh includes
22#include "libmesh/dense_vector.h"
23#include "libmesh/fem_function_base.h"
24#include "libmesh/int_range.h"
25#include "libmesh/libmesh.h"
26#include "libmesh/point.h"
27
28// C++ includes
29#include <algorithm>
30#include <utility>
31#include <vector>
32
33namespace libMesh
34{
35
43template <typename Output=Number>
45{
46public:
47 explicit
49
55
62
66 virtual ~CompositeFEMFunction () = default;
67
74 std::vector<unsigned int> index_map)
75 {
76 const unsigned int subfunction_index =
77 cast_int<unsigned int>(subfunctions.size());
78 libmesh_assert_equal_to(subfunctions.size(), index_maps.size());
79
80 subfunctions.push_back(f.clone());
81
82 unsigned int max_index =
83 *std::max_element(index_map.begin(), index_map.end());
84
85 if (max_index >= reverse_index_map.size())
87 (max_index+1, std::make_pair(libMesh::invalid_uint,
89
90 for (auto j : index_range(index_map))
91 {
92 libmesh_assert_less(index_map[j], reverse_index_map.size());
93 libmesh_assert_equal_to(reverse_index_map[index_map[j]].first,
95 libmesh_assert_equal_to(reverse_index_map[index_map[j]].second,
97 reverse_index_map[index_map[j]] =
98 std::make_pair(subfunction_index, j);
99 }
100
101 index_maps.push_back(std::move(index_map));
102 }
103
104 virtual Output operator() (const FEMContext & c,
105 const Point & p,
106 const Real time = 0) override
107 {
108 return this->component(c,0,p,time);
109 }
110
111 virtual void operator() (const FEMContext & c,
112 const Point & p,
113 const Real time,
114 DenseVector<Output> & output) override
115 {
116 libmesh_assert_greater_equal (output.size(),
117 reverse_index_map.size());
118
119 // Necessary in case we have output components not covered by
120 // any subfunctions
121 output.zero();
122
124 for (auto i : index_range(subfunctions))
125 {
126 temp.resize(cast_int<unsigned int>(index_maps[i].size()));
127 (*subfunctions[i])(c, p, time, temp);
128 for (auto j : index_range(temp))
129 output(index_maps[i][j]) = temp(j);
130 }
131 }
132
133 virtual Output component (const FEMContext & c,
134 unsigned int i,
135 const Point & p,
136 Real time) override
137 {
138 if (i >= reverse_index_map.size() ||
140 return 0;
141
142 libmesh_assert_less(reverse_index_map[i].first,
143 subfunctions.size());
144 libmesh_assert_not_equal_to(reverse_index_map[i].second,
146 return subfunctions[reverse_index_map[i].first]->
147 component(c, reverse_index_map[i].second, p, time);
148 }
149
150 virtual std::unique_ptr<FEMFunctionBase<Output>> clone() const override
151 {
152 auto returnval = std::make_unique<CompositeFEMFunction>();
153 for (auto i : index_range(subfunctions))
154 returnval->attach_subfunction(*subfunctions[i], index_maps[i]);
155 return returnval;
156 }
157
158 unsigned int n_subfunctions () const
159 {
160 return subfunctions.size();
161 }
162
163 unsigned int n_components () const
164 {
165 return reverse_index_map.size();
166 }
167
168private:
169 // list of functions which fill in our values
170 std::vector<std::unique_ptr<FEMFunctionBase<Output>>> subfunctions;
171
172 // for each function, list of which global indices it fills in
173 std::vector<std::vector<unsigned int>> index_maps;
174
175 // for each global index, which local index of which function is it?
176 std::vector<std::pair<unsigned int, unsigned int>> reverse_index_map;
177};
178
179
180} // namespace libMesh
181
182#endif // LIBMESH_COMPOSITE_FEM_FUNCTION_H
FEMFunction which is a function of another function.
void attach_subfunction(const FEMFunctionBase< Output > &f, std::vector< unsigned int > index_map)
Attach a new subfunction, along with a map from the indices of that subfunction to the indices of the...
CompositeFEMFunction(const CompositeFEMFunction &)=delete
This class contains unique_ptr members so it can't be default copied or assigned.
virtual Output operator()(const FEMContext &c, const Point &p, const Real time=0) override
std::vector< std::pair< unsigned int, unsigned int > > reverse_index_map
std::vector< std::vector< unsigned int > > index_maps
CompositeFEMFunction(CompositeFEMFunction &&)=default
This class can be default move constructed and assigned.
CompositeFEMFunction & operator=(CompositeFEMFunction &&)=default
virtual ~CompositeFEMFunction()=default
The subfunctions vector is automatically cleaned up.
std::vector< std::unique_ptr< FEMFunctionBase< Output > > > subfunctions
virtual std::unique_ptr< FEMFunctionBase< Output > > clone() const override
virtual Output component(const FEMContext &c, unsigned int i, const Point &p, Real time) override
Defines a dense vector for use in Finite Element-type computations.
void resize(const unsigned int n)
Resize the vector.
virtual void zero() override final
Set every element in the vector to 0.
virtual unsigned int size() const override final
This class provides all data required for a physics package (e.g.
Definition fem_context.h:63
FEMFunctionBase is a base class from which users can derive in order to define "function-like" object...
virtual std::unique_ptr< FEMFunctionBase< Output > > clone() const =0
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition point.h:40
The libMesh namespace provides an interface to certain functionality in the library.
auto index_range(const T &sizable)
Helper function that returns an IntRange<std::size_t> representing all the indices of the passed-in v...
Definition int_range.h:153
const unsigned int invalid_uint
A number which is used quite often to represent an invalid or uninitialized value for an unsigned int...
Definition libmesh.h:303
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real