MAST
level_set_constrain_dofs.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 // MAST includes
24 #include "base/nonlinear_system.h"
26 
27 
28 // libMesh includes
29 #include "libmesh/dof_map.h"
30 
31 
32 
35  MAST::FieldFunction<Real>& level_set):
36 _constrain_all_negative_indices (false),
37 _sys (sys),
38 _level_set (level_set),
39 _intersection (nullptr) {
40 
42 }
43 
44 
45 
47 
48  delete _intersection;
49 }
50 
51 
54 
55  return *_intersection;
56 }
57 
58 
59 
60 void
62 
63  MAST::NonlinearSystem& nonlin_sys = _sys.system();
64 
65  libMesh::DofMap& dof_map = nonlin_sys.get_dof_map();
66 
67  libMesh::MeshBase::const_element_iterator el =
68  nonlin_sys.get_mesh().active_local_elements_begin();
69  const libMesh::MeshBase::const_element_iterator end_el =
70  nonlin_sys.get_mesh().active_local_elements_end();
71 
72 
73  std::vector<libMesh::dof_id_type>
74  dof_indices;
75  std::set<libMesh::dof_id_type>
76  all_dof_indices,
77  negative_dof_indices,
78  connected_dof_indices;
79 
80  for ( ; el != end_el; ++el) {
81 
82  const libMesh::Elem* elem = *el;
83 
84  _intersection->init(_level_set, *elem, nonlin_sys.time,
85  nonlin_sys.get_mesh().max_elem_id(),
86  nonlin_sys.get_mesh().max_node_id());
87 
88  dof_indices.clear();
89  dof_map.dof_indices(elem, dof_indices);
90 
91  // our intent is to constrain only those dofs that belong to the
92  // unintersected elements on the negative phi side of level set, AND
93  // if they do not belong to any elements intersected by the level set.
94  for (unsigned int i=0; i<dof_indices.size(); i++)
95  all_dof_indices.insert(dof_indices[i]);
96 
98  // This identifies if the element is has some positive phi
99  // region. If it does, then it will provide a contribution to
100  // the dofs connected to it.
101 
102  for (unsigned int i=0; i<dof_indices.size(); i++)
103  connected_dof_indices.insert(dof_indices[i]);
104  }
105 
107 
108  // if the element has a node on negative side of the level set,
109  // we will constrain all dofs of the node to be zero
110 
112  for (unsigned int i=0; i<elem->n_nodes(); i++) {
113 
114  const libMesh::Node* nd = elem->node_ptr(i);
115  if (_intersection->get_node_phi_value(nd) <= 0.) {
116 
117  dof_indices.clear();
118  dof_map.dof_indices(nd, dof_indices);
119  for (unsigned int i=0; i<dof_indices.size(); i++)
120  negative_dof_indices.insert(dof_indices[i]);
121  }
122  }
123  }
124  }
125 
126  _intersection->clear();
127  }
128 
129  // create a set so that we only deal with unique set of ids.
130  dof_indices.clear();
131  dof_indices.reserve(all_dof_indices.size() - connected_dof_indices.size());
132 
133  std::set_difference(all_dof_indices.begin(),
134  all_dof_indices.end(),
135  connected_dof_indices.begin(),
136  connected_dof_indices.end(),
137  std::inserter(dof_indices, dof_indices.begin()));
138 
139  all_dof_indices.clear();
140  connected_dof_indices.clear();
141 
142  // now, constrain everythign in the set
143  std::vector<libMesh::dof_id_type>::const_iterator
144  dof_it = dof_indices.begin(),
145  dof_end = dof_indices.end();
146 
147  for ( ; dof_it != dof_end; dof_it++) {
148 
149  // if the dof is already Dirichlet constrained, then we do not
150  // add another constraint on it
151  if (!dof_map.is_constrained_dof(*dof_it)) {
152 
153  libMesh::DofConstraintRow c_row;
154  dof_map.add_constraint_row(*dof_it, c_row, true);
155  }
156  }
157 
158 
160 
161  // now, constrain everythign in the set
162  std::set<libMesh::dof_id_type>::const_iterator
163  dof_it = negative_dof_indices.begin(),
164  dof_end = negative_dof_indices.end();
165 
166  for ( ; dof_it != dof_end; dof_it++) {
167 
168  // if the dof is already Dirichlet constrained, then we do not
169  // add another constraint on it
170  if (!dof_map.is_constrained_dof(*dof_it)) {
171 
172  libMesh::DofConstraintRow c_row;
173  dof_map.add_constraint_row(*dof_it, c_row, true);
174  }
175  }
176  }
177 }
178 
179 
180 
MAST::SystemInitialization & _sys
MAST::FieldFunction< Real > & _level_set
MAST::NonlinearSystem & system()
This class implements a system for solution of nonlinear systems.
LevelSetConstrainDofs(MAST::SystemInitialization &sys, MAST::FieldFunction< Real > &level_set)
void init(const MAST::FieldFunction< Real > &phi, const libMesh::Elem &e, const Real t, unsigned int max_elem_id, unsigned int max_node_id)
Real get_node_phi_value(const libMesh::Node *n) const
MAST::LevelSetIntersection * _intersection
virtual void constrain()
provides implementation of the libMesh::System::Constraint::constrain() virtual method ...
MAST::LevelSetIntersection & get_intersection()
void clear()
clears the data structures