// determinant and the quadrature point weight (that one
// gets together by the call to FEValues::JxW() ). Finally,
// this is repeated for all shape functions $i$ and $j$:
- for (unsigned int i = 0; i < dofs_per_cell; ++i)
- for (unsigned int j = 0; j < dofs_per_cell; ++j)
+ for (const unsigned int i : fe_values.dof_indices())
+ for (const unsigned int j : fe_values.dof_indices())
cell_matrix(i, j) +=
(fe_values.shape_grad(i, q_index) * // grad phi_i(x_q)
fe_values.shape_grad(j, q_index) * // grad phi_j(x_q)
// hand side function, which we choose to be the function
// with constant value one (more interesting examples will
// be considered in the following programs).
- for (unsigned int i = 0; i < dofs_per_cell; ++i)
+ for (const unsigned int i : fe_values.dof_indices())
cell_rhs(i) += (fe_values.shape_value(i, q_index) * // phi_i(x_q)
1 * // f(x_q)
fe_values.JxW(q_index)); // dx
// Then again loop over all shape functions i and j and transfer the
// local elements to the global matrix. The global numbers can be
// obtained using local_dof_indices[i]:
- for (unsigned int i = 0; i < dofs_per_cell; ++i)
- for (unsigned int j = 0; j < dofs_per_cell; ++j)
+ for (const unsigned int i : fe_values.dof_indices())
+ for (const unsigned int j : fe_values.dof_indices())
system_matrix.add(local_dof_indices[i],
local_dof_indices[j],
cell_matrix(i, j));
// And again, we do the same thing for the right hand side vector.
- for (unsigned int i = 0; i < dofs_per_cell; ++i)
+ for (const unsigned int i : fe_values.dof_indices())
system_rhs(local_dof_indices[i]) += cell_rhs(i);
}
// constant right hand side with value 1, we use the object representing
// the right hand side and evaluate it at the quadrature points:
for (const unsigned int q_index : fe_values.quadrature_point_indices())
- for (unsigned int i = 0; i < dofs_per_cell; ++i)
+ for (const unsigned int i : fe_values.dof_indices())
{
- for (unsigned int j = 0; j < dofs_per_cell; ++j)
+ for (const unsigned int j : fe_values.dof_indices())
cell_matrix(i, j) +=
(fe_values.shape_grad(i, q_index) * // grad phi_i(x_q)
fe_values.shape_grad(j, q_index) * // grad phi_j(x_q)
// and right hand side is done exactly as before, but here we have again
// merged some loops for efficiency:
cell->get_dof_indices(local_dof_indices);
- for (unsigned int i = 0; i < dofs_per_cell; ++i)
+ for (const unsigned int i : fe_values.dof_indices())
{
- for (unsigned int j = 0; j < dofs_per_cell; ++j)
+ for (const unsigned int j : fe_values.dof_indices())
system_matrix.add(local_dof_indices[i],
local_dof_indices[j],
cell_matrix(i, j));
{
const double current_coefficient =
coefficient<dim>(fe_values.quadrature_point(q_index));
- for (unsigned int i = 0; i < dofs_per_cell; ++i)
+ for (const unsigned int i : fe_values.dof_indices())
{
- for (unsigned int j = 0; j < dofs_per_cell; ++j)
+ for (const unsigned int j : fe_values.dof_indices())
cell_matrix(i, j) +=
(current_coefficient * // a(x_q)
fe_values.shape_grad(i, q_index) * // grad phi_i(x_q)
cell->get_dof_indices(local_dof_indices);
- for (unsigned int i = 0; i < dofs_per_cell; ++i)
+ for (const unsigned int i : fe_values.dof_indices())
{
- for (unsigned int j = 0; j < dofs_per_cell; ++j)
+ for (const unsigned int j : fe_values.dof_indices())
system_matrix.add(local_dof_indices[i],
local_dof_indices[j],
cell_matrix(i, j));
//
// The rest of the code that forms the local contributions remains
// unchanged. It is worth noting, however, that under the hood several things
-// are different than before. First, the variables <code>dofs_per_cell</code>
-// and <code>n_q_points</code> now are 9 each, where they were 4
-// before. Introducing such variables as abbreviations is a good strategy to
-// make code work with different elements without having to change too much
-// code. Secondly, the <code>fe_values</code> object of course needs to do
-// other things as well, since the shape functions are now quadratic, rather
-// than linear, in each coordinate variable. Again, however, this is something
-// that is completely handled by the library.
+// are different than before. First, the variable <code>dofs_per_cell</code>
+// and return value of <code>quadrature_formula.size()</code> now are 9 each,
+// where they were 4 before. Introducing such variables as abbreviations is a
+// good strategy to make code work with different elements without having to
+// change too much code. Secondly, the <code>fe_values</code> object of course
+// needs to do other things as well, since the shape functions are now
+// quadratic, rather than linear, in each coordinate variable. Again, however,
+// this is something that is completely handled by the library.
template <int dim>
void Step6<dim>::assemble_system()
{
update_quadrature_points | update_JxW_values);
const unsigned int dofs_per_cell = fe.dofs_per_cell;
- const unsigned int n_q_points = quadrature_formula.size();
FullMatrix<double> cell_matrix(dofs_per_cell, dofs_per_cell);
Vector<double> cell_rhs(dofs_per_cell);
fe_values.reinit(cell);
- for (unsigned int q_index = 0; q_index < n_q_points; ++q_index)
+ for (const unsigned int q_index : fe_values.quadrature_point_indices())
{
const double current_coefficient =
coefficient<dim>(fe_values.quadrature_point(q_index));
- for (unsigned int i = 0; i < dofs_per_cell; ++i)
+ for (const unsigned int i : fe_values.dof_indices())
{
- for (unsigned int j = 0; j < dofs_per_cell; ++j)
+ for (const unsigned int j : fe_values.dof_indices())
cell_matrix(i, j) +=
(current_coefficient * // a(x_q)
fe_values.shape_grad(i, q_index) * // grad phi_i(x_q)
//
// With this knowledge, we can assemble the local matrix
// contributions:
- for (unsigned int i = 0; i < dofs_per_cell; ++i)
+ for (const unsigned int i : fe_values.dof_indices())
{
const unsigned int component_i =
fe.system_to_component_index(i).first;
- for (unsigned int j = 0; j < dofs_per_cell; ++j)
+ for (const unsigned int j : fe_values.dof_indices())
{
const unsigned int component_j =
fe.system_to_component_index(j).first;
- for (unsigned int q_point = 0; q_point < n_q_points; ++q_point)
+ for (const unsigned int q_point :
+ fe_values.quadrature_point_indices())
{
cell_matrix(i, j) +=
// The first term is $\lambda \partial_i u_i, \partial_j
// Assembling the right hand side is also just as discussed in the
// introduction:
- for (unsigned int i = 0; i < dofs_per_cell; ++i)
+ for (const unsigned int i : fe_values.dof_indices())
{
const unsigned int component_i =
fe.system_to_component_index(i).first;
- for (unsigned int q_point = 0; q_point < n_q_points; ++q_point)
+ for (const unsigned int q_point :
+ fe_values.quadrature_point_indices())
cell_rhs(i) += fe_values.shape_value(i, q_point) *
rhs_values[q_point][component_i] *
fe_values.JxW(q_point);