16 #include <deal.II/lac/constraint_matrix.h> 17 #include <deal.II/lac/constraint_matrix.templates.h> 19 #include <deal.II/base/memory_consumption.h> 20 #include <deal.II/lac/dynamic_sparsity_pattern.h> 21 #include <deal.II/lac/block_vector.h> 22 #include <deal.II/lac/block_sparse_matrix.h> 23 #include <deal.II/lac/sparse_matrix_ez.h> 24 #include <deal.II/lac/chunk_sparse_matrix.h> 25 #include <deal.II/lac/block_sparse_matrix_ez.h> 26 #include <deal.II/lac/parallel_vector.h> 27 #include <deal.II/lac/parallel_block_vector.h> 28 #include <deal.II/lac/petsc_vector.h> 29 #include <deal.II/lac/petsc_block_vector.h> 30 #include <deal.II/lac/petsc_sparse_matrix.h> 31 #include <deal.II/lac/petsc_block_sparse_matrix.h> 32 #include <deal.II/lac/petsc_parallel_vector.h> 33 #include <deal.II/lac/petsc_parallel_block_vector.h> 34 #include <deal.II/lac/petsc_parallel_sparse_matrix.h> 35 #include <deal.II/lac/petsc_parallel_block_sparse_matrix.h> 36 #include <deal.II/lac/trilinos_vector.h> 37 #include <deal.II/lac/trilinos_block_vector.h> 38 #include <deal.II/lac/trilinos_sparse_matrix.h> 39 #include <deal.II/lac/trilinos_block_sparse_matrix.h> 40 #include <deal.II/lac/matrix_block.h> 47 DEAL_II_NAMESPACE_OPEN
59 return (p.second == 0);
75 return line == a.
line;
93 for (std::set<size_type>::const_iterator
94 i = lines.begin(); i != lines.end(); ++i)
104 if (lines[i] ==
true)
122 const std::vector<std::pair<size_type,double> > &col_val_pairs)
128 Assert (line_ptr->
line == line, ExcInternalError());
135 for (std::vector<std::pair<size_type,double> >::const_iterator
136 col_val_pair = col_val_pairs.begin();
137 col_val_pair!=col_val_pairs.end(); ++col_val_pair)
139 Assert (line != col_val_pair->first,
140 ExcMessage (
"Can't constrain a degree of freedom to itself"));
142 for (ConstraintLine::Entries::const_iterator
144 p != line_ptr->
entries.end(); ++p)
145 if (p->first == col_val_pair->first)
148 Assert (p->second == col_val_pair->second,
149 ExcEntryAlreadyExists(line, col_val_pair->first,
150 p->second, col_val_pair->second));
154 line_ptr->
entries.push_back (*col_val_pair);
168 ExcMessage (
"Filter needs to be larger than constraint matrix size."));
169 for (std::vector<ConstraintLine>::const_iterator line=constraints.
lines.begin();
170 line!=constraints.
lines.end(); ++line)
176 for (
size_type i=0; i<line->entries.size(); ++i)
177 if (filter.
is_element(line->entries[i].first))
179 line->entries[i].second);
196 std::vector<size_type> new_lines (
lines_cache.size(),
199 for (std::vector<ConstraintLine>::const_iterator line=
lines.begin();
212 for (std::vector<ConstraintLine>::iterator line =
lines.begin();
213 line!=
lines.end(); ++line)
217 line->entries.erase (std::remove_if (line->entries.begin(),
220 line->entries.end());
233 for (std::vector<ConstraintLine>::iterator line =
lines.begin();
234 line!=
lines.end(); ++line)
236 for (ConstraintLine::Entries::iterator it = line->entries.begin(); it!=line->entries.end(); ++it)
238 largest_idx=std::max(largest_idx, it->first);
258 bool chained_constraint_replaced =
false;
260 for (std::vector<ConstraintLine>::iterator line =
lines.begin();
261 line!=
lines.end(); ++line)
274 while (entry < line->entries.size())
282 chained_constraint_replaced =
true;
285 const size_type dof_index = line->entries[entry].first;
286 const double weight = line->entries[entry].second;
288 Assert (dof_index != line->line,
289 ExcMessage (
"Cycle in constraints detected!"));
304 if (constrained_line->
entries.size() > 0)
308 ExcMessage (
"Cycle in constraints detected!"));
312 line->entries[entry] =
313 std::make_pair (constrained_line->
entries[0].first,
314 constrained_line->
entries[0].second *
319 .push_back (std::make_pair (constrained_line->
entries[i].first,
320 constrained_line->
entries[i].second *
328 Assert(n_replacements/2<largest_idx,
ExcMessage(
"Cycle in constraints detected!"));
329 if (n_replacements/2>=largest_idx)
340 line->entries.erase (line->entries.begin()+entry);
358 if (chained_constraint_replaced ==
false)
365 Assert (iteration <=
lines.size(), ExcInternalError());
372 for (std::vector<ConstraintLine>::iterator line =
lines.begin();
373 line!=
lines.end(); ++line)
375 std::sort (line->entries.begin(), line->entries.end());
382 for (
size_type i=1; i<line->entries.size(); ++i)
383 if (line->entries[i].first == line->entries[i-1].first)
386 if (duplicates > 0 || line->entries.size() < line->entries.capacity())
393 new_entries = line->entries;
398 new_entries.reserve (line->entries.size() - duplicates);
399 new_entries.push_back(line->entries[0]);
400 for (
size_type j=1; j<line->entries.size(); ++j)
401 if (line->entries[j].first == line->entries[j-1].first)
403 Assert (new_entries.back().first == line->entries[j].first,
405 new_entries.back().second += line->entries[j].second;
408 new_entries.push_back (line->entries[j]);
410 Assert (new_entries.size() == line->entries.size() - duplicates,
415 for (
size_type j=1; j<new_entries.size(); ++j)
417 Assert (new_entries[j].first != new_entries[j-1].first,
419 Assert (new_entries[j].first > new_entries[j-1].first,
425 line->entries.swap (new_entries);
439 for (
size_type i=0; i<line->entries.size(); ++i)
440 sum += line->entries[i].second;
441 if ((sum != 1.0) && (std::fabs (sum-1.) < 1.e-13))
443 for (
size_type i=0; i<line->entries.size(); ++i)
444 line->entries[i].second /= sum;
445 line->inhomogeneity /= sum;
453 for (std::vector<ConstraintLine>::const_iterator line=
lines.begin();
454 line!=
lines.end(); ++line)
455 for (ConstraintLine::Entries::const_iterator
456 entry=line->entries.begin();
457 entry!=line->entries.end(); ++entry)
464 Assert (is_circle ==
false,
465 ExcDoFConstrainedToConstrainedDoF(line->line, entry->first));
479 ExcNotImplemented());
482 const bool object_was_sorted =
sorted;
498 for (std::vector<ConstraintLine>::iterator line=
lines.begin();
499 line!=
lines.end(); ++line)
502 for (
size_type i=0; i<line->entries.size(); ++i)
506 if (other_constraints.
is_constrained(line->entries[i].first) ==
false 513 tmp.push_back(line->entries[i]);
524 const double weight = line->entries[i].second;
526 for (ConstraintLine::Entries::const_iterator j=other_line->begin();
527 j!=other_line->end(); ++j)
528 tmp.push_back (std::pair<size_type,double>(j->first,
531 line->inhomogeneity += other_constraints.
get_inhomogeneity(line->entries[i].first) *
536 line->entries.swap (tmp);
542 for (std::vector<ConstraintLine>::const_iterator
543 line=other_constraints.
lines.begin();
544 line!=other_constraints.
lines.end(); ++line)
546 lines.push_back (*line);
551 switch (merge_conflict_behavior)
555 ExcDoFIsConstrainedFromBothObjects (line->line));
568 = line->inhomogeneity;
572 Assert (
false, ExcNotImplemented());
578 for (std::vector<ConstraintLine>::const_iterator line=
lines.begin();
584 if (object_was_sorted ==
true)
598 for (std::vector<ConstraintLine>::iterator i =
lines.begin();
599 i !=
lines.end(); ++i)
602 for (ConstraintLine::Entries::iterator
603 j = i->entries.begin();
604 j != i->entries.end(); ++j)
614 std::vector<ConstraintLine> tmp;
619 std::vector<size_type> tmp;
675 ((entry != sparsity.
end(row)) &&
676 entry->is_valid_entry());
679 const size_type column = entry->column();
700 const size_type column = entry->column();
778 sparsity.
add (row, new_col);
781 if ((new_col < column) && (old_rowlength != new_rowlength))
783 old_rowlength = new_rowlength;
806 .entries.size(); ++q)
846 const std::pair<size_type,size_type>
847 block_index = index_mapping.global_to_local(row);
848 const size_type block_row = block_index.first;
857 for (
size_type block_col=0; block_col<n_blocks; ++block_col)
860 block_sparsity = sparsity.
block(block_row, block_col);
863 entry = block_sparsity.
begin(block_index.second);
864 (entry != block_sparsity.
end(block_index.second)) &&
869 = index_mapping.local_to_global(block_col, entry->column());
887 for (
size_type block_col=0; block_col<n_blocks; ++block_col)
890 block_sparsity = sparsity.
block(block_row,block_col);
893 entry = block_sparsity.
begin(block_index.second);
894 (entry != block_sparsity.
end(block_index.second)) &&
899 = index_mapping.local_to_global (block_col, entry->column());
957 const std::pair<size_type,size_type>
958 block_index = index_mapping.global_to_local(row);
959 const size_type block_row = block_index.first;
960 const size_type local_row = block_index.second;
975 for (
size_type block_col=0; block_col<n_blocks; ++block_col)
978 block_sparsity = sparsity.
block(block_row, block_col);
983 = index_mapping.local_to_global(block_col,
992 .entries.size(); ++q)
1003 for (
size_type block_col=0; block_col<n_blocks; ++block_col)
1006 block_sparsity = sparsity.
block(block_row,block_col);
1011 = index_mapping.local_to_global (block_col,
1047 Assert (p.
line == index, ExcInternalError());
1051 return ((p.
entries.size() == 1) &&
1052 (p.
entries[0].second == 1.0));
1062 Assert (p.
line == index1, ExcInternalError());
1066 return ((p.
entries.size() == 1) &&
1067 (p.
entries[0].first == index2) &&
1068 (p.
entries[0].second == 1.0));
1073 Assert (p.
line == index2, ExcInternalError());
1077 return ((p.
entries.size() == 1) &&
1078 (p.
entries[0].first == index1) &&
1079 (p.
entries[0].second == 1.0));
1091 for (std::vector<ConstraintLine>::const_iterator i=
lines.begin();
1092 i!=
lines.end(); ++i)
1095 return_value = std::max(return_value,
1096 static_cast<size_type>(i->entries.size()));
1098 return return_value;
1105 for (std::vector<ConstraintLine>::const_iterator i=
lines.begin();
1106 i!=
lines.end(); ++i)
1107 if (i->inhomogeneity != 0.)
1119 if (
lines[i].entries.size() > 0)
1122 out <<
" " <<
lines[i].line
1123 <<
" " <<
lines[i].entries[j].first
1124 <<
": " <<
lines[i].entries[j].second <<
"\n";
1127 if (
lines[i].inhomogeneity != 0)
1128 out <<
" " <<
lines[i].line
1129 <<
": " <<
lines[i].inhomogeneity <<
"\n";
1136 if (
lines[i].inhomogeneity != 0)
1137 out <<
" " <<
lines[i].line
1138 <<
" = " <<
lines[i].inhomogeneity
1141 out <<
" " <<
lines[i].line <<
" = 0\n";
1153 out <<
"digraph constraints {" 1158 if (
lines[i].entries.size() > 0)
1160 out <<
" " <<
lines[i].line <<
"->" <<
lines[i].entries[j].first
1162 <<
lines[i].entries[j].second
1165 out <<
" " <<
lines[i].line <<
"\n";
1167 out <<
"}" << std::endl;
1186 const unsigned int indices_size = indices.size();
1187 const std::vector<std::pair<types::global_dof_index,double> > *line_ptr;
1188 for (
unsigned int i=0; i<indices_size; ++i)
1195 const unsigned int line_size = line_ptr->size();
1196 for (
unsigned int j=0; j<line_size; ++j)
1197 indices.push_back((*line_ptr)[j].first);
1202 std::sort(indices.begin(),indices.end());
1203 std::vector<types::global_dof_index>::iterator it;
1204 it = std::unique(indices.begin(),indices.end());
1205 indices.resize(it-indices.begin());
1220 #define VECTOR_FUNCTIONS(VectorType) \ 1221 template void ConstraintMatrix::condense<VectorType >(const VectorType &uncondensed,\ 1222 VectorType &condensed) const;\ 1223 template void ConstraintMatrix::condense<VectorType >(VectorType &vec) const;\ 1224 template void ConstraintMatrix:: \ 1225 distribute_local_to_global<VectorType > (const Vector<double> &, \ 1226 const std::vector<ConstraintMatrix::size_type> &, \ 1228 const FullMatrix<double> &) const 1230 #define PARALLEL_VECTOR_FUNCTIONS(VectorType) \ 1231 template void ConstraintMatrix:: \ 1232 distribute_local_to_global<VectorType > (const Vector<double> &, \ 1233 const std::vector<ConstraintMatrix::size_type> &, \ 1235 const FullMatrix<double> &) const 1238 #ifdef DEAL_II_WITH_PETSC 1243 #ifdef DEAL_II_WITH_TRILINOS 1248 #define MATRIX_VECTOR_FUNCTIONS(MatrixType, VectorType) \ 1249 template void ConstraintMatrix:: \ 1250 distribute_local_to_global<MatrixType,VectorType > (const FullMatrix<MatrixType::value_type> &, \ 1251 const Vector<VectorType::value_type> &, \ 1252 const std::vector<ConstraintMatrix::size_type> &, \ 1256 internal::bool2type<false>) const 1257 #define MATRIX_FUNCTIONS(MatrixType) \ 1258 template void ConstraintMatrix:: \ 1259 distribute_local_to_global<MatrixType,Vector<MatrixType::value_type> > (const FullMatrix<MatrixType::value_type> &, \ 1260 const Vector<MatrixType::value_type> &, \ 1261 const std::vector<ConstraintMatrix::size_type> &, \ 1263 Vector<MatrixType::value_type> &, \ 1265 internal::bool2type<false>) const 1266 #define BLOCK_MATRIX_VECTOR_FUNCTIONS(MatrixType, VectorType) \ 1267 template void ConstraintMatrix:: \ 1268 distribute_local_to_global<MatrixType,VectorType > (const FullMatrix<MatrixType::value_type> &, \ 1269 const Vector<VectorType::value_type> &, \ 1270 const std::vector<ConstraintMatrix::size_type> &, \ 1274 internal::bool2type<true>) const 1275 #define BLOCK_MATRIX_FUNCTIONS(MatrixType) \ 1276 template void ConstraintMatrix:: \ 1277 distribute_local_to_global<MatrixType,Vector<MatrixType::value_type> > (const FullMatrix<MatrixType::value_type> &, \ 1278 const Vector<MatrixType::value_type> &, \ 1279 const std::vector<ConstraintMatrix::size_type> &, \ 1281 Vector<MatrixType::value_type> &, \ 1283 internal::bool2type<true>) const 1289 MATRIX_FUNCTIONS(
FullMatrix<std::complex<double> >);
1304 #ifdef DEAL_II_WITH_PETSC 1315 #ifdef DEAL_II_WITH_TRILINOS 1325 #define SPARSITY_FUNCTIONS(SparsityPatternType) \ 1326 template void ConstraintMatrix::add_entries_local_to_global<SparsityPatternType> ( \ 1327 const std::vector<ConstraintMatrix::size_type> &, \ 1328 SparsityPatternType &, \ 1330 const Table<2,bool> &, \ 1331 internal::bool2type<false>) const; \ 1332 template void ConstraintMatrix::add_entries_local_to_global<SparsityPatternType> ( \ 1333 const std::vector<ConstraintMatrix::size_type> &, \ 1334 const std::vector<ConstraintMatrix::size_type> &, \ 1335 SparsityPatternType &, \ 1337 const Table<2,bool> &) const 1338 #define BLOCK_SPARSITY_FUNCTIONS(SparsityPatternType) \ 1339 template void ConstraintMatrix::add_entries_local_to_global<SparsityPatternType> ( \ 1340 const std::vector<ConstraintMatrix::size_type> &, \ 1341 SparsityPatternType &, \ 1343 const Table<2,bool> &, \ 1344 internal::bool2type<true>) const; \ 1345 template void ConstraintMatrix::add_entries_local_to_global<SparsityPatternType> ( \ 1346 const std::vector<ConstraintMatrix::size_type> &, \ 1347 const std::vector<ConstraintMatrix::size_type> &, \ 1348 SparsityPatternType &, \ 1350 const Table<2,bool> &) const 1357 #ifdef DEAL_II_WITH_TRILINOS 1359 BLOCK_SPARSITY_FUNCTIONS(TrilinosWrappers::BlockSparsityPattern);
1363 #define ONLY_MATRIX_FUNCTIONS(MatrixType) \ 1364 template void ConstraintMatrix::distribute_local_to_global<MatrixType > (\ 1365 const FullMatrix<MatrixType::value_type> &, \ 1366 const std::vector<ConstraintMatrix::size_type> &, \ 1367 const std::vector<ConstraintMatrix::size_type> &, \ 1379 #ifdef DEAL_II_WITH_TRILINOS 1384 #ifdef DEAL_II_WITH_PETSC 1391 #include "constraint_matrix.inst" 1399 #define SCRATCH_INITIALIZER(Number,Name) \ 1400 ConstraintMatrixData<Number>::ScratchData scratch_data_initializer_##Name; \ 1401 template<> Threads::ThreadLocalStorage<ConstraintMatrixData<Number>::ScratchData> \ 1402 ConstraintMatrixData<Number>::scratch_data(scratch_data_initializer_##Name) 1404 SCRATCH_INITIALIZER(
double,
double);
1405 SCRATCH_INITIALIZER(
float,
float);
1406 SCRATCH_INITIALIZER(
long double,ldouble);
1407 SCRATCH_INITIALIZER(std::complex<double>,cdouble);
1408 SCRATCH_INITIALIZER(std::complex<float>,cfloat);
1409 SCRATCH_INITIALIZER(std::complex<long double>,cldouble);
1410 #undef SCRATCH_INITIALIZER 1414 DEAL_II_NAMESPACE_CLOSE
const types::global_dof_index invalid_size_type
bool operator<(const ConstraintLine &) const
std::vector< size_type > lines_cache
void print(std::ostream &) const
static bool check_zero_weight(const std::pair< size_type, double > &p)
size_type nth_index_in_set(const unsigned int local_index) const
std::size_t memory_consumption() const
size_type column_number(const size_type row, const size_type index) const
DEAL_VOLATILE unsigned int counter
void add(const size_type i, const size_type j)
size_type n_block_cols() const
size_type n_block_rows() const
::ExceptionBase & ExcMessage(std::string arg1)
Auxiliary class aiding in the handling of block structures like in BlockVector or FESystem...
void add_entries(const size_type line, const std::vector< std::pair< size_type, double > > &col_val_pairs)
#define AssertThrow(cond, exc)
types::global_dof_index size_type
std::vector< std::pair< size_type, double > > Entries
bool is_compressed() const
SparsityPatternType & block(const size_type row, const size_type column)
bool is_valid_entry() const
void add_line(const size_type line)
bool operator==(const ConstraintLine &) const
void add_entry(const size_type line, const size_type column, const double value)
void add(const size_type i, const size_type j)
void add(const size_type i, const size_type j)
#define Assert(cond, exc)
size_type index_within_set(const size_type global_index) const
void condense(SparsityPattern &sparsity) const
size_type n_constraints() const
const BlockIndices & get_row_indices() const
void resolve_indices(std::vector< types::global_dof_index > &indices) const
bool has_inhomogeneities() const
static const Table< 2, bool > default_empty_table
std::size_t memory_consumption() const
void add_lines(const std::vector< bool > &lines)
size_type max_constraint_indirections() const
size_type calculate_line_index(const size_type line) const
void distribute(VectorType &vec) const
std_cxx11::enable_if< std_cxx11::is_fundamental< T >::value, std::size_t >::type memory_consumption(const T &t)
void merge(const ConstraintMatrix &other_constraints, const MergeConflictBehavior merge_conflict_behavior=no_conflicts_allowed)
void write_dot(std::ostream &) const
size_type row_length(const size_type row) const
bool is_identity_constrained(const size_type index) const
void shift(const size_type offset)
bool are_identity_constrained(const size_type index1, const size_type index2) const
bool is_element(const size_type index) const
void reinit(const IndexSet &local_constraints=IndexSet())
void add_selected_constraints(const ConstraintMatrix &constraints_in, const IndexSet &filter)
const std::vector< std::pair< size_type, double > > * get_constraint_entries(const size_type line) const
double get_inhomogeneity(const size_type line) const
void set_inhomogeneity(const size_type line, const double value)
std::vector< ConstraintLine > lines
bool is_constrained(const size_type index) const
bool is_compressed() const
size_type n_elements() const
const BlockIndices & get_column_indices() const