MAST
Multidisciplinary-design Adaptation and Sensitivity Toolkit (MAST)
panel_2d_small_disturbance_frequency_domain.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/fluid/panel_small_disturbance_frequency_domain_analysis_2D/panel_small_disturbance_frequency_domain_analysis_2d.h"
27 #include "base/nonlinear_system.h"
28 #include "base/parameter.h"
29 #include "tests/base/test_comparisons.h"
30 
31 // libMesh includes
32 #include "libmesh/numeric_vector.h"
33 
34 
35 BOOST_FIXTURE_TEST_SUITE (PanelSmallDisturbanceFrequencyDomain2D,
36  MAST::PanelInviscidSmallDisturbanceFrequencyDomain2DAnalysis)
37 
38 BOOST_AUTO_TEST_CASE (FreqDomainSensitivityWrtOmega) {
39 
40  MAST::Parameter& f = *_omega;
41  f = 100.; // some arbitrary value
42 
43  const Real
44  delta = 1.e-5,
45  tol = 1.e-3;
46 
47  // verify the sensitivity solution of this system
49  sol_re,
50  sol_im,
51  dsol_re,
52  dsol_im,
53  dsol_fd_re,
54  dsol_fd_im;
55 
56  solve();
57 
58  // get the solutions
59  std::string
60  nm_re = _sys->name() + "real_sol",
61  nm_im = _sys->name() + "imag_sol",
62  nm_re_sens = _sys->name() + "real_sol_sens",
63  nm_im_sens = _sys->name() + "imag_sol_sens";
64 
65  libMesh::NumericVector<Real>
66  & sol_vec_re = _sys->get_vector(nm_re),
67  & sol_vec_im = _sys->get_vector(nm_im);
68 
69  const unsigned int
70  n_dofs = sol_vec_re.size();
71 
72  sol_re = RealVectorX::Zero(n_dofs);
73  sol_im = RealVectorX::Zero(n_dofs);
74  dsol_re = RealVectorX::Zero(n_dofs);
75  dsol_im = RealVectorX::Zero(n_dofs);
76  dsol_fd_re = RealVectorX::Zero(n_dofs);
77  dsol_fd_im = RealVectorX::Zero(n_dofs);
78 
79  // copy the solution for later use
80  for (unsigned int i=0; i<n_dofs; i++) {
81 
82  sol_re(i) = sol_vec_re(i);
83  sol_im(i) = sol_vec_im(i);
84  }
85 
86  // now iterate over all the parameters and calculate the analytical
87  // sensitivity and compare with the numerical sensitivity
88 
89  Real
90  p0 = 0.,
91  dp = 0.;
92 
94  // now evaluate the direct sensitivity
96 
97  //for (unsigned int i=0; i<_params_for_sensitivity.size(); i++ ) {
98 
99  //MAST::Parameter& f = *_params_for_sensitivity[i];
100 
101  dsol_re = RealVectorX::Zero(n_dofs);
102  dsol_im = RealVectorX::Zero(n_dofs);
103  dsol_fd_re = RealVectorX::Zero(n_dofs);
104  dsol_fd_im = RealVectorX::Zero(n_dofs);
105 
106  // calculate the analytical sensitivity
107  // analysis is required at the baseline before sensitivity solution
108  // and the solution has changed after the previous perturbed solution
109  solve();
110  sensitivity_solve(f);
111 
112  libMesh::NumericVector<Real>
113  & dsol_vec_re = _sys->get_vector(nm_re_sens),
114  & dsol_vec_im = _sys->get_vector(nm_im_sens);
115 
116  // copy the sensitivity solution
117  for (unsigned int j=0; j<n_dofs; j++) {
118 
119  dsol_re(j) = dsol_vec_re(j);
120  dsol_im(j) = dsol_vec_im(j);
121  }
122 
123  // now calculate the finite difference sensitivity
124 
125  // identify the perturbation in the parameter
126  p0 = f();
127  (fabs(p0) > 0)? dp=delta*p0 : dp=delta;
128  f() += dp;
129 
130  // solve at the perturbed parameter value
131  solve();
132 
133  libMesh::NumericVector<Real>
134  & dsol_vec_re_fd = _sys->get_vector(nm_re),
135  & dsol_vec_im_fd = _sys->get_vector(nm_im);
136 
137  // copy the perturbed solution
138  for (unsigned int j=0; j<n_dofs; j++) {
139 
140  dsol_fd_re(j) = dsol_vec_re_fd(j);
141  dsol_fd_im(j) = dsol_vec_im_fd(j);
142  }
143 
144  // calculate the finite difference sensitivity for solution
145  dsol_fd_re -= sol_re;
146  dsol_fd_im -= sol_im;
147  dsol_fd_re /= dp;
148  dsol_fd_im /= dp;
149 
150  // reset the parameter value
151  f() = p0;
152 
153  // now compare the solution sensitivity
154  BOOST_TEST_MESSAGE(" ** dX_re/dp (total) wrt : " << f.name() << " **");
155  BOOST_CHECK(MAST::compare_vector( dsol_fd_re, dsol_re, tol));
156 
157  BOOST_TEST_MESSAGE(" ** dX_im/dp (total) wrt : " << f.name() << " **");
158  BOOST_CHECK(MAST::compare_vector( dsol_fd_im, dsol_im, tol));
159 
160  //}
161 
162 }
163 
164 
165 
166 BOOST_AUTO_TEST_SUITE_END()
167 
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_FIXTURE_TEST_SUITE(PanelSmallDisturbanceFrequencyDomain2D, MAST::PanelInviscidSmallDisturbanceFrequencyDomain2DAnalysis) BOOST_AUTO_TEST_CASE(FreqDomainSensitivityWrtOmega)
libMesh::Real Real
BOOST_AUTO_TEST_CASE(InternalForceJacobianZeroFreq)
Matrix< Real, Dynamic, 1 > RealVectorX