MAST3
Multidisciplinary-design Adaptation and Sensitivity Toolkit (MAST)
material_point_output_sensitivity.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_material_point_output_sensitivity_h__
21 #define __mast_libmesh_material_point_output_sensitivity_h__
22 
23 // MAST includes
25 #include <mast/base/exceptions.hpp>
31 
32 // libMesh includes
33 #include <libmesh/parallel.h>
34 
35 
36 namespace MAST {
37 namespace Base {
38 namespace Assembly {
39 namespace libMeshWrapper {
40 
47 template <typename ScalarType,
48  typename ResidualElemOpsType,
49  typename OutputElemOpsType>
51 
52 public:
53 
54  static_assert(std::is_same<ScalarType,
55  typename ResidualElemOpsType::scalar_t>::value,
56  "Scalar type of assembly and element operations must be same");
57  static_assert(std::is_same<ScalarType,
58  typename OutputElemOpsType::scalar_t>::value,
59  "Scalar type of assembly and element operations must be same");
60 
61 
62  MaterialPointOutputSensitivity(const libMesh::Parallel::Communicator &comm):
63  _comm (comm),
64  _e_ops (nullptr),
65  _output_e_ops (nullptr)
66  { }
67 
69 
70  inline void set_elem_ops(ResidualElemOpsType &e_ops,
71  OutputElemOpsType &output_ops) {
72 
73  _e_ops = &e_ops;
74  _output_e_ops = &output_ops;
75  }
76 
81  template <typename Vec1Type,
82  typename Vec2Type,
83  typename IndexingType,
84  typename StorageType,
85  typename ContextType,
86  typename ScalarFieldType>
87  inline ScalarType
88  assemble(ContextType &c,
89  ScalarFieldType &f,
90  const Vec1Type &X,
91  const Vec2Type &X_adj,
92  const IndexingType &index,
93  const StorageType &stress) {
94 
95  Assert0(_e_ops && _output_e_ops, "Elem Operation objects not initialized");
96 
97  ScalarType
98  val = 0.;
99 
100  // iterate over each element, initialize it and get the relevant
101  // analysis quantities
103  sol_accessor (*c.sys, X),
104  adj_accessor (*c.sys, X_adj);
105 
106  using elem_vector_t = typename ResidualElemOpsType::vector_t;
107  using elem_matrix_t = typename ResidualElemOpsType::matrix_t;
108 
109  elem_vector_t
110  dsol_e,
111  dres_e;
112 
113  uint_t
114  idx = 0;
115 
116  libMesh::MeshBase::const_element_iterator
117  el = c.mesh->active_local_elements_begin(),
118  end_el = c.mesh->active_local_elements_end();
119 
120  // first compute the sensitivity information assuming unfiltered
121  // density variables.
122  for ( ; el != end_el; ++el) {
123 
124  // set element in the context, which will be used for
125  // the initialization routines
126  c.elem = *el;
127 
128  sol_accessor.init (*c.elem);
129  adj_accessor.init (*c.elem);
130 
131  dsol_e.setZero(sol_accessor.n_dofs());
132  dres_e.setZero(sol_accessor.n_dofs());
133 
134  // first we compute the partial derivative of the
135  // residual wrt the parameter.
136  _e_ops->derivative(c,
137  f,
138  sol_accessor,
139  dres_e,
140  nullptr);
141 
142 
143  // partial derivative of output
144  val += _output_e_ops->derivative(c, f,
145  sol_accessor,
146  dsol_e,
147  index,
148  stress);
149 
150  // the adjoint vector combined w/ res sens
151  val += adj_accessor.dot(dres_e);
152  }
153 
155 
156  return val;
157  }
158 
159 private:
160 
161  const libMesh::Parallel::Communicator &_comm;
162  ResidualElemOpsType *_e_ops;
163  OutputElemOpsType *_output_e_ops;
164 };
165 
166 } // namespace libMeshWrapper
167 } // namespace Assembly
168 } // namespace Base
169 } // namespace MAST
170 
171 
172 #endif // __mast_libmesh_material_point_output_sensitivity_h__
void init(const libMesh::Elem &e)
Definition: accessor.hpp:69
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)
ScalarType assemble(ContextType &c, ScalarFieldType &f, const Vec1Type &X, const Vec2Type &X_adj, const IndexingType &index, const StorageType &stress)
output derivative is defined as a
#define Assert0(cond, msg)
Definition: exceptions.hpp:134
unsigned int uint_t
ScalarType dot(const Vec2Type &v) const
Definition: accessor.hpp:84
void comm_sum(const libMesh::Parallel::Communicator &comm, real_t &v)
Definition: utility.hpp:328
void set_elem_ops(ResidualElemOpsType &e_ops, OutputElemOpsType &output_ops)
This class computes the adjoint sensitivity of scalar output quantity that is defined based on materi...