MAST3
Multidisciplinary-design Adaptation and Sensitivity Toolkit (MAST)
residual_and_jacobian.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_optimization_topology_simp_libmesh_residual_and_jacobian_h__
21 #define __mast_optimization_topology_simp_libmesh_residual_and_jacobian_h__
22 
23 // MAST includes
25 #include <mast/base/exceptions.hpp>
29 
30 // libMesh includes
31 #include <libmesh/nonlinear_implicit_system.h>
32 #include <libmesh/dof_map.h>
33 
34 namespace MAST {
35 namespace Optimization {
36 namespace Topology {
37 namespace SIMP {
38 namespace libMeshWrapper {
39 
40 template <typename ScalarType,
41  typename ElemOpsType>
43 
44 public:
45 
47  "Scalar type of assembly and element operations must be same");
48 
50  _finalize_jac (true),
51  _e_ops (nullptr)
52  { }
53 
54  virtual ~ResidualAndJacobian() { }
55 
56  inline void set_finalize_jac(bool f) { _finalize_jac = f;}
57 
58  inline void set_elem_ops(ElemOpsType& e_ops) { _e_ops = &e_ops; }
59 
60  template <typename Vec1Type,
61  typename Vec2Type,
62  typename MatType,
63  typename ContextType>
64  inline void assemble(ContextType &c,
65  const Vec1Type &X,
66  const Vec2Type &density,
67  Vec1Type *R,
68  MatType *J) {
69 
70  Assert0( R || J, "Atleast one assembled quantity should be specified.");
71 
74 
75  // iterate over each element, initialize it and get the relevant
76  // analysis quantities
78  sol_accessor (*c.sys, X),
79  density_accessor (*c.rho_sys, density);
80 
81  using elem_vector_t = typename ElemOpsType::vector_t;
82  using elem_matrix_t = typename ElemOpsType::matrix_t;
83 
84  elem_vector_t res_e, density_e;
85  elem_matrix_t jac_e;
86 
87 
88  libMesh::MeshBase::const_element_iterator
89  el = c.mesh->active_local_elements_begin(),
90  end_el = c.mesh->active_local_elements_end();
91 
92  for ( ; el != end_el; ++el) {
93 
94  // set element in the context, which will be used for the initialization routines
95  c.elem = *el;
96 
97  sol_accessor.init(*c.elem);
98  density_accessor.init(*c.elem);
99 
100  res_e.setZero(sol_accessor.n_dofs());
101  if (J) jac_e.setZero(sol_accessor.n_dofs(), sol_accessor.n_dofs());
102 
103  // perform the element level calculations
104  _e_ops->compute(c,
105  sol_accessor,
106  density_accessor,
107  res_e,
108  J?&jac_e:nullptr);
109 
110  // constrain the quantities to account for hanging dofs,
111  // Dirichlet constraints, etc.
112  if (R && J)
114  <ScalarType, Vec1Type, MatType, elem_vector_t, elem_matrix_t>
115  (*R, *J, c.sys->get_dof_map(), sol_accessor.dof_indices(), res_e, jac_e);
116  else if (R)
118  <ScalarType, Vec1Type, elem_vector_t>
119  (*R, c.sys->get_dof_map(), sol_accessor.dof_indices(), res_e);
120  else
122  <ScalarType, MatType, elem_matrix_t>
123  (*J, c.sys->get_dof_map(), sol_accessor.dof_indices(), jac_e);
124  }
125 
126  // parallel matrix/vector require finalization of communication
129  }
130 
131 private:
132 
134  ElemOpsType *_e_ops;
135 };
136 
137 } // namespace libMeshWrapper
138 } // namespace SIMP
139 } // namespace Topology
140 } // namespace Optimization
141 } // namespace MAST
142 
143 #endif // __mast_optimization_topology_simp_libmesh_residual_and_jacobian_h__
void init(const libMesh::Elem &e)
Definition: accessor.hpp:69
void setZero(ValType &m)
Definition: utility.hpp:44
void finalize(ValType &m)
Definition: utility.hpp:252
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
#define Assert0(cond, msg)
Definition: exceptions.hpp:134
void assemble(ContextType &c, const Vec1Type &X, const Vec2Type &density, Vec1Type *R, MatType *J)
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