Predicts error after adaptation based on future_fe_indices and CellStatus.
--- /dev/null
+// ---------------------------------------------------------------------
+//
+// Copyright (C) 2019 - 2020 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// The deal.II library is free software; you can use it, redistribute
+// it, and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// The full text of the license can be found in the file LICENSE.md at
+// the top level directory of deal.II.
+//
+// ---------------------------------------------------------------------
+
+#ifndef dealii_distributed_error_predictor_h
+#define dealii_distributed_error_predictor_h
+
+#include <deal.II/base/config.h>
+
+#include <deal.II/base/smartpointer.h>
+
+#include <boost/range/iterator_range.hpp>
+
+#include <vector>
+
+
+DEAL_II_NAMESPACE_OPEN
+
+
+// forward declarations
+#ifndef DOXYGEN
+template <typename Number>
+class Vector;
+
+namespace parallel
+{
+ namespace distributed
+ {
+ template <int dim, int spacedim>
+ class Triangulation;
+ }
+} // namespace parallel
+
+namespace hp
+{
+ template <int dim, int spacedim>
+ class DoFHandler;
+}
+#endif
+
+
+namespace parallel
+{
+ namespace distributed
+ {
+ /**
+ * Predict how current error indicators will change after refinement and
+ * coarsening were to happen on the provided hp::DoFHandler in context of a
+ * parallel::distributed::Triangulation.
+ *
+ * This algorithm follows the same logic as the error prediction algorithm
+ * presented by @cite melenk2001hp and has been implemented in deal.II via
+ * the function hp::Refinement::predict_error(). See the documentation of
+ * this particular function for details on the algorithm and all featured
+ * formulas.
+ *
+ * In theory, the combination of hp::Refinement::predict_error() to predict
+ * how the error will change with parallel::distributed::CellDataTransfer
+ * to transfer data across meshes forms the intended way to apply the
+ * prediction algorithm. However, p4est determines the details of grid
+ * refinement in the parallel distributed case; consequently, it yields more
+ * reliable and trustworthy results when we determine the predicted errors
+ * during the adaptation process. This is achieved with this class, similar
+ * to the parallel::distributed::SolutionTransfer and
+ * parallel::distributed::CellDataTransfer classes.
+ *
+ * Before adaptation happens, one or multiple vectors containing error
+ * estimates for every cell have to be registered with this class using the
+ * prepare_for_coarsening_and_refinement() functions. Performing adaptation
+ * on the triangulation initiates the calculation of the error prediction
+ * based on how p4est performed grid adaptation. After the refinement
+ * process, the predicted errors need to be unpacked on the updated mesh via
+ * one of the unpack() functions.
+ *
+ * The following code snippet demonstrates how to impose hp-adaptivity based
+ * on refinement history in a parallel distributed application:
+ * @code
+ * // [initialization...]
+ * Vector<float> predicted_error_per_cell(triangulation.n_active_cells());
+ * for(unsigned int i = 0; i < triangulation.n_active_cells(); ++i)
+ * predicted_error_per_cell[i] = std::numeric_limits<float>::infinity();
+ *
+ * // [during each refinement step...]
+ * // set h-adaptivity flags
+ * Vector<float> estimated_error_per_cell(triangulation.n_active_cells());
+ * KellyErrorEstimator<dim>::estimate(...);
+ * parallel::distributed::GridRefinement::
+ * refine_and_coarsen_fixed_{number|fraction}(...);
+ *
+ * // set p-adaptivity flags
+ * hp::Refinement::p_adaptivity_from_reference(
+ * hp_dof_handler,
+ * estimated_error_per_cell,
+ * predicted_error_per_cell
+ * std::less<float>(),
+ * std::less<float>());
+ * hp::Refinement::{choose|force}_p_over_h(hp_dof_handler);
+ *
+ * // perform adaptation and predict error for the subsequent adaptation
+ * parallel::distributed::ErrorPredictor<dim> predictor(hp_dof_handler);
+ * predictor.prepare_for_coarsening_and_refinement(estimated_error_per_cell);
+ * triangulation.execute_coarsening_and_refinement();
+ *
+ * // unpack predicted errors
+ * predicted_error_per_cell.reinit(triangulation.n_active_cells());
+ * predictor.unpack(predicted_error_per_cell);
+ * @endcode
+ *
+ * For serialization of predicted errors, use the
+ * parallel::distributed::CellDataTransfer class.
+ *
+ * @ingroup distributed
+ * @author Marc Fehling, 2019 - 2020
+ */
+ template <int dim, int spacedim = dim>
+ class ErrorPredictor
+ {
+ public:
+ /**
+ * Constructor.
+ *
+ * @param[in] dof The hp::DoFHandler on which all operations will
+ * happen. At the time when this constructor is called, the
+ * DoFHandler still points to the triangulation before the
+ * refinement in question happens.
+ */
+ ErrorPredictor(const hp::DoFHandler<dim, spacedim> &dof);
+
+ /**
+ * Prepare the current object for coarsening and refinement.
+ * @p all_in includes all vectors that are to be interpolated onto the
+ * new (refined and/or coarsened) grid.
+ *
+ * As specified in the error prediction algorithm in
+ * hp::Refinement::predict_error(), the control parameters @p gamma_p,
+ * @p gamma_h, @p gamma_n can be used to influence the predicted errors in
+ * case of p-adaptation, h-adaptation, and no adapation, respectively.
+ * Their default values comply to the studies of @cite melenk2001hp.
+ */
+ void
+ prepare_for_coarsening_and_refinement(
+ const std::vector<const Vector<float> *> &all_in,
+ const double gamma_p = std::sqrt(0.4),
+ const double gamma_h = 2.,
+ const double gamma_n = 1.);
+
+ /**
+ * Same as the previous function but for only one discrete function to be
+ * interpolated.
+ */
+ void
+ prepare_for_coarsening_and_refinement(
+ const Vector<float> &in,
+ const double gamma_p = std::sqrt(0.4),
+ const double gamma_h = 2.,
+ const double gamma_n = 1.);
+
+ /**
+ * Interpolate the data previously stored in this object before the mesh
+ * was refined or coarsened onto the current set of cells. Do so for
+ * each of the vectors provided to
+ * prepare_for_coarsening_and_refinement() and write the result into the
+ * given set of vectors.
+ */
+ void
+ unpack(std::vector<Vector<float> *> &all_out);
+
+ /**
+ * Same as the previous function. It interpolates only one function. It
+ * assumes the vectors having the right sizes (i.e.
+ * <tt>in.size()==n_cells_old</tt>, <tt>out.size()==n_cells_refined</tt>)
+ *
+ * Multiple calling of this function is NOT allowed. Interpolating
+ * several functions can be performed in one step by using the above
+ * function.
+ */
+ void
+ unpack(Vector<float> &out);
+
+ private:
+ /**
+ * Pointer to the degree of freedom handler to work with.
+ */
+ SmartPointer<const hp::DoFHandler<dim, spacedim>,
+ ErrorPredictor<dim, spacedim>>
+ dof_handler;
+
+ /**
+ * A vector that stores pointers to all the vectors we are supposed to
+ * copy over from the old to the new mesh.
+ */
+ std::vector<const Vector<float> *> error_indicators;
+
+ /**
+ * The handle that the Triangulation has assigned to this object
+ * with which we can access our memory offset and our pack function.
+ */
+ unsigned int handle;
+
+ /**
+ * Control parameters for the prediction algorithm.
+ */
+ double gamma_p, gamma_h, gamma_n;
+
+ /**
+ * A callback function used to pack the data on the current mesh into
+ * objects that can later be retrieved after refinement, coarsening and
+ * repartitioning.
+ */
+ std::vector<char>
+ pack_callback(
+ const typename Triangulation<dim, spacedim>::cell_iterator &cell,
+ const typename Triangulation<dim, spacedim>::CellStatus status);
+
+ /**
+ * A callback function used to unpack the data on the current mesh that
+ * has been packed up previously on the mesh before refinement,
+ * coarsening and repartitioning.
+ */
+ void
+ unpack_callback(
+ const typename Triangulation<dim, spacedim>::cell_iterator &cell,
+ const typename Triangulation<dim, spacedim>::CellStatus status,
+ const boost::iterator_range<std::vector<char>::const_iterator>
+ & data_range,
+ std::vector<Vector<float> *> &all_out);
+
+
+ /**
+ * Registers the pack_callback() function to the
+ * parallel::distributed::Triangulation that has been assigned to the
+ * DoFHandler class member and stores the returning handle.
+ */
+ void
+ register_data_attach();
+ };
+ } // namespace distributed
+} // namespace parallel
+
+
+DEAL_II_NAMESPACE_CLOSE
+
+#endif
/**
* Predict how the current @p error_indicators will adapt after refinement
- * and coarsening has happened on the provided @p dof_handler, and write its
+ * and coarsening were to happen on the provided @p dof_handler, and write its
* results to @p predicted_errors. Each entry of @p error_indicators and
* @p predicted_errors corresponds to an active cell on the underlying
* Triangulation, thus each container has to be of size
* // set h-adaptivity flags
* Vector<float> estimated_error_per_cell(triangulation.n_active_cells());
* KellyErrorEstimator::estimate(...);
- * GridRefinemet::refine_and_coarsen_fixed_fraction(...);
+ * GridRefinemet::refine_and_coarsen_fixed_{number|fraction}(...);
*
* // set p-adaptivity flags
* hp::Refinement::p_adaptivity_from_reference(
grid_refinement.cc
cell_weights.cc
cell_data_transfer.cc
+ error_predictor.cc
fully_distributed_tria.cc
solution_transfer.cc
tria.cc
grid_refinement.inst.in
cell_weights.inst.in
cell_data_transfer.inst.in
+ error_predictor.inst.in
fully_distributed_tria.inst.in
solution_transfer.inst.in
tria.inst.in
--- /dev/null
+// ---------------------------------------------------------------------
+//
+// Copyright (C) 2019 - 2020 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// The deal.II library is free software; you can use it, redistribute
+// it, and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// The full text of the license can be found in the file LICENSE.md at
+// the top level directory of deal.II.
+//
+// ---------------------------------------------------------------------
+
+
+#include <deal.II/base/config.h>
+
+#ifdef DEAL_II_WITH_P4EST
+
+# include <deal.II/distributed/error_predictor.h>
+# include <deal.II/distributed/tria.h>
+
+# include <deal.II/dofs/dof_accessor.h>
+# include <deal.II/dofs/dof_tools.h>
+
+# include <deal.II/grid/tria_accessor.h>
+# include <deal.II/grid/tria_iterator.h>
+
+# include <deal.II/hp/dof_handler.h>
+
+# include <deal.II/lac/block_vector.h>
+# include <deal.II/lac/la_parallel_block_vector.h>
+# include <deal.II/lac/la_parallel_vector.h>
+# include <deal.II/lac/petsc_block_vector.h>
+# include <deal.II/lac/petsc_vector.h>
+# include <deal.II/lac/trilinos_parallel_block_vector.h>
+# include <deal.II/lac/trilinos_vector.h>
+# include <deal.II/lac/vector.h>
+
+# include <functional>
+# include <numeric>
+
+
+DEAL_II_NAMESPACE_OPEN
+
+
+namespace parallel
+{
+ namespace distributed
+ {
+ template <int dim, int spacedim>
+ ErrorPredictor<dim, spacedim>::ErrorPredictor(
+ const hp::DoFHandler<dim, spacedim> &dof)
+ : dof_handler(&dof, typeid(*this).name())
+ , handle(numbers::invalid_unsigned_int)
+ , gamma_p(0.)
+ , gamma_h(0.)
+ , gamma_n(0.)
+ {
+ Assert(
+ (dynamic_cast<const parallel::distributed::Triangulation<dim, spacedim>
+ *>(&dof_handler->get_triangulation()) != nullptr),
+ ExcMessage(
+ "parallel::distributed::ErrorPredictor requires a parallel::distributed::Triangulation object."));
+ }
+
+
+
+ template <int dim, int spacedim>
+ void
+ ErrorPredictor<dim, spacedim>::prepare_for_coarsening_and_refinement(
+ const std::vector<const Vector<float> *> &all_in,
+ const double gamma_p,
+ const double gamma_h,
+ const double gamma_n)
+ {
+ error_indicators = all_in;
+ this->gamma_p = gamma_p;
+ this->gamma_h = gamma_h;
+ this->gamma_n = gamma_n;
+ register_data_attach();
+ }
+
+
+
+ template <int dim, int spacedim>
+ void
+ ErrorPredictor<dim, spacedim>::register_data_attach()
+ {
+ // TODO: casting away constness is bad
+ parallel::distributed::Triangulation<dim, spacedim> *tria =
+ (dynamic_cast<parallel::distributed::Triangulation<dim, spacedim> *>(
+ const_cast<dealii::Triangulation<dim, spacedim> *>(
+ &dof_handler->get_triangulation())));
+ Assert(tria != nullptr, ExcInternalError());
+
+ handle = tria->register_data_attach(
+ [this](const typename Triangulation<dim, spacedim>::cell_iterator &cell,
+ const typename Triangulation<dim, spacedim>::CellStatus status) {
+ return this->pack_callback(cell, status);
+ },
+ /*returns_variable_size_data=*/false);
+ }
+
+
+
+ template <int dim, int spacedim>
+ void
+ ErrorPredictor<dim, spacedim>::prepare_for_coarsening_and_refinement(
+ const Vector<float> &in,
+ const double gamma_p,
+ const double gamma_h,
+ const double gamma_n)
+ {
+ std::vector<const Vector<float> *> all_in(1, &in);
+ prepare_for_coarsening_and_refinement(all_in, gamma_p, gamma_h, gamma_n);
+ }
+
+
+
+ template <int dim, int spacedim>
+ void
+ ErrorPredictor<dim, spacedim>::unpack(std::vector<Vector<float> *> &all_out)
+ {
+ Assert(error_indicators.size() == all_out.size(),
+ ExcDimensionMismatch(error_indicators.size(), all_out.size()));
+
+ // TODO: casting away constness is bad
+ parallel::distributed::Triangulation<dim, spacedim> *tria =
+ (dynamic_cast<parallel::distributed::Triangulation<dim, spacedim> *>(
+ const_cast<dealii::Triangulation<dim, spacedim> *>(
+ &dof_handler->get_triangulation())));
+ Assert(tria != nullptr, ExcInternalError());
+
+ tria->notify_ready_to_unpack(
+ handle,
+ [this, &all_out](
+ const typename Triangulation<dim, spacedim>::cell_iterator &cell,
+ const typename Triangulation<dim, spacedim>::CellStatus status,
+ const boost::iterator_range<std::vector<char>::const_iterator>
+ &data_range) {
+ this->unpack_callback(cell, status, data_range, all_out);
+ });
+
+ for (const auto &out : all_out)
+ out->compress(::dealii::VectorOperation::insert);
+
+ error_indicators.clear();
+ }
+
+
+
+ template <int dim, int spacedim>
+ void
+ ErrorPredictor<dim, spacedim>::unpack(Vector<float> &out)
+ {
+ std::vector<Vector<float> *> all_out(1, &out);
+ unpack(all_out);
+ }
+
+
+
+ template <int dim, int spacedim>
+ std::vector<char>
+ ErrorPredictor<dim, spacedim>::pack_callback(
+ const typename Triangulation<dim, spacedim>::cell_iterator &cell_,
+ const typename Triangulation<dim, spacedim>::CellStatus status)
+ {
+ typename hp::DoFHandler<dim, spacedim>::cell_iterator cell(*cell_,
+ dof_handler);
+
+ // create buffer for each individual input vector
+ std::vector<float> predicted_errors(error_indicators.size());
+
+ auto predicted_error_it = predicted_errors.begin();
+ auto estimated_error_it = error_indicators.cbegin();
+ for (; estimated_error_it != error_indicators.cend();
+ ++predicted_error_it, ++estimated_error_it)
+ switch (status)
+ {
+ case parallel::distributed::Triangulation<dim,
+ spacedim>::CELL_PERSIST:
+ {
+ if (cell->future_fe_index_set())
+ {
+ const int degree_difference =
+ dof_handler->get_fe_collection()[cell->future_fe_index()]
+ .degree -
+ cell->get_fe().degree;
+
+ *predicted_error_it =
+ (**estimated_error_it)[cell->active_cell_index()] *
+ std::pow(gamma_p, degree_difference);
+ }
+ else
+ {
+ *predicted_error_it =
+ (**estimated_error_it)[cell->active_cell_index()] *
+ gamma_n;
+ }
+ break;
+ }
+
+ case parallel::distributed::Triangulation<dim,
+ spacedim>::CELL_REFINE:
+ {
+ // Determine the exponent by the finite element degree on the
+ // adapted mesh.
+ const unsigned int future_fe_degree =
+ dof_handler->get_fe_collection()[cell->future_fe_index()]
+ .degree;
+
+ *predicted_error_it =
+ (**estimated_error_it)[cell->active_cell_index()] *
+ (gamma_h * std::pow(.5, future_fe_degree));
+
+ // If the future fe index differs from the active one, also take
+ // into account p-adaptation.
+ if (cell->future_fe_index_set())
+ *predicted_error_it *=
+ std::pow(gamma_p,
+ static_cast<int>(future_fe_degree -
+ cell->get_fe().degree));
+
+ break;
+ }
+
+ case parallel::distributed::Triangulation<dim,
+ spacedim>::CELL_COARSEN:
+ {
+ // First figure out which finite element will be assigned to the
+ // parent cell after h-adaptation analogously to
+ // dealii::internal::hp::DoFHandlerImplementation::Implementation::
+ // collect_fe_indices_on_cells_to_be_refined()
+ std::set<unsigned int> fe_indices_children;
+ for (unsigned int child_index = 0;
+ child_index < cell->n_children();
+ ++child_index)
+ {
+ const auto child = cell->child(child_index);
+ Assert(child->is_active() && child->coarsen_flag_set(),
+ typename dealii::Triangulation<
+ dim>::ExcInconsistentCoarseningFlags());
+
+ fe_indices_children.insert(child->future_fe_index());
+ }
+
+ const unsigned int future_fe_index =
+ dof_handler->get_fe_collection().find_dominated_fe_extended(
+ fe_indices_children, /*codim=*/0);
+
+ const unsigned int future_fe_degree =
+ dof_handler->get_fe_collection()[future_fe_index].degree;
+
+ // Then determine the actually contirbution to the predicted
+ // error of every single cells that is about to be coarsened.
+ float sqrsum_of_predicted_errors = 0.;
+ float predicted_error = 0.;
+ int degree_difference = 0;
+ for (unsigned int child_index = 0;
+ child_index < cell->n_children();
+ ++child_index)
+ {
+ const auto child = cell->child(child_index);
+
+ predicted_error =
+ (**estimated_error_it)[child->active_cell_index()] /
+ (gamma_h * std::pow(.5, future_fe_degree));
+
+ degree_difference =
+ future_fe_degree - child->get_fe().degree;
+
+ if (degree_difference != 0)
+ predicted_error *= std::pow(gamma_p, degree_difference);
+
+ sqrsum_of_predicted_errors +=
+ predicted_error * predicted_error;
+ }
+ *predicted_error_it = std::sqrt(sqrsum_of_predicted_errors);
+
+ break;
+ }
+
+ default:
+ Assert(false, ExcInternalError());
+ break;
+ }
+
+ // We don't have to pack the whole container if there is just one entry.
+ if (error_indicators.size() == 1)
+ return Utilities::pack(predicted_errors[0],
+ /*allow_compression=*/false);
+ else
+ return Utilities::pack(predicted_errors, /*allow_compression=*/false);
+ }
+
+
+
+ template <int dim, int spacedim>
+ void
+ ErrorPredictor<dim, spacedim>::unpack_callback(
+ const typename Triangulation<dim, spacedim>::cell_iterator &cell,
+ const typename Triangulation<dim, spacedim>::CellStatus status,
+ const boost::iterator_range<std::vector<char>::const_iterator>
+ & data_range,
+ std::vector<Vector<float> *> &all_out)
+ {
+ std::vector<float> predicted_errors;
+
+ if (all_out.size() == 1)
+ predicted_errors.push_back(
+ Utilities::unpack<float>(data_range.begin(),
+ data_range.end(),
+ /*allow_compression=*/false));
+ else
+ predicted_errors =
+ Utilities::unpack<std::vector<float>>(data_range.begin(),
+ data_range.end(),
+ /*allow_compression=*/false);
+
+ Assert(predicted_errors.size() == all_out.size(), ExcInternalError());
+
+ auto it_input = predicted_errors.cbegin();
+ auto it_output = all_out.begin();
+ for (; it_input != predicted_errors.cend(); ++it_input, ++it_output)
+ switch (status)
+ {
+ case parallel::distributed::Triangulation<dim,
+ spacedim>::CELL_PERSIST:
+ case parallel::distributed::Triangulation<dim,
+ spacedim>::CELL_COARSEN:
+ (**it_output)[cell->active_cell_index()] = *it_input;
+ break;
+
+
+ case parallel::distributed::Triangulation<dim,
+ spacedim>::CELL_REFINE:
+ for (unsigned int child_index = 0;
+ child_index < cell->n_children();
+ ++child_index)
+ (**it_output)[cell->child(child_index)->active_cell_index()] =
+ (*it_input) / std::sqrt(cell->n_children());
+ break;
+
+ default:
+ Assert(false, ExcInternalError());
+ break;
+ }
+ }
+ } // namespace distributed
+} // namespace parallel
+
+
+// explicit instantiations
+# include "error_predictor.inst"
+
+DEAL_II_NAMESPACE_CLOSE
+
+#endif /* DEAL_II_WITH_P4EST */
--- /dev/null
+// ---------------------------------------------------------------------
+//
+// Copyright (C) 2010 - 2018 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// The deal.II library is free software; you can use it, redistribute
+// it, and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// The full text of the license can be found in the file LICENSE.md at
+// the top level directory of deal.II.
+//
+// ---------------------------------------------------------------------
+
+
+
+for (deal_II_dimension : DIMENSIONS; deal_II_space_dimension : SPACE_DIMENSIONS)
+ {
+ namespace parallel
+ \{
+ namespace distributed
+ \{
+#if deal_II_dimension <= deal_II_space_dimension
+ template class ErrorPredictor<deal_II_dimension,
+ deal_II_space_dimension>;
+#endif
+ \}
+ \}
+ }
--- /dev/null
+// ---------------------------------------------------------------------
+//
+// Copyright (C) 2019 - 2020 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// The deal.II library is free software; you can use it, redistribute
+// it, and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// The full text of the license can be found in the file LICENSE.md at
+// the top level directory of deal.II.
+//
+// ---------------------------------------------------------------------
+
+
+
+// Test to check if ErrorPredictor works in parallel with hp::DoFHandler.
+// This tests is based on hp/error_prediction.cc
+
+
+#include <deal.II/distributed/error_predictor.h>
+#include <deal.II/distributed/tria.h>
+
+#include <deal.II/dofs/dof_tools.h>
+
+#include <deal.II/fe/fe_q.h>
+
+#include <deal.II/grid/grid_generator.h>
+
+#include <deal.II/hp/dof_handler.h>
+
+#include <deal.II/lac/vector.h>
+
+#include "../tests.h"
+
+
+template <int dim>
+void
+test()
+{
+ const unsigned int myid = Utilities::MPI::this_mpi_process(MPI_COMM_WORLD);
+
+ const unsigned int n_cells = 4;
+
+ // ------ setup ------
+ parallel::distributed::Triangulation<dim> tria(MPI_COMM_WORLD);
+ std::vector<unsigned int> rep(dim, 1);
+ rep[0] = n_cells;
+ Point<dim> p1, p2;
+ for (unsigned int d = 0; d < dim; ++d)
+ {
+ p1[d] = 0;
+ p2[d] = (d == 0) ? n_cells : 1;
+ }
+ GridGenerator::subdivided_hyper_rectangle(tria, rep, p1, p2);
+
+ {
+ auto first = tria.begin(0);
+ if (first->id().to_string() == "0_0:")
+ first->set_refine_flag();
+ }
+ tria.execute_coarsening_and_refinement();
+
+ hp::FECollection<dim> fes;
+ for (unsigned int d = 1; d <= 3; ++d)
+ fes.push_back(FE_Q<dim>(d));
+
+ hp::DoFHandler<dim> dh(tria);
+ dh.set_fe(fes);
+ for (auto cell = dh.begin(0); cell != dh.end(0); ++cell)
+ if (cell->id().to_string() == "0_0:")
+ {
+ // h-coarsening
+ for (unsigned int i = 0; i < cell->n_children(); ++i)
+ if (cell->child(i)->is_locally_owned())
+ cell->child(i)->set_coarsen_flag();
+ }
+ else if (cell->id().to_string() == "1_0:")
+ {
+ // h-refinement
+ if (cell->is_locally_owned())
+ cell->set_refine_flag();
+ }
+ else if (cell->id().to_string() == "2_0:")
+ {
+ // p-refinement
+ if (cell->is_locally_owned())
+ cell->set_future_fe_index(2);
+ }
+
+ // ----- prepare error indicators -----
+ Vector<float> error_indicators(tria.n_active_cells());
+ for (unsigned int i = 0; i < error_indicators.size(); ++i)
+ error_indicators(i) = 10.;
+
+ // ----- verify ------
+ deallog << "pre_adaptation" << std::endl;
+ for (const auto &cell : dh.active_cell_iterators())
+ if (cell->is_locally_owned())
+ {
+ deallog << " cell:" << cell->id().to_string()
+ << " fe_deg:" << cell->get_fe().degree
+ << " error:" << error_indicators[cell->active_cell_index()];
+
+ if (cell->coarsen_flag_set())
+ deallog << " coarsening";
+ else if (cell->refine_flag_set())
+ deallog << " refining";
+
+ if (cell->future_fe_index_set())
+ deallog << " future_fe_deg:" << fes[cell->future_fe_index()].degree;
+
+ deallog << std::endl;
+ }
+
+ // ----- execute adaptation -----
+ parallel::distributed::ErrorPredictor<dim> predictor(dh);
+
+ predictor.prepare_for_coarsening_and_refinement(error_indicators,
+ /*gamma_p=*/0.5,
+ /*gamma_h=*/1.,
+ /*gamma_n=*/1.);
+ tria.execute_coarsening_and_refinement();
+
+ Vector<float> predicted_errors(tria.n_active_cells());
+ predictor.unpack(predicted_errors);
+
+ // ------ verify ------
+ deallog << "post_adaptation" << std::endl;
+ for (const auto &cell : dh.active_cell_iterators())
+ if (cell->is_locally_owned())
+ deallog << " cell:" << cell->id().to_string()
+ << " predicted:" << predicted_errors(cell->active_cell_index())
+ << std::endl;
+
+ // make sure no processor is hanging
+ MPI_Barrier(MPI_COMM_WORLD);
+
+ deallog << "OK" << std::endl;
+}
+
+
+
+int
+main(int argc, char *argv[])
+{
+ Utilities::MPI::MPI_InitFinalize mpi_initialization(argc, argv, 1);
+ MPILogInitAll log;
+
+ deallog.push("2d");
+ test<2>();
+ deallog.pop();
+ deallog.push("3d");
+ test<3>();
+ deallog.pop();
+}
--- /dev/null
+
+DEAL:0:2d::pre_adaptation
+DEAL:0:2d:: cell:1_0: fe_deg:1 error:10.0000 refining
+DEAL:0:2d:: cell:2_0: fe_deg:1 error:10.0000 future_fe_deg:3
+DEAL:0:2d:: cell:3_0: fe_deg:1 error:10.0000
+DEAL:0:2d:: cell:0_1:0 fe_deg:1 error:10.0000 coarsening
+DEAL:0:2d:: cell:0_1:1 fe_deg:1 error:10.0000 coarsening
+DEAL:0:2d:: cell:0_1:2 fe_deg:1 error:10.0000 coarsening
+DEAL:0:2d:: cell:0_1:3 fe_deg:1 error:10.0000 coarsening
+DEAL:0:2d::post_adaptation
+DEAL:0:2d:: cell:0_0: predicted:40.0000
+DEAL:0:2d:: cell:2_0: predicted:2.50000
+DEAL:0:2d:: cell:3_0: predicted:10.0000
+DEAL:0:2d:: cell:1_1:0 predicted:2.50000
+DEAL:0:2d:: cell:1_1:1 predicted:2.50000
+DEAL:0:2d:: cell:1_1:2 predicted:2.50000
+DEAL:0:2d:: cell:1_1:3 predicted:2.50000
+DEAL:0:2d::OK
+DEAL:0:3d::pre_adaptation
+DEAL:0:3d:: cell:1_0: fe_deg:1 error:10.0000 refining
+DEAL:0:3d:: cell:2_0: fe_deg:1 error:10.0000 future_fe_deg:3
+DEAL:0:3d:: cell:3_0: fe_deg:1 error:10.0000
+DEAL:0:3d:: cell:0_1:0 fe_deg:1 error:10.0000 coarsening
+DEAL:0:3d:: cell:0_1:1 fe_deg:1 error:10.0000 coarsening
+DEAL:0:3d:: cell:0_1:2 fe_deg:1 error:10.0000 coarsening
+DEAL:0:3d:: cell:0_1:3 fe_deg:1 error:10.0000 coarsening
+DEAL:0:3d:: cell:0_1:4 fe_deg:1 error:10.0000 coarsening
+DEAL:0:3d:: cell:0_1:5 fe_deg:1 error:10.0000 coarsening
+DEAL:0:3d:: cell:0_1:6 fe_deg:1 error:10.0000 coarsening
+DEAL:0:3d:: cell:0_1:7 fe_deg:1 error:10.0000 coarsening
+DEAL:0:3d::post_adaptation
+DEAL:0:3d:: cell:0_0: predicted:56.5685
+DEAL:0:3d:: cell:2_0: predicted:2.50000
+DEAL:0:3d:: cell:3_0: predicted:10.0000
+DEAL:0:3d:: cell:1_1:0 predicted:1.76777
+DEAL:0:3d:: cell:1_1:1 predicted:1.76777
+DEAL:0:3d:: cell:1_1:2 predicted:1.76777
+DEAL:0:3d:: cell:1_1:3 predicted:1.76777
+DEAL:0:3d:: cell:1_1:4 predicted:1.76777
+DEAL:0:3d:: cell:1_1:5 predicted:1.76777
+DEAL:0:3d:: cell:1_1:6 predicted:1.76777
+DEAL:0:3d:: cell:1_1:7 predicted:1.76777
+DEAL:0:3d::OK
--- /dev/null
+
+DEAL:0:2d::pre_adaptation
+DEAL:0:2d::post_adaptation
+DEAL:0:2d:: cell:0_0: predicted:40.0000
+DEAL:0:2d::OK
+DEAL:0:3d::pre_adaptation
+DEAL:0:3d::post_adaptation
+DEAL:0:3d:: cell:0_0: predicted:56.5685
+DEAL:0:3d::OK
+
+DEAL:1:2d::pre_adaptation
+DEAL:1:2d:: cell:0_1:0 fe_deg:1 error:10.0000 coarsening
+DEAL:1:2d:: cell:0_1:1 fe_deg:1 error:10.0000 coarsening
+DEAL:1:2d:: cell:0_1:2 fe_deg:1 error:10.0000 coarsening
+DEAL:1:2d:: cell:0_1:3 fe_deg:1 error:10.0000 coarsening
+DEAL:1:2d::post_adaptation
+DEAL:1:2d:: cell:1_1:0 predicted:2.50000
+DEAL:1:2d:: cell:1_1:1 predicted:2.50000
+DEAL:1:2d:: cell:1_1:2 predicted:2.50000
+DEAL:1:2d:: cell:1_1:3 predicted:2.50000
+DEAL:1:2d::OK
+DEAL:1:3d::pre_adaptation
+DEAL:1:3d:: cell:0_1:0 fe_deg:1 error:10.0000 coarsening
+DEAL:1:3d:: cell:0_1:1 fe_deg:1 error:10.0000 coarsening
+DEAL:1:3d:: cell:0_1:2 fe_deg:1 error:10.0000 coarsening
+DEAL:1:3d:: cell:0_1:3 fe_deg:1 error:10.0000 coarsening
+DEAL:1:3d:: cell:0_1:4 fe_deg:1 error:10.0000 coarsening
+DEAL:1:3d:: cell:0_1:5 fe_deg:1 error:10.0000 coarsening
+DEAL:1:3d:: cell:0_1:6 fe_deg:1 error:10.0000 coarsening
+DEAL:1:3d:: cell:0_1:7 fe_deg:1 error:10.0000 coarsening
+DEAL:1:3d::post_adaptation
+DEAL:1:3d:: cell:1_1:0 predicted:1.76777
+DEAL:1:3d:: cell:1_1:1 predicted:1.76777
+DEAL:1:3d:: cell:1_1:2 predicted:1.76777
+DEAL:1:3d:: cell:1_1:3 predicted:1.76777
+DEAL:1:3d:: cell:1_1:4 predicted:1.76777
+DEAL:1:3d:: cell:1_1:5 predicted:1.76777
+DEAL:1:3d:: cell:1_1:6 predicted:1.76777
+DEAL:1:3d:: cell:1_1:7 predicted:1.76777
+DEAL:1:3d::OK
+
+
+DEAL:2:2d::pre_adaptation
+DEAL:2:2d:: cell:1_0: fe_deg:1 error:10.0000 refining
+DEAL:2:2d::post_adaptation
+DEAL:2:2d::OK
+DEAL:2:3d::pre_adaptation
+DEAL:2:3d::post_adaptation
+DEAL:2:3d::OK
+
+
+DEAL:3:2d::pre_adaptation
+DEAL:3:2d:: cell:2_0: fe_deg:1 error:10.0000 future_fe_deg:3
+DEAL:3:2d:: cell:3_0: fe_deg:1 error:10.0000
+DEAL:3:2d::post_adaptation
+DEAL:3:2d:: cell:2_0: predicted:2.50000
+DEAL:3:2d:: cell:3_0: predicted:10.0000
+DEAL:3:2d::OK
+DEAL:3:3d::pre_adaptation
+DEAL:3:3d:: cell:1_0: fe_deg:1 error:10.0000 refining
+DEAL:3:3d:: cell:2_0: fe_deg:1 error:10.0000 future_fe_deg:3
+DEAL:3:3d:: cell:3_0: fe_deg:1 error:10.0000
+DEAL:3:3d::post_adaptation
+DEAL:3:3d:: cell:2_0: predicted:2.50000
+DEAL:3:3d:: cell:3_0: predicted:10.0000
+DEAL:3:3d::OK
+
--- /dev/null
+// ---------------------------------------------------------------------
+//
+// Copyright (C) 2019 - 2020 by the deal.II authors
+//
+// This file is part of the deal.II library.
+//
+// The deal.II library is free software; you can use it, redistribute
+// it, and/or modify it under the terms of the GNU Lesser General
+// Public License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+// The full text of the license can be found in the file LICENSE.md at
+// the top level directory of deal.II.
+//
+// ---------------------------------------------------------------------
+
+
+
+// Test to check if ErrorPredictor works in parallel with hp::DoFHandler.
+// This tests is based on hp/error_prediction.cc
+
+
+#include <deal.II/distributed/error_predictor.h>
+#include <deal.II/distributed/tria.h>
+
+#include <deal.II/dofs/dof_tools.h>
+
+#include <deal.II/fe/fe_q.h>
+
+#include <deal.II/grid/grid_generator.h>
+
+#include <deal.II/hp/dof_handler.h>
+
+#include <deal.II/lac/vector.h>
+
+#include "../tests.h"
+
+
+template <int dim>
+void
+test()
+{
+ const unsigned int myid = Utilities::MPI::this_mpi_process(MPI_COMM_WORLD);
+
+ const unsigned int n_cells = 4;
+
+ // ------ setup ------
+ parallel::distributed::Triangulation<dim> tria(MPI_COMM_WORLD);
+ std::vector<unsigned int> rep(dim, 1);
+ rep[0] = n_cells;
+ Point<dim> p1, p2;
+ for (unsigned int d = 0; d < dim; ++d)
+ {
+ p1[d] = 0;
+ p2[d] = (d == 0) ? n_cells : 1;
+ }
+ GridGenerator::subdivided_hyper_rectangle(tria, rep, p1, p2);
+
+ for (auto cell = tria.begin(0); cell != tria.end(0); ++cell)
+ if (cell->id().to_string() == "0_0:" || cell->id().to_string() == "1_0:")
+ cell->set_refine_flag();
+ tria.execute_coarsening_and_refinement();
+
+ hp::FECollection<dim> fes;
+ for (unsigned int d = 1; d <= 3; ++d)
+ fes.push_back(FE_Q<dim>(d));
+
+ hp::DoFHandler<dim> dh(tria);
+ dh.set_fe(fes);
+ for (const auto &cell : dh.active_cell_iterators())
+ {
+ // set active fe index
+ if (cell->is_locally_owned())
+ cell->set_active_fe_index(1);
+ }
+ for (auto cell = dh.begin(0); cell != dh.end(0); ++cell)
+ {
+ // set refinement/coarsening flags
+ if (cell->id().to_string() == "0_0:")
+ {
+ // h-coarsening and p-refinement
+ for (unsigned int i = 0; i < cell->n_children(); ++i)
+ if (cell->child(i)->is_locally_owned())
+ {
+ cell->child(i)->set_coarsen_flag();
+ cell->child(i)->set_future_fe_index(2);
+ }
+ }
+ else if (cell->id().to_string() == "1_0:")
+ {
+ // h-coarsening and p-coarsening
+ for (unsigned int i = 0; i < cell->n_children(); ++i)
+ if (cell->child(i)->is_locally_owned())
+ {
+ cell->child(i)->set_coarsen_flag();
+ cell->child(i)->set_future_fe_index(0);
+ }
+ }
+ else if (cell->id().to_string() == "2_0:")
+ {
+ // h-refinement and p-refinement
+ if (cell->is_locally_owned())
+ {
+ cell->set_refine_flag();
+ cell->set_future_fe_index(2);
+ }
+ }
+ else if (cell->id().to_string() == "3_0:")
+ {
+ // h-refinement and p-coarsening
+ if (cell->is_locally_owned())
+ {
+ cell->set_refine_flag();
+ cell->set_future_fe_index(0);
+ }
+ }
+ }
+
+ // ----- prepare error indicators -----
+ Vector<float> error_indicators(tria.n_active_cells());
+ for (unsigned int i = 0; i < error_indicators.size(); ++i)
+ error_indicators(i) = 10.;
+
+ // ----- verify ------
+ deallog << "pre_adaptation" << std::endl;
+ for (const auto &cell : dh.active_cell_iterators())
+ if (cell->is_locally_owned())
+ {
+ deallog << " cell:" << cell->id().to_string()
+ << " fe_deg:" << cell->get_fe().degree
+ << " error:" << error_indicators[cell->active_cell_index()];
+
+ if (cell->coarsen_flag_set())
+ deallog << " coarsening";
+ else if (cell->refine_flag_set())
+ deallog << " refining";
+
+ if (cell->future_fe_index_set())
+ deallog << " future_fe_deg:" << fes[cell->future_fe_index()].degree;
+
+ deallog << std::endl;
+ }
+
+ // ----- execute adaptation -----
+ parallel::distributed::ErrorPredictor<dim> predictor(dh);
+
+ predictor.prepare_for_coarsening_and_refinement(error_indicators,
+ /*gamma_p=*/0.5,
+ /*gamma_h=*/1.,
+ /*gamma_n=*/1.);
+ tria.execute_coarsening_and_refinement();
+
+ Vector<float> predicted_errors(tria.n_active_cells());
+ predictor.unpack(predicted_errors);
+
+ // ------ verify ------
+ deallog << "post_adaptation" << std::endl;
+ for (const auto &cell : dh.active_cell_iterators())
+ if (cell->is_locally_owned())
+ deallog << " cell:" << cell->id().to_string()
+ << " predicted:" << predicted_errors(cell->active_cell_index())
+ << std::endl;
+
+ // make sure no processor is hanging
+ MPI_Barrier(MPI_COMM_WORLD);
+
+ deallog << "OK" << std::endl;
+}
+
+
+
+int
+main(int argc, char *argv[])
+{
+ Utilities::MPI::MPI_InitFinalize mpi_initialization(argc, argv, 1);
+ MPILogInitAll log;
+
+ deallog.push("2d");
+ test<2>();
+ deallog.pop();
+ deallog.push("3d");
+ test<3>();
+ deallog.pop();
+}
--- /dev/null
+
+DEAL:0:2d::pre_adaptation
+DEAL:0:2d:: cell:2_0: fe_deg:2 error:10.0000 refining future_fe_deg:3
+DEAL:0:2d:: cell:3_0: fe_deg:2 error:10.0000 refining future_fe_deg:1
+DEAL:0:2d:: cell:0_1:0 fe_deg:2 error:10.0000 coarsening future_fe_deg:3
+DEAL:0:2d:: cell:0_1:1 fe_deg:2 error:10.0000 coarsening future_fe_deg:3
+DEAL:0:2d:: cell:0_1:2 fe_deg:2 error:10.0000 coarsening future_fe_deg:3
+DEAL:0:2d:: cell:0_1:3 fe_deg:2 error:10.0000 coarsening future_fe_deg:3
+DEAL:0:2d:: cell:1_1:0 fe_deg:2 error:10.0000 coarsening future_fe_deg:1
+DEAL:0:2d:: cell:1_1:1 fe_deg:2 error:10.0000 coarsening future_fe_deg:1
+DEAL:0:2d:: cell:1_1:2 fe_deg:2 error:10.0000 coarsening future_fe_deg:1
+DEAL:0:2d:: cell:1_1:3 fe_deg:2 error:10.0000 coarsening future_fe_deg:1
+DEAL:0:2d::post_adaptation
+DEAL:0:2d:: cell:0_0: predicted:80.0000
+DEAL:0:2d:: cell:1_0: predicted:80.0000
+DEAL:0:2d:: cell:2_1:0 predicted:0.312500
+DEAL:0:2d:: cell:2_1:1 predicted:0.312500
+DEAL:0:2d:: cell:2_1:2 predicted:0.312500
+DEAL:0:2d:: cell:2_1:3 predicted:0.312500
+DEAL:0:2d:: cell:3_1:0 predicted:5.00000
+DEAL:0:2d:: cell:3_1:1 predicted:5.00000
+DEAL:0:2d:: cell:3_1:2 predicted:5.00000
+DEAL:0:2d:: cell:3_1:3 predicted:5.00000
+DEAL:0:2d::OK
+DEAL:0:3d::pre_adaptation
+DEAL:0:3d:: cell:2_0: fe_deg:2 error:10.0000 refining future_fe_deg:3
+DEAL:0:3d:: cell:3_0: fe_deg:2 error:10.0000 refining future_fe_deg:1
+DEAL:0:3d:: cell:0_1:0 fe_deg:2 error:10.0000 coarsening future_fe_deg:3
+DEAL:0:3d:: cell:0_1:1 fe_deg:2 error:10.0000 coarsening future_fe_deg:3
+DEAL:0:3d:: cell:0_1:2 fe_deg:2 error:10.0000 coarsening future_fe_deg:3
+DEAL:0:3d:: cell:0_1:3 fe_deg:2 error:10.0000 coarsening future_fe_deg:3
+DEAL:0:3d:: cell:0_1:4 fe_deg:2 error:10.0000 coarsening future_fe_deg:3
+DEAL:0:3d:: cell:0_1:5 fe_deg:2 error:10.0000 coarsening future_fe_deg:3
+DEAL:0:3d:: cell:0_1:6 fe_deg:2 error:10.0000 coarsening future_fe_deg:3
+DEAL:0:3d:: cell:0_1:7 fe_deg:2 error:10.0000 coarsening future_fe_deg:3
+DEAL:0:3d:: cell:1_1:0 fe_deg:2 error:10.0000 coarsening future_fe_deg:1
+DEAL:0:3d:: cell:1_1:1 fe_deg:2 error:10.0000 coarsening future_fe_deg:1
+DEAL:0:3d:: cell:1_1:2 fe_deg:2 error:10.0000 coarsening future_fe_deg:1
+DEAL:0:3d:: cell:1_1:3 fe_deg:2 error:10.0000 coarsening future_fe_deg:1
+DEAL:0:3d:: cell:1_1:4 fe_deg:2 error:10.0000 coarsening future_fe_deg:1
+DEAL:0:3d:: cell:1_1:5 fe_deg:2 error:10.0000 coarsening future_fe_deg:1
+DEAL:0:3d:: cell:1_1:6 fe_deg:2 error:10.0000 coarsening future_fe_deg:1
+DEAL:0:3d:: cell:1_1:7 fe_deg:2 error:10.0000 coarsening future_fe_deg:1
+DEAL:0:3d::post_adaptation
+DEAL:0:3d:: cell:0_0: predicted:113.137
+DEAL:0:3d:: cell:1_0: predicted:113.137
+DEAL:0:3d:: cell:2_1:0 predicted:0.220971
+DEAL:0:3d:: cell:2_1:1 predicted:0.220971
+DEAL:0:3d:: cell:2_1:2 predicted:0.220971
+DEAL:0:3d:: cell:2_1:3 predicted:0.220971
+DEAL:0:3d:: cell:2_1:4 predicted:0.220971
+DEAL:0:3d:: cell:2_1:5 predicted:0.220971
+DEAL:0:3d:: cell:2_1:6 predicted:0.220971
+DEAL:0:3d:: cell:2_1:7 predicted:0.220971
+DEAL:0:3d:: cell:3_1:0 predicted:3.53553
+DEAL:0:3d:: cell:3_1:1 predicted:3.53553
+DEAL:0:3d:: cell:3_1:2 predicted:3.53553
+DEAL:0:3d:: cell:3_1:3 predicted:3.53553
+DEAL:0:3d:: cell:3_1:4 predicted:3.53553
+DEAL:0:3d:: cell:3_1:5 predicted:3.53553
+DEAL:0:3d:: cell:3_1:6 predicted:3.53553
+DEAL:0:3d:: cell:3_1:7 predicted:3.53553
+DEAL:0:3d::OK
--- /dev/null
+
+DEAL:0:2d::pre_adaptation
+DEAL:0:2d:: cell:0_1:0 fe_deg:2 error:10.0000 coarsening future_fe_deg:3
+DEAL:0:2d:: cell:0_1:1 fe_deg:2 error:10.0000 coarsening future_fe_deg:3
+DEAL:0:2d:: cell:0_1:2 fe_deg:2 error:10.0000 coarsening future_fe_deg:3
+DEAL:0:2d:: cell:0_1:3 fe_deg:2 error:10.0000 coarsening future_fe_deg:3
+DEAL:0:2d::post_adaptation
+DEAL:0:2d:: cell:0_0: predicted:80.0000
+DEAL:0:2d:: cell:1_0: predicted:80.0000
+DEAL:0:2d::OK
+DEAL:0:3d::pre_adaptation
+DEAL:0:3d:: cell:0_1:0 fe_deg:2 error:10.0000 coarsening future_fe_deg:3
+DEAL:0:3d:: cell:0_1:1 fe_deg:2 error:10.0000 coarsening future_fe_deg:3
+DEAL:0:3d:: cell:0_1:2 fe_deg:2 error:10.0000 coarsening future_fe_deg:3
+DEAL:0:3d:: cell:0_1:3 fe_deg:2 error:10.0000 coarsening future_fe_deg:3
+DEAL:0:3d:: cell:0_1:4 fe_deg:2 error:10.0000 coarsening future_fe_deg:3
+DEAL:0:3d:: cell:0_1:5 fe_deg:2 error:10.0000 coarsening future_fe_deg:3
+DEAL:0:3d:: cell:0_1:6 fe_deg:2 error:10.0000 coarsening future_fe_deg:3
+DEAL:0:3d:: cell:0_1:7 fe_deg:2 error:10.0000 coarsening future_fe_deg:3
+DEAL:0:3d::post_adaptation
+DEAL:0:3d:: cell:0_0: predicted:113.137
+DEAL:0:3d:: cell:1_0: predicted:113.137
+DEAL:0:3d::OK
+
+DEAL:1:2d::pre_adaptation
+DEAL:1:2d::post_adaptation
+DEAL:1:2d:: cell:2_1:0 predicted:0.312500
+DEAL:1:2d:: cell:2_1:1 predicted:0.312500
+DEAL:1:2d:: cell:2_1:2 predicted:0.312500
+DEAL:1:2d:: cell:2_1:3 predicted:0.312500
+DEAL:1:2d::OK
+DEAL:1:3d::pre_adaptation
+DEAL:1:3d::post_adaptation
+DEAL:1:3d:: cell:2_1:0 predicted:0.220971
+DEAL:1:3d:: cell:2_1:1 predicted:0.220971
+DEAL:1:3d:: cell:2_1:2 predicted:0.220971
+DEAL:1:3d:: cell:2_1:3 predicted:0.220971
+DEAL:1:3d:: cell:2_1:4 predicted:0.220971
+DEAL:1:3d:: cell:2_1:5 predicted:0.220971
+DEAL:1:3d:: cell:2_1:6 predicted:0.220971
+DEAL:1:3d:: cell:2_1:7 predicted:0.220971
+DEAL:1:3d::OK
+
+
+DEAL:2:2d::pre_adaptation
+DEAL:2:2d:: cell:1_1:0 fe_deg:2 error:10.0000 coarsening future_fe_deg:1
+DEAL:2:2d:: cell:1_1:1 fe_deg:2 error:10.0000 coarsening future_fe_deg:1
+DEAL:2:2d:: cell:1_1:2 fe_deg:2 error:10.0000 coarsening future_fe_deg:1
+DEAL:2:2d:: cell:1_1:3 fe_deg:2 error:10.0000 coarsening future_fe_deg:1
+DEAL:2:2d::post_adaptation
+DEAL:2:2d::OK
+DEAL:2:3d::pre_adaptation
+DEAL:2:3d:: cell:1_1:0 fe_deg:2 error:10.0000 coarsening future_fe_deg:1
+DEAL:2:3d:: cell:1_1:1 fe_deg:2 error:10.0000 coarsening future_fe_deg:1
+DEAL:2:3d:: cell:1_1:2 fe_deg:2 error:10.0000 coarsening future_fe_deg:1
+DEAL:2:3d:: cell:1_1:3 fe_deg:2 error:10.0000 coarsening future_fe_deg:1
+DEAL:2:3d:: cell:1_1:4 fe_deg:2 error:10.0000 coarsening future_fe_deg:1
+DEAL:2:3d:: cell:1_1:5 fe_deg:2 error:10.0000 coarsening future_fe_deg:1
+DEAL:2:3d:: cell:1_1:6 fe_deg:2 error:10.0000 coarsening future_fe_deg:1
+DEAL:2:3d:: cell:1_1:7 fe_deg:2 error:10.0000 coarsening future_fe_deg:1
+DEAL:2:3d::post_adaptation
+DEAL:2:3d::OK
+
+
+DEAL:3:2d::pre_adaptation
+DEAL:3:2d:: cell:2_0: fe_deg:2 error:10.0000 refining future_fe_deg:3
+DEAL:3:2d:: cell:3_0: fe_deg:2 error:10.0000 refining future_fe_deg:1
+DEAL:3:2d::post_adaptation
+DEAL:3:2d:: cell:3_1:0 predicted:5.00000
+DEAL:3:2d:: cell:3_1:1 predicted:5.00000
+DEAL:3:2d:: cell:3_1:2 predicted:5.00000
+DEAL:3:2d:: cell:3_1:3 predicted:5.00000
+DEAL:3:2d::OK
+DEAL:3:3d::pre_adaptation
+DEAL:3:3d:: cell:2_0: fe_deg:2 error:10.0000 refining future_fe_deg:3
+DEAL:3:3d:: cell:3_0: fe_deg:2 error:10.0000 refining future_fe_deg:1
+DEAL:3:3d::post_adaptation
+DEAL:3:3d:: cell:3_1:0 predicted:3.53553
+DEAL:3:3d:: cell:3_1:1 predicted:3.53553
+DEAL:3:3d:: cell:3_1:2 predicted:3.53553
+DEAL:3:3d:: cell:3_1:3 predicted:3.53553
+DEAL:3:3d:: cell:3_1:4 predicted:3.53553
+DEAL:3:3d:: cell:3_1:5 predicted:3.53553
+DEAL:3:3d:: cell:3_1:6 predicted:3.53553
+DEAL:3:3d:: cell:3_1:7 predicted:3.53553
+DEAL:3:3d::OK
+