libMesh
Loading...
Searching...
No Matches
boundary_volume_solution_transfer.C
Go to the documentation of this file.
1// The libMesh Finite Element Library.
2// Copyright (C) 2002-2026 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
23namespace 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 libmesh_error_msg_if(from_dimension == to_dimension,
38 "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
49transfer_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 int from_sys_number = from_sys->number();
62 const unsigned int from_var_number = from_var.number();
63
64 const unsigned int to_sys_number = to_sys->number();
65 const unsigned int to_var_number = to_var.number();
66
67 // Get a constant reference to variables, get their number of components
68 const unsigned int from_n_comp = from_var.n_components(from_sys->get_mesh());
69 const unsigned int to_n_comp = to_var.n_components(to_mesh);
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 libmesh_error_msg_if(!from_elem, "Error, transfer must be between a Mesh and its associated BoundaryMesh.");
84
85 // loop through all nodes in each boundary element.
86 for (const Node & to_node : to_elem->node_ref_range())
87 {
88 // Nodes in interior_parent element.
89 for (const Node & from_node : from_elem->node_ref_range())
90 {
91 const dof_id_type from_dof = from_node.dof_number(from_sys_number,
92 from_var_number,
93 from_n_comp - 1);
94
95 // If we've already mapped this dof, we don't need to map
96 // it again or do floating point comparisons.
97 if (!dof_mapping.count(from_dof) &&
98 from_node.absolute_fuzzy_equals(to_node, TOLERANCE))
99 {
100 // Global dof_index for node in BoundaryMesh.
101 const dof_id_type to_dof = to_node.dof_number(to_sys_number,
102 to_var_number,
103 to_n_comp - 1);
104
105 // Keep track of the volume system dof index which is needed.
106 dof_mapping[from_dof] = to_dof;
107 }
108 }
109 }
110 }
111
112 // Construct a vector of the indices needed from the Volume system's
113 // global solution vector on this processor.
114 std::vector<numeric_index_type> needed_indices;
115 needed_indices.reserve(dof_mapping.size());
116 {
117 DofMapping::iterator
118 it = dof_mapping.begin(),
119 end = dof_mapping.end();
120
121 for (; it!=end; ++it)
122 needed_indices.push_back(it->first);
123 }
124
125 // Communicate just the required values without making a copy of the
126 // global solution vector.
127 std::vector<Number> needed_values;
128 from_sys->solution->localize(needed_values, needed_indices);
129
130 // Loop over DofMapping again, assigning values in the
131 // Boundary System solution vector.
132 {
133 DofMapping::iterator
134 it = dof_mapping.begin(),
135 end = dof_mapping.end();
136
137 for (unsigned idx=0; it!=end; ++it, ++idx)
138 to_sys->solution->set(it->second, needed_values[idx]);
139 }
140}
141
142
144transfer_boundary_volume(const Variable & from_var, const Variable & to_var)
145{
146 // Get references to the Systems from the Variables
147 System * from_sys = from_var.system(); // boundary system
148 System * to_sys = to_var.system(); // volume system
149
150 // Get reference to BoundaryMesh.
151 const MeshBase & from_mesh = from_sys->get_mesh();
152
153 // DofMap for BoundaryMesh
154 const DofMap & dof_map = from_sys->get_dof_map();
155
156 // Get system number and variable numbers
157 const unsigned int to_sys_number = to_sys->number();
158 const unsigned int to_var_number = to_var.number();
159 const unsigned int from_var_number = from_var.number();
160 const unsigned int to_n_comp = to_var.n_components(to_sys->get_mesh());
161
162 // In order to get solution vectors from BoundaryMesh
163 std::vector<dof_id_type> from_dof_indices;
164 std::vector<Number> value;
165
166 // Loop through all boundary elements.
167 for (const auto & from_elem : from_mesh.active_local_element_ptr_range())
168 {
169 const Elem * to_elem = from_elem->interior_parent();
170
171 libmesh_error_msg_if(!to_elem, "Error, transfer must be between a Mesh and its associated BoundaryMesh.");
172
173 // Get dof indices for phi2 for all nodes on this boundary element
174 dof_map.dof_indices(from_elem, from_dof_indices, from_var_number);
175
176 // Get values from BoundaryMesh for this element
177 from_sys->current_local_solution->get(from_dof_indices, value);
178
179 // loop through all nodes in each boundary element.
180 for (auto node : from_elem->node_index_range())
181 {
182 // Node in boundary element.
183 const Node * from_node = from_elem->node_ptr(node);
184
185 // Nodes in interior_parent element.
186 for (const Node & to_node : to_elem->node_ref_range())
187 {
188 // Match BoundaryNode & VolumeNode.
189 if (to_node.absolute_fuzzy_equals(*from_node, TOLERANCE))
190 {
191 // Global dof_index for node in VolumeMesh.
192 const dof_id_type to_dof = to_node.dof_number(to_sys_number,
193 to_var_number,
194 to_n_comp - 1);
195
196 // Assign values to boundary in VolumeMesh.
197 to_sys->solution->set(to_dof, value[node]);
198 }
199 }
200 }
201 }
202}
203
204} // namespace libMesh
virtual void transfer(const Variable &from_var, const Variable &to_var) override
Transfer values from a Variable in a System associated with a volume mesh to a Variable in a System a...
void transfer_boundary_volume(const Variable &from_var, const Variable &to_var)
Transfer values from boundary mesh to volume mesh.
void transfer_volume_boundary(const Variable &from_var, const Variable &to_var)
Transfer values from volume mesh to boundary mesh.
This class handles the numbering of degrees of freedom on a mesh.
Definition dof_map.h:181
void dof_indices(const Elem *const elem, std::vector< dof_id_type > &di) const
Definition dof_map.C:2201
dof_id_type dof_number(const unsigned int s, const unsigned int var, const unsigned int comp) const
This is the base class from which all geometric element types are derived.
Definition elem.h:96
SimpleRange< NodeRefIter > node_ref_range()
Returns a range with all nodes of an element, usable in range-based for loops.
Definition elem.h:2682
const Elem * interior_parent() const
Definition elem.C:1160
This is the MeshBase class.
Definition mesh_base.h:81
unsigned int mesh_dimension() const
Definition mesh_base.C:430
A Node is like a Point, but with more information.
Definition node.h:55
Manages consistently variables, degrees of freedom, and coefficient vectors.
Definition system.h:100
std::unique_ptr< NumericVector< Number > > current_local_solution
All the values I need to compute my contribution to the simulation at hand.
Definition system.h:1667
std::unique_ptr< NumericVector< Number > > solution
Data structure to hold solution values.
Definition system.h:1655
const DofMap & get_dof_map() const
Definition system.h:2417
unsigned int number() const
Definition system.h:2393
const MeshBase & get_mesh() const
Definition system.h:2401
This class defines the notion of a variable in the system.
Definition variable.h:51
System * system() const
Definition variable.h:114
unsigned int n_components() const
Definition variable.C:23
unsigned int number() const
Definition variable.h:128
The libMesh namespace provides an interface to certain functionality in the library.
static constexpr Real TOLERANCE
uint8_t dof_id_type
Definition id_types.h:67
static const bool value
Definition xdr_io.C:55