MAST
Multidisciplinary-design Adaptation and Sensitivity Toolkit (MAST)
stress_evaluations.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"
30 #include "tests/base/test_comparisons.h"
32 #include "elasticity/structural_discipline.h"
34 #include "base/parameter.h"
39 #include "base/nonlinear_system.h"
40 
41 
42 // libMesh includes
43 #include "libmesh/dof_map.h"
44 #include "libmesh/elem.h"
45 #include "libmesh/edge_edge2.h"
46 
47 
48 
49 void
50 set_deformation(const unsigned int dim,
51  const unsigned int case_num,
52  const libMesh::ElemType e,
53  RealVectorX& vec) {
54  if (dim == 1) {
55 
56  // assuming an edge2 with Lagrange interpolation
57  vec = RealVectorX::Zero(12);
58 
59 
60  switch (case_num) {
61  case 0: // some arbitrary axial deformation
62  vec(1) = 2.e-2;
63  break;
64  case 1: // some arbitrary bending deformation
65  vec(9) = 2.e-2;
66  break;
67  case 2: { // combination of axial and bending
68  vec(1) = 2.e-2;
69  vec(9) = 2.e-2;
70  }
71  case 3: { // combination of axial and bending
72  vec(1) = 2.e-1; // u
73  vec(3) = 2.e-1; // v
74  vec(5) = 2.e-1; // w
75  vec(9) = 2.e-1; // theta-y
76  vec(11) = 2.e-1; // theta-z
77  }
78  break;
79  default:
80  libmesh_error(); // should not get here
81  }
82  }
83  else if (dim == 2) {
84 
85  // assuming a quad4 with Lagrange interpolation
86 
87  std::vector<unsigned int>
88  mem_dofs,
89  bend_dofs;
90 
91  if (e == libMesh::QUAD4) {
92  vec = RealVectorX::Zero(24);
93  mem_dofs = {2, 3, 6, 7};
94  bend_dofs = {10, 11, 14, 15, 18, 19};
95  }
96  else if (e == libMesh::TRI3) {
97  vec = RealVectorX::Zero(18);
98  mem_dofs = {1, 2, 4, 5};
99  bend_dofs = {7, 8, 10, 11, 13, 14};
100  }
101  else
102  libmesh_error(); // should not get here.
103 
104  switch (case_num) {
105 
106  case 0: { // sets values for u and v
107  vec(mem_dofs[0]) = 2.e-2;
108  vec(mem_dofs[1]) = 4.e-2;
109 
110  vec(mem_dofs[2]) = -2.e-2;
111  vec(mem_dofs[3]) = +6.e-2;
112  }
113  break;
114 
115  case 1: { // sets values for theta-x and theta-y
116  vec(bend_dofs[0]) = 2.e-2;
117  vec(bend_dofs[1]) = 4.e-2;
118 
119  vec(bend_dofs[2]) = -2.e-2;
120  vec(bend_dofs[3]) = +6.e-2;
121 
122  vec(bend_dofs[4]) = -2.e-2;
123  vec(bend_dofs[5]) = +6.e-2;
124  }
125  break;
126 
127  case 2: {
128  vec(mem_dofs[0]) = 2.e-2;
129  vec(mem_dofs[1]) = 4.e-2;
130 
131  vec(mem_dofs[2]) = -2.e-2;
132  vec(mem_dofs[3]) = +6.e-2;
133 
134  vec(bend_dofs[0]) = 2.e-2;
135  vec(bend_dofs[1]) = 4.e-2;
136 
137  vec(bend_dofs[2]) = -2.e-2;
138  vec(bend_dofs[3]) = +6.e-2;
139 
140  vec(bend_dofs[4]) = -2.e-2;
141  vec(bend_dofs[5]) = +6.e-2;
142  }
143  break;
144 
145  case 3: {
146  vec(mem_dofs[0]) = 2.e-1;
147  vec(mem_dofs[1]) = 4.e-1;
148 
149  vec(mem_dofs[2]) = -2.e-1;
150  vec(mem_dofs[3]) = +6.e-1;
151 
152  vec(bend_dofs[0]) = 2.e-1;
153  vec(bend_dofs[1]) = 4.e-1;
154 
155  vec(bend_dofs[2]) = -2.e-1;
156  vec(bend_dofs[3]) = +6.e-1;
157 
158  vec(bend_dofs[4]) = -2.e-1;
159  vec(bend_dofs[5]) = +6.e-1;
160  }
161  break;
162 
163  default:
164  libmesh_assert(false); // should not get here.
165  }
166  }
167 
168 }
169 
170 template <typename ValType>
171 void check_stress (ValType& v, const RealVectorX& x0) {
172 
173  const Real
174  delta = 1.e-5,
175  tol = 1.e-2;
176 
177  // stress output
179  std::vector<libMesh::Point> pts(1);
180  pts[0] = libMesh::Point(0., 1., 0.); // upper surface, elem mid-point
181 
182  //pts[1] = libMesh::Point(0.,-1., 0.); // lower surface, elem mid-point
183  output.set_points_for_evaluation(pts);
184  std::multimap<libMesh::subdomain_id_type, MAST::OutputFunctionBase*> output_map;
185  output_map.insert(std::pair<libMesh::subdomain_id_type, MAST::OutputFunctionBase*>
186  (0, &output));
187 
188 
189  // get reference to the element in this mesh
190  const libMesh::Elem& elem = **(v._mesh->local_elements_begin());
191 
192  // now create the structural element
193  std::unique_ptr<MAST::StructuralElementBase>
194  e(MAST::build_structural_element(*v._structural_sys,
195  elem,
196  *v._p_card).release());
197 
198 
199  // number of dofs in this element
200  const libMesh::DofMap& dofmap = v._sys->get_dof_map();
201  std::vector<unsigned int> dof_ids;
202  dofmap.dof_indices(&elem, dof_ids);
203 
204  const unsigned int ndofs = (unsigned int)dof_ids.size();
205 
206  // make sure that the input dof vector is properly sized
207  libmesh_assert_equal_to(ndofs, x0.size());
208 
209  // now get the residual and Jacobian evaluations
211  xdot0 = RealVectorX::Zero(ndofs),
212  x = RealVectorX::Zero(ndofs),
213  xdot = RealVectorX::Zero(ndofs),
214  stress0 = RealVectorX::Zero(6),
215  stress = RealVectorX::Zero(6),
216  strain0 = RealVectorX::Zero(6),
217  strain = RealVectorX::Zero(6),
218  dvm_dX0 = RealVectorX::Zero(ndofs),
219  dvmf_dX0 = RealVectorX::Zero(ndofs),
220  dvm_dX_fd = RealVectorX::Zero(ndofs),
221  dvmf_dX_fd = RealVectorX::Zero(ndofs),
222  dstressdp = RealVectorX::Zero(6),
223  dstraindp = RealVectorX::Zero(6);
224 
226  dstressdX0 = RealMatrixX::Zero(6, ndofs),
227  dstressdX_fd = RealMatrixX::Zero(6, ndofs),
228  dstraindX0 = RealMatrixX::Zero(6, ndofs),
229  dstraindX_fd = RealMatrixX::Zero(6, ndofs);
230 
231 
232  Real
233  vm0 = 0.,
234  vm = 0.,
235  vmf0 = 0.,
236  dvmdp = 0.,
237  dvmf_dp = 0.,
238  dvmf_dp_fd = 0.,
239  p0 = 0.,
240  dp = 0.;
241 
242  const Real
243  pval = 3.;
244 
245  // tell the element about the solution and velocity
246  e->set_solution(x0);
247  e->set_velocity(xdot0);
248 
249  // also ask for the derivative of the stress/strain
250  e->volume_output_quantity(true, false, output_map);
251 
252  // get access to the vector of stress/strain data for this element.
253  {
254  const std::vector<MAST::StressStrainOutputBase::Data*>&
255  stress_data = output.get_stress_strain_data_for_elem(&elem);
256 
257  libmesh_assert_equal_to(stress_data.size(), 1); // this should have one element
258 
259  stress0 = stress_data[0]->stress();
260  strain0 = stress_data[0]->strain();
261  dstressdX0 = stress_data[0]->get_dstress_dX();
262  dstraindX0 = stress_data[0]->get_dstrain_dX();
263  vm0 = stress_data[0]->von_Mises_stress();
264  dvm_dX0 = stress_data[0]->dvon_Mises_stress_dX();
265  vmf0 = output.von_Mises_p_norm_functional_for_all_elems(pval);
266  dvmf_dX0 = output.von_Mises_p_norm_functional_state_derivartive_for_all_elems(pval);
267 
268  output.clear(false);
269  }
270 
271  // now, verify the adjoints using finite differencing
272  for (unsigned int i=0; i<ndofs; i++) {
273  x = x0;
274  x(i) += delta;
275  e->set_solution(x);
276  e->set_velocity(xdot);
277 
278  e->volume_output_quantity(false, false, output_map);
279 
280  // now use the updated stress to calculate the finite difference data
281  {
282  const std::vector<MAST::StressStrainOutputBase::Data*>&
283  stress_data = output.get_stress_strain_data_for_elem(&elem);
284 
285  libmesh_assert_equal_to(stress_data.size(), 1); // this should have one element
286 
287  stress = stress_data[0]->stress();
288  strain = stress_data[0]->strain();
289  dstressdX_fd.col(i) = (stress-stress0)/delta;
290  dstraindX_fd.col(i) = (strain-strain0)/delta;
291  vm = stress_data[0]->von_Mises_stress();
292  dvm_dX_fd(i) = (vm-vm0)/delta;
293  dvmf_dX_fd(i) = (output.von_Mises_p_norm_functional_for_all_elems(pval)-vm0)/delta;
294 
295  output.clear(false);
296  }
297  }
298 
299  // now compare the matrices
300  BOOST_TEST_MESSAGE(" ** Stress Derivative wrt State **");
301  BOOST_CHECK(MAST::compare_matrix( dstressdX_fd, dstressdX0, tol));
302  BOOST_TEST_MESSAGE(" ** Strain Derivative wrt State **");
303  BOOST_CHECK(MAST::compare_matrix( dstraindX_fd, dstraindX0, tol));
304  BOOST_TEST_MESSAGE(" ** VM-Stress Derivative wrt State **");
305  BOOST_CHECK(MAST::compare_vector( dvm_dX_fd, dvm_dX0, tol));
306  BOOST_TEST_MESSAGE(" ** VM_func-Stress Derivative wrt State **");
307  BOOST_CHECK(MAST::compare_vector( dvmf_dX_fd, dvmf_dX0, tol));
308 
309  // now, check the sensitivity with respect to various parameters
310 
311  // NOTE:
312  // First, we will set the dX/dp = 0, so that the derivative of the output
313  // quantity is only the partial derivative wrt the parameter.
314  //
315 
316  for (unsigned int i=0; i<v._params_for_sensitivity.size(); i++) {
317 
318  MAST::Parameter& f = *v._params_for_sensitivity[i];
319 
320  // set the sensitivity of solution to be zero
321  x = RealVectorX::Zero(ndofs);
322  e->sensitivity_param = &f;
323  e->set_solution(x0);
324  e->set_solution(x, true); // sets the sensitivity to zero
325 
326  // get the stress, strain and von Mises stress sensitivity
327  e->volume_output_quantity(false, true, output_map);
328 
329  // next, check the total derivative of the quantity wrt the parameter
330  {
331  const std::vector<MAST::StressStrainOutputBase::Data*>&
332  stress_data = output.get_stress_strain_data_for_elem(&elem);
333 
334  libmesh_assert_equal_to(stress_data.size(), 1); // this should have one element
335 
336  dstressdp = stress_data[0]->get_stress_sensitivity(&f);
337  dstraindp = stress_data[0]->get_strain_sensitivity(&f);
338  dvmdp = stress_data[0]->dvon_Mises_stress_dp (&f);
339  dvmf_dp =
340  output.von_Mises_p_norm_functional_sensitivity_for_all_elems(pval, &f);
341 
342  output.clear(false);
343  }
344 
345 
346  // now the finite difference sensitivity
347  // identify the perturbation in the parameter
348  p0 = f();
349  (fabs(p0) > 0)? dp=delta*p0 : dp=delta;
350  f() += dp;
351 
352  // get the stress, strain and von Mises stress sensitivity
353  e->volume_output_quantity(false, false, output_map);
354 
355  // reset the parameter value
356  f() = p0;
357 
358  // next, check the total derivative of the quantity wrt the parameter
359  {
360  const std::vector<MAST::StressStrainOutputBase::Data*>&
361  stress_data = output.get_stress_strain_data_for_elem(&elem);
362 
363  libmesh_assert_equal_to(stress_data.size(), 1); // this should have one element
364 
365  stress = (stress_data[0]->stress() - stress0)/dp;
366  strain = (stress_data[0]->strain() - strain0)/dp;
367  vm = (stress_data[0]->von_Mises_stress() - vm0)/dp;
368  dvmf_dp_fd =
369  (output.von_Mises_p_norm_functional_for_all_elems(pval)-vmf0)/dp;
370 
371  output.clear(false);
372  }
373 
374  // compare and benchmark the values
375  BOOST_TEST_MESSAGE(" ** dStress/dp (partial) wrt : " << f.name() << " **");
376  BOOST_CHECK(MAST::compare_vector(stress, dstressdp, tol));
377  BOOST_TEST_MESSAGE(" ** dStrain/dp (partial) wrt : " << f.name() << " **");
378  BOOST_CHECK(MAST::compare_vector(strain, dstraindp, tol));
379  BOOST_TEST_MESSAGE(" ** dVM-Stress/dp (partial) wrt : " << f.name() << " **");
380  BOOST_CHECK(MAST::compare_value ( vm, dvmdp, tol));
381  BOOST_TEST_MESSAGE(" ** dVM_func-Stress/dp (partial) wrt : " << f.name() << " **");
382  BOOST_CHECK(MAST::compare_value (dvmf_dp_fd, dvmf_dp, tol));
383  }
384 
385 
386  //
387  // now the total sensitivity including the sensitivity of the state.
388  // Each dof is independently assigned a nonzero sensitivity value
389  //
390  for (unsigned int i=0; i<v._params_for_sensitivity.size(); i++) {
391 
392  MAST::Parameter& f = *v._params_for_sensitivity[i];
393 
394 
395  // now perturb each element of the vector independently
396  for (unsigned int j=0; j<ndofs; j++) {
397 
398  // first calculate the analytical sensitivity
399  e->set_solution(x0);
400  // identify the perturbation in the parameter
401  // if delta=1.e-5, and dp=1.e-3, then delta/dp = 1.e-2
402  // magnitude of delta/dp should not matter, since the
403  // sensitivity is linear in it. We really want delta and dp to be
404  // small so that finite differencing can be accurately done
405  p0 = f();
406  (fabs(p0) > 0)? dp=std::max(delta*p0, delta) : dp=delta;
407  // now, set the solution sensitivity for analytical sensitivity
408  x = RealVectorX::Zero(ndofs);
409  x(j) = delta/dp;
410  e->set_solution(x, true); // sets the sensitivity
411  e->sensitivity_param = &f;
412 
413  // sensitivity output
414  e->volume_output_quantity(false, true, output_map);
415 
416  {
417  // copy it for comparison
418  const std::vector<MAST::StressStrainOutputBase::Data*>&
419  stress_data = output.get_stress_strain_data_for_elem(&elem);
420 
421  libmesh_assert_equal_to(stress_data.size(), 1); // this should have one element
422 
423  dstressdp = stress_data[0]->get_stress_sensitivity(&f);
424  dstraindp = stress_data[0]->get_strain_sensitivity(&f);
425  dvmdp = stress_data[0]->dvon_Mises_stress_dp (&f);
426  dvmf_dp =
427  output.von_Mises_p_norm_functional_sensitivity_for_all_elems(pval, &f);
428 
429  output.clear(false);
430  }
431 
432 
433  // now pertueb the parameter for finite differencing
434  f() += dp;
435 
436  // remove the sensitivity association
437  e->sensitivity_param = nullptr;
438 
439  // first perturb the solution for fd sensitivity
440  x = x0;
441  x(j) += delta;
442  e->set_solution(x);
443  // now, set the solution sensitivity for analytical sensitivity
444  x = RealVectorX::Zero(ndofs);
445  e->set_solution(x, true); // sets the sensitivity to zero
446 
447  // get the stress, strain and von Mises stress for finite-differencing
448  e->volume_output_quantity(false, false, output_map);
449 
450  // reset the parameter value
451  f() = p0;
452 
453  // next, check the total derivative of the quantity wrt the parameter
454  {
455  const std::vector<MAST::StressStrainOutputBase::Data*>&
456  stress_data = output.get_stress_strain_data_for_elem(&elem);
457 
458  libmesh_assert_equal_to(stress_data.size(), 1); // this should have one element
459 
460  stress = (stress_data[0]->stress() - stress0)/dp;
461  strain = (stress_data[0]->strain() - strain0)/dp;
462  vm = (stress_data[0]->von_Mises_stress() - vm0)/dp;
463  dvmf_dp_fd =
464  (output.von_Mises_p_norm_functional_for_all_elems(pval)-vmf0)/dp;
465 
466  output.clear(false);
467  }
468 
469  // compare and benchmark the values
470  BOOST_TEST_MESSAGE(" ** dStress/dp (total: dof = " << j << ") wrt : " << f.name() << " **");
471  BOOST_CHECK(MAST::compare_vector( stress, dstressdp, tol));
472  BOOST_TEST_MESSAGE(" ** dStrain/dp (total: dof = " << j << ") wrt : " << f.name() << " **");
473  BOOST_CHECK(MAST::compare_vector( strain, dstraindp, tol));
474  BOOST_TEST_MESSAGE(" ** dVM-Stress/dp (total: dof = " << j << ") wrt : " << f.name() << " **");
475  BOOST_CHECK(MAST::compare_value ( vm, dvmdp, tol));
476  BOOST_TEST_MESSAGE(" ** dVM_func-Stress/dp (total: dof = " << j << ") wrt : " << f.name() << " **");
477  BOOST_CHECK(MAST::compare_value ( dvmf_dp_fd, dvmf_dp, tol));
478  }
479  }
480 }
481 
482 
483 BOOST_AUTO_TEST_CASE (VonMisesStress) {
484 
485  const Real
486  tol = 1.e-2;
487 
488  // check the accuracy of sensitivity analysis of von Mises stress,
489  // and the von Mises stress functional
490  // this simulates a case with 4 different stress values for an element
491 
492  std::unique_ptr<libMesh::Elem> elem(new libMesh::Edge2);
493  MAST::Parameter f("a", 0.);
494  libMesh::Point p;
496  strain = RealVectorX::Zero(6),
497  stress = RealVectorX::Zero(6);
498 
499 
500  Real
501  stress1 = 5.e6,
502  stress2 = 15.e6,
503  dstress1 = -1.e8,
504  dstress2 = -3.e8,
505  func = 0.,
506  dfunc = 0.,
507  JxW = 0.1;
508 
510 
511  // the four stress values
512  stress(0) = stress1;
513  output.add_stress_strain_at_qp_location(elem.get(), p, p, stress, strain, JxW);
514  stress(0) = -stress1;
515  output.add_stress_strain_at_qp_location(elem.get(), p, p, stress, strain, JxW);
516  stress(0) = stress2;
517  output.add_stress_strain_at_qp_location(elem.get(), p, p, stress, strain, JxW);
518  stress(0) = -stress2;
519  output.add_stress_strain_at_qp_location(elem.get(), p, p, stress, strain, JxW);
520 
521  // now, the stress sensitivity values
522  const std::vector<MAST::StressStrainOutputBase::Data*>&
523  data = output.get_stress_strain_data_for_elem(elem.get());
524 
525  // set the sensitivity for each stress
526  stress(0) = dstress1;
527  data[0]->set_sensitivity(&f, stress, strain);
528  stress(0) = -dstress1;
529  data[1]->set_sensitivity(&f, stress, strain);
530  stress(0) = dstress2;
531  data[2]->set_sensitivity(&f, stress, strain);
532  stress(0) = -dstress2;
533  data[3]->set_sensitivity(&f, stress, strain);
534 
535  // now check the vm stress value for each case
536  BOOST_TEST_MESSAGE(" ** von Mises Stress ** ");
537  BOOST_CHECK(MAST::compare_value(fabs(stress1),
538  data[0]->von_Mises_stress(),
539  tol));
540  BOOST_CHECK(MAST::compare_value(fabs(stress1),
541  data[1]->von_Mises_stress(),
542  tol));
543  BOOST_CHECK(MAST::compare_value(fabs(stress2),
544  data[2]->von_Mises_stress(),
545  tol));
546  BOOST_CHECK(MAST::compare_value(fabs(stress2),
547  data[3]->von_Mises_stress(),
548  tol));
549 
550  BOOST_TEST_MESSAGE(" ** dvm-stress/dp **");
551  BOOST_CHECK(MAST::compare_value(dstress1,
552  data[0]->dvon_Mises_stress_dp(&f),
553  tol));
554  BOOST_CHECK(MAST::compare_value(dstress1,
555  data[1]->dvon_Mises_stress_dp(&f),
556  tol));
557  BOOST_CHECK(MAST::compare_value(dstress2,
558  data[2]->dvon_Mises_stress_dp(&f),
559  tol));
560  BOOST_CHECK(MAST::compare_value(dstress2,
561  data[3]->dvon_Mises_stress_dp(&f),
562  tol));
563 
564  BOOST_TEST_MESSAGE(" ** vm-stress functional **");
565  func = stress2/pow(4.*JxW,0.5)*
566  pow(pow(fabs( stress1)/stress2,2)*JxW +
567  pow(fabs(-stress1)/stress2,2)*JxW +
568  pow(fabs( stress2)/stress2,2)*JxW +
569  pow(fabs(-stress2)/stress2,2)*JxW,0.5);
570 
571  BOOST_CHECK(MAST::compare_value(func,
572  output.von_Mises_p_norm_functional_for_all_elems(2),
573  tol));
574 
575 
576  BOOST_TEST_MESSAGE(" ** dvm-stress functional/dp **");
577  // update the stress values for a small perturbation
578  dfunc = stress2/pow(4.*JxW,0.5)*0.5*
579  pow(pow(fabs( stress1)/stress2,2)*JxW +
580  pow(fabs(-stress1)/stress2,2)*JxW +
581  pow(fabs( stress2)/stress2,2)*JxW +
582  pow(fabs(-stress2)/stress2,2)*JxW,-.5) *
583  2 *(fabs( stress1)/stress2*dstress1/stress2*JxW +
584  fabs(-stress1)/stress2*dstress1/stress2*JxW +
585  fabs( stress2)/stress2*dstress2/stress2*JxW +
586  fabs(-stress2)/stress2*dstress2/stress2*JxW);
587 
588  BOOST_CHECK(MAST::compare_value
589  (dfunc,
590  output.von_Mises_p_norm_functional_sensitivity_for_all_elems(2, &f),
591  tol));
592 
593 }
594 
595 
596 
597 BOOST_FIXTURE_TEST_SUITE (Structural1DStressEvaluation, MAST::BuildStructural1DElem)
598 
599 BOOST_AUTO_TEST_CASE (StressLinear1DIndependentOffset) {
600 
601  this->init(false, false);
602 
603  RealVectorX v;
604 
605  // pure axial deformation
606  BOOST_TEST_MESSAGE("**** Pure Extension Deformation **");
607  set_deformation(1, 0, libMesh::INVALID_ELEM, v);
608  check_stress(*this, v);
609 
610  // pure bending deformation
611  BOOST_TEST_MESSAGE("**** Pure Bending Deformation **");
612  set_deformation(1, 1, libMesh::INVALID_ELEM, v);
613  check_stress(*this, v);
614 
615  // combination of axial and bending deformation
616  BOOST_TEST_MESSAGE("**** Combined Extension-Bending Deformation **");
617  set_deformation(1, 2, libMesh::INVALID_ELEM, v);
618  check_stress(*this, v);
619 }
620 
621 
622 
623 
624 BOOST_AUTO_TEST_CASE (StressNonlinear1DIndependentOffset) {
625 
626  this->init(false, true);
627 
628  RealVectorX v;
629 
630  // combination of axial and bending deformation
631  BOOST_TEST_MESSAGE("**** Combined Extension-Bending Large Deformation **");
632  set_deformation(1, 3, libMesh::INVALID_ELEM, v);
633  check_stress(*this, v);
634 }
635 
636 
637 
638 BOOST_AUTO_TEST_CASE (StressLinear1DDependentOffset) {
639 
640  this->init(true, false);
641 
642  RealVectorX v;
643 
644  // pure axial deformation
645  BOOST_TEST_MESSAGE("**** Pure Extension Deformation **");
646  set_deformation(1, 0, libMesh::INVALID_ELEM, v);
647  check_stress(*this, v);
648 
649  // pure bending deformation
650  BOOST_TEST_MESSAGE("**** Pure Bending Deformation **");
651  set_deformation(1, 1, libMesh::INVALID_ELEM, v);
652  check_stress(*this, v);
653 
654  // combination of axial and bending deformation
655  BOOST_TEST_MESSAGE("**** Combined Extension-Bending Deformation **");
656  set_deformation(1, 2, libMesh::INVALID_ELEM, v);
657  check_stress(*this, v);
658 }
659 
660 
661 
662 BOOST_AUTO_TEST_CASE (StressNonlinear1DDependentOffset) {
663 
664  this->init(true, true);
665 
666  RealVectorX v;
667 
668  // combination of axial and bending deformation
669  BOOST_TEST_MESSAGE("**** Combined Extension-Bending Large Deformation **");
670  set_deformation(1, 3, libMesh::INVALID_ELEM, v);
671  check_stress(*this, v);
672 }
673 
674 
675 BOOST_AUTO_TEST_SUITE_END()
676 
677 
678 BOOST_FIXTURE_TEST_SUITE (Structural2DStressEvaluation, MAST::BuildStructural2DElem)
679 
680 BOOST_AUTO_TEST_CASE (StressLinear2DIndependentOffsetQUAD4) {
681 
682  this->init(false, false, libMesh::QUAD4);
683 
684  RealVectorX v;
685 
686  // pure axial deformation
687  BOOST_TEST_MESSAGE("**** Pure Extension Deformation **");
688  set_deformation(2, 0, libMesh::QUAD4, v);
689  check_stress(*this, v);
690 
691  BOOST_TEST_MESSAGE("**** Pure Bending Deformation **");
692  set_deformation(2, 1, libMesh::QUAD4, v);
693  check_stress(*this, v);
694 
695  BOOST_TEST_MESSAGE("**** Combined Extension-Bending Deformation **");
696  set_deformation(2, 2, libMesh::QUAD4, v);
697  check_stress(*this, v);
698 }
699 
700 
701 
702 BOOST_AUTO_TEST_CASE (Stress2DNonlinearIndependentOffsetQUAD4) {
703 
704  this->init(false, true, libMesh::QUAD4);
705 
706  RealVectorX v;
707 
708  BOOST_TEST_MESSAGE("**** Combined Extension-Bending Large Deformation **");
709  set_deformation(2, 3, libMesh::QUAD4, v);
710  check_stress(*this, v);
711 }
712 
713 
714 
715 BOOST_AUTO_TEST_CASE (StressLinear2DIndependentOffsetTRI3) {
716 
717  this->init(false, false, libMesh::TRI3);
718 
719  RealVectorX v;
720 
721  // pure axial deformation
722  BOOST_TEST_MESSAGE("**** Pure Extension Deformation **");
723  set_deformation(2, 0, libMesh::TRI3, v);
724  check_stress(*this, v);
725 
726  BOOST_TEST_MESSAGE("**** Pure Bending Deformation **");
727  set_deformation(2, 1, libMesh::TRI3, v);
728  check_stress(*this, v);
729 
730  BOOST_TEST_MESSAGE("**** Combined Extension-Bending Deformation **");
731  set_deformation(2, 2, libMesh::TRI3, v);
732  check_stress(*this, v);
733 }
734 
735 
736 
737 BOOST_AUTO_TEST_CASE (StressNonlinear2DIndependentOffsetTRI3) {
738 
739  this->init(false, true, libMesh::TRI3);
740 
741  RealVectorX v;
742 
743  BOOST_TEST_MESSAGE("**** Combined Extension-Bending Large Deformation **");
744  set_deformation(2, 3, libMesh::TRI3, v);
745  check_stress(*this, v);
746 }
747 
748 
749 
750 BOOST_AUTO_TEST_CASE (StressLinear2DDependentOffsetQUAD4) {
751 
752  this->init(true, false, libMesh::QUAD4);
753 
754  RealVectorX v;
755 
756  // pure axial deformation
757  BOOST_TEST_MESSAGE("**** Pure Extension Deformation **");
758  set_deformation(2, 0, libMesh::QUAD4, v);
759  check_stress(*this, v);
760 
761  BOOST_TEST_MESSAGE("**** Pure Bending Deformation **");
762  set_deformation(2, 1, libMesh::QUAD4, v);
763  check_stress(*this, v);
764 
765  BOOST_TEST_MESSAGE("**** Combined Extension-Bending Deformation **");
766  set_deformation(2, 2, libMesh::QUAD4, v);
767  check_stress(*this, v);
768 }
769 
770 
771 
772 BOOST_AUTO_TEST_CASE (StressNonlinear2DDependentOffsetQUAD4) {
773 
774  this->init(true, true, libMesh::QUAD4);
775 
776  RealVectorX v;
777 
778  BOOST_TEST_MESSAGE("**** Combined Extension-Bending Large Deformation **");
779  set_deformation(2, 3, libMesh::QUAD4, v);
780  check_stress(*this, v);
781 }
782 
783 
784 
785 BOOST_AUTO_TEST_CASE (StressLinear2DDependentOffsetTRI3) {
786 
787  this->init(true, false, libMesh::TRI3);
788 
789  RealVectorX v;
790 
791  // pure axial deformation
792  BOOST_TEST_MESSAGE("**** Pure Extension Deformation **");
793  set_deformation(2, 0, libMesh::TRI3, v);
794  check_stress(*this, v);
795 
796  BOOST_TEST_MESSAGE("**** Pure Bending Deformation **");
797  set_deformation(2, 1, libMesh::TRI3, v);
798  check_stress(*this, v);
799 
800  BOOST_TEST_MESSAGE("**** Combined Extension-Bending Deformation **");
801  set_deformation(2, 2, libMesh::TRI3, v);
802  check_stress(*this, v);
803 }
804 
805 
806 
807 
808 BOOST_AUTO_TEST_CASE (StressNonlinear2DDependentOffsetTRI3) {
809 
810  this->init(true, true, libMesh::TRI3);
811 
812  RealVectorX v;
813 
814  BOOST_TEST_MESSAGE("**** Combined Extension-Bending Large Deformation **");
815  set_deformation(2, 3, libMesh::TRI3, v);
816  check_stress(*this, v);
817 }
818 
819 
820 
821 BOOST_AUTO_TEST_SUITE_END()
822 
823 
const std::string & name() const
returns the name of this function
Definition: function_base.h:60
Data structure provides the mechanism to store stress and strain output from a structural analysis...
void clear()
clears the data structure of any stored values so that it can be used for another element...
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)
virtual const std::vector< MAST::StressStrainOutputBase::Data * > & get_stress_strain_data_for_elem(const MAST::GeomElem &e) const
bool compare_matrix(const RealMatrixX &m0, const RealMatrixX &m, const Real tol)
libMesh::Real Real
BOOST_AUTO_TEST_CASE(VonMisesStress)
Matrix< Real, Dynamic, Dynamic > RealMatrixX
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
bool compare_value(const Real v0, const Real v, const Real tol)
void check_stress(ValType &v, const RealVectorX &x0)
virtual MAST::StressStrainOutputBase::Data & add_stress_strain_at_qp_location(const MAST::GeomElem &e, const unsigned int qp, const libMesh::Point &quadrature_pt, const libMesh::Point &physical_pt, const RealVectorX &stress, const RealVectorX &strain, Real JxW)
add the stress tensor associated with the qp.
void set_deformation(const unsigned int dim, const unsigned int case_num, const libMesh::ElemType e, RealVectorX &vec)