24
25
#include <multigrid/mg_dof_handler.h>
25
26
#include <multigrid/mg_dof_accessor.h>
27
#include <multigrid/mg_tools.h>
26
28
#include <multigrid/mg_transfer.h>
27
29
#include <multigrid/mg_transfer.templates.h>
29
31
DEAL_II_NAMESPACE_OPEN
33
template <typename number>
36
* Adjust vectors on all levels to
37
* correct size. Here, we just
38
* count the numbers of degrees
39
* of freedom on each level and
40
* @p reinit each level vector
42
* For compatibility reasons with
44
* the target_component is added
45
* here but is not used.
47
template <int dim, typename number, int spacedim>
49
reinit_vector (const dealii::MGDoFHandler<dim,spacedim> &mg_dof,
50
std::vector<unsigned int> ,
51
MGLevelObject<dealii::Vector<number> > &v)
53
for (unsigned int level=v.get_minlevel();
54
level<=v.get_maxlevel();++level)
56
unsigned int n = mg_dof.n_dofs (level);
64
* Adjust vectors on all levels to
65
* correct size. Here, we just
66
* count the numbers of degrees
67
* of freedom on each level and
68
* @p reinit each level vector
69
* to this length. The target_component
70
* is handed to MGTools::count_dofs_per_block.
71
* See for documentation there.
73
template <int dim, typename number, int spacedim>
75
reinit_vector (const dealii::MGDoFHandler<dim,spacedim> &mg_dof,
76
std::vector<unsigned int> target_component,
77
MGLevelObject<BlockVector<number> > &v)
79
const unsigned int n_blocks = mg_dof.get_fe().n_blocks();
80
if (target_component.size()==0)
82
target_component.resize(n_blocks);
83
for (unsigned int i=0;i<n_blocks;++i)
84
target_component[i] = i;
86
Assert(target_component.size()==n_blocks,
87
ExcDimensionMismatch(target_component.size(),n_blocks));
88
const unsigned int max_block
89
= *std::max_element (target_component.begin(),
90
target_component.end());
91
const unsigned int n_target_blocks = max_block + 1;
93
std::vector<std::vector<unsigned int> >
94
ndofs(mg_dof.get_tria().n_levels(),
95
std::vector<unsigned int>(n_target_blocks));
96
MGTools::count_dofs_per_block (mg_dof, ndofs, target_component);
98
for (unsigned int level=v.get_minlevel();
99
level<=v.get_maxlevel();++level)
101
v[level].reinit(n_target_blocks);
102
for (unsigned int b=0; b<n_target_blocks; ++b)
103
v[level].block(b).reinit(ndofs[level][b]);
104
v[level].collect_sizes();
111
template <class VECTOR>
112
template <int dim, class InVector, int spacedim>
114
MGTransferPrebuilt<VECTOR>::copy_to_mg (
115
const MGDoFHandler<dim,spacedim>& mg_dof_handler,
116
MGLevelObject<VECTOR>& dst,
117
const InVector& src) const
119
reinit_vector(mg_dof_handler, component_to_block_map, dst);
121
for (unsigned int level=mg_dof_handler.get_tria().n_levels();level != 0;)
124
VECTOR& dst_level = dst[level];
126
typedef std::vector<std::pair<unsigned int, unsigned int> >::const_iterator IT;
127
for (IT i= copy_indices[level].begin();
128
i != copy_indices[level].end();++i)
129
dst_level(i->second) = src(i->first);
131
// For non-DG: degrees of
132
// freedom in the refinement
133
// face may need special
134
// attention, since they belong
135
// to the coarse level, but
136
// have fine level basis
138
#ifdef BAERBEL_MG_TEST
139
deallog << "dst [" << level << "] "
140
<< dst[level].l2_norm() << std::endl;
144
restrict_and_add (level+1, dst[level], dst[level+1]);
146
#ifdef BAERBEL_MG_TEST
147
deallog << "dst [" << level << "] "
148
<< dst[level].l2_norm() << std::endl;
155
template <typename VECTOR>
34
156
template <int dim, int spacedim>
35
void MGTransferPrebuilt<number>::build_matrices (
36
const MGDoFHandler<dim,spacedim> &mg_dof)
157
void MGTransferPrebuilt<VECTOR>::build_matrices (
158
const MGDoFHandler<dim,spacedim> &mg_dof,
159
const std::vector<std::set<unsigned int> > &boundary_indices
38
162
const unsigned int n_levels = mg_dof.get_tria().n_levels();
39
163
const unsigned int dofs_per_cell = mg_dof.get_fe().dofs_per_cell;
41
165
sizes.resize(n_levels);
42
166
for (unsigned int l=0;l<n_levels;++l)
43
167
sizes[l] = mg_dof.n_dofs(l);
45
169
// reset the size of the array of
46
170
// matrices. call resize(0) first,
47
171
// in order to delete all elements
55
179
prolongation_matrices.resize (0);
56
180
prolongation_sparsities.resize (0);
58
182
for (unsigned int i=0; i<n_levels-1; ++i)
60
prolongation_sparsities
61
.push_back (std_cxx1x::shared_ptr<SparsityPattern> (new SparsityPattern));
63
.push_back (std_cxx1x::shared_ptr<SparseMatrix<double> > (new SparseMatrix<double>));
184
prolongation_sparsities.push_back
185
(std_cxx1x::shared_ptr<SparsityPattern> (new SparsityPattern));
186
prolongation_matrices.push_back
187
(std_cxx1x::shared_ptr<SparseMatrix<double> > (new SparseMatrix<double>));
66
190
// two fields which will store the
67
191
// indices of the multigrid dofs
68
192
// for a cell and one of its children
69
193
std::vector<unsigned int> dof_indices_parent (dofs_per_cell);
70
194
std::vector<unsigned int> dof_indices_child (dofs_per_cell);
72
196
// for each level: first build the sparsity
73
197
// pattern of the matrices and then build the
74
198
// matrices themselves. note that we only
141
266
// prolongation matrix for
143
268
const FullMatrix<double> &prolongation
144
= mg_dof.get_fe().get_prolongation_matrix (child, cell->refinement_case());
269
= mg_dof.get_fe().get_prolongation_matrix (child,
270
cell->refinement_case());
146
272
cell->child(child)->get_mg_dof_indices (dof_indices_child);
148
274
// now set the entries in the
150
276
for (unsigned int i=0; i<dofs_per_cell; ++i)
151
for (unsigned int j=0; j<dofs_per_cell; ++j)
152
if (prolongation(i,j) != 0)
153
prolongation_matrices[level]->set (dof_indices_child[i],
154
dof_indices_parent[j],
277
prolongation_matrices[level]->set (dof_indices_child[i],
279
&dof_indices_parent[0],
160
copy_indices.resize(mg_dof.get_tria().n_levels());
287
// impose boundary conditions
288
// but only in the column of
289
// the prolongation matrix
290
if (boundary_indices.size() != 0)
292
std::vector<unsigned int> constrain_indices;
293
for (int level=n_levels-2; level>=0; --level)
295
if (boundary_indices[level].size() == 0)
298
// need to delete all the columns in the
299
// matrix that are on the boundary. to achive
300
// this, create an array as long as there are
301
// matrix columns, and find which columns we
302
// need to filter away.
303
constrain_indices.resize (0);
304
constrain_indices.resize (prolongation_matrices[level]->n(), 0);
305
std::set<unsigned int>::const_iterator dof = boundary_indices[level].begin(),
306
endd = boundary_indices[level].end();
307
for (; dof != endd; ++dof)
308
constrain_indices[*dof] = 1;
310
const unsigned int n_dofs = prolongation_matrices[level]->m();
311
for (unsigned int i=0; i<n_dofs; ++i)
313
SparseMatrix<double>::iterator
314
start_row = prolongation_matrices[level]->begin(i),
315
end_row = prolongation_matrices[level]->end(i);
316
for(; start_row != end_row; ++start_row)
318
if (constrain_indices[start_row->column()] == 1)
319
start_row->value() = 0;
325
// to find the indices that describe the
326
// relation between global dofs and local
327
// numbering on the individual level, first
328
// create a temp vector where the ith level
329
// entry contains the respective global
330
// entry. this gives a neat way to find those
331
// indices. in a second step, actually build
332
// the std::vector<std::pair<uint,uint> > that
333
// only contains the active dofs on the
335
interface_dofs.resize(mg_dof.get_tria().n_levels());
336
for(unsigned int l=0; l<mg_dof.get_tria().n_levels(); ++l)
337
interface_dofs[l].resize(mg_dof.n_dofs(l));
338
MGTools::extract_inner_interface_dofs (mg_dof, interface_dofs);
340
copy_indices.resize(n_levels);
341
std::vector<unsigned int> temp_copy_indices;
161
342
std::vector<unsigned int> global_dof_indices (dofs_per_cell);
162
343
std::vector<unsigned int> level_dof_indices (dofs_per_cell);
163
344
for (int level=mg_dof.get_tria().n_levels()-1; level>=0; --level)
180
364
global_cell.get_dof_indices(global_dof_indices);
181
365
level_cell->get_mg_dof_indices (level_dof_indices);
183
367
for (unsigned int i=0; i<dofs_per_cell; ++i)
185
copy_indices[level].insert(
186
std::make_pair(global_dof_indices[i], level_dof_indices[i]));
369
if(!interface_dofs[level][level_dof_indices[i]])
370
temp_copy_indices[level_dof_indices[i]] = global_dof_indices[i];
374
// now all the active dofs got a valid entry,
375
// the other ones have an invalid entry. Count
376
// the invalid entries and then resize the
377
// copy_indices object. Then, insert the pairs
378
// of global index and level index into
380
const unsigned int n_active_dofs =
381
std::count_if (temp_copy_indices.begin(), temp_copy_indices.end(),
382
std::bind2nd(std::not_equal_to<unsigned int>(),
383
numbers::invalid_unsigned_int));
384
copy_indices[level].resize (n_active_dofs);
385
unsigned int counter = 0;
386
for (unsigned int i=0; i<temp_copy_indices.size(); ++i)
387
if (temp_copy_indices[i] != numbers::invalid_unsigned_int)
388
copy_indices[level][counter++] =
389
std::pair<unsigned int, unsigned int> (temp_copy_indices[i], i);
390
Assert (counter == n_active_dofs, ExcInternalError());
395
//TODO: Use template expander script
195
398
void MGTransferPrebuilt<Vector<float> >::build_matrices<deal_II_dimension>
196
(const MGDoFHandler<deal_II_dimension> &mg_dof);
399
(const MGDoFHandler<deal_II_dimension> &mg_dof,
400
const std::vector<std::set<unsigned int> >&boundary_indices);
199
403
void MGTransferPrebuilt<Vector<double> >::build_matrices<deal_II_dimension>
200
(const MGDoFHandler<deal_II_dimension> &mg_dof);
404
(const MGDoFHandler<deal_II_dimension> &mg_dof,
405
const std::vector<std::set<unsigned int> >&boundary_indices);
203
408
void MGTransferPrebuilt<BlockVector<float> >::build_matrices<deal_II_dimension>
204
(const MGDoFHandler<deal_II_dimension> &mg_dof);
409
(const MGDoFHandler<deal_II_dimension> &mg_dof,
410
const std::vector<std::set<unsigned int> >&boundary_indices);
207
413
void MGTransferPrebuilt<BlockVector<double> >::build_matrices<deal_II_dimension>
208
(const MGDoFHandler<deal_II_dimension> &mg_dof);
414
(const MGDoFHandler<deal_II_dimension> &mg_dof,
415
const std::vector<std::set<unsigned int> >&boundary_indices);
211
418
MGTransferPrebuilt<Vector<float> >::copy_to_mg (