// --------------------------------------------------------------------- // // Copyright (C) 2023 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. // // Authors: Peter Munch, Martin Kronbichler // // --------------------------------------------------------------------- #pragma once #ifndef bps_cpu_h # define bps_cpu_h // deal.II includes # include # include # include # include # include # include # include // local includes # include "bps.h" using namespace dealii; /** * Operator CPU implementation using deal.II. */ template class OperatorDealii : public OperatorBase { public: using VectorType = typename OperatorBase::VectorType; /** * Constructor. */ OperatorDealii(const Mapping &mapping, const DoFHandler &dof_handler, const AffineConstraints &constraints, const Quadrature &quadrature, const BPType &bp) : mapping(mapping) , dof_handler(dof_handler) , constraints(constraints) , quadrature(quadrature) , bp(bp) { reinit(); } /** * Destructor. */ ~OperatorDealii() = default; /** * Initialized internal data structures, particularly, MatrixFree. */ void reinit() override { // configure MatrixFree typename MatrixFree::AdditionalData additional_data; additional_data.tasks_parallel_scheme = MatrixFree::AdditionalData::TasksParallelScheme::none; // create MatrixFree matrix_free.reinit(mapping, dof_handler, constraints, quadrature, additional_data); } /** * Matrix-vector product. */ void vmult(VectorType &dst, const VectorType &src) const override { if (dof_handler.get_fe().n_components() == 1) { matrix_free.cell_loop(&OperatorDealii::do_cell_integral_range<1>, this, dst, src, true); } else { AssertThrow(dof_handler.get_fe().n_components() == dim, ExcInternalError()); matrix_free.cell_loop(&OperatorDealii::do_cell_integral_range, this, dst, src, true); } } /** * Initialize vector. */ void initialize_dof_vector(VectorType &vec) const override { matrix_free.initialize_dof_vector(vec); } /** * Compute inverse of diagonal. */ void compute_inverse_diagonal(VectorType &diagonal) const override { this->initialize_dof_vector(diagonal); if (dof_handler.get_fe().n_components() == 1) { MatrixFreeTools::compute_diagonal(matrix_free, diagonal, &OperatorDealii::do_cell_integral_local<1>, this); } else { AssertThrow(dof_handler.get_fe().n_components() == dim, ExcInternalError()); MatrixFreeTools::compute_diagonal(matrix_free, diagonal, &OperatorDealii::do_cell_integral_local, this); } for (auto &i : diagonal) i = (std::abs(i) > 1.0e-10) ? (1.0 / i) : 1.0; } private: /** * Cell integral without vector access. */ template void do_cell_integral_local(FEEvaluation &phi) const { if (bp <= BPType::BP2) // mass matrix { phi.evaluate(EvaluationFlags::values); for (const auto q : phi.quadrature_point_indices()) phi.submit_value(phi.get_value(q), q); phi.integrate(EvaluationFlags::values); } else // Poisson operator { phi.evaluate(EvaluationFlags::gradients); for (const auto q : phi.quadrature_point_indices()) phi.submit_gradient(phi.get_gradient(q), q); phi.integrate(EvaluationFlags::gradients); } } /** * Cell integral on a range of cells. */ template void do_cell_integral_range(const MatrixFree &matrix_free, VectorType &dst, const VectorType &src, const std::pair &range) const { FEEvaluation phi(matrix_free, range); for (unsigned cell = range.first; cell < range.second; ++cell) { phi.reinit(cell); phi.read_dof_values(src); // read source vector do_cell_integral_local(phi); // cell integral phi.distribute_local_to_global(dst); // write to destination vector } } /** * Mapping object passed to the constructor. */ const Mapping &mapping; /** * DoFHandler object passed to the constructor. */ const DoFHandler &dof_handler; /** * Constraints object passed to the constructor. */ const AffineConstraints &constraints; /** * Quadrature rule object passed to the constructor. */ const Quadrature &quadrature; /** * Selected BP. */ const BPType bp; /** * MatrixFree object. */ MatrixFree matrix_free; }; #endif