MAST
Multidisciplinary-design Adaptation and Sensitivity Toolkit (MAST)
physics_discipline_base.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 // MAST includes
23 #include "base/parameter.h"
24 #include "base/nonlinear_system.h"
26 #include "mesh/geom_elem.h"
27 
28 // libMesh includes
29 #include "libmesh/dof_map.h"
30 #include "libmesh/dirichlet_boundaries.h"
31 #include "libmesh/fe_interface.h"
32 #include "libmesh/dirichlet_boundaries.h"
33 #include "libmesh/elem.h"
34 #include "libmesh/boundary_info.h"
35 
36 
37 void
39  _side_bc_map.clear();
40  _vol_bc_map.clear();
41 }
42 
43 
44 
45 void
46 MAST::PhysicsDisciplineBase::add_side_load(libMesh::boundary_id_type bid,
48  // make sure that this boundary and load haven't already been applied
49  std::pair<MAST::SideBCMapType::const_iterator, MAST::SideBCMapType::const_iterator> it =
50  _side_bc_map.equal_range(bid);
51 
52  for ( ; it.first != it.second; it.first++)
53  libmesh_assert(it.first->second != &load);
54 
55  // displacement boundary condition needs to be hadled separately
56  _side_bc_map.insert(MAST::SideBCMapType::value_type(bid, &load));
57 }
58 
59 
60 
61 void
62 MAST::PhysicsDisciplineBase::remove_side_load(libMesh::boundary_id_type bid,
64  // make sure that this boundary and load have been applied
65  std::pair<MAST::SideBCMapType::const_iterator, MAST::SideBCMapType::const_iterator> it =
66  _side_bc_map.equal_range(bid);
67 
68  for ( ; it.first != it.second; it.first++)
69  if (it.first->second == &load) {
70 
71  _side_bc_map.erase(it.first);
72  break;
73  }
74 }
75 
76 
77 
78 
79 
80 void
81 MAST::PhysicsDisciplineBase::add_dirichlet_bc(libMesh::boundary_id_type bid,
83 
84  bool insert_success =
85  _dirichlet_bc_map.insert(MAST::DirichletBCMapType::value_type(bid, &load)).second;
86 
87  libmesh_assert(insert_success);
88 }
89 
90 
91 
92 void
94 constrain_subdomain_dofs_for_var(const libMesh::subdomain_id_type sid,
95  const unsigned int var) {
96 
97  std::map<libMesh::subdomain_id_type, std::vector<unsigned int> >::iterator
98  it = _subdomain_var_constraint.find(sid);
99 
100  if (it == _subdomain_var_constraint.end()) {
101  it = _subdomain_var_constraint.insert
102  (std::pair<libMesh::subdomain_id_type, std::vector<unsigned int> >
103  (sid, std::vector<unsigned int>())).first;
104  }
105 
106  it->second.push_back(var);
107 }
108 
109 
110 
111 void
112 MAST::PhysicsDisciplineBase::add_volume_load(libMesh::subdomain_id_type sid,
114  std::pair<MAST::VolumeBCMapType::iterator, MAST::VolumeBCMapType::iterator> it =
115  _vol_bc_map.equal_range(sid);
116 
117  for ( ; it.first != it.second; it.first++)
118  libmesh_assert(it.first->second != &load);
119 
120  _vol_bc_map.insert(MAST::VolumeBCMapType::value_type(sid, &load));
121 }
122 
123 
124 void
125 MAST::PhysicsDisciplineBase::remove_volume_load(libMesh::subdomain_id_type sid,
127  std::pair<MAST::VolumeBCMapType::iterator, MAST::VolumeBCMapType::iterator> it =
128  _vol_bc_map.equal_range(sid);
129 
130  for ( ; it.first != it.second; it.first++) {
131  if (it.first->second == &load) {
132 
133  _vol_bc_map.erase(it.first);
134  break;
135  }
136  }
137 }
138 
139 
140 
141 
142 void
144 
145  libmesh_assert(!_point_loads.count(&load));
146 
147  _point_loads.insert(&load);
148 }
149 
150 
151 
152 void
153 MAST::PhysicsDisciplineBase::clear_volume_load(libMesh::subdomain_id_type bid,
155  std::pair<MAST::VolumeBCMapType::iterator, MAST::VolumeBCMapType::iterator> it =
156  _vol_bc_map.equal_range(bid);
157 
158  for ( ; it.first != it.second; it.first++)
159  if (it.first->second == &load) {
160  _vol_bc_map.erase(it.first);
161  return;
162  }
163 
164  // should not get here
165  libmesh_assert(false);
166 }
167 
168 
169 
170 void
172 set_property_for_subdomain(const libMesh::subdomain_id_type sid,
173  const MAST::ElementPropertyCardBase& prop) {
174 
175  MAST::PropertyCardMapType::const_iterator elem_p_it = _element_property.find(sid);
176  libmesh_assert(elem_p_it == _element_property.end());
177 
178  _element_property[sid] = &prop;
179 }
180 
181 
182 
184 MAST::PhysicsDisciplineBase::get_property_card(const unsigned int sid) const {
185 
186  MAST::PropertyCardMapType::const_iterator
187  elem_p_it = _element_property.find(sid);
188  libmesh_assert(elem_p_it != _element_property.end());
189 
190  return *elem_p_it->second;
191 }
192 
193 
194 
196 MAST::PhysicsDisciplineBase::get_property_card(const libMesh::Elem& elem) const {
197 
198  MAST::PropertyCardMapType::const_iterator
199  elem_p_it = _element_property.find(elem.subdomain_id());
200  libmesh_assert(elem_p_it != _element_property.end());
201 
202  return *elem_p_it->second;
203 }
204 
205 
208 
209  MAST::PropertyCardMapType::const_iterator
210  elem_p_it = _element_property.find(elem.get_reference_elem().subdomain_id());
211  libmesh_assert(elem_p_it != _element_property.end());
212 
213  return *elem_p_it->second;
214 }
215 
216 
217 
218 void
221 
222 
223  // iterate over all the dirichlet boundary conditions and add them
224  // to the system
225  MAST::DirichletBCMapType::const_iterator it = _dirichlet_bc_map.begin();
226 
227  for ( ; it != _dirichlet_bc_map.end(); it++)
228  sys.get_dof_map().add_dirichlet_boundary(it->second->dirichlet_boundary());
229 }
230 
231 
232 
233 
234 void
237 
238  // iterate over all the dirichlet boundary conditions and add them
239  // to the system
240  MAST::DirichletBCMapType::const_iterator it = _dirichlet_bc_map.begin();
241 
242  for ( ; it != _dirichlet_bc_map.end(); it++)
243  sys.get_dof_map().remove_dirichlet_boundary(it->second->dirichlet_boundary());
244 
245 }
246 
247 
248 
249 void
251 get_system_dirichlet_bc_dofs(libMesh::System& sys,
252  std::set<unsigned int>& dof_ids) const {
253 
254  dof_ids.clear();
255 
256  // first prepare a map of boundary ids and the constrained vars on that
257  // boundary
258  std::map<libMesh::boundary_id_type, std::vector<unsigned int> >
259  constrained_vars_map;
260 
261  // iterate over all the dirichlet boundary conditions and add them
262  // to the system
263  MAST::DirichletBCMapType::const_iterator it = _dirichlet_bc_map.begin();
264 
265  for ( ; it != _dirichlet_bc_map.end(); it++) {
266 
267  libMesh::DirichletBoundary& dirichlet_b = it->second->dirichlet_boundary();
268  sys.get_dof_map().add_dirichlet_boundary(dirichlet_b);
269  constrained_vars_map[it->first] = dirichlet_b.variables;
270  }
271 
272 
273  //
274  // now collect the ids that correspond to the specified boundary conditions
275  //
276  // Get a constant reference to the mesh object
277  const libMesh::MeshBase& mesh = sys.get_mesh();
278 
279  // The dimension that we are running.
280  const unsigned int dim = mesh.mesh_dimension();
281 
282  // Get a constant reference to the Finite Element type
283  // for the first variable in the system.
284  libMesh::FEType fe_type = sys.get_dof_map().variable_type(0);
285 
286  const libMesh::DofMap& dof_map = sys.get_dof_map();
287 
288  libMesh::MeshBase::const_element_iterator
289  el = mesh.active_local_elements_begin(),
290  end_el = mesh.active_local_elements_end();
291 
292  for ( ; el != end_el; ++el) {
293  const libMesh::Elem* elem = *el;
294 
295  // check if the any subdomain variables have been constrained
296  std::map<libMesh::subdomain_id_type, std::vector<unsigned int> >::const_iterator
297  it = _subdomain_var_constraint.find(elem->subdomain_id());
298 
299  if (it != _subdomain_var_constraint.end()) {
300  // constrain all element dofs on this element that belong to this
301  // variable
302  for (unsigned int i=0; i<it->second.size(); i++) {
303 
304  std::vector<libMesh::dof_id_type> dof_indices;
305  dof_map.dof_indices (*el, dof_indices, it->second[i]);
306 
307  for(unsigned int ii=0; ii<dof_indices.size(); ii++)
308  dof_ids.insert(dof_indices[ii]);
309  }
310  }
311 
312 
313  // boundary condition is applied only on sides with no neighbors
314  // and if the side's boundary id has a boundary condition tag on it
315  for (unsigned int s=0; s<elem->n_sides(); s++)
316  if ((*el)->neighbor_ptr(s) == nullptr &&
317  mesh.boundary_info->n_boundary_ids(elem, s)) {
318 
319  std::vector<libMesh::boundary_id_type> bc_ids;
320  mesh.boundary_info->boundary_ids(elem, s, bc_ids);
321 
322  for (unsigned int i_bid=0; i_bid<bc_ids.size(); i_bid++)
323  if (constrained_vars_map.count(bc_ids[i_bid])) {
324 
325  const std::vector<unsigned int>&
326  vars = constrained_vars_map[bc_ids[i_bid]];
327 
328  // now iterate over each constrained variable for this boundary
329  // and collect its dofs
330  for (unsigned int i_var=0; i_var<vars.size(); i_var++) {
331 
332  std::vector<libMesh::dof_id_type> dof_indices;
333  dof_map.dof_indices (*el, dof_indices, vars[i_var]);
334 
335  // all boundary dofs are Dirichlet dofs in this case
336  std::vector<unsigned int> side_dofs;
337  libMesh::FEInterface::dofs_on_side(*el,
338  dim,
339  fe_type,
340  s,
341  side_dofs);
342 
343  for(unsigned int ii=0; ii<side_dofs.size(); ii++)
344  dof_ids.insert(dof_indices[side_dofs[ii]]);
345  }
346  } // end of boundary loop
347  } // end of side loop
348  }// end of element loop
349 
350  // also, it is likely that some of the bcs have been applied via the
351  // DofMap API by specification of row constraints. In that case,
352  // factor out the dofs that are not coupled to any other dofs
353  libMesh::DofConstraints::const_iterator
354  constraint_it = dof_map.constraint_rows_begin(),
355  constraint_end = dof_map.constraint_rows_end();
356 
357  for ( ; constraint_it != constraint_end; constraint_it++) {
358  // if the dof constraint has only one entry, then add it to the
359  // constrained set
360  if (!constraint_it->second.size())
361  dof_ids.insert(constraint_it->first);
362  }
363 }
364 
365 
void add_volume_load(libMesh::subdomain_id_type bid, MAST::BoundaryConditionBase &load)
adds the specified volume loads for the elements with subdomain tag s_id
void clear_volume_load(libMesh::subdomain_id_type sid, MAST::BoundaryConditionBase &load)
clear the specified volume load from the applied loads
const MAST::ElementPropertyCardBase & get_property_card(const libMesh::Elem &elem) const
get property card for the specified element
virtual const libMesh::Elem & get_reference_elem() const
Definition: geom_elem.cpp:54
This class implements a system for solution of nonlinear systems.
MAST::VolumeBCMapType _vol_bc_map
volume boundary condition map of boundary id and load
void init_system_dirichlet_bc(MAST::NonlinearSystem &sys) const
initializes the system for dirichlet boundary conditions
void remove_volume_load(libMesh::subdomain_id_type bid, MAST::BoundaryConditionBase &load)
remove the specified volume loads for the elements with subdomain tag s_id
void add_dirichlet_bc(libMesh::boundary_id_type bid, MAST::DirichletBoundaryCondition &load)
adds the specified Dirichlet boundary condition for the boundary with tag b_id
void add_side_load(libMesh::boundary_id_type bid, MAST::BoundaryConditionBase &load)
adds the specified side loads for the boudnary with tag b_id
void clear_loads()
clear the loads and pointer to static solution system for this structural model
void remove_side_load(libMesh::boundary_id_type bid, MAST::BoundaryConditionBase &load)
remove the specified side loads for the boudnary with tag b_id
std::map< libMesh::subdomain_id_type, std::vector< unsigned int > > _subdomain_var_constraint
variables constrained on subdomain
This class allows for the specification of load associated with specified nodes in a user-provided se...
void get_system_dirichlet_bc_dofs(libMesh::System &sys, std::set< unsigned int > &dof_ids) const
Prepares a list of the constrained dofs for system sys and returns in dof_ids.
void clear_system_dirichlet_bc(MAST::NonlinearSystem &sys) const
clears the system dirichlet boundary conditions
void constrain_subdomain_dofs_for_var(const libMesh::subdomain_id_type sid, const unsigned int var)
constrain dofs on a subdomain to zero
This class acts as a wrapper around libMesh::Elem for the purpose of providing a uniform interface fo...
Definition: geom_elem.h:59
void add_point_load(MAST::PointLoadCondition &load)
adds the specified point load
MAST::DirichletBCMapType _dirichlet_bc_map
Dirichlet boundary condition map of boundary id and load.
void set_property_for_subdomain(const libMesh::subdomain_id_type sid, const MAST::ElementPropertyCardBase &prop)
sets the same property for all elements in the specified subdomain
MAST::PointLoadSetType _point_loads
point loads
MAST::PropertyCardMapType _element_property
map of element property cards for each element
MAST::SideBCMapType _side_bc_map
side boundary condition map of boundary id and load