MAST
Multidisciplinary-design Adaptation and Sensitivity Toolkit (MAST)
plate_modal_analysis.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 "examples/structural/plate_modal_analysis/plate_modal_analysis.h"
27 #include "tests/base/test_comparisons.h"
29 #include "elasticity/structural_discipline.h"
31 #include "base/parameter.h"
35 #include "base/nonlinear_system.h"
36 
37 
38 BOOST_FIXTURE_TEST_SUITE (StructuralPlateModalAnalysis,
39  MAST::PlateModalAnalysis)
40 
41 BOOST_AUTO_TEST_CASE (PlateModalSolution) {
42 
43  // initialize plate object
44  this->init(libMesh::QUAD4, false);
45 
46  const Real
47  tol = 1.e-2;
48 
49  std::vector<Real>
50  eig;
51 
52  this->solve(false, &eig);
53 
54  // check the solution
55  // iterate over each node, and compare the nodal solution with the
56  // expected anlaytical value
57  Real
58  th = (*_th)(),
59  rho = (*_rho)(),
60  Eval = (*_E)(),
61  nu = (*_nu)(),
62  D = pow(th,3)/12.*Eval/(1-nu*nu),
63  pi = acos(-1.),
64  analytical = 0.;
65 
66 
67  // analytical solution to the natural frequency of simply supported problem
68  // is
69  // lambda = omega^2 = (n pi/L)^4 EI/(rho A)
70  //
71  unsigned int
72  nconv = std::min(_sys->get_n_converged_eigenvalues(),
73  _sys->get_n_requested_eigenvalues());
74 
75  std::set<Real> factors_set;
76 
77  for (unsigned int n=1; n<4; n++) {
78  for (unsigned int m=1; m<4; m++) {
79  factors_set.insert((pow( n/_length,4) + pow( m/_width,4) +
80  2.* pow( n/_length,2) * pow( m/_width,2)));
81  }
82  }
83 
84  // convert this to a vector of sorted factors
85  std::vector<Real> factors;
86  std::set<Real>::const_iterator
87  it = factors_set.begin(),
88  end = factors_set.end();
89 
90  for ( ; it != end; it++) {
91  factors.push_back(*it);
92  }
93 
94  // make sure that the size of factors is greater thn nconv
95  libmesh_assert_greater(factors.size(), nconv);
96 
97  BOOST_TEST_MESSAGE(" ** Plate Bending Eigenvalues **");
98  for (unsigned int i=0; i<nconv; i++) {
99 
100  analytical = D*pow(pi,4)/rho/th * factors[i];
101 
102  // compare the eigenvalues
103 
104  BOOST_CHECK(MAST::compare_value(analytical, eig[i], tol));
105  }
106 }
107 
108 
109 
110 BOOST_AUTO_TEST_CASE (PlateModalSolutionSensitivity) {
111 
112  // initialize plate object
113  this->init(libMesh::QUAD4, false);
114 
115  const Real
116  delta = 1.e-5,
117  tol = 1.e-3;
118 
119  std::vector<Real>
120  eig_vec,
121  deig_vec;
122 
123  this->solve(false, &eig_vec);
124 
125  unsigned int
126  nconv = std::min(_sys->get_n_converged_eigenvalues(),
127  _sys->get_n_requested_eigenvalues());
128 
129 
130  // verify the sensitivity solution of this system
132  eig = RealVectorX::Zero(nconv),
133  deig = RealVectorX::Zero(nconv),
134  deig_fd = RealVectorX::Zero(nconv);
135 
136  for (unsigned int i=0; i<nconv; i++) eig(i) = eig_vec[i];
137 
138 
139  // now iterate over all the parameters and calculate the analytical
140  // sensitivity and compare with the numerical sensitivity
141 
142  Real
143  p0 = 0.,
144  dp = 0.;
145 
147  // now evaluate the direct sensitivity
149 
150  for (unsigned int i=0; i<this->_params_for_sensitivity.size(); i++ ) {
151 
152  MAST::Parameter& f = *this->_params_for_sensitivity[i];
153 
154  // calculate the analytical sensitivity
155  // analysis is required at the baseline before sensitivity solution
156  // and the solution has changed after the previous perturbed solution
157  this->solve(false, &eig_vec);
158  std::vector<Real> deig_vec(nconv);
159  this->sensitivity_solve(f, deig_vec);
160  for (unsigned int i=0; i<nconv; i++) deig(i) = deig_vec[i];
161 
162  // now calculate the finite difference sensitivity
163 
164  // identify the perturbation in the parameter
165  p0 = f();
166  (fabs(p0) > 0)? dp=delta*p0 : dp=delta;
167  f() += dp;
168 
169  // solve at the perturbed parameter value
170  this->solve(false, &eig_vec);
171  for (unsigned int i=0; i<nconv; i++) deig_fd(i) = eig_vec[i];
172 
173  deig_fd -= eig;
174  deig_fd /= dp;
175 
176  // reset the parameter value
177  f() = p0;
178 
179  // now compare the eigenvalue sensitivity
180  BOOST_TEST_MESSAGE(" ** dlambda/dp (total) wrt : " << f.name() << " **");
181  BOOST_CHECK(MAST::compare_vector( deig_fd, deig, tol));
182  }
183 }
184 
185 BOOST_AUTO_TEST_SUITE_END()
186 
187 
188 
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
libMesh::Real Real
Matrix< Real, Dynamic, 1 > RealVectorX
bool compare_value(const Real v0, const Real v, const Real tol)
BOOST_AUTO_TEST_CASE(PlateModalSolutionSensitivity)
#define pi
BOOST_FIXTURE_TEST_SUITE(StructuralPlateModalAnalysis, MAST::PlateModalAnalysis) BOOST_AUTO_TEST_CASE(PlateModalSolution)