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.