From e6b4e3ca194a114962a2175fe43211ac1ed20ff0 Mon Sep 17 00:00:00 2001 From: David Wells Date: Sat, 7 Jul 2018 23:14:57 -0400 Subject: [PATCH] step-9: do some simple modernizations. 1. Use AffineConstraints, not ConstraintMatrix. 2. Use lambdas instead of std::functions. 3. Use auto in a few places instead of very long type names. 4. Use range-based for loops. --- examples/step-9/step-9.cc | 51 +++++++++++++++------------------------ 1 file changed, 19 insertions(+), 32 deletions(-) diff --git a/examples/step-9/step-9.cc b/examples/step-9/step-9.cc index d10f1583b5..ad29716a41 100644 --- a/examples/step-9/step-9.cc +++ b/examples/step-9/step-9.cc @@ -158,7 +158,7 @@ namespace Step9 FE_Q fe; - ConstraintMatrix hanging_node_constraints; + AffineConstraints hanging_node_constraints; SparsityPattern sparsity_pattern; SparseMatrix system_matrix; @@ -907,7 +907,7 @@ namespace Step9 WorkStream::run(dof_handler.begin_active(), dof_handler.end(), &GradientEstimation::template estimate_cell, - std::function(), + [](const EstimateCopyData &) {}, EstimateScratchData(dof_handler.get_fe(), solution, error_per_cell), @@ -935,8 +935,8 @@ namespace Step9 // arguments, we declare this function with three arguments, but simply // ignore the last one. // - // (This is unsatisfactory from an aesthetic perspective. It can be avoided, - // at the cost of some other trickery. If you allow, let us here show + // (This is unsatisfactory from an aesthetic perspective. It can be avoided + // by using an anonymous (lambda) function. If you allow, let us here show // how. First, assume that we had declared this function to only take two // arguments by omitting the unused last one. Now, WorkStream::run still // wants to call this function with three arguments, so we need to find a @@ -944,22 +944,19 @@ namespace Step9 // WorkStream::run the pointer to the function as we do above will not do // this -- the compiler will complain that a function declared to have two // arguments is called with three arguments. However, we can do this by - // passing the following as the third argument when calling WorkStream::run() - // above: + // passing the following as the third argument to WorkStream::run(): // @code - // std::function::active_cell_iterator - // &, - // EstimateScratchData &, - // EstimateCopyData &)> - // (std::bind (&GradientEstimation::template estimate_cell, - // std::placeholders::_1, - // std::placeholders::_2)) + // [](const typename DoFHandler::active_cell_iterator &cell, + // EstimateScratchData & scratch_data, + // EstimateCopyData &) + // { + // GradientEstimation::estimate_cell(cell, scratch_data); + // } // @endcode - // This creates a function object taking three arguments, but when it calls - // the underlying function object, it simply only uses the first and second - // argument -- we simply "forget" to use the third argument :-) - // In the end, this isn't completely obvious either, and so we didn't - // implement it, but hey -- it can be done!) + // This is not much better than the solution implemented below: either the + // routine itself must take three arguments or it must be wrapped by + // something that takes three arguments. We don't use this since adding the + // unused argument at the beginning is simpler. // // Now for the details: template @@ -1015,10 +1012,8 @@ namespace Step9 { // First define an abbreviation for the iterator to the face and // the neighbor - const typename DoFHandler::face_iterator face = - cell->face(face_n); - const typename DoFHandler::cell_iterator neighbor = - cell->neighbor(face_n); + const auto face = cell->face(face_n); + const auto neighbor = cell->neighbor(face_n); // Then check whether the neighbor is active. If it is, then it // is on the same level or one level coarser (if we are not in @@ -1035,8 +1030,7 @@ namespace Step9 // we are left of the present cell (n==0), or go to the // left child if we are on the right (n==1), until we // find an active cell. - typename DoFHandler::cell_iterator neighbor_child = - neighbor; + auto neighbor_child = neighbor; while (neighbor_child->has_children()) neighbor_child = neighbor_child->child(face_n == 0 ? 1 : 0); @@ -1100,15 +1094,8 @@ namespace Step9 // expensive operation): std::vector neighbor_midpoint_value(1); Tensor<1, dim> projected_gradient; - typename std::vector::active_cell_iterator>:: - const_iterator neighbor_ptr = active_neighbors.begin(); - for (; neighbor_ptr != active_neighbors.end(); ++neighbor_ptr) + for (const auto &neighbor : active_neighbors) { - // First define an abbreviation for the iterator to the active - // neighbor cell: - const typename DoFHandler::active_cell_iterator neighbor = - *neighbor_ptr; - // Then get the center of the neighbor cell and the value of the // finite element function at that point. Note that for this // information we have to reinitialize the FEValues -- 2.39.5