MAST
structural_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"
28 #include "mesh/geom_elem.h"
29 
30 // libMesh includes
31 #include "libmesh/petsc_nonlinear_solver.h"
32 #include "libmesh/petsc_vector.h"
33 #include "libmesh/dof_map.h"
34 
35 
36 // monitor function for PETSc solver so that
37 // the incompatible solution can be updated after each converged iterate
38 PetscErrorCode
40  PetscInt its,
41  PetscReal norm2,
42  void* ctx) {
43 
44  // convert the context pointer to the assembly object pointer
45  MAST::AssemblyBase* assembly = (MAST::AssemblyBase*)ctx;
46 
47  // system for which this is being processed
48  MAST::NonlinearSystem& sys = assembly->system();
49 
51  str_assembly = dynamic_cast<MAST::StructuralAssembly*>(assembly->get_solver_monitor());
52 
53  // if this is the first iteration, create a vector in system
54  // as the initial approximation of the system solution
55  if (its == 0) {
56  sys.add_vector("old_solution");
57  }
58  else {
59  // use the previous solution as the base solution
60 
61  // get the solution update from SNES
62  Vec dx;
63  PetscErrorCode ierr = SNESGetSolutionUpdate(snes, &dx);
64  libmesh_assert(!ierr);
65 
66  // attach the vector to a NumericVector object
67  std::unique_ptr<libMesh::NumericVector<Real> >
68  vec(new libMesh::PetscVector<Real>(dx, sys.comm())),
69  vec_scaled(vec->clone().release());
70 
71  // the solution update provided by SNES is -ve of the dX
72  // hence, scale the vector by -1
73  vec_scaled->scale(-1.);
74  vec_scaled->close();
75 
76  // ask the assembly to update the incompatible mode solution
77  // for all the 3D elements based on the solution update here
78  str_assembly->update_incompatible_solution(sys.get_vector("old_solution"),
79  *vec_scaled);
80  }
81 
82 
83 
84  // finally, update the solution
85  sys.get_vector("old_solution") = *sys.solution;
86  sys.get_vector("old_solution").close();
87 
88 
89  return 0;
90 }
91 
92 
93 
94 
96 MAST::AssemblyBase::SolverMonitor(),
97 _assembly (nullptr) {
98 
99 }
100 
101 
103 
104 }
105 
106 
107 void
109 
110  const libMesh::Elem& e = elem.elem().get_reference_elem();
111 
112  if (elem.if_incompatible_modes()) {
113 
114  // init the solution if it is not currently set
115  if (!_incompatible_sol.count(&e))
116  _incompatible_sol[&e] = RealVectorX::Zero(elem.incompatible_mode_size());
117 
118  // use the solution currently available
120  }
121 }
122 
123 
124 void
126 
127  // should be cleared before initialization
128  libmesh_assert(!_assembly);
129 
130  _assembly = &assembly;
131 
132  // get the nonlinear solver SNES object from System and
133  // add a monitor to it so that it can be used to update the
134  // incompatible mode solution after each update
135 
136  libMesh::PetscNonlinearSolver<Real> &petsc_nonlinear_solver =
137  *(dynamic_cast<libMesh::PetscNonlinearSolver<Real>*>
138  (dynamic_cast<MAST::NonlinearSystem&>(assembly.system()).nonlinear_solver.get()));
139 
140 
141  // initialize the solver before getting the snes object
142  if (libMesh::on_command_line("--solver_system_names"))
143  petsc_nonlinear_solver.init((assembly.system().name()+"_").c_str());
144 
145  // get the SNES object
146  SNES snes = petsc_nonlinear_solver.snes();
147 
148  PetscErrorCode ierr =
149  SNESMonitorSet(snes,
151  (void*)this,
152  PETSC_NULL);
153 
154  libmesh_assert(!ierr);
155 }
156 
157 
158 
159 void
161 
162  // next, remove the monitor function from the snes object
163  libMesh::PetscNonlinearSolver<Real> &petsc_nonlinear_solver =
164  *(dynamic_cast<libMesh::PetscNonlinearSolver<Real>*>
165  (dynamic_cast<MAST::NonlinearSystem&>(_assembly->system()).nonlinear_solver.get()));
166 
167  // get the SNES object
168  SNES snes = petsc_nonlinear_solver.snes();
169 
170  PetscErrorCode ierr =
171  SNESMonitorCancel(snes);
172  libmesh_assert(!ierr);
173 
174  _assembly = nullptr;
175 }
176 
177 
178 
179 void
181  libMesh::NumericVector<Real>& dX) {
182 
183 
184  // iterate over each element and ask the 3D elements to update
185  // their local solutions
186 
188 
189  // iterate over each element, initialize it and get the relevant
190  // analysis quantities
191  RealVectorX sol, dsol;
192 
193  std::vector<libMesh::dof_id_type> dof_indices;
194  const libMesh::DofMap& dof_map = sys.get_dof_map();
195 
196 
197  std::unique_ptr<libMesh::NumericVector<Real> >
198  localized_solution(_assembly->build_localized_vector(sys,
199  X).release()),
200  localized_dsolution(_assembly->build_localized_vector(sys,
201  dX).release());
202 
203 
204  // if a solution function is attached, initialize it
205  //if (_sol_function)
206  // _sol_function->init( X);
207 
208 
209  libMesh::MeshBase::const_element_iterator el =
210  sys.get_mesh().active_local_elements_begin();
211  const libMesh::MeshBase::const_element_iterator end_el =
212  sys.get_mesh().active_local_elements_end();
213 
214 
215  for ( ; el != end_el; ++el) {
216 
217  const libMesh::Elem* elem = *el;
219 
220  MAST::GeomElem geom_elem;
221  ops.set_elem_data(elem->dim(), *elem, geom_elem);
222  geom_elem.init(*elem, _assembly->system_init());
223 
224  ops.init(geom_elem);
225 
227  dynamic_cast<MAST::StructuralElementBase&>(ops.get_physics_elem());
228 
229  if (p_elem.if_incompatible_modes()) {
230 
231  dof_map.dof_indices (elem, dof_indices);
232 
233  // get the solution
234  unsigned int ndofs = (unsigned int)dof_indices.size();
235  sol.setZero(ndofs);
236  dsol.setZero(ndofs);
237 
238  for (unsigned int i=0; i<dof_indices.size(); i++) {
239  sol(i) = (*localized_solution) (dof_indices[i]);
240  dsol(i) = (*localized_dsolution)(dof_indices[i]);
241  }
242 
243  p_elem.set_solution(sol);
245 
246  //if (_sol_function)
247  // p_elem.attach_active_solution_function(*_sol_function);
248 
249  // perform the element level calculations
251 
253  }
254  }
255 
256 
257  // if a solution function is attached, clear it
258  //if (_sol_function)
259  // _sol_function->clear();
260 }
261 
262 
263 //void
264 //MAST::StructuralAssembly::
265 //_assemble_point_loads(MAST::PhysicsDisciplineBase& discipline,
266 // MAST::SystemInitialization& system,
267 // libMesh::NumericVector<Real>& res) {
268 //
269 // // get a reference to the system, mesh and dof map
270 // MAST::NonlinearSystem& sys = system.system();
271 // libMesh::DofMap& dof_map = sys.get_dof_map();
272 //
273 // // get a reference to the set of loads
274 // const MAST::PointLoadSetType& point_loads = discipline.point_loads();
275 //
276 // // iterate over the loads and process them
277 // MAST::PointLoadSetType::const_iterator
278 // load_it = point_loads.begin(),
279 // load_end = point_loads.end();
280 //
281 // for ( ; load_it != load_end; load_it++) {
282 // const MAST::PointLoadCondition& load = **load_it;
283 // const std::set<libMesh::Node*>& nodes = load.get_nodes();
284 //
285 // std::set<libMesh::Node*>::const_iterator
286 // n_it = nodes.begin(),
287 // n_end = nodes.end();
288 //
289 // for ( ; n_it != n_end; n_it++) {
290 //
291 // // iterate over the nodes and the variables on them
292 //
293 // // get the dof id for the var on node
294 //
295 // // if the dof is not constrained, then add the
296 //
297 // // load to the residual vector
298 // }
299 //
300 // }
301 //
302 // res.close();
303 //}
304 
305 
306 
virtual void update_incompatible_mode_solution(const RealVectorX &dsol)
updates the incompatible solution for this element.
This class implements a system for solution of nonlinear systems.
This class provides some routines that are common to structural assembly routines.
std::map< const libMesh::Elem *, RealVectorX > _incompatible_sol
map of local incompatible mode solution per 3D elements
void detach_active_solution_function()
Detaches the function object that may have been attached to the element.
Definition: elem_base.cpp:158
const MAST::GeomElem & elem() const
Definition: elem_base.h:117
void set_elem_incompatible_sol(MAST::StructuralElementBase &elem)
virtual bool if_incompatible_modes() const =0
virtual const libMesh::Elem & get_reference_elem() const
Definition: geom_elem.cpp:54
virtual void set_elem_data(unsigned int dim, const libMesh::Elem &ref_elem, MAST::GeomElem &elem) const =0
some analyses may want to set additional element data before initialization of the GeomElem...
MAST::ElementBase & get_physics_elem()
MAST::AssemblyBase * _assembly
assembles the point loas
void update_incompatible_solution(libMesh::NumericVector< Real > &X, libMesh::NumericVector< Real > &dX)
virtual void init(MAST::AssemblyBase &assembly)
virtual void set_solution(const RealVectorX &vec, bool if_sens=false)
stores vec as solution for element level calculations, or its sensitivity if if_sens is true...
Matrix< Real, Dynamic, 1 > RealVectorX
virtual void init(const MAST::GeomElem &elem)=0
initializes the object for calculation of element quantities for the specified elem.
virtual unsigned int incompatible_mode_size() const
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...
MAST::AssemblyBase::SolverMonitor * get_solver_monitor()
This class acts as a wrapper around libMesh::Elem for the purpose of providing a uniform interface fo...
Definition: geom_elem.h:59
MAST::SystemInitialization & system_init()
MAST::AssemblyElemOperations & get_elem_ops()
virtual void init(const libMesh::Elem &elem, const MAST::SystemInitialization &sys_init)
initialize the object for the specified reference elem.
Definition: geom_elem.cpp:128
void set_incompatible_mode_solution(RealVectorX &vec)
sets the pointer to the incompatible mode solution vector.
PetscErrorCode _snes_structural_nonlinear_assembly_monitor_function(SNES snes, PetscInt its, PetscReal norm2, void *ctx)
const MAST::NonlinearSystem & system() const