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:

  224 void
  225 ConstraintMatrix::add_entries
  226 (const size_type                                  line,
  227  const std::vector<std::pair<size_type,double> > &col_val_pairs)
  228 {
  229   Assert (sorted==false, ExcMatrixIsClosed());
  230   Assert (is_constrained(line), ExcLineInexistant(line));
  231 
  232   ConstraintLine *line_ptr = &lines[lines_cache[calculate_line_index(
line)]];
  233   Assert (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
  240   for (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     {
  244       Assert (line != col_val_pair->first,
  245               ExcMessage ("Can't constrain a degree of freedom to 
itself"));
  246 
  247       for (ConstraintLine::Entries::const_iterator
  248            p=line_ptr->entries.begin();
  249            p != line_ptr->entries.end(); ++p)
  250         if (p->first == col_val_pair->first)
  251           {
  252             // entry exists, break innermost loop
  253             Assert (p->second == col_val_pair->second,
  254                     ExcEntryAlreadyExists(line, col_val_pair->first,
  255                                           p->second, col_val_pair->
second));
  256             break;
  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_pair in the case this entry already exist. The break 
command terminates the innermost loop but the push_back operation 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.

 224 void
 225 ConstraintMatrix::add_entries
 226 (const size_type                                  line,
 227  const std::vector<std::pair<size_type,double> > &col_val_pairs)
 228 {
 229   Assert (sorted==false, ExcMatrixIsClosed());
 230   Assert (is_constrained(line), ExcLineInexistant(line));
 231 
 232   ConstraintLine *line_ptr = &lines[lines_cache[calculate_line_index(
line)]];
 233   Assert (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
 240   for (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     {
 244       Assert (line != col_val_pair->first,
 245               ExcMessage ("Can't constrain a degree of freedom to 
itself"));
 246
 246a      bool entry_exists = false;
 247       for (ConstraintLine::Entries::const_iterator
 248            p=line_ptr->entries.begin();
 249            p != line_ptr->entries.end(); ++p)
 250         if (p->first == col_val_pair->first)
 251           {
 252             // entry exists, break innermost loop
 253             Assert (p->second == col_val_pair->second,
 254                     ExcEntryAlreadyExists(line, col_val_pair->first,
 255                                           p->second, 
col_val_pair->second));
 255a            entry_exists = true;
 256             break;
 257           }
 258
 258a       if (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+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to