libMesh
composite_fem_function.h
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2017 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/libmesh.h"
25 #include "libmesh/point.h"
26 
27 // C++ includes
28 #include <algorithm>
29 #include <utility>
30 #include <vector>
31 
32 namespace libMesh
33 {
34 
42 template <typename Output=Number>
43 class CompositeFEMFunction : public FEMFunctionBase<Output>
44 {
45 public:
46  explicit
48 
50  {
51  for (std::size_t i=0; i != subfunctions.size(); ++i)
52  delete subfunctions[i];
53  }
54 
61  const std::vector<unsigned int> & index_map)
62  {
63  const unsigned int subfunction_index = subfunctions.size();
64  libmesh_assert_equal_to(subfunctions.size(), index_maps.size());
65 
66  subfunctions.push_back(f.clone().release());
67  index_maps.push_back(index_map);
68 
69  unsigned int max_index =
70  *std::max_element(index_map.begin(), index_map.end());
71 
72  if (max_index >= reverse_index_map.size())
73  reverse_index_map.resize
74  (max_index+1, std::make_pair(libMesh::invalid_uint,
76 
77  for (std::size_t j=0; j != index_map.size(); ++j)
78  {
79  libmesh_assert_less(index_map[j], reverse_index_map.size());
80  libmesh_assert_equal_to(reverse_index_map[index_map[j]].first,
82  libmesh_assert_equal_to(reverse_index_map[index_map[j]].second,
84  reverse_index_map[index_map[j]] =
85  std::make_pair(subfunction_index, j);
86  }
87  }
88 
89  virtual Output operator() (const FEMContext & c,
90  const Point & p,
91  const Real time = 0) libmesh_override
92  {
93  return this->component(c,0,p,time);
94  }
95 
96  virtual void operator() (const FEMContext & c,
97  const Point & p,
98  const Real time,
99  DenseVector<Output> & output) libmesh_override
100  {
101  libmesh_assert_greater_equal (output.size(),
102  reverse_index_map.size());
103 
104  // Necessary in case we have output components not covered by
105  // any subfunctions
106  output.zero();
107 
108  DenseVector<Output> temp;
109  for (std::size_t i=0; i != subfunctions.size(); ++i)
110  {
111  temp.resize(index_maps[i].size());
112  (*subfunctions[i])(c, p, time, temp);
113  for (std::size_t j=0; j != temp.size(); ++j)
114  output(index_maps[i][j]) = temp(j);
115  }
116  }
117 
118  virtual Output component (const FEMContext & c,
119  unsigned int i,
120  const Point & p,
121  Real time) libmesh_override
122  {
123  if (i >= reverse_index_map.size() ||
125  return 0;
126 
127  libmesh_assert_less(reverse_index_map[i].first,
128  subfunctions.size());
129  libmesh_assert_not_equal_to(reverse_index_map[i].second,
131  return subfunctions[reverse_index_map[i].first]->
132  component(c, reverse_index_map[i].second, p, time);
133  }
134 
135  virtual UniquePtr<FEMFunctionBase<Output>> clone() const libmesh_override
136  {
137  CompositeFEMFunction * returnval = new CompositeFEMFunction();
138  for (std::size_t i=0; i != subfunctions.size(); ++i)
139  returnval->attach_subfunction(*subfunctions[i], index_maps[i]);
140  return UniquePtr<FEMFunctionBase<Output>> (returnval);
141  }
142 
143  unsigned int n_subfunctions () const
144  {
145  return subfunctions.size();
146  }
147 
148  unsigned int n_components () const
149  {
150  return reverse_index_map.size();
151  }
152 
153 private:
154  // list of functions which fill in our values
155  std::vector<FEMFunctionBase<Output> *> subfunctions;
156 
157  // for each function, list of which global indices it fills in
158  std::vector<std::vector<unsigned int>> index_maps;
159 
160  // for each global index, which local index of which function is it?
161  std::vector<std::pair<unsigned int, unsigned int>> reverse_index_map;
162 };
163 
164 
165 } // namespace libMesh
166 
167 #endif // LIBMESH_COMPOSITE_FEM_FUNCTION_H
virtual Output operator()(const FEMContext &c, const Point &p, const Real time=0) libmesh_override
virtual UniquePtr< FEMFunctionBase< Output > > clone() const libmesh_override
const unsigned int invalid_uint
A number which is used quite often to represent an invalid or uninitialized value.
Definition: libmesh.h:184
std::vector< std::pair< unsigned int, unsigned int > > reverse_index_map
void resize(const unsigned int n)
Resize the vector.
Definition: dense_vector.h:350
void attach_subfunction(const FEMFunctionBase< Output > &f, const 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...
The libMesh namespace provides an interface to certain functionality in the library.
virtual unsigned int size() const libmesh_override
Definition: dense_vector.h:87
std::unique_ptr< T > UniquePtr
Definition: auto_ptr.h:46
std::vector< std::vector< unsigned int > > index_maps
FEMFunction which is a function of another function.
This class provides all data required for a physics package (e.g.
Definition: fem_context.h:61
virtual Output component(const FEMContext &c, unsigned int i, const Point &p, Real time) libmesh_override
DIE A HORRIBLE DEATH HERE typedef LIBMESH_DEFAULT_SCALAR_TYPE Real
virtual UniquePtr< FEMFunctionBase< Output > > clone() const =0
Defines a dense vector for use in Finite Element-type computations.
FEMFunctionBase is a base class from which users can derive in order to define "function-like" object...
A Point defines a location in LIBMESH_DIM dimensional Real space.
Definition: point.h:38
std::vector< FEMFunctionBase< Output > * > subfunctions