MAST3
Multidisciplinary-design Adaptation and Sensitivity Toolkit (MAST)
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_output_sensitivity_h__
21 #define __mast_libmesh_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 
41 template <typename ScalarType,
42  typename ResidualElemOpsType,
43  typename OutputElemOpsType>
45 
46 public:
47 
48  static_assert(std::is_same<ScalarType,
49  typename ResidualElemOpsType::scalar_t>::value,
50  "Scalar type of assembly and element operations must be same");
51  static_assert(std::is_same<ScalarType,
52  typename OutputElemOpsType::scalar_t>::value,
53  "Scalar type of assembly and element operations must be same");
54 
55 
56  OutputSensitivity(libMesh::Communicator &comm):
57  _comm (comm),
58  _e_ops (nullptr),
59  _output_e_ops (nullptr)
60  { }
61 
62  virtual ~OutputSensitivity() {}
63 
64  inline void set_elem_ops(ResidualElemOpsType &e_ops,
65  OutputElemOpsType &output_ops) {
66 
67  _e_ops = &e_ops;
68  _output_e_ops = &output_ops;
69  }
70 
75  template <typename Vec1Type,
76  typename Vec2Type,
77  typename ContextType,
78  typename ScalarFieldType>
79  inline ScalarType
80  assemble(ContextType &c,
81  ScalarFieldType &f,
82  const Vec1Type &X,
83  const Vec1Type &X_adj) {
84 
85  Assert0(_e_ops && _output_e_ops, "Elem Operation objects not initialized");
86 
87  ScalarType
88  val = 0.;
89 
90  // iterate over each element, initialize it and get the relevant
91  // analysis quantities
93  sol_accessor (*c.sys, X),
94  adj_accessor (*c.sys, X_adj);
95 
96  using elem_vector_t = typename ResidualElemOpsType::vector_t;
97  using elem_matrix_t = typename ResidualElemOpsType::matrix_t;
98 
99  elem_vector_t
100  dres_e;
101 
102  uint_t
103  idx = 0;
104 
105  libMesh::MeshBase::const_element_iterator
106  el = c.mesh->active_local_elements_begin(),
107  end_el = c.mesh->active_local_elements_end();
108 
109  // first compute the sensitivity information assuming unfiltered
110  // density variables.
111  for ( ; el != end_el; ++el) {
112 
113  // set element in the context, which will be used for
114  // the initialization routines
115  c.elem = *el;
116 
117  sol_accessor.init(*c.elem);
118  adj_accessor.init(*c.elem);
119 
120  dres_e.setZero(sol_accessor.n_dofs());
121 
122  // first we compute the partial derivative of the
123  // residual wrt the parameter.
124  _e_ops->derivative(c,
125  f,
126  sol_accessor,
127  dres_e,
128  nullptr);
129 
130 
131  val +=
132  _output_e_ops->derivative(c, f, sol_accessor) // partial derivative of output
133  + adj_accessor.dot(dres_e)); // the adjoint vector combined w/ res sens
134  }
135 
137 
138  return val;
139  }
140 
141 private:
142 
143  libMesh::Comm &_comm;
144  ResidualElemOpsType *_e_ops;
145  OutputElemOpsType *_output_e_ops;
146 };
147 
148 } // namespace libMeshWrapper
149 } // namespace Assembly
150 } // namespace Base
151 } // namespace MAST
152 
153 
154 #endif // __mast_libmesh_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 Vec1Type &X_adj)
output derivative is defined as a
#define Assert0(cond, msg)
Definition: exceptions.hpp:134
unsigned int uint_t
void set_elem_ops(ResidualElemOpsType &e_ops, OutputElemOpsType &output_ops)
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