MAST3
Multidisciplinary-design Adaptation and Sensitivity Toolkit (MAST)
utility.hpp
Go to the documentation of this file.
1 /*
2 * MAST: Multidisciplinary-design Adaptation and Sensitivity Toolkit
3 * Copyright (C) 2013-2020 Manav Bhatia and MAST authors
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19 
20 #ifndef __mast_libmesh_assembly_utility_h__
21 #define __mast_libmesh_assembly_utility_h__
22 
23 // MAST includes
25 #include <mast/base/exceptions.hpp>
27 
28 // libMesh includes
29 #include <libmesh/dof_map.h>
30 #include <libmesh/dense_vector.h>
31 #include <libmesh/dense_matrix.h>
32 #include <libmesh/numeric_vector.h>
33 #include <libmesh/sparse_matrix.h>
34 
35 namespace MAST {
36 namespace Base {
37 namespace Assembly {
38 namespace libMeshWrapper {
39 
40 
41 template <typename ScalarType, typename VecType>
42 inline void
43 add_to_vector(VecType& v, const uint_t i, const ScalarType& s) {
44 
45  v(i) += s;
46 }
47 
48 
49 inline void
50 add_to_vector(libMesh::NumericVector<real_t>& v, const uint_t i, const real_t& s) {
51 
52  v.add(i, s);
53 }
54 
55 
56 template <typename ScalarType, typename MatType>
57 inline void
58 add_to_matrix(MatType& m, const uint_t i, const uint_t j, const ScalarType& v) {
59 
60  m(i, j) += v;
61 }
62 
63 
64 inline void
65 add_to_matrix(libMesh::SparseMatrix<real_t>& m, const uint_t i, const uint_t j, const real_t& v) {
66 
67  m.add(i, j, v);
68 }
69 
70 
71 template <typename ScalarType, int P2, typename P3>
72 inline void
73 add_to_matrix(Eigen::SparseMatrix<ScalarType, P2, P3> &m,
74  const uint_t i, const uint_t j, const ScalarType& v) {
75 
76  m.coeffRef(i, j) += v;
77 }
78 
79 
80 template <typename ScalarType,
81  typename VecType,
82  typename MatType,
83  typename SubVecType,
84  typename SubMatType>
85 inline
88  MatType &m,
89  const libMesh::DofMap &dof_map,
90  std::vector<libMesh::dof_id_type> &dof_indices,
91  SubVecType &v_sub,
92  SubMatType &m_sub) {
93 
94  libMesh::DenseVector<real_t> v1;
95  libMesh::DenseMatrix<real_t> m1;
98 
99  dof_map.constrain_element_matrix_and_vector(m1, v1, dof_indices);
100 
101  for (uint_t i=0; i<dof_indices.size(); i++)
102  add_to_vector(v, dof_indices[i], v1(i));
103 
104  for (uint_t i=0; i<dof_indices.size(); i++)
105  for (uint_t j=0; j<dof_indices.size(); j++)
106  add_to_matrix(m, dof_indices[i], dof_indices[j], m1(i,j));
107 }
108 
109 
110 template <typename ScalarType, typename VecType, typename SubVecType>
111 inline
112 typename std::enable_if<std::is_same<ScalarType, real_t>::value, void>::type
114  const libMesh::DofMap &dof_map,
115  std::vector<libMesh::dof_id_type> &dof_indices,
116  SubVecType &v_sub) {
117 
118  libMesh::DenseVector<real_t> v1;
120 
121  dof_map.constrain_element_vector(v1, dof_indices);
122 
123  for (uint_t i=0; i<dof_indices.size(); i++)
124  add_to_vector(v, dof_indices[i], v1(i));
125 }
126 
127 
128 
129 template <typename ScalarType, typename MatType, typename SubMatType>
130 inline
131 typename std::enable_if<std::is_same<ScalarType, real_t>::value, void>::type
133  const libMesh::DofMap &dof_map,
134  std::vector<libMesh::dof_id_type> &dof_indices,
135  SubMatType &m_sub) {
136 
137  libMesh::DenseMatrix<real_t> m1;
139 
140  dof_map.constrain_element_matrix(m1, dof_indices);
141 
142  for (uint_t i=0; i<dof_indices.size(); i++)
143  for (uint_t j=0; j<dof_indices.size(); j++)
144  add_to_matrix(m, dof_indices[i], dof_indices[j], m1(i,j));
145 }
146 
147 
148 
149 template <typename ScalarType,
150  typename VecType,
151  typename MatType,
152  typename SubVecType,
153  typename SubMatType>
154 inline
157  MatType &m,
158  const libMesh::DofMap &dof_map,
159  std::vector<libMesh::dof_id_type> &dof_indices,
160  SubVecType &v_sub,
161  SubMatType &m_sub) {
162 
163  Assert2(v_sub.size() == dof_indices.size(),
164  v_sub.size(), dof_indices.size(),
165  "Incompatible vector size");
166  Assert2(m_sub.rows() == dof_indices.size(),
167  m_sub.rows(), dof_indices.size(),
168  "Incompatible matrix rows");
169  Assert2(m_sub.cols() == dof_indices.size(),
170  m_sub.cols(), dof_indices.size(),
171  "Incompatible matrix columns");
172 
173  // complex matrix and vector require that the complex and imaginary parts of the matrix
174  // and vector be independently constrained
175  libMesh::DenseVector<real_t>
176  v_re(v_sub.size()),
177  v_im(v_sub.size());
178  libMesh::DenseMatrix<real_t>
179  m_re(v_sub.size(), v_sub.size()),
180  m_im(v_sub.size(), v_sub.size());
181 
182  std::vector<libMesh::dof_id_type>
183  dof_indices_im = dof_indices;
184 
185  // copy the real and imaginary parts
186  for (uint_t i=0; i<v_sub.size(); i++) {
187 
188  v_re(i) = v_sub(i).real();
189  v_im(i) = v_sub(i).imag();
190 
191  for (uint_t j=0; j<v_sub.size(); j++) {
192 
193  m_re(i, j) = m_sub(i, j).real();
194  m_im(i, j) = m_sub(i, j).imag();
195  }
196  }
197 
198  // now constraint the vector and matrix. The imaginary part is homogenously constrained
199  //
200  dof_map.constrain_element_matrix_and_vector(m_re, v_re, dof_indices);
201  dof_map.constrain_element_matrix_and_vector(m_im, v_im, dof_indices_im);
202 
203 
204  for (uint_t i=0; i<dof_indices.size(); i++) {
205 
206  v(dof_indices[i]) += complex_t(v_re(i), v_im(i));
207 
208  for (uint_t j=0; j<dof_indices.size(); j++)
209  add_to_matrix(m, dof_indices[i], dof_indices[j], complex_t(m_re(i,j), m_im(i,j)));
210  }
211 }
212 
213 
214 template <typename ScalarType, typename VecType, typename SubVecType>
215 inline
216 typename std::enable_if<std::is_same<ScalarType, complex_t>::value, void>::type
218  const libMesh::DofMap &dof_map,
219  std::vector<libMesh::dof_id_type> &dof_indices,
220  SubVecType &v_sub) {
221 
222  Assert2(v_sub.size() == dof_indices.size(),
223  v_sub.size(), dof_indices.size(),
224  "Incompatible vector size");
225 
226  // complex matrix and vector require that the complex and imaginary parts of the matrix
227  // and vector be independently constrained
228  libMesh::DenseVector<real_t>
229  v_re(v_sub.size()),
230  v_im(v_sub.size());
231 
232  std::vector<libMesh::dof_id_type>
233  dof_indices_im = dof_indices;
234 
235  // copy the real and imaginary parts
236  for (uint_t i=0; i<v_sub.size(); i++) {
237 
238  v_re(i) = v_sub(i).real();
239  v_im(i) = v_sub(i).imag();
240  }
241 
242  // now constraint the vector and matrix. The imaginary part is homogenously constrained
243  //
244  dof_map.constrain_element_vector(v_re, dof_indices);
245  dof_map.constrain_element_vector(v_im, dof_indices_im);
246 
247 
248  for (uint_t i=0; i<dof_indices.size(); i++)
249  v(dof_indices[i]) += complex_t(v_re(i), v_im(i));
250 }
251 
252 
253 template <typename ScalarType, typename MatType, typename SubMatType>
254 inline
255 typename std::enable_if<std::is_same<ScalarType, complex_t>::value, void>::type
257  const libMesh::DofMap &dof_map,
258  std::vector<libMesh::dof_id_type> &dof_indices,
259  SubMatType &m_sub) {
260 
261  Assert2(m_sub.rows() == dof_indices.size(),
262  m_sub.rows(), dof_indices.size(),
263  "Incompatible matrix rows");
264  Assert2(m_sub.cols() == dof_indices.size(),
265  m_sub.cols(), dof_indices.size(),
266  "Incompatible matrix columns");
267 
268  // complex matrix and vector require that the complex and imaginary parts of the matrix
269  // and vector be independently constrained
270  libMesh::DenseMatrix<real_t>
271  m_re(m_sub.rows(), m_sub.cols()),
272  m_im(m_sub.rows(), m_sub.cols());
273 
274  std::vector<libMesh::dof_id_type>
275  dof_indices_im = dof_indices;
276 
277  // copy the real and imaginary parts
278  for (uint_t i=0; i<m_sub.rows(); i++)
279  for (uint_t j=0; j<m_sub.cols(); j++) {
280 
281  m_re(i, j) = m_sub(i, j).real();
282  m_im(i, j) = m_sub(i, j).imag();
283  }
284 
285  // now constraint the vector and matrix. The imaginary part is homogenously constrained
286  //
287  dof_map.constrain_element_matrix(m_re, dof_indices);
288  dof_map.constrain_element_matrix(m_im, dof_indices_im);
289 
290 
291  for (uint_t i=0; i<dof_indices.size(); i++)
292  for (uint_t j=0; j<dof_indices.size(); j++)
293  add_to_matrix(m, dof_indices[i], dof_indices[j], complex_t(m_re(i,j), m_im(i,j)));
294 }
295 
296 
297 inline void
298 constrain_and_add_matrix_and_vector(libMesh::NumericVector<real_t> &v,
299  libMesh::SparseMatrix<real_t> &m,
300  const libMesh::DofMap &dof_map,
301  std::vector<libMesh::dof_id_type> &dof_indices,
302  libMesh::DenseVector<real_t> &v_sub,
303  libMesh::DenseMatrix<real_t> &m_sub) {
304 
305  dof_map.constrain_element_matrix_and_vector(m_sub, v_sub, dof_indices);
306  m.add_matrix(m_sub, dof_indices);
307  v.add_vector(v_sub, dof_indices);
308 }
309 
310 
311 inline void
312 constrain_and_add_vector(libMesh::NumericVector<real_t> &v,
313  const libMesh::DofMap &dof_map,
314  std::vector<libMesh::dof_id_type> &dof_indices,
315  libMesh::DenseVector<real_t> &v_sub) {
316 
317  dof_map.constrain_element_vector(v_sub, dof_indices);
318  v.add_vector(v_sub, dof_indices);
319 }
320 
321 
322 inline void
323 constrain_and_add_matrix(libMesh::SparseMatrix<real_t> &m,
324  const libMesh::DofMap &dof_map,
325  std::vector<libMesh::dof_id_type> &dof_indices,
326  libMesh::DenseMatrix<real_t> &m_sub) {
327 
328  dof_map.constrain_element_matrix(m_sub, dof_indices);
329  m.add_matrix(m_sub, dof_indices);
330 }
331 
332 
333 } // namespace libMeshWrapper
334 } // namespace Assembly
335 } // namespace Base
336 } // namespace MAST
337 
338 #endif // __mast_libmesh_assembly_utility_h__
std::complex< real_t > complex_t
std::enable_if< Dim< 3, ScalarType >::typesource_load_multiplier(const SourceLoadFieldType *f, const SectionAreaType *s, ContextType &c) { Assert0(f, "Invalid pointer");Assert0(s, "Invalid pointer");return f-> value(c) *s -> value(c)
std::enable_if< std::is_same< ScalarType, real_t >::value, void >::type constrain_and_add_matrix_and_vector(VecType &v, MatType &m, const libMesh::DofMap &dof_map, std::vector< libMesh::dof_id_type > &dof_indices, SubVecType &v_sub, SubMatType &m_sub)
Definition: utility.hpp:87
std::enable_if< std::is_same< ScalarType, real_t >::value, void >::type constrain_and_add_vector(VecType &v, const libMesh::DofMap &dof_map, std::vector< libMesh::dof_id_type > &dof_indices, SubVecType &v_sub)
Definition: utility.hpp:113
void add_to_matrix(MatType &m, const uint_t i, const uint_t j, const ScalarType &v)
Definition: utility.hpp:58
void add_to_vector(VecType &v, const uint_t i, const ScalarType &s)
Definition: utility.hpp:43
unsigned int uint_t
#define Assert2(cond, v1, v2, msg)
Definition: exceptions.hpp:152
void copy(const VecType &v_from, libMesh::DenseVector< ScalarType > &v_to)
Definition: utility.hpp:305
double real_t
std::enable_if< std::is_same< ScalarType, real_t >::value, void >::type constrain_and_add_matrix(MatType &m, const libMesh::DofMap &dof_map, std::vector< libMesh::dof_id_type > &dof_indices, SubMatType &m_sub)
Definition: utility.hpp:132