Dustin,
good observation. I think you have found a bug indeed. I've put this
here for now:
https://github.com/dealii/dealii/issues/7101
Your fix seems reasonable to me. Do you want to put that into a pull
request? Let us know if you need help with that (and with writing a test).
(For reference, post-9.0, the class is now called AffineConstraints.)
Best and thanks for pointing this out!
Wolfgang
On 08/22/2018 08:30 AM, Dustin Kumor wrote:
> Dear all,
>
> in my opinion there is a small bug in the implementation of the
> ConstraintMatrix member function add_entries in file
> constraint_matrix.cc (release Version 9.0, lines 224-261). The current
> piece of code is:
>
> |
> 224void
> 225ConstraintMatrix::add_entries
> 226(constsize_type line,
> 227conststd::vector<std::pair<size_type,double>>&col_val_pairs)
> 228{
> 229Assert(sorted==false,ExcMatrixIsClosed());
> 230Assert(is_constrained(line),ExcLineInexistant(line));
> 231
> 232ConstraintLine*line_ptr =&lines[lines_cache[calculate_line_index(line)]];
> 233Assert(line_ptr->index ==line,ExcInternalError());
> 234
> 235// if in debug mode, check whether an entry for this column already
> 236// exists and if its the same as the one entered at present
> 237//
> 238// in any case: skip this entry if an entry for this column already
> 239// exists, since we don't want to enter it twice
> 240for(std::vector<std::pair<size_type,double>>::const_iterator
> 241 col_val_pair =col_val_pairs.begin();
> 242 col_val_pair!=col_val_pairs.end();++col_val_pair)
> 243{
> 244Assert(line !=col_val_pair->first,
> 245ExcMessage("Can't constrain a degree of freedom to itself"));
> 246
> 247for(ConstraintLine::Entries::const_iterator
> 248 p=line_ptr->entries.begin();
> 249 p !=line_ptr->entries.end();++p)
> 250if(p->first ==col_val_pair->first)
> 251{
> 252// entry exists, break innermost loop
> 253Assert(p->second ==col_val_pair->second,
> 254ExcEntryAlreadyExists(line,col_val_pair->first,
> 255
> p->second,col_val_pair->second));
> 256break;
> 257}
> 258
> 259 line_ptr->entries.push_back (*col_val_pair);
> 260}
> 261}
> |
>
> Although, it is stated in the comments (lines 235-239) there is no skip
> of the entry col_val_pairin the case this entry already exist. The
> breakcommand terminates the innermost loop but the push_backoperation is
> performed nevertheless, i.e. for every element of col_val_pairs. This
> leads to duplicates in the constraint matrix.
> I solved the problem by just addind the three lines 246a, 255a, 258a.
>
> |
> 224void
> 225ConstraintMatrix::add_entries
> 226(constsize_type line,
> 227conststd::vector<std::pair<size_type,double>>&col_val_pairs)
> 228{
> 229Assert(sorted==false,ExcMatrixIsClosed());
> 230Assert(is_constrained(line),ExcLineInexistant(line));
> 231
> 232ConstraintLine*line_ptr =&lines[lines_cache[calculate_line_index(line)]];
> 233Assert(line_ptr->index==line,ExcInternalError());
> 234
> 235// if in debug mode, check whether an entry for this column already
> 236// exists and if its the same as the one entered at present
> 237//
> 238// in any case: skip this entry if an entry for this column already
> 239// exists, since we don't want to enter it twice
> 240for(std::vector<std::pair<size_type,double> >::const_iterator
> 241 col_val_pair = col_val_pairs.begin();
> 242 col_val_pair!=col_val_pairs.end(); ++col_val_pair)
> 243 {
> 244Assert(line != col_val_pair->first,
> 245ExcMessage("Can't constrain a degree of freedom to itself"));
> 246
> 246aboolentry_exists =false;
> 247for(ConstraintLine::Entries::const_iterator
> 248 p=line_ptr->entries.begin();
> 249 p !=line_ptr->entries.end();++p)
> 250if(p->first ==col_val_pair->first)
> 251{
> 252// entry exists, break innermost loop
> 253Assert(p->second == col_val_pair->second,
> 254ExcEntryAlreadyExists(line, col_val_pair->first,
> 255 p->second,
> col_val_pair->second));
> 255a entry_exists =true;
> 256break;
> 257}
> 258
> 258aif(entry_exists ==fase)
> 259 line_ptr->entries.push_back (*col_val_pair);
> 260}
> 261}
> |
>
> May be there is a more elegant way to do this.
>
> Best regards
> Dustin
>
> --
> The deal.II project is located at
http://www.dealii.org/
> For mailing list/forum options, see
>
https://groups.google.com/d/forum/dealii?hl=en
> ---
> You received this message because you are subscribed to the Google
> Groups "deal.II User Group" group.
> To unsubscribe from this group and stop receiving emails from it, send
> an email to
dealii+un...@googlegroups.com
> <mailto:
dealii+un...@googlegroups.com>.
> For more options, visit
https://groups.google.com/d/optout.
--
------------------------------------------------------------------------
Wolfgang Bangerth email:
bang...@colostate.edu
www:
http://www.math.colostate.edu/~bangerth/