MAST
Multidisciplinary-design Adaptation and Sensitivity Toolkit (MAST)
internal_residual_sensitivity.cpp
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 
21 // BOOST includes
22 #include <boost/test/unit_test.hpp>
23 
24 
25 // MAST includes
26 #include "tests/structural/build_structural_elem_1D.h"
27 #include "tests/structural/build_structural_elem_2D.h"
28 #include "tests/base/test_comparisons.h"
30 #include "elasticity/structural_discipline.h"
34 #include "base/parameter.h"
38 #include "base/nonlinear_system.h"
39 
40 
41 // libMesh includes
42 #include "libmesh/dof_map.h"
43 
44 extern void
45 set_deformation(const unsigned int dim,
46  const unsigned int case_num,
47  const libMesh::ElemType e_type,
48  RealVectorX& vec);
49 
50 
51 template <typename ValType>
53  const RealVectorX& x) {
54  const Real
55  delta = 1.e-5,
56  tol = 1.e-2;
57 
58  // get reference to the element in this mesh
59  const libMesh::Elem& elem = **(v._mesh->local_elements_begin());
60 
61  // now create the structural element
62  std::unique_ptr<MAST::StructuralElementBase>
63  e(MAST::build_structural_element(*v._structural_sys,
64  elem,
65  *v._p_card).release());
66 
67 
68  // number of dofs in this element
69  const libMesh::DofMap& dofmap = v._sys->get_dof_map();
70  std::vector<unsigned int> dof_ids;
71  dofmap.dof_indices(&elem, dof_ids);
72 
73  const unsigned int ndofs = (unsigned int)dof_ids.size();
74 
75  // make sure that the input dof vector is properly sized
76  libmesh_assert(ndofs == x.size());
77 
78  // now get the residual and Jacobian evaluations
80  res0 = RealVectorX::Zero(ndofs),
81  dresdp = RealVectorX::Zero(ndofs),
82  dresdp_fd = RealVectorX::Zero(ndofs);
83 
85  jac0 = RealMatrixX::Zero(ndofs, ndofs),
86  djacdp = RealMatrixX::Zero(ndofs, ndofs),
87  djacdp_fd = RealMatrixX::Zero(ndofs, ndofs),
88  dummy;
89 
90  Real
91  p0 = 0.,
92  dp = 0.;
93 
94 
95  // tell the element about the solution
96  e->set_solution(x);
97  e->internal_residual(true, res0, jac0);
98 
99 
100  for (unsigned int i=0; i<v._params_for_sensitivity.size(); i++) {
101 
102  MAST::Parameter& f = *v._params_for_sensitivity[i];
103 
104  // set the sensitivity of solution to be zero
105  e->sensitivity_param = &f;
106 
107  // get the base residual vector and the Jacobians for numerical comparisons
108  // later.
109  dresdp.setZero();
110  djacdp.setZero();
111  e->internal_residual_sensitivity(true, dresdp, djacdp);
112 
113  // reset the sensitivity parameter
114  e->sensitivity_param = nullptr;
115 
116  // now calculate the finite difference sensitivity
117 
118  // identify the perturbation in the parameter
119  p0 = f();
120  (fabs(p0) > 0)? dp=delta*p0 : dp=delta;
121  f() += dp;
122 
123  dresdp_fd.setZero();
124  djacdp_fd.setZero();
125  e->internal_residual(true, dresdp_fd, djacdp_fd);
126 
127  // reset the parameter value
128  f() = p0;
129 
130  // calculate the finite-difference quantities
131  dresdp_fd -= res0;
132  dresdp_fd /= dp;
133  djacdp_fd -= jac0;
134  djacdp_fd /= dp;
135 
136  // now compare the matrices
137  BOOST_TEST_MESSAGE(" ** dres/dp (partial) wrt : " << f.name() << " **");
138  BOOST_CHECK(MAST::compare_vector( dresdp_fd, dresdp, tol));
139  BOOST_TEST_MESSAGE(" ** djac/dp (partial) wrt : " << f.name() << " **");
140  BOOST_CHECK(MAST::compare_matrix( djacdp_fd, djacdp, tol));
141  }
142 }
143 
144 
145 
146 BOOST_FIXTURE_TEST_SUITE (Structural1DInternalForceSensitivity,
148 
149 BOOST_AUTO_TEST_CASE (InternalForceJacobianLinearSensitivity1DIndependentOffset) {
150 
151  this->init(false, false);
152 
153  RealVectorX v;
154 
155  // pure axial deformation
156  BOOST_TEST_MESSAGE("**** Pure Extension Deformation **");
157  set_deformation(1, 0, libMesh::INVALID_ELEM, v);
158  check_internal_force_and_jacobian_sensitivity<MAST::BuildStructural1DElem>
159  (*this, v);
160 
161  // pure bending deformation
162  BOOST_TEST_MESSAGE("**** Pure Bending Deformation **");
163  set_deformation(1, 1, libMesh::INVALID_ELEM, v);
164  check_internal_force_and_jacobian_sensitivity<MAST::BuildStructural1DElem>
165  (*this, v);
166 
167  // combination of axial and bending deformation
168  BOOST_TEST_MESSAGE("**** Combined Extension-Bending Deformation **");
169  set_deformation(1, 2, libMesh::INVALID_ELEM, v);
170  check_internal_force_and_jacobian_sensitivity<MAST::BuildStructural1DElem>
171  (*this, v);
172 
173 }
174 
175 
176 
177 BOOST_AUTO_TEST_CASE (InternalForceJacobianNonlinearSensitivity1DIndependentOffset) {
178 
179  this->init(false, true);
180 
181  RealVectorX v;
182 
183  // large deformation
184  BOOST_TEST_MESSAGE("**** Combined Extension-Bending Large Deformation **");
185  set_deformation(1, 3, libMesh::INVALID_ELEM, v);
186  check_internal_force_and_jacobian_sensitivity<MAST::BuildStructural1DElem>
187  (*this, v);
188 
189 }
190 
191 
192 
193 BOOST_AUTO_TEST_CASE (InternalForceJacobianLinearSensitivity1DDependentOffset) {
194 
195  this->init(true, false);
196 
197  RealVectorX v;
198 
199  // pure axial deformation
200  BOOST_TEST_MESSAGE("**** Pure Extension Deformation **");
201  set_deformation(1, 0, libMesh::INVALID_ELEM, v);
202  check_internal_force_and_jacobian_sensitivity<MAST::BuildStructural1DElem>
203  (*this, v);
204 
205  // pure bending deformation
206  BOOST_TEST_MESSAGE("**** Pure Bending Deformation **");
207  set_deformation(1, 1, libMesh::INVALID_ELEM, v);
208  check_internal_force_and_jacobian_sensitivity<MAST::BuildStructural1DElem>
209  (*this, v);
210 
211  // combination of axial and bending deformation
212  BOOST_TEST_MESSAGE("**** Combined Extension-Bending Deformation **");
213  set_deformation(1, 2, libMesh::INVALID_ELEM, v);
214  check_internal_force_and_jacobian_sensitivity<MAST::BuildStructural1DElem>
215  (*this, v);
216 
217 }
218 
219 
220 BOOST_AUTO_TEST_CASE (InternalForceJacobianNonlinearSensitivity1DDependentOffset) {
221 
222  this->init(true, true);
223 
224  RealVectorX v;
225 
226  // large deformation
227  BOOST_TEST_MESSAGE("**** Combined Extension-Bending Large Deformation **");
228  set_deformation(1, 3, libMesh::INVALID_ELEM, v);
229  check_internal_force_and_jacobian_sensitivity<MAST::BuildStructural1DElem>
230  (*this, v);
231 }
232 
233 
234 BOOST_AUTO_TEST_SUITE_END()
235 
236 
237 
238 BOOST_FIXTURE_TEST_SUITE (Structural2DInternalForceSensitivity,
239  MAST::BuildStructural2DElem)
240 
241 BOOST_AUTO_TEST_CASE (InternalForceJacobianLinearSensitivity2DIndependentOffsetQUAD4) {
242 
243  this->init(false, true, libMesh::QUAD4);
244 
245  RealVectorX v;
246 
247  // pure axial deformation
248  BOOST_TEST_MESSAGE("**** Pure Extension Deformation **");
249  set_deformation(2, 0, libMesh::QUAD4, v);
250  check_internal_force_and_jacobian_sensitivity<MAST::BuildStructural2DElem>
251  (*this, v);
252 
253  BOOST_TEST_MESSAGE("**** Pure Bending Deformation **");
254  set_deformation(2, 1, libMesh::QUAD4, v);
255  check_internal_force_and_jacobian_sensitivity<MAST::BuildStructural2DElem>
256  (*this, v);
257 
258  BOOST_TEST_MESSAGE("**** Combined Extension-Bending Deformation **");
259  set_deformation(2, 2, libMesh::QUAD4, v);
260  check_internal_force_and_jacobian_sensitivity<MAST::BuildStructural2DElem>
261  (*this, v);
262 }
263 
264 
265 
266 
267 BOOST_AUTO_TEST_CASE (InternalForceJacobianNonlinearSensitivity2DIndependentOffsetQUAD4) {
268 
269  this->init(false, true, libMesh::QUAD4);
270 
271  RealVectorX v;
272 
273  BOOST_TEST_MESSAGE("**** Combined Extension-Bending Large Deformation **");
274  set_deformation(2, 3, libMesh::QUAD4, v);
275  check_internal_force_and_jacobian_sensitivity<MAST::BuildStructural2DElem>
276  (*this, v);
277 }
278 
279 
280 
281 BOOST_AUTO_TEST_CASE (InternalForceJacobianLinearSensitivity2DIndependentOffsetTRI3) {
282 
283  this->init(false, false, libMesh::TRI3);
284 
285  RealVectorX v;
286 
287  // pure axial deformation
288  BOOST_TEST_MESSAGE("**** Pure Extension Deformation **");
289  set_deformation(2, 0, libMesh::TRI3, v);
290  check_internal_force_and_jacobian_sensitivity<MAST::BuildStructural2DElem>
291  (*this, v);
292 
293  BOOST_TEST_MESSAGE("**** Pure Bending Deformation **");
294  set_deformation(2, 1, libMesh::TRI3, v);
295  check_internal_force_and_jacobian_sensitivity<MAST::BuildStructural2DElem>
296  (*this, v);
297 
298  BOOST_TEST_MESSAGE("**** Combined Extension-Bending Deformation **");
299  set_deformation(2, 2, libMesh::TRI3, v);
300  check_internal_force_and_jacobian_sensitivity<MAST::BuildStructural2DElem>
301  (*this, v);
302 }
303 
304 
305 
306 BOOST_AUTO_TEST_CASE (InternalForceJacobianNonlinearSensitivity2DIndependentOffsetTRI3) {
307 
308  this->init(false, true, libMesh::TRI3);
309 
310  RealVectorX v;
311 
312  BOOST_TEST_MESSAGE("**** Combined Extension-Bending Large Deformation **");
313  set_deformation(2, 3, libMesh::TRI3, v);
314  check_internal_force_and_jacobian_sensitivity<MAST::BuildStructural2DElem>
315  (*this, v);
316 }
317 
318 
319 
320 
321 BOOST_AUTO_TEST_CASE (InternalForceJacobianLinearSensitivity2DDependentOffsetQUAD4) {
322 
323  this->init(true, false, libMesh::QUAD4);
324 
325  RealVectorX v;
326 
327  // pure axial deformation
328  BOOST_TEST_MESSAGE("**** Pure Extension Deformation **");
329  set_deformation(2, 0, libMesh::QUAD4, v);
330  check_internal_force_and_jacobian_sensitivity<MAST::BuildStructural2DElem>
331  (*this, v);
332 
333  BOOST_TEST_MESSAGE("**** Pure Bending Deformation **");
334  set_deformation(2, 1, libMesh::QUAD4, v);
335  check_internal_force_and_jacobian_sensitivity<MAST::BuildStructural2DElem>
336  (*this, v);
337 
338  BOOST_TEST_MESSAGE("**** Combined Extension-Bending Deformation **");
339  set_deformation(2, 2, libMesh::QUAD4, v);
340  check_internal_force_and_jacobian_sensitivity<MAST::BuildStructural2DElem>
341  (*this, v);
342 }
343 
344 
345 
346 BOOST_AUTO_TEST_CASE (InternalForceJacobianNonlinearSensitivity2DDependentOffsetQUAD4) {
347 
348  this->init(true, true, libMesh::QUAD4);
349 
350  RealVectorX v;
351 
352  BOOST_TEST_MESSAGE("**** Combined Extension-Bending Large Deformation **");
353  set_deformation(2, 3, libMesh::QUAD4, v);
354  check_internal_force_and_jacobian_sensitivity<MAST::BuildStructural2DElem>
355  (*this, v);
356 }
357 
358 
359 
360 BOOST_AUTO_TEST_CASE (InternalForceJacobianLinearSensitivity2DDependentOffsetTRI3) {
361 
362  this->init(true, false, libMesh::TRI3);
363 
364  RealVectorX v;
365 
366  // pure axial deformation
367  BOOST_TEST_MESSAGE("**** Pure Extension Deformation **");
368  set_deformation(2, 0, libMesh::TRI3, v);
369  check_internal_force_and_jacobian_sensitivity<MAST::BuildStructural2DElem>
370  (*this, v);
371 
372  BOOST_TEST_MESSAGE("**** Pure Bending Deformation **");
373  set_deformation(2, 1, libMesh::TRI3, v);
374  check_internal_force_and_jacobian_sensitivity<MAST::BuildStructural2DElem>
375  (*this, v);
376 
377  BOOST_TEST_MESSAGE("**** Combined Extension-Bending Deformation **");
378  set_deformation(2, 2, libMesh::TRI3, v);
379  check_internal_force_and_jacobian_sensitivity<MAST::BuildStructural2DElem>
380  (*this, v);
381 }
382 
383 
384 
385 
386 BOOST_AUTO_TEST_CASE (InternalForceJacobianNonlinearSensitivity2DDependentOffsetTRI3) {
387 
388  this->init(true, true, libMesh::TRI3);
389 
390  RealVectorX v;
391 
392  BOOST_TEST_MESSAGE("**** Combined Extension-Bending Large Deformation **");
393  set_deformation(2, 3, libMesh::TRI3, v);
394  check_internal_force_and_jacobian_sensitivity<MAST::BuildStructural2DElem>
395  (*this, v);
396 }
397 
398 
399 
400 BOOST_AUTO_TEST_SUITE_END()
401 
void set_deformation(const unsigned int dim, const unsigned int case_num, const libMesh::ElemType e_type, RealVectorX &vec)
BOOST_FIXTURE_TEST_SUITE(Structural1DInternalForceSensitivity, MAST::BuildStructural1DElem) BOOST_AUTO_TEST_CASE(InternalForceJacobianLinearSensitivity1DIndependentOffset)
const std::string & name() const
returns the name of this function
Definition: function_base.h:60
bool compare_vector(const RealVectorX &v0, const RealVectorX &v, const Real tol)
This is a scalar function whose value can be changed and one that can be used as a design variable in...
Definition: parameter.h:35
BOOST_AUTO_TEST_CASE(InternalForceJacobianNonlinearSensitivity1DIndependentOffset)
bool compare_matrix(const RealMatrixX &m0, const RealMatrixX &m, const Real tol)
libMesh::Real Real
Matrix< Real, Dynamic, Dynamic > RealMatrixX
void check_internal_force_and_jacobian_sensitivity(ValType &v, const RealVectorX &x)
Matrix< Real, Dynamic, 1 > RealVectorX
std::unique_ptr< MAST::StructuralElementBase > build_structural_element(MAST::SystemInitialization &sys, const MAST::GeomElem &elem, const MAST::ElementPropertyCardBase &p)
builds the structural element for the specified element type