* advisable to have the list of
* fixed nodes available when
* calling the present function.
- *
- * However, it is worth noting
- * that even though the the
- * function obtains the list of
- * boundary nodes, this does not
- * guarantee that the boundary
- * values will be correct after
- * solving the linear system. The
- * reason is that the for fixed
- * (boundary) nodes, the matrix
- * has an empty row and column
- * except for the diagonal entry,
- * and the value of the solution
- * vector for this dof is the
- * right hand side value divided
- * by the diagonal entry. In
- * order to guarantee that the
- * resulting value is correct, we
- * need to have knowledge of both
- * the matrix and the right hand
- * side vector, something that
- * the
- * MatrixTools::apply_boundary_values
- * function does but this one
- * does not. Therefore, unless
- * you want to handle boundary
- * values yourself after
- * assembling the matrix by
- * adjusting the diagonal entries
- * of the matrix and the rows of
- * the right hand side vector of
- * the fixed nodes, it is advised
- * to not call this function here
- * directly, but rather to call
- * the
- * distribute_local_to_global()
- * function that does the work
- * for the matrix and right hand
- * side vector at the same time,
- * as demonstrated in step-17.
*/
template <typename VectorType>
void
distribute_local_to_global (const Vector<double> &local_vector,
const std::vector<unsigned int> &local_dof_indices,
- const std::map<unsigned int, double> &fixed_dofs,
VectorType &global_vector) const;
/**
* the condense function after the
* vectors and matrices are fully
* assembled.
- *
- * In order to do its work
- * properly, this function has to
- * know which degrees of freedom
- * are fixed, for example
- * boundary values. For this, the
- * third argument is a map
- * between the numbers of the
- * DoFs that are fixed and the
- * values they are fixed to. One
- * can pass an empty map in for
- * this argument, but note that
- * you will then have to fix
- * these nodes later on again,
- * for example by using
- * MatrixTools::apply_boundary_values
- * to the resulting
- * matrix. However, since the
- * present function was written
- * for the express purpose of not
- * having to use tools that later
- * modify the matrix, it is
- * advisable to have the list of
- * fixed nodes available when
- * calling the present function.
- *
- * However, it is worth noting
- * that even though the the
- * function obtains the list of
- * boundary nodes, this does not
- * guarantee that the boundary
- * values will be correct after
- * solving the linear system. The
- * reason is that the for fixed
- * (boundary) nodes, the matrix
- * has an empty row and column
- * except for the diagonal entry,
- * and the value of the solution
- * vector for this dof is the
- * right hand side value divided
- * by the diagonal entry. In
- * order to guarantee that the
- * resulting value is correct, we
- * need to have knowledge of both
- * the matrix and the right hand
- * side vector, something that
- * the
- * MatrixTools::apply_boundary_values
- * function does but this one
- * does not. Therefore, unless
- * you want to handle boundary
- * values yourself after
- * assembling the matrix by
- * adjusting the diagonal entries
- * of the matrix and the rows of
- * the right hand side vector of
- * the fixed nodes, it is advised
- * to not call this function here
- * directly, but rather to call
- * the
- * distribute_local_to_global()
- * function that does the work
- * for the matrix and right hand
- * side vector at the same time,
- * as demonstrated in step-17.
*/
template <typename MatrixType>
void
distribute_local_to_global (const FullMatrix<double> &local_matrix,
const std::vector<unsigned int> &local_dof_indices,
- const std::map<unsigned int, double> &fixed_dofs,
MatrixType &global_matrix) const;
/**
-namespace
-{
- // an abbreviation to see if a
- // certain index is contained in a
- // map
- inline
- bool
- is_fixed (const std::map<unsigned int, double> &fixed_dofs,
- const unsigned int i)
- {
- return (fixed_dofs.find(i) != fixed_dofs.end());
- }
-}
-
-
-
-
template<typename number>
void
ConstraintMatrix::condense (const SparseMatrix<number> &uncondensed,
ConstraintMatrix::
distribute_local_to_global (const Vector<double> &local_vector,
const std::vector<unsigned int> &local_dof_indices,
- const std::map<unsigned int, double> &fixed_dofs,
VectorType &global_vector) const
{
Assert (local_vector.size() == local_dof_indices.size(),
global_vector(local_dof_indices[i]) += local_vector(i);
else
{
- if (!is_fixed(fixed_dofs, local_dof_indices[i]))
- {
- for (unsigned int j=0; j<position->entries.size(); ++j)
- if (!is_fixed(fixed_dofs, position->entries[j].first))
- global_vector(position->entries[j].first)
- += local_vector(i) * position->entries[j].second;
- }
- else
- {
- global_vector(local_dof_indices[i]) += local_vector(i);
- for (unsigned int j=0; j<position->entries.size(); ++j)
- Assert (is_fixed(fixed_dofs, position->entries[j].first),
- ExcInternalError());
- }
+ for (unsigned int j=0; j<position->entries.size(); ++j)
+ global_vector(position->entries[j].first)
+ += local_vector(i) * position->entries[j].second;
}
}
}
ConstraintMatrix::
distribute_local_to_global (const FullMatrix<double> &local_matrix,
const std::vector<unsigned int> &local_dof_indices,
- const std::map<unsigned int, double> &fixed_dofs,
MatrixType &global_matrix) const
{
Assert (local_matrix.n() == local_dof_indices.size(),
// ok, row is constrained,
// but column is not
for (unsigned int q=0; q<position_i->entries.size(); ++q)
- if (!is_fixed(fixed_dofs, position_i->entries[q].first))
- global_matrix.add (position_i->entries[q].first,
- local_dof_indices[j],
- local_matrix(i,j) *
- position_i->entries[q].second);
+ global_matrix.add (position_i->entries[q].first,
+ local_dof_indices[j],
+ local_matrix(i,j) *
+ position_i->entries[q].second);
}
else if ((is_constrained_i == false) &&
(is_constrained_j == true))
// round: row ok, column is
// constrained
for (unsigned int q=0; q<position_j->entries.size(); ++q)
- if (!is_fixed(fixed_dofs, position_j->entries[q].first))
- global_matrix.add (local_dof_indices[i],
- position_j->entries[q].first,
- local_matrix(i,j) *
- position_j->entries[q].second);
+ global_matrix.add (local_dof_indices[i],
+ position_j->entries[q].first,
+ local_matrix(i,j) *
+ position_j->entries[q].second);
}
else if ((is_constrained_i == true) &&
(is_constrained_j == true))
// last case: both row and
// column are constrained
for (unsigned int p=0; p<position_i->entries.size(); ++p)
- if (!is_fixed(fixed_dofs, position_i->entries[p].first))
- for (unsigned int q=0; q<position_j->entries.size(); ++q)
- if (!is_fixed(fixed_dofs, position_j->entries[q].first))
- global_matrix.add (position_i->entries[p].first,
- position_j->entries[q].first,
- local_matrix(i,j) *
- position_i->entries[p].second *
- position_j->entries[q].second);
+ for (unsigned int q=0; q<position_j->entries.size(); ++q)
+ global_matrix.add (position_i->entries[p].first,
+ position_j->entries[q].first,
+ local_matrix(i,j) *
+ position_i->entries[p].second *
+ position_j->entries[q].second);
// to make sure that the
// global matrix remains