MAST
level_set_stress_assembly.cpp
Go to the documentation of this file.
1 /*
2  * MAST: Multidisciplinary-design Adaptation and Sensitivity Toolkit
3  * Copyright (C) 2013-2019 Manav Bhatia
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 // MAST includes
25 #include "base/nonlinear_system.h"
26 #include "base/elem_base.h"
29 #include "level_set/sub_cell_fe.h"
31 
32 
33 // libMesh includes
34 #include "libmesh/system.h"
35 #include "libmesh/dof_map.h"
36 #include "libmesh/numeric_vector.h"
37 
40 _level_set (nullptr),
41 _intersection (nullptr),
42 _dof_handler (nullptr) {
43 
44 }
45 
46 
48 
49 }
50 
51 
52 
53 
54 void
56  MAST::LevelSetInterfaceDofHandler* dof_handler) {
57 
58  libmesh_assert(!_level_set);
59  libmesh_assert(!_intersection);
60  libmesh_assert(_system);
61 
62  _level_set = &level_set;
64  _dof_handler = dof_handler;
65 }
66 
67 
68 
69 void
71 
72  _level_set = nullptr;
73  _dof_handler = nullptr;
74 
75  if (_intersection) {
76  delete _intersection;
77  _intersection = nullptr;
78  }
79 }
80 
81 
82 
83 extern void
84 get_max_stress_strain_values(const std::vector<MAST::StressStrainOutputBase::Data*>& data,
85  RealVectorX& max_strain,
86  RealVectorX& max_stress,
87  Real& max_vm,
88  const MAST::FunctionBase* p);
89 
90 
91 
92 
95  const libMesh::NumericVector<Real>& X) {
96 
97  // make sure it has been initialized
98  libmesh_assert(_system);
99  libmesh_assert(_discipline);
100  libmesh_assert(!_elem_ops);
101 
102  this->set_elem_operation_object(ops);
103 
104  RealVectorX sol;
105 
106  const MAST::NonlinearSystem&
107  structural_sys = _system->system();
108 
109  libMesh::System&
110  stress_sys = dynamic_cast<MAST::StructuralSystemInitialization*>(_system)->get_stress_sys();
111  const std::vector<unsigned int>&
112  stress_vars = dynamic_cast<MAST::StructuralSystemInitialization*>(_system)->get_stress_var_ids();
113 
114  stress_sys.solution->zero();
115 
116  std::vector<libMesh::dof_id_type> dof_indices;
117  const libMesh::DofMap& dof_map = structural_sys.get_dof_map();
118 
119  std::unique_ptr<libMesh::NumericVector<Real> > localized_solution;
120  localized_solution.reset(this->build_localized_vector(structural_sys,
121  X).release());
122 
123 
124  libMesh::MeshBase::const_element_iterator el =
125  structural_sys.get_mesh().active_local_elements_begin();
126  const libMesh::MeshBase::const_element_iterator end_el =
127  structural_sys.get_mesh().active_local_elements_end();
128 
129  libMesh::dof_id_type
130  dof_id = 0;
131 
132  unsigned int
133  sys_num = stress_sys.number();
134 
136  max_strain_vals = RealVectorX::Zero(6),
137  max_stress_vals = RealVectorX::Zero(6);
138 
139  Real
140  max_vm_stress = 0.;
141 
142  for ( ; el != end_el; el++) {
143 
144  const libMesh::Elem* elem = *el;
145 
146  _intersection->init(*_level_set, *elem, structural_sys.time,
147  structural_sys.get_mesh().max_elem_id(),
148  structural_sys.get_mesh().max_node_id());
149 
150  // clear data structure since each element will account for all
151  // sub elements only
152  ops.clear();
153 
154  // process only if the element has any positive region
156 
157  dof_map.dof_indices (elem, dof_indices);
158 
159  unsigned int ndofs = (unsigned int)dof_indices.size();
160  sol.setZero(ndofs);
161 
162  for (unsigned int i=0; i<dof_indices.size(); i++)
163  sol(i) = (*localized_solution)(dof_indices[i]);
164 
167 
168  const std::vector<const libMesh::Elem *> &
170 
171  std::vector<const libMesh::Elem*>::const_iterator
172  hi_sub_elem_it = elems_hi.begin(),
173  hi_sub_elem_end = elems_hi.end();
174 
175  for (; hi_sub_elem_it != hi_sub_elem_end; hi_sub_elem_it++ ) {
176 
177  const libMesh::Elem* sub_elem = *hi_sub_elem_it;
179  ops.set_elem_data(elem->dim(), *elem, geom_elem);
180  geom_elem.init(*sub_elem, *_system, *_intersection);
181 
182  // clear before calculating the data
183  ops.init(geom_elem);
184  ops.set_elem_solution(sol);
185  ops.evaluate();
186  ops.clear_elem();
187  }
188 
189  // get the stress-strain data map from the object
190  const std::map<const libMesh::dof_id_type,
191  std::vector<MAST::StressStrainOutputBase::Data*> >& output_map =
193 
194  // make sure that the number of elements in this is the same
195  // as the number of elements in the subelement vector
196  libmesh_assert_equal_to(output_map.size(), elems_hi.size());
197 
198  // now iterate over all the elements and set the value in the
199  // new system used for output
200  std::map<const libMesh::dof_id_type,
201  std::vector<MAST::StressStrainOutputBase::Data*> >::const_iterator
202  e_it = output_map.begin(),
203  e_end = output_map.end();
204 
206  max_vals = RealVectorX::Zero(13);
207 
208  // get the max of all quantities
209  for ( ; e_it != e_end; e_it++) {
210 
211  get_max_stress_strain_values(e_it->second,
212  max_strain_vals,
213  max_stress_vals,
214  max_vm_stress,
215  nullptr);
216 
217 
218  for (unsigned int i=0; i<6; i++) {
219  if (std::fabs(max_strain_vals(i)) > std::fabs(max_vals(i)))
220  max_vals(i) = max_strain_vals(i);
221  if (std::fabs(max_stress_vals(i)) > std::fabs(max_vals(i+6)))
222  max_vals(i+6) = max_stress_vals(i);
223  }
224  max_vals(12) = std::max(max_vm_stress, max_vals(12));
225  }
226 
227  // set the values in the system
228  // stress value
229  dof_id = elem->dof_number(sys_num, stress_vars[12], 0);
230  stress_sys.solution->set(dof_id, max_vals(12));
231 
232  for (unsigned int i=0; i<6; i++) {
233  // strain value
234  dof_id = elem->dof_number(sys_num, stress_vars[i], 0);
235  stress_sys.solution->set(dof_id, max_vals(i));
236 
237  // stress value
238  dof_id = elem->dof_number(sys_num, stress_vars[i+6], 0);
239  stress_sys.solution->set(dof_id, max_vals(i+6));
240  }
241  }
242 
243  _intersection->clear();
244  }
245 
246  stress_sys.solution->close();
248 }
249 
MAST::AssemblyElemOperations * _elem_ops
provides assembly elem operations for use by this class
MAST::NonlinearSystem & system()
virtual void clear()
clears association with level set function
Data structure provides the mechanism to store stress and strain output from a structural analysis...
This class implements a system for solution of nonlinear systems.
void get_max_stress_strain_values(const std::vector< MAST::StressStrainOutputBase::Data * > &data, RealVectorX &max_strain, RealVectorX &max_stress, Real &max_vm, const MAST::FunctionBase *p)
void solution_of_factored_element(const libMesh::Elem &elem, RealVectorX &elem_sol)
updates the components of the solution vector in elem_sol for the void domain using the stored soluti...
virtual void clear_elem_operation_object()
clears the association of this object with the assembly element operation object. ...
MAST::LevelSetInterfaceDofHandler * _dof_handler
void clear()
clears the data structure of any stored values so that it can be used for another element...
virtual void init(const libMesh::Elem &elem, const MAST::SystemInitialization &sys_init)
This method should not get called for this class.
MAST::FieldFunction< Real > * _level_set
virtual void set_elem_operation_object(MAST::AssemblyElemOperations &elem_ops)
attaches a element operation to this object, and associated this with the element operation object...
virtual void set_elem_solution(const RealVectorX &sol)
sets the element solution
libMesh::Real Real
void init(const MAST::FieldFunction< Real > &phi, const libMesh::Elem &e, const Real t, unsigned int max_elem_id, unsigned int max_node_id)
virtual void init(MAST::FieldFunction< Real > &level_set, MAST::LevelSetInterfaceDofHandler *dof_handler=nullptr)
attaches level set function to this.
MAST::SystemInitialization * _system
System for which this assembly is performed.
virtual ~LevelSetStressAssembly()
destructor resets the association of this assembly object with the system
virtual void update_stress_strain_data(MAST::StressStrainOutputBase &ops, const libMesh::NumericVector< Real > &X)
updates the stresses and strains for the specified solution vector X.
MAST::PhysicsDisciplineBase * _discipline
PhysicsDisciplineBase object for which this class is assembling.
virtual const std::map< const libMesh::dof_id_type, std::vector< MAST::StressStrainOutputBase::Data * > > & get_stress_strain_data() const
LevelSetStressAssembly()
constructor associates this assembly object with the system
This class inherits from MAST::GeomElem and provides an interface to initialize FE objects on sub-ele...
virtual void init(const MAST::GeomElem &elem)
initialize for the element.
virtual void set_elem_data(unsigned int dim, const libMesh::Elem &ref_elem, MAST::GeomElem &elem) const
sets the structural element y-vector if 1D element is used.
Matrix< Real, Dynamic, 1 > RealVectorX
std::unique_ptr< libMesh::NumericVector< Real > > build_localized_vector(const libMesh::System &sys, const libMesh::NumericVector< Real > &global) const
localizes the parallel vector so that the local copy stores all values necessary for calculation of t...
const std::vector< const libMesh::Elem * > & get_sub_elems_positive_phi() const
virtual void evaluate()
this evaluates all relevant stress components on the element to evaluate the p-averaged quantity...
virtual void clear_elem()
clears the element initialization
MAST::LevelSetIntersection * _intersection
bool if_factor_element(const libMesh::Elem &elem) const
void clear()
clears the data structures