libMesh
boundary_volume_solution_transfer.C
Go to the documentation of this file.
1 // The libMesh Finite Element Library.
2 // Copyright (C) 2002-2017 Benjamin S. Kirk, John W. Peterson, Roy H. Stogner
3 
4 // This library is free software; you can redistribute it and/or
5 // modify it under the terms of the GNU Lesser General Public
6 // License as published by the Free Software Foundation; either
7 // version 2.1 of the License, or (at your option) any later version.
8 
9 // This library is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 // Lesser General Public License for more details.
13 
14 // You should have received a copy of the GNU Lesser General Public
15 // License along with this library; if not, write to the Free Software
16 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 
18 #include "libmesh/boundary_volume_solution_transfer.h"
19 #include "libmesh/elem.h"
20 #include "libmesh/numeric_vector.h"
21 #include "libmesh/dof_map.h"
22 
23 namespace libMesh {
24 
26  const Variable & to_var)
27 {
28  // Determine which direction the transfer is in
29  System * from_sys = from_var.system();
30  System * to_sys = to_var.system();
31 
32  unsigned int
33  from_dimension = from_sys->get_mesh().mesh_dimension(),
34  to_dimension = to_sys->get_mesh().mesh_dimension();
35 
36  // Sanity check
37  if (from_dimension == to_dimension)
38  libmesh_error_msg("Error: Transfer must be from volume mesh to its boundary or vice-versa!");
39 
40  if (from_dimension > to_dimension)
41  this->transfer_volume_boundary(from_var, to_var);
42  else
43  this->transfer_boundary_volume(from_var, to_var);
44 }
45 
46 
47 
49 transfer_volume_boundary(const Variable & from_var, const Variable & to_var)
50 {
51  // Get references to the Systems from the Variables
52  System * from_sys = from_var.system(); // volume system
53  System * to_sys = to_var.system(); // boundary system
54 
55  // Get reference to the BoundaryMesh. Note: we always loop over the
56  // BoundaryMesh since, by definition, it has fewer dofs than the
57  // volume mesh.
58  const MeshBase & to_mesh = to_sys->get_mesh();
59 
60  // Get system number and variable numbers
61  const unsigned short int from_sys_number = from_sys->number();
62  const unsigned short int from_var_number = from_var.number();
63 
64  const unsigned short int to_sys_number = to_sys->number();
65  const unsigned short int to_var_number = to_var.number();
66 
67  // Get a constant reference to variables, get their number of components
68  const unsigned short int from_n_comp = from_var.n_components();
69  const unsigned short int to_n_comp = to_var.n_components();
70 
71  // Sanity check that the variables have the same number of components
72  libmesh_assert_equal_to(from_n_comp, to_n_comp);
73 
74  // Construct map from "from" dofs to "to" dofs.
75  typedef std::map<numeric_index_type, numeric_index_type> DofMapping;
76  DofMapping dof_mapping;
77 
78  // Loop through all boundary elements.
79  for (const auto & to_elem : to_mesh.active_local_element_ptr_range())
80  {
81  const Elem * from_elem = to_elem->interior_parent();
82 
83  if (!from_elem)
84  libmesh_error_msg("Error, transfer must be between a Mesh and its associated BoundaryMesh.");
85 
86  // loop through all nodes in each boundary element.
87  for (unsigned int node=0; node < to_elem->n_nodes(); node++)
88  {
89  // Node in boundary element.
90  const Node * to_node = to_elem->node_ptr(node);
91 
92  for (unsigned int node_id=0; node_id < from_elem->n_nodes(); node_id++)
93  {
94  // Nodes in interior_parent element.
95  const Node * from_node = from_elem->node_ptr(node_id);
96 
97  const dof_id_type from_dof = from_node->dof_number(from_sys_number,
98  from_var_number,
99  from_n_comp - 1);
100 
101  // See if we've already encountered this DOF in the loop
102  // over boundary elements.
103  DofMapping::iterator it = dof_mapping.find(from_dof);
104 
105  // If we've already mapped this dof, we don't need to map
106  // it again or do floating point comparisons.
107  if (it == dof_mapping.end() &&
108  from_node->absolute_fuzzy_equals(*to_node, TOLERANCE))
109  {
110  // Global dof_index for node in BoundaryMesh.
111  const dof_id_type to_dof = to_node->dof_number(to_sys_number,
112  to_var_number,
113  to_n_comp - 1);
114 
115  // Keep track of the volume system dof index which is needed.
116  dof_mapping[from_dof] = to_dof;
117  }
118  }
119  }
120  }
121 
122  // Construct a vector of the indices needed from the Volume system's
123  // global solution vector on this processor.
124  std::vector<numeric_index_type> needed_indices;
125  needed_indices.reserve(dof_mapping.size());
126  {
127  DofMapping::iterator
128  it = dof_mapping.begin(),
129  end = dof_mapping.end();
130 
131  for (; it!=end; ++it)
132  needed_indices.push_back(it->first);
133  }
134 
135  // Communicate just the required values without making a copy of the
136  // global solution vector.
137  std::vector<Number> needed_values;
138  from_sys->solution->localize(needed_values, needed_indices);
139 
140  // Loop over DofMapping again, assigning values in the
141  // Boundary System solution vector.
142  {
143  DofMapping::iterator
144  it = dof_mapping.begin(),
145  end = dof_mapping.end();
146 
147  for (unsigned idx=0; it!=end; ++it, ++idx)
148  to_sys->solution->set(it->second, needed_values[idx]);
149  }
150 }
151 
152 
154 transfer_boundary_volume(const Variable & from_var, const Variable & to_var)
155 {
156  // Get references to the Systems from the Variables
157  System * from_sys = from_var.system(); // boundary system
158  System * to_sys = to_var.system(); // volume system
159 
160  // Get reference to BoundaryMesh.
161  const MeshBase & from_mesh = from_sys->get_mesh();
162 
163  // DofMap for BoundaryMesh
164  const DofMap & dof_map = from_sys->get_dof_map();
165 
166  // Get system number and variable numbers
167  const unsigned short int to_sys_number = to_sys->number();
168  const unsigned short int to_var_number = to_var.number();
169  const unsigned short int from_var_number = from_var.number();
170  const unsigned short int to_n_comp = to_var.n_components();
171 
172  // In order to get solution vectors from BoundaryMesh
173  std::vector<dof_id_type> from_dof_indices;
174  std::vector<Number> value;
175 
176  // Loop through all boundary elements.
177  for (const auto & from_elem : from_mesh.active_local_element_ptr_range())
178  {
179  const Elem * to_elem = from_elem->interior_parent();
180 
181  if (!to_elem)
182  libmesh_error_msg("Error, transfer must be between a Mesh and its associated BoundaryMesh.");
183 
184  // Get dof indices for phi2 for all nodes on this boundary element
185  dof_map.dof_indices(from_elem, from_dof_indices, from_var_number);
186 
187  // Get values from BoundaryMesh for this element
188  from_sys->current_local_solution->get(from_dof_indices, value);
189 
190  // loop through all nodes in each boundary element.
191  for (unsigned int node=0; node < from_elem->n_nodes(); node++)
192  {
193  // Node in boundary element.
194  const Node * from_node = from_elem->node_ptr(node);
195 
196  for (unsigned int node_id=0; node_id < to_elem->n_nodes(); node_id++)
197  {
198  // Nodes in interior_parent element.
199  const Node * to_node = to_elem->node_ptr(node_id);
200 
201  // Match BoundaryNode & VolumeNode.
202  if (to_node->absolute_fuzzy_equals(*from_node, TOLERANCE))
203  {
204  // Global dof_index for node in VolumeMesh.
205  const dof_id_type to_dof = to_node->dof_number(to_sys_number,
206  to_var_number,
207  to_n_comp - 1);
208 
209  // Assign values to boundary in VolumeMesh.
210  to_sys->solution->set(to_dof, value[node]);
211  }
212  }
213  }
214  }
215 }
216 
217 } // namespace libMesh
void transfer_boundary_volume(const Variable &from_var, const Variable &to_var)
Transfer values from boundary mesh to volume mesh.
A Node is like a Point, but with more information.
Definition: node.h:52
virtual void transfer(const Variable &from_var, const Variable &to_var) libmesh_override
Transfer values from a Variable in a System associated with a volume mesh to a Variable in a System a...
const Elem * interior_parent() const
Definition: elem.C:951
This is the base class from which all geometric element types are derived.
Definition: elem.h:89
UniquePtr< NumericVector< Number > > current_local_solution
All the values I need to compute my contribution to the simulation at hand.
Definition: system.h:1535
dof_id_type dof_number(const unsigned int s, const unsigned int var, const unsigned int comp) const
Definition: dof_object.h:810
static const Real TOLERANCE
IterBase * end
Also have a polymorphic pointer to the end object, this prevents iterating past the end...
The libMesh namespace provides an interface to certain functionality in the library.
This is the MeshBase class.
Definition: mesh_base.h:68
unsigned int number() const
Definition: variable.h:106
virtual unsigned int n_nodes() const =0
virtual SimpleRange< element_iterator > active_local_element_ptr_range()=0
This class handles the numbering of degrees of freedom on a mesh.
Definition: dof_map.h:167
const MeshBase & get_mesh() const
Definition: system.h:2014
This class defines the notion of a variable in the system.
Definition: variable.h:49
const DofMap & get_dof_map() const
Definition: system.h:2030
const Node * node_ptr(const unsigned int i) const
Definition: elem.h:1874
This is the base class for classes which contain information related to any physical process that mig...
Definition: system.h:76
UniquePtr< NumericVector< Number > > solution
Data structure to hold solution values.
Definition: system.h:1523
bool absolute_fuzzy_equals(const TypeVector< T > &rhs, Real tol=TOLERANCE) const
Definition: type_vector.h:962
unsigned int number() const
Definition: system.h:2006
unsigned int n_components() const
Definition: variable.h:125
System * system() const
Definition: variable.h:92
unsigned int mesh_dimension() const
Definition: mesh_base.C:148
static const bool value
Definition: xdr_io.C:108
void transfer_volume_boundary(const Variable &from_var, const Variable &to_var)
Transfer values from volume mesh to boundary mesh.
unsigned int idx(const ElemType type, const unsigned int nx, const unsigned int i, const unsigned int j)
A useful inline function which replaces the macros used previously.
uint8_t dof_id_type
Definition: id_types.h:64
void dof_indices(const Elem *const elem, std::vector< dof_id_type > &di) const
Fills the vector di with the global degree of freedom indices for the element.
Definition: dof_map.C:1917