52
50
class DofMapBuilder
55
// FIXME: Test which 'map' is most efficient
56
typedef std::map<dolfin::la_index, dolfin::la_index> map;
57
typedef std::map<dolfin::la_index, dolfin::la_index>::const_iterator
59
//typedef std::set<std::size_t> set;
60
//typedef std::set<std::size_t>::const_iterator set_iterator;
62
typedef boost::unordered_set<std::size_t> set;
63
typedef boost::unordered_set<std::size_t>::const_iterator set_iterator;
64
//typedef std::set<std::size_t> set;
65
//typedef std::set<std::size_t>::const_iterator set_iterator;
67
typedef std::vector<std::size_t>::const_iterator vector_it;
68
typedef boost::unordered_map<std::size_t, std::vector<unsigned int> >
71
typedef std::pair<std::size_t, std::size_t> facet_data;
72
typedef std::map<std::size_t, std::size_t> periodic_map;
73
typedef std::vector<facet_data> vector_of_pairs;
74
typedef periodic_map::iterator periodic_map_iterator;
75
typedef std::vector<std::pair<facet_data, facet_data> > facet_pair_type;
79
/// Build dofmap. The restriction may be a null pointer, in which
80
/// case it is ignored.
55
/// Build dofmap. The constrained domain may be
56
/// a null pointer, in which case it is ignored.
81
57
static void build(DofMap& dofmap, const Mesh& dolfin_mesh,
82
std::shared_ptr<const std::map<unsigned int, std::map<unsigned int,
83
std::pair<unsigned int, unsigned int> > > > slave_master_entities,
84
std::shared_ptr<const Restriction> restriction);
58
std::shared_ptr<const SubDomain> constrained_domain);
87
static void build_sub_map(DofMap& sub_dofmap,
88
const DofMap& parent_dofmap,
89
const std::vector<std::size_t>& component,
60
/// Build sub-dofmap. This is a view into the parent dofmap.
61
static void build_sub_map_view(DofMap& sub_dofmap,
62
const DofMap& parent_dofmap,
63
const std::vector<std::size_t>& component,
94
// Build UFC-based dofmap
95
static void build_ufc_dofmap(DofMap& dofmap, map& restricted_dofs_inverse,
68
// Build modified global entity indices that account for periodic
70
static std::size_t build_constrained_vertex_indices(
97
std::shared_ptr<const std::map<unsigned int, std::map<unsigned int,
98
std::pair<unsigned int, unsigned int> > > > slave_master_entities,
99
std::shared_ptr<const Restriction> restriction);
101
// Build modified global entity indices that account for periodic bcs
102
static std::size_t build_constrained_vertex_indices(const Mesh& mesh,
103
const std::map<unsigned int, std::pair<unsigned int, unsigned int> >& slave_to_master_vertices,
104
std::vector<std::size_t>& modified_global_indices);
106
// Re-order local dofmap for dof spatial locality. Re-ordering is
107
// optional, but re-ordering can make other algorithms (e.g.,
108
// matrix-vector products) significantly faster.
109
static void reorder_local(DofMap& dofmap, const Mesh& mesh,
110
std::size_t block_size,
111
const std::set<std::size_t>& global_dofs);
113
// Re-order distributed dof map for process locality
72
const std::map<unsigned int, std::pair<unsigned int,
73
unsigned int>>& slave_to_master_vertices,
74
std::vector<std::size_t>& modified_vertex_indices_global);
76
// Build simple local UFC-based dofmap data structure (does not
77
// account for master/slave constraints)
115
reorder_distributed(DofMap& dofmap,
117
std::shared_ptr<const Restriction> restriction,
118
const map& restricted_dofs_inverse,
119
std::size_t block_size,
120
const std::set<std::size_t>& global_dofs);
79
build_local_ufc_dofmap(std::vector<std::vector<dolfin::la_index>>& dofmap,
80
const ufc::dofmap& ufc_dofmap,
122
83
// Compute which process 'owns' each node (point at which dofs live)
123
// node_ownership[0] -> all dofs owned by this process (will
124
// intersect dof_ownership[1])
125
// node_ownership[1] -> dofs shared with other processes and
126
// owned by this process
127
// node_ownership[2] -> dofs shared with other processes and
128
// owned by another process
130
compute_node_ownership(boost::array<set, 3>& node_ownership,
131
vec_map& shared_node_processes,
133
const std::set<std::size_t>& global_dofs,
135
std::shared_ptr<const Restriction> restriction,
136
const map& restricted_dofs_inverse,
137
std::size_t block_size);
84
// - node_ownership = -1 -> dof shared but not 'owned' by this
86
// - node_ownership = 0 -> dof owned by this process and shared
87
// with other processes
88
// - node_ownership = 1 -> dof owned by this process and not
91
// Also computes map from shared node to sharing processes and a
92
// set of process that share dofs on this process.
93
// Returns: number of locally owned nodes
94
static int compute_node_ownership(
95
std::vector<short int>& node_ownership,
96
std::unordered_map<int, std::vector<int>>& shared_node_to_processes,
97
std::set<int>& neighbours,
98
const std::vector<std::vector<la_index>>& node_dofmap,
99
const std::vector<int>& boundary_nodes,
100
const std::set<std::size_t>& global_nodes,
101
const std::vector<std::size_t>& node_local_to_global,
103
const std::size_t global_dim);
139
// Re-order distributed dofmap for process locality based on
105
// Build dofmap based on re-ordered nodes
142
parallel_renumber(const boost::array<set, 3>& node_ownership,
143
const vec_map& shared_node_processes,
145
const std::set<std::size_t>& global_dofs,
147
std::shared_ptr<const Restriction> restriction,
148
const map& restricted_dofs_inverse,
149
std::size_t block_size);
107
build_dofmap(std::vector<std::vector<la_index>>& dofmap,
108
const std::vector<std::vector<la_index>>& node_dofmap,
109
const std::vector<int>& old_to_new_node_local,
110
const std::size_t block_size);
151
112
// Compute set of global dofs (e.g. Reals associated with global
152
113
// Lagrange multipliers) based on UFC numbering. Global dofs are
153
// not associated with any mesh entity.
154
static std::set<std::size_t> compute_global_dofs(const DofMap& dofmap);
114
// not associated with any mesh entity. The returned indices are
115
// local to the process.
116
static std::set<std::size_t>
117
compute_global_dofs(std::shared_ptr<const ufc::dofmap> ufc_dofmap,
118
const std::vector<std::size_t>& num_mesh_entities_local);
156
120
// Iterate recursively over all sub-dof maps to find global
157
121
// degrees of freedom
158
static void compute_global_dofs(std::set<std::size_t>& global_dofs,
160
std::shared_ptr<const ufc::dofmap> ufc_dofmap,
161
const DofMap& dofmap);
123
compute_global_dofs(std::set<std::size_t>& global_dofs,
124
std::size_t& offset_local,
125
std::shared_ptr<const ufc::dofmap> ufc_dofmap,
126
const std::vector<std::size_t>& num_mesh_entities_local);
163
128
// Recursively extract UFC sub-dofmap and compute offset
164
static std::shared_ptr<ufc::dofmap>
165
extract_ufc_sub_dofmap(const ufc::dofmap& ufc_dofmap,
167
const std::vector<std::size_t>& component,
168
const std::vector<std::size_t>& num_global_mesh_entities);
129
static std::shared_ptr<ufc::dofmap> extract_ufc_sub_dofmap(
130
const ufc::dofmap& ufc_dofmap,
132
const std::vector<std::size_t>& component,
133
const std::vector<std::size_t>& num_global_mesh_entities);
170
135
// Compute block size, e.g. in 3D elasticity block_size = 3
171
136
static std::size_t compute_blocksize(const ufc::dofmap& ufc_dofmap);
138
static void compute_constrained_mesh_indices(
139
std::vector<std::vector<std::size_t>>& global_entity_indices,
140
std::vector<std::size_t>& num_mesh_entities_global,
141
const std::vector<bool>& needs_mesh_entities,
143
const SubDomain& constrained_domain);
145
static std::shared_ptr<const ufc::dofmap>
146
build_ufc_node_graph(
147
std::vector<std::vector<la_index>>& node_dofmap,
148
std::vector<std::size_t>& node_local_to_global,
149
std::vector<std::size_t>& num_mesh_entities_global,
150
std::shared_ptr<const ufc::dofmap> ufc_dofmap,
152
std::shared_ptr<const SubDomain> constrained_domain,
153
const std::size_t block_size);
155
static std::shared_ptr<const ufc::dofmap>
156
build_ufc_node_graph_constrained(
157
std::vector<std::vector<la_index>>& node_dofmap,
158
std::vector<std::size_t>& node_local_to_global,
159
std::vector<int>& node_ufc_local_to_local,
160
std::vector<std::size_t>& num_mesh_entities_global,
161
std::shared_ptr<const ufc::dofmap> ufc_dofmap,
163
std::shared_ptr<const SubDomain> constrained_domain,
164
const std::size_t block_size);
167
// Mark shared nodes. Boundary nodes are assigned a random
168
// positive integer, interior nodes are marked as -1, interior
169
// nodes in ghost layer of other processes are marked -2, and
170
// ghost nodes are marked as -3
171
static void compute_shared_nodes(
172
std::vector<int>& boundary_nodes,
173
const std::vector<std::vector<la_index>>& node_dofmap,
174
const std::size_t num_nodes_local,
175
const ufc::dofmap& ufc_dofmap,
178
static void compute_node_reordering(
179
std::vector<std::size_t>& local_to_global_unowned,
180
std::vector<int>& off_process_owner,
181
std::vector<int>& old_to_new_local,
182
const std::unordered_map<int, std::vector<int>>& node_to_sharing_processes,
183
const std::vector<std::size_t>& old_local_to_global,
184
const std::vector<std::vector<la_index>>& node_dofmap,
185
const std::vector<short int>& node_ownership,
186
const std::set<std::size_t>& global_nodes,
187
const MPI_Comm mpi_comm);
189
static void get_cell_data_local(ufc::cell& ufc_cell,
192
static void get_cell_data_global_constrained(
193
ufc::cell& ufc_cell, const Cell& cell,
194
const std::vector<std::vector<std::size_t>>& global_entity_indices);
196
// Compute number of mesh entities for dimensions required by
198
static std::vector<std::size_t>
199
compute_num_mesh_entities_local(const Mesh& mesh,
200
const ufc::dofmap& ufc_dofmap);