18c81f8b0SPeter Munch // --------------------------------------------------------------------- 28c81f8b0SPeter Munch // 38c81f8b0SPeter Munch // Copyright (C) 2023 by the deal.II authors 48c81f8b0SPeter Munch // 58c81f8b0SPeter Munch // This file is part of the deal.II library. 68c81f8b0SPeter Munch // 78c81f8b0SPeter Munch // The deal.II library is free software; you can use it, redistribute 88c81f8b0SPeter Munch // it, and/or modify it under the terms of the GNU Lesser General 98c81f8b0SPeter Munch // Public License as published by the Free Software Foundation; either 108c81f8b0SPeter Munch // version 2.1 of the License, or (at your option) any later version. 118c81f8b0SPeter Munch // The full text of the license can be found in the file LICENSE.md at 128c81f8b0SPeter Munch // the top level directory of deal.II. 138c81f8b0SPeter Munch // 148c81f8b0SPeter Munch // Authors: Peter Munch, Martin Kronbichler 158c81f8b0SPeter Munch // 168c81f8b0SPeter Munch // --------------------------------------------------------------------- 178c81f8b0SPeter Munch 188c81f8b0SPeter Munch // deal.II includes 198c81f8b0SPeter Munch #include <deal.II/dofs/dof_tools.h> 208c81f8b0SPeter Munch 218c81f8b0SPeter Munch #include <deal.II/fe/mapping.h> 228c81f8b0SPeter Munch 238c81f8b0SPeter Munch #include <deal.II/lac/la_parallel_vector.h> 248c81f8b0SPeter Munch 258c81f8b0SPeter Munch #include <deal.II/matrix_free/fe_evaluation.h> 268c81f8b0SPeter Munch #include <deal.II/matrix_free/matrix_free.h> 278c81f8b0SPeter Munch #include <deal.II/matrix_free/tools.h> 288c81f8b0SPeter Munch 298c81f8b0SPeter Munch // libCEED includes 308c81f8b0SPeter Munch #include <ceed/ceed.h> 318c81f8b0SPeter Munch 328c81f8b0SPeter Munch // QFunction source 338c81f8b0SPeter Munch #include "bps-qfunctions.h" 348c81f8b0SPeter Munch 358c81f8b0SPeter Munch using namespace dealii; 368c81f8b0SPeter Munch 378c81f8b0SPeter Munch /** 388c81f8b0SPeter Munch * BP types. For more details, see https://ceed.exascaleproject.org/bps/. 398c81f8b0SPeter Munch */ 408c81f8b0SPeter Munch enum class BPType : unsigned int 418c81f8b0SPeter Munch { 428c81f8b0SPeter Munch BP1, 438c81f8b0SPeter Munch BP2, 448c81f8b0SPeter Munch BP3, 458c81f8b0SPeter Munch BP4, 468c81f8b0SPeter Munch BP5, 478c81f8b0SPeter Munch BP6 488c81f8b0SPeter Munch }; 498c81f8b0SPeter Munch 508c81f8b0SPeter Munch 518c81f8b0SPeter Munch 528c81f8b0SPeter Munch /** 538c81f8b0SPeter Munch * Struct storing relevant information regarding each BP. 548c81f8b0SPeter Munch */ 558c81f8b0SPeter Munch struct BPInfo 568c81f8b0SPeter Munch { 578c81f8b0SPeter Munch BPInfo(const BPType type, const int dim, const int fe_degree) 588c81f8b0SPeter Munch : type(type) 598c81f8b0SPeter Munch , dim(dim) 608c81f8b0SPeter Munch , fe_degree(fe_degree) 618c81f8b0SPeter Munch { 628c81f8b0SPeter Munch if (type == BPType::BP1) 638c81f8b0SPeter Munch type_string = "BP1"; 648c81f8b0SPeter Munch else if (type == BPType::BP2) 658c81f8b0SPeter Munch type_string = "BP2"; 668c81f8b0SPeter Munch else if (type == BPType::BP3) 678c81f8b0SPeter Munch type_string = "BP3"; 688c81f8b0SPeter Munch else if (type == BPType::BP4) 698c81f8b0SPeter Munch type_string = "BP4"; 708c81f8b0SPeter Munch else if (type == BPType::BP5) 718c81f8b0SPeter Munch type_string = "BP5"; 728c81f8b0SPeter Munch else if (type == BPType::BP6) 738c81f8b0SPeter Munch type_string = "BP6"; 748c81f8b0SPeter Munch 758c81f8b0SPeter Munch this->n_q_points_1d = (type <= BPType::BP4) ? (fe_degree + 2) : (fe_degree + 1); 768c81f8b0SPeter Munch 778c81f8b0SPeter Munch this->n_components = 788c81f8b0SPeter Munch (type == BPType::BP1 || type == BPType::BP3 || type == BPType::BP5) ? 1 : dim; 798c81f8b0SPeter Munch } 808c81f8b0SPeter Munch 818c81f8b0SPeter Munch 828c81f8b0SPeter Munch BPType type; 838c81f8b0SPeter Munch std::string type_string; 848c81f8b0SPeter Munch unsigned int dim; 858c81f8b0SPeter Munch unsigned int fe_degree; 868c81f8b0SPeter Munch unsigned int n_q_points_1d; 878c81f8b0SPeter Munch unsigned int n_components; 888c81f8b0SPeter Munch }; 898c81f8b0SPeter Munch 908c81f8b0SPeter Munch 918c81f8b0SPeter Munch 928c81f8b0SPeter Munch /** 938c81f8b0SPeter Munch * Base class of operators. 948c81f8b0SPeter Munch */ 958c81f8b0SPeter Munch template <typename Number> 968c81f8b0SPeter Munch class OperatorBase 978c81f8b0SPeter Munch { 988c81f8b0SPeter Munch public: 998c81f8b0SPeter Munch /** 1008c81f8b0SPeter Munch * deal.II vector type 1018c81f8b0SPeter Munch */ 1028c81f8b0SPeter Munch using VectorType = LinearAlgebra::distributed::Vector<Number>; 1038c81f8b0SPeter Munch 1048c81f8b0SPeter Munch /** 1058c81f8b0SPeter Munch * Initialize vector. 1068c81f8b0SPeter Munch */ 1078c81f8b0SPeter Munch virtual void 1088c81f8b0SPeter Munch reinit() = 0; 1098c81f8b0SPeter Munch 1108c81f8b0SPeter Munch /** 1118c81f8b0SPeter Munch * Perform matrix-vector product 1128c81f8b0SPeter Munch */ 1138c81f8b0SPeter Munch virtual void 1148c81f8b0SPeter Munch vmult(VectorType &dst, const VectorType &src) const = 0; 1158c81f8b0SPeter Munch 1168c81f8b0SPeter Munch /** 1178c81f8b0SPeter Munch * Initialize vector. 1188c81f8b0SPeter Munch */ 1198c81f8b0SPeter Munch virtual void 1208c81f8b0SPeter Munch initialize_dof_vector(VectorType &vec) const = 0; 1218c81f8b0SPeter Munch 1228c81f8b0SPeter Munch /** 1238c81f8b0SPeter Munch * Compute inverse of diagonal. 1248c81f8b0SPeter Munch */ 1258c81f8b0SPeter Munch virtual void 1268c81f8b0SPeter Munch compute_inverse_diagonal(VectorType &diagonal) const = 0; 1278c81f8b0SPeter Munch }; 1288c81f8b0SPeter Munch 1298c81f8b0SPeter Munch 1308c81f8b0SPeter Munch /** 1318c81f8b0SPeter Munch * Operator implementation using libCEED. 1328c81f8b0SPeter Munch */ 1338c81f8b0SPeter Munch template <int dim, typename Number> 1348c81f8b0SPeter Munch class OperatorCeed : public OperatorBase<Number> 1358c81f8b0SPeter Munch { 1368c81f8b0SPeter Munch public: 1378c81f8b0SPeter Munch using VectorType = typename OperatorBase<Number>::VectorType; 1388c81f8b0SPeter Munch 1398c81f8b0SPeter Munch /** 1408c81f8b0SPeter Munch * Constructor. 1418c81f8b0SPeter Munch */ 1428c81f8b0SPeter Munch OperatorCeed(const Mapping<dim> &mapping, 1438c81f8b0SPeter Munch const DoFHandler<dim> &dof_handler, 1448c81f8b0SPeter Munch const AffineConstraints<Number> &constraints, 1458c81f8b0SPeter Munch const Quadrature<dim> &quadrature, 1468c81f8b0SPeter Munch const BPType &bp, 1478c81f8b0SPeter Munch const std::string &resource) 1488c81f8b0SPeter Munch : mapping(mapping) 1498c81f8b0SPeter Munch , dof_handler(dof_handler) 1508c81f8b0SPeter Munch , constraints(constraints) 1518c81f8b0SPeter Munch , quadrature(quadrature) 1528c81f8b0SPeter Munch , bp(bp) 1538c81f8b0SPeter Munch , resource(resource) 1548c81f8b0SPeter Munch { 1558c81f8b0SPeter Munch reinit(); 1568c81f8b0SPeter Munch } 1578c81f8b0SPeter Munch 1588c81f8b0SPeter Munch /** 1598c81f8b0SPeter Munch * Destructor. 1608c81f8b0SPeter Munch */ 1618c81f8b0SPeter Munch ~OperatorCeed() 1628c81f8b0SPeter Munch { 1638c81f8b0SPeter Munch CeedOperatorDestroy(&op_apply); 1648c81f8b0SPeter Munch CeedQFunctionDestroy(&qf_apply); 1658c81f8b0SPeter Munch CeedQFunctionContextDestroy(&build_ctx); 1668c81f8b0SPeter Munch CeedVectorDestroy(&q_data); 1678c81f8b0SPeter Munch CeedElemRestrictionDestroy(&q_data_restriction); 1688c81f8b0SPeter Munch CeedElemRestrictionDestroy(&sol_restriction); 1698c81f8b0SPeter Munch CeedBasisDestroy(&sol_basis); 1708c81f8b0SPeter Munch CeedDestroy(&ceed); 1718c81f8b0SPeter Munch } 1728c81f8b0SPeter Munch 1738c81f8b0SPeter Munch /** 1748c81f8b0SPeter Munch * Initialized internal data structures, particularly, libCEED. 1758c81f8b0SPeter Munch */ 1768c81f8b0SPeter Munch void 1778c81f8b0SPeter Munch reinit() override 1788c81f8b0SPeter Munch { 1798c81f8b0SPeter Munch const auto &tria = dof_handler.get_triangulation(); 1808c81f8b0SPeter Munch const auto &fe = dof_handler.get_fe(); 1818c81f8b0SPeter Munch 1828c81f8b0SPeter Munch const auto n_components = fe.n_components(); 1838c81f8b0SPeter Munch 1848c81f8b0SPeter Munch if (bp == BPType::BP1 || bp == BPType::BP3 || bp == BPType::BP5) 1858c81f8b0SPeter Munch { 1868c81f8b0SPeter Munch AssertThrow(n_components == 1, ExcInternalError()); 1878c81f8b0SPeter Munch } 1888c81f8b0SPeter Munch else 1898c81f8b0SPeter Munch { 1908c81f8b0SPeter Munch AssertThrow(n_components == dim, ExcInternalError()); 1918c81f8b0SPeter Munch } 1928c81f8b0SPeter Munch 1938c81f8b0SPeter Munch // 1) create CEED instance -> "MatrixFree" 1948c81f8b0SPeter Munch const char *ceed_spec = resource.c_str(); 1958c81f8b0SPeter Munch CeedInit(ceed_spec, &ceed); 1968c81f8b0SPeter Munch 1978c81f8b0SPeter Munch // 2) create shape functions -> "ShapeInfo" 1988c81f8b0SPeter Munch const unsigned int fe_degree = fe.tensor_degree(); 1998c81f8b0SPeter Munch const unsigned int n_q_points = quadrature.get_tensor_basis()[0].size(); 2008c81f8b0SPeter Munch CeedBasisCreateTensorH1Lagrange( 2018c81f8b0SPeter Munch ceed, dim, n_components, fe_degree + 1, n_q_points, CEED_GAUSS, &sol_basis); 2028c81f8b0SPeter Munch 2038c81f8b0SPeter Munch // 3) create restriction matrix -> DoFInfo 2048c81f8b0SPeter Munch unsigned int n_local_active_cells = 0; 2058c81f8b0SPeter Munch 2068c81f8b0SPeter Munch for (const auto &cell : dof_handler.active_cell_iterators()) 2078c81f8b0SPeter Munch if (cell->is_locally_owned()) 2088c81f8b0SPeter Munch n_local_active_cells++; 2098c81f8b0SPeter Munch 2108c81f8b0SPeter Munch partitioner = 2118c81f8b0SPeter Munch std::make_shared<Utilities::MPI::Partitioner>(dof_handler.locally_owned_dofs(), 2128c81f8b0SPeter Munch DoFTools::extract_locally_active_dofs( 2138c81f8b0SPeter Munch dof_handler), 2148c81f8b0SPeter Munch dof_handler.get_communicator()); 2158c81f8b0SPeter Munch 2168c81f8b0SPeter Munch std::vector<CeedInt> indices; 2178c81f8b0SPeter Munch indices.reserve(n_local_active_cells * fe.n_dofs_per_cell() / n_components); 2188c81f8b0SPeter Munch 2198c81f8b0SPeter Munch const auto dof_mapping = FETools::lexicographic_to_hierarchic_numbering<dim>(fe_degree); 2208c81f8b0SPeter Munch 2218c81f8b0SPeter Munch std::vector<types::global_dof_index> local_indices(fe.n_dofs_per_cell()); 2228c81f8b0SPeter Munch 2238c81f8b0SPeter Munch for (const auto &cell : dof_handler.active_cell_iterators()) 2248c81f8b0SPeter Munch if (cell->is_locally_owned()) 2258c81f8b0SPeter Munch { 2268c81f8b0SPeter Munch cell->get_dof_indices(local_indices); 2278c81f8b0SPeter Munch 2288c81f8b0SPeter Munch for (const auto i : dof_mapping) 2298c81f8b0SPeter Munch indices.emplace_back( 2308c81f8b0SPeter Munch partitioner->global_to_local(local_indices[fe.component_to_system_index(0, i)]) / 2318c81f8b0SPeter Munch n_components); 2328c81f8b0SPeter Munch } 2338c81f8b0SPeter Munch 2348c81f8b0SPeter Munch CeedElemRestrictionCreate(ceed, 2358c81f8b0SPeter Munch n_local_active_cells, 2368c81f8b0SPeter Munch fe.n_dofs_per_cell() / n_components, 2378c81f8b0SPeter Munch n_components, 2388c81f8b0SPeter Munch std::max<unsigned int>(this->extended_local_size() / n_components, 1), 2398c81f8b0SPeter Munch this->extended_local_size(), 2408c81f8b0SPeter Munch CEED_MEM_HOST, 2418c81f8b0SPeter Munch CEED_COPY_VALUES, 2428c81f8b0SPeter Munch indices.data(), 2438c81f8b0SPeter Munch &sol_restriction); 2448c81f8b0SPeter Munch 2458c81f8b0SPeter Munch // 4) create mapping -> MappingInfo 2468c81f8b0SPeter Munch const unsigned int n_components_metric = (bp <= BPType::BP2) ? 1 : (dim * (dim + 1) / 2); 2478c81f8b0SPeter Munch 2488c81f8b0SPeter Munch this->weights = compute_metric_data(ceed, mapping, tria, quadrature, bp); 2498c81f8b0SPeter Munch 2508c81f8b0SPeter Munch strides = {{1, 2518c81f8b0SPeter Munch static_cast<int>(quadrature.size()), 2528c81f8b0SPeter Munch static_cast<int>(quadrature.size() * n_components_metric)}}; 2538c81f8b0SPeter Munch CeedVectorCreate(ceed, weights.size(), &q_data); 2548c81f8b0SPeter Munch CeedVectorSetArray(q_data, CEED_MEM_HOST, CEED_USE_POINTER, weights.data()); 2558c81f8b0SPeter Munch CeedElemRestrictionCreateStrided(ceed, 2568c81f8b0SPeter Munch n_local_active_cells, 2578c81f8b0SPeter Munch quadrature.size(), 2588c81f8b0SPeter Munch n_components_metric, 2598c81f8b0SPeter Munch weights.size(), 2608c81f8b0SPeter Munch strides.data(), 2618c81f8b0SPeter Munch &q_data_restriction); 2628c81f8b0SPeter Munch 2638c81f8b0SPeter Munch build_ctx_data.dim = dim; 2648c81f8b0SPeter Munch build_ctx_data.space_dim = dim; 2658c81f8b0SPeter Munch 2668c81f8b0SPeter Munch CeedQFunctionContextCreate(ceed, &build_ctx); 2678c81f8b0SPeter Munch CeedQFunctionContextSetData( 2688c81f8b0SPeter Munch build_ctx, CEED_MEM_HOST, CEED_USE_POINTER, sizeof(build_ctx_data), &build_ctx_data); 2698c81f8b0SPeter Munch 2708c81f8b0SPeter Munch // 5) create q operation 2718c81f8b0SPeter Munch if (bp == BPType::BP1) 2728c81f8b0SPeter Munch CeedQFunctionCreateInterior(ceed, 1, f_apply_mass, f_apply_mass_loc, &qf_apply); 2738c81f8b0SPeter Munch else if (bp == BPType::BP2) 2748c81f8b0SPeter Munch CeedQFunctionCreateInterior(ceed, 1, f_apply_mass_vec, f_apply_mass_vec_loc, &qf_apply); 2758c81f8b0SPeter Munch else if (bp == BPType::BP3 || bp == BPType::BP5) 2768c81f8b0SPeter Munch CeedQFunctionCreateInterior(ceed, 1, f_apply_poisson, f_apply_poisson_loc, &qf_apply); 2778c81f8b0SPeter Munch else if (bp == BPType::BP4 || bp == BPType::BP6) 2788c81f8b0SPeter Munch CeedQFunctionCreateInterior(ceed, 1, f_apply_poisson_vec, f_apply_poisson_vec_loc, &qf_apply); 2798c81f8b0SPeter Munch else 2808c81f8b0SPeter Munch AssertThrow(false, ExcInternalError()); 2818c81f8b0SPeter Munch 2828c81f8b0SPeter Munch if (bp <= BPType::BP2) 2838c81f8b0SPeter Munch CeedQFunctionAddInput(qf_apply, "u", n_components, CEED_EVAL_INTERP); 2848c81f8b0SPeter Munch else 2858c81f8b0SPeter Munch CeedQFunctionAddInput(qf_apply, "u", dim * n_components, CEED_EVAL_GRAD); 2868c81f8b0SPeter Munch 2878c81f8b0SPeter Munch CeedQFunctionAddInput(qf_apply, "qdata", n_components_metric, CEED_EVAL_NONE); 2888c81f8b0SPeter Munch 2898c81f8b0SPeter Munch if (bp <= BPType::BP2) 2908c81f8b0SPeter Munch CeedQFunctionAddOutput(qf_apply, "v", n_components, CEED_EVAL_INTERP); 2918c81f8b0SPeter Munch else 2928c81f8b0SPeter Munch CeedQFunctionAddOutput(qf_apply, "v", dim * n_components, CEED_EVAL_GRAD); 2938c81f8b0SPeter Munch 2948c81f8b0SPeter Munch CeedQFunctionSetContext(qf_apply, build_ctx); 2958c81f8b0SPeter Munch 2968c81f8b0SPeter Munch // 6) put everything together 2978c81f8b0SPeter Munch CeedOperatorCreate(ceed, qf_apply, CEED_QFUNCTION_NONE, CEED_QFUNCTION_NONE, &op_apply); 2988c81f8b0SPeter Munch 2998c81f8b0SPeter Munch CeedOperatorSetField(op_apply, "u", sol_restriction, sol_basis, CEED_VECTOR_ACTIVE); 300*fab7d8a4SJeremy L Thompson CeedOperatorSetField(op_apply, "qdata", q_data_restriction, CEED_BASIS_NONE, q_data); 3018c81f8b0SPeter Munch CeedOperatorSetField(op_apply, "v", sol_restriction, sol_basis, CEED_VECTOR_ACTIVE); 3028c81f8b0SPeter Munch } 3038c81f8b0SPeter Munch 3048c81f8b0SPeter Munch /** 3058c81f8b0SPeter Munch * Perform matrix-vector product. 3068c81f8b0SPeter Munch */ 3078c81f8b0SPeter Munch void 3088c81f8b0SPeter Munch vmult(VectorType &dst, const VectorType &src) const override 3098c81f8b0SPeter Munch { 3108c81f8b0SPeter Munch // communicate: update ghost values 3118c81f8b0SPeter Munch src.update_ghost_values(); 3128c81f8b0SPeter Munch 3138c81f8b0SPeter Munch if (dof_handler.get_fe().n_components() == 1) 3148c81f8b0SPeter Munch { 3158c81f8b0SPeter Munch // create libCEED view on deal.II vectors 3168c81f8b0SPeter Munch VectorTypeCeed src_ceed(ceed, src); 3178c81f8b0SPeter Munch VectorTypeCeed dst_ceed(ceed, dst); 3188c81f8b0SPeter Munch 3198c81f8b0SPeter Munch // apply operator 3208c81f8b0SPeter Munch CeedOperatorApply(op_apply, src_ceed(), dst_ceed(), CEED_REQUEST_IMMEDIATE); 3218c81f8b0SPeter Munch } 3228c81f8b0SPeter Munch else // TODO: needed for multiple components 3238c81f8b0SPeter Munch { 3248c81f8b0SPeter Munch // allocate space for block vectors 3258c81f8b0SPeter Munch src_tmp.reinit(this->extended_local_size(), true); 3268c81f8b0SPeter Munch dst_tmp.reinit(this->extended_local_size(), true); 3278c81f8b0SPeter Munch 3288c81f8b0SPeter Munch copy_to_block_vector(src_tmp, src); // copy to block vector 3298c81f8b0SPeter Munch 3308c81f8b0SPeter Munch // create libCEED view on deal.II vectors 3318c81f8b0SPeter Munch VectorTypeCeed src_ceed(ceed, src_tmp); 3328c81f8b0SPeter Munch VectorTypeCeed dst_ceed(ceed, dst_tmp); 3338c81f8b0SPeter Munch 3348c81f8b0SPeter Munch // apply operator 3358c81f8b0SPeter Munch CeedOperatorApply(op_apply, src_ceed(), dst_ceed(), CEED_REQUEST_IMMEDIATE); 3368c81f8b0SPeter Munch 3378c81f8b0SPeter Munch dst_ceed.sync_to_host(); // pull libCEED data back to host 3388c81f8b0SPeter Munch copy_from_block_vector(dst, dst_tmp); // copy from block vector 3398c81f8b0SPeter Munch } 3408c81f8b0SPeter Munch 3418c81f8b0SPeter Munch // communicate: compress 3428c81f8b0SPeter Munch src.zero_out_ghost_values(); 3438c81f8b0SPeter Munch dst.compress(VectorOperation::add); 3448c81f8b0SPeter Munch 3458c81f8b0SPeter Munch // apply constraints: we assume homogeneous DBC 3468c81f8b0SPeter Munch constraints.set_zero(dst); 3478c81f8b0SPeter Munch } 3488c81f8b0SPeter Munch 3498c81f8b0SPeter Munch /** 3508c81f8b0SPeter Munch * Initialized vector. 3518c81f8b0SPeter Munch */ 3528c81f8b0SPeter Munch void 3538c81f8b0SPeter Munch initialize_dof_vector(VectorType &vec) const override 3548c81f8b0SPeter Munch { 3558c81f8b0SPeter Munch vec.reinit(partitioner); 3568c81f8b0SPeter Munch } 3578c81f8b0SPeter Munch 3588c81f8b0SPeter Munch /** 3598c81f8b0SPeter Munch * Compute inverse of diagonal. 3608c81f8b0SPeter Munch */ 3618c81f8b0SPeter Munch void 3628c81f8b0SPeter Munch compute_inverse_diagonal(VectorType &diagonal) const override 3638c81f8b0SPeter Munch { 3648c81f8b0SPeter Munch this->initialize_dof_vector(diagonal); 3658c81f8b0SPeter Munch 3668c81f8b0SPeter Munch VectorTypeCeed diagonal_ceed(ceed, diagonal); 3678c81f8b0SPeter Munch 3688c81f8b0SPeter Munch CeedOperatorLinearAssembleDiagonal(op_apply, diagonal_ceed(), CEED_REQUEST_IMMEDIATE); 3698c81f8b0SPeter Munch 3708c81f8b0SPeter Munch const unsigned int n_components = dof_handler.get_fe().n_components(); 3718c81f8b0SPeter Munch 3728c81f8b0SPeter Munch if (n_components > 1) // TODO: needed for multiple components 3738c81f8b0SPeter Munch { 3748c81f8b0SPeter Munch VectorType tmp(diagonal); 3758c81f8b0SPeter Munch 3768c81f8b0SPeter Munch copy_from_block_vector(tmp, diagonal); 3778c81f8b0SPeter Munch 3788c81f8b0SPeter Munch std::swap(tmp, diagonal); 3798c81f8b0SPeter Munch } 3808c81f8b0SPeter Munch 3818c81f8b0SPeter Munch diagonal.compress(VectorOperation::add); 3828c81f8b0SPeter Munch 3838c81f8b0SPeter Munch for (auto &i : diagonal) 3848c81f8b0SPeter Munch i = (std::abs(i) > 1.0e-10) ? (1.0 / i) : 1.0; 3858c81f8b0SPeter Munch } 3868c81f8b0SPeter Munch 3878c81f8b0SPeter Munch private: 3888c81f8b0SPeter Munch /** 3898c81f8b0SPeter Munch * Wrapper around a deal.II vector to create a libCEED vector view. 3908c81f8b0SPeter Munch */ 3918c81f8b0SPeter Munch class VectorTypeCeed 3928c81f8b0SPeter Munch { 3938c81f8b0SPeter Munch public: 3948c81f8b0SPeter Munch /** 3958c81f8b0SPeter Munch * Constructor. 3968c81f8b0SPeter Munch */ 3978c81f8b0SPeter Munch VectorTypeCeed(const Ceed &ceed, const VectorType &vec) 3988c81f8b0SPeter Munch { 3998c81f8b0SPeter Munch const unsigned int n_dofs = 4008c81f8b0SPeter Munch vec.get_partitioner()->locally_owned_size() + vec.get_partitioner()->n_ghost_indices(); 4018c81f8b0SPeter Munch 4028c81f8b0SPeter Munch CeedVectorCreate(ceed, n_dofs, &vec_ceed); 4038c81f8b0SPeter Munch CeedVectorSetArray(vec_ceed, CEED_MEM_HOST, CEED_USE_POINTER, vec.get_values()); 4048c81f8b0SPeter Munch } 4058c81f8b0SPeter Munch 4068c81f8b0SPeter Munch /** 4078c81f8b0SPeter Munch * Return libCEED vector view. 4088c81f8b0SPeter Munch */ 4098c81f8b0SPeter Munch CeedVector & 4108c81f8b0SPeter Munch operator()() 4118c81f8b0SPeter Munch { 4128c81f8b0SPeter Munch return vec_ceed; 4138c81f8b0SPeter Munch } 4148c81f8b0SPeter Munch 4158c81f8b0SPeter Munch /** 4168c81f8b0SPeter Munch * Sync memory from device to host. 4178c81f8b0SPeter Munch */ 4188c81f8b0SPeter Munch void 4198c81f8b0SPeter Munch sync_to_host() 4208c81f8b0SPeter Munch { 4218c81f8b0SPeter Munch CeedVectorSyncArray(vec_ceed, CEED_MEM_HOST); 4228c81f8b0SPeter Munch } 4238c81f8b0SPeter Munch 4248c81f8b0SPeter Munch /** 4258c81f8b0SPeter Munch * Destructor: destroy vector view. 4268c81f8b0SPeter Munch */ 4278c81f8b0SPeter Munch ~VectorTypeCeed() 4288c81f8b0SPeter Munch { 4298c81f8b0SPeter Munch CeedScalar *ptr; 4308c81f8b0SPeter Munch CeedVectorTakeArray(vec_ceed, CEED_MEM_HOST, &ptr); 4318c81f8b0SPeter Munch CeedVectorDestroy(&vec_ceed); 4328c81f8b0SPeter Munch } 4338c81f8b0SPeter Munch 4348c81f8b0SPeter Munch private: 4358c81f8b0SPeter Munch /** 4368c81f8b0SPeter Munch * libCEED vector view. 4378c81f8b0SPeter Munch */ 4388c81f8b0SPeter Munch CeedVector vec_ceed; 4398c81f8b0SPeter Munch }; 4408c81f8b0SPeter Munch 4418c81f8b0SPeter Munch /** 4428c81f8b0SPeter Munch * Copy from block vector. 4438c81f8b0SPeter Munch * 4448c81f8b0SPeter Munch * @note Only needed for multiple components. 4458c81f8b0SPeter Munch */ 4468c81f8b0SPeter Munch void 4478c81f8b0SPeter Munch copy_from_block_vector(VectorType &dst, const VectorType &src) const 4488c81f8b0SPeter Munch { 4498c81f8b0SPeter Munch const unsigned int scalar_size = this->extended_local_size() / dim; 4508c81f8b0SPeter Munch 4518c81f8b0SPeter Munch for (unsigned int i = 0; i < scalar_size; ++i) 4528c81f8b0SPeter Munch for (unsigned int j = 0; j < dim; ++j) 4538c81f8b0SPeter Munch dst.get_values()[j + i * dim] = src.get_values()[j * scalar_size + i]; 4548c81f8b0SPeter Munch } 4558c81f8b0SPeter Munch 4568c81f8b0SPeter Munch /** 4578c81f8b0SPeter Munch * Copy to block vector. 4588c81f8b0SPeter Munch * 4598c81f8b0SPeter Munch * @note Only needed for multiple components. 4608c81f8b0SPeter Munch */ 4618c81f8b0SPeter Munch void 4628c81f8b0SPeter Munch copy_to_block_vector(VectorType &dst, const VectorType &src) const 4638c81f8b0SPeter Munch { 4648c81f8b0SPeter Munch const unsigned int scalar_size = this->extended_local_size() / dim; 4658c81f8b0SPeter Munch 4668c81f8b0SPeter Munch for (unsigned int i = 0; i < scalar_size; ++i) 4678c81f8b0SPeter Munch for (unsigned int j = 0; j < dim; ++j) 4688c81f8b0SPeter Munch dst.get_values()[j * scalar_size + i] = src.get_values()[j + i * dim]; 4698c81f8b0SPeter Munch } 4708c81f8b0SPeter Munch 4718c81f8b0SPeter Munch /** 4728c81f8b0SPeter Munch * Number of locally active DoFs. 4738c81f8b0SPeter Munch */ 4748c81f8b0SPeter Munch unsigned int 4758c81f8b0SPeter Munch extended_local_size() const 4768c81f8b0SPeter Munch { 4778c81f8b0SPeter Munch return partitioner->locally_owned_size() + partitioner->n_ghost_indices(); 4788c81f8b0SPeter Munch } 4798c81f8b0SPeter Munch 4808c81f8b0SPeter Munch /** 4818c81f8b0SPeter Munch * Compute metric data: Jacobian, ... 4828c81f8b0SPeter Munch */ 4838c81f8b0SPeter Munch static std::vector<double> 4848c81f8b0SPeter Munch compute_metric_data(const Ceed &ceed, 4858c81f8b0SPeter Munch const Mapping<dim> &mapping, 4868c81f8b0SPeter Munch const Triangulation<dim> &tria, 4878c81f8b0SPeter Munch const Quadrature<dim> &quadrature, 4888c81f8b0SPeter Munch const BPType bp) 4898c81f8b0SPeter Munch { 4908c81f8b0SPeter Munch std::vector<double> weights; 4918c81f8b0SPeter Munch 4928c81f8b0SPeter Munch if (false) 4938c81f8b0SPeter Munch { 4948c81f8b0SPeter Munch FE_Nothing<dim> dummy_fe; 4958c81f8b0SPeter Munch FEValues<dim> fe_values(mapping, dummy_fe, quadrature, update_JxW_values); 4968c81f8b0SPeter Munch 4978c81f8b0SPeter Munch for (const auto &cell : tria.active_cell_iterators()) 4988c81f8b0SPeter Munch if (cell->is_locally_owned()) 4998c81f8b0SPeter Munch { 5008c81f8b0SPeter Munch fe_values.reinit(cell); 5018c81f8b0SPeter Munch 5028c81f8b0SPeter Munch for (const auto q : fe_values.quadrature_point_indices()) 5038c81f8b0SPeter Munch weights.emplace_back(fe_values.JxW(q)); 5048c81f8b0SPeter Munch } 5058c81f8b0SPeter Munch 5068c81f8b0SPeter Munch return weights; 5078c81f8b0SPeter Munch } 5088c81f8b0SPeter Munch 5098c81f8b0SPeter Munch CeedBasis geo_basis; 5108c81f8b0SPeter Munch CeedVector q_data; 5118c81f8b0SPeter Munch CeedElemRestriction q_data_restriction; 5128c81f8b0SPeter Munch CeedVector node_coords; 5138c81f8b0SPeter Munch CeedElemRestriction geo_restriction; 5148c81f8b0SPeter Munch CeedQFunctionContext build_ctx; 5158c81f8b0SPeter Munch CeedQFunction qf_build; 5168c81f8b0SPeter Munch CeedOperator op_build; 5178c81f8b0SPeter Munch 5188c81f8b0SPeter Munch const unsigned int n_q_points = quadrature.get_tensor_basis()[0].size(); 5198c81f8b0SPeter Munch 5208c81f8b0SPeter Munch const unsigned int n_components = (bp <= BPType::BP2) ? 1 : (dim * (dim + 1) / 2); 5218c81f8b0SPeter Munch 5228c81f8b0SPeter Munch const auto mapping_q = dynamic_cast<const MappingQ<dim> *>(&mapping); 5238c81f8b0SPeter Munch 5248c81f8b0SPeter Munch AssertThrow(mapping_q, ExcMessage("Wrong mapping!")); 5258c81f8b0SPeter Munch 5268c81f8b0SPeter Munch const unsigned int fe_degree = mapping_q->get_degree(); 5278c81f8b0SPeter Munch 5288c81f8b0SPeter Munch CeedBasisCreateTensorH1Lagrange( 5298c81f8b0SPeter Munch ceed, dim, dim, fe_degree + 1, n_q_points, CEED_GAUSS, &geo_basis); 5308c81f8b0SPeter Munch 5318c81f8b0SPeter Munch unsigned int n_local_active_cells = 0; 5328c81f8b0SPeter Munch 5338c81f8b0SPeter Munch for (const auto &cell : tria.active_cell_iterators()) 5348c81f8b0SPeter Munch if (cell->is_locally_owned()) 5358c81f8b0SPeter Munch n_local_active_cells++; 5368c81f8b0SPeter Munch 5378c81f8b0SPeter Munch std::vector<double> geo_support_points; 5388c81f8b0SPeter Munch std::vector<CeedInt> geo_indices; 5398c81f8b0SPeter Munch 5408c81f8b0SPeter Munch FE_Q<dim> geo_fe(fe_degree); 5418c81f8b0SPeter Munch 5428c81f8b0SPeter Munch DoFHandler<dim> geo_dof_handler(tria); 5438c81f8b0SPeter Munch geo_dof_handler.distribute_dofs(geo_fe); 5448c81f8b0SPeter Munch 5458c81f8b0SPeter Munch const auto geo_partitioner = 5468c81f8b0SPeter Munch std::make_shared<Utilities::MPI::Partitioner>(geo_dof_handler.locally_owned_dofs(), 5478c81f8b0SPeter Munch DoFTools::extract_locally_active_dofs( 5488c81f8b0SPeter Munch geo_dof_handler), 5498c81f8b0SPeter Munch geo_dof_handler.get_communicator()); 5508c81f8b0SPeter Munch 5518c81f8b0SPeter Munch geo_indices.reserve(n_local_active_cells * geo_fe.n_dofs_per_cell()); 5528c81f8b0SPeter Munch 5538c81f8b0SPeter Munch const auto dof_mapping = FETools::lexicographic_to_hierarchic_numbering<dim>(fe_degree); 5548c81f8b0SPeter Munch 5558c81f8b0SPeter Munch FEValues<dim> fe_values(mapping, 5568c81f8b0SPeter Munch geo_fe, 5578c81f8b0SPeter Munch geo_fe.get_unit_support_points(), 5588c81f8b0SPeter Munch update_quadrature_points); 5598c81f8b0SPeter Munch 5608c81f8b0SPeter Munch std::vector<types::global_dof_index> local_indices(geo_fe.n_dofs_per_cell()); 5618c81f8b0SPeter Munch 5628c81f8b0SPeter Munch const unsigned int n_points = 5638c81f8b0SPeter Munch geo_partitioner->locally_owned_size() + geo_partitioner->n_ghost_indices(); 5648c81f8b0SPeter Munch 5658c81f8b0SPeter Munch geo_support_points.resize(dim * n_points); 5668c81f8b0SPeter Munch 5678c81f8b0SPeter Munch for (const auto &cell : geo_dof_handler.active_cell_iterators()) 5688c81f8b0SPeter Munch if (cell->is_locally_owned()) 5698c81f8b0SPeter Munch { 5708c81f8b0SPeter Munch fe_values.reinit(cell); 5718c81f8b0SPeter Munch cell->get_dof_indices(local_indices); 5728c81f8b0SPeter Munch 5738c81f8b0SPeter Munch for (const auto i : dof_mapping) 5748c81f8b0SPeter Munch { 5758c81f8b0SPeter Munch const auto index = geo_partitioner->global_to_local(local_indices[i]); 5768c81f8b0SPeter Munch geo_indices.emplace_back(index); 5778c81f8b0SPeter Munch 5788c81f8b0SPeter Munch const auto point = fe_values.quadrature_point(i); 5798c81f8b0SPeter Munch 5808c81f8b0SPeter Munch for (unsigned int d = 0; d < dim; ++d) 5818c81f8b0SPeter Munch geo_support_points[index + d * n_points] = point[d]; 5828c81f8b0SPeter Munch } 5838c81f8b0SPeter Munch } 5848c81f8b0SPeter Munch 5858c81f8b0SPeter Munch weights.resize(n_local_active_cells * quadrature.size() * n_components); 5868c81f8b0SPeter Munch 5878c81f8b0SPeter Munch CeedInt strides[3] = {1, 5888c81f8b0SPeter Munch static_cast<int>(quadrature.size()), 5898c81f8b0SPeter Munch static_cast<int>(quadrature.size() * n_components)}; 5908c81f8b0SPeter Munch 5918c81f8b0SPeter Munch CeedVectorCreate(ceed, weights.size(), &q_data); 5928c81f8b0SPeter Munch CeedVectorSetArray(q_data, CEED_MEM_HOST, CEED_USE_POINTER, weights.data()); 5938c81f8b0SPeter Munch CeedElemRestrictionCreateStrided(ceed, 5948c81f8b0SPeter Munch n_local_active_cells, 5958c81f8b0SPeter Munch quadrature.size(), 5968c81f8b0SPeter Munch n_components, 5978c81f8b0SPeter Munch weights.size(), 5988c81f8b0SPeter Munch strides, 5998c81f8b0SPeter Munch &q_data_restriction); 6008c81f8b0SPeter Munch 6018c81f8b0SPeter Munch CeedVectorCreate(ceed, geo_support_points.size(), &node_coords); 6028c81f8b0SPeter Munch CeedVectorSetArray(node_coords, CEED_MEM_HOST, CEED_USE_POINTER, geo_support_points.data()); 6038c81f8b0SPeter Munch 6048c81f8b0SPeter Munch CeedElemRestrictionCreate(ceed, 6058c81f8b0SPeter Munch n_local_active_cells, 6068c81f8b0SPeter Munch geo_fe.n_dofs_per_cell(), 6078c81f8b0SPeter Munch dim, 6088c81f8b0SPeter Munch std::max<unsigned int>(geo_support_points.size() / dim, 1), 6098c81f8b0SPeter Munch geo_support_points.size(), 6108c81f8b0SPeter Munch CEED_MEM_HOST, 6118c81f8b0SPeter Munch CEED_COPY_VALUES, 6128c81f8b0SPeter Munch geo_indices.data(), 6138c81f8b0SPeter Munch &geo_restriction); 6148c81f8b0SPeter Munch 6158c81f8b0SPeter Munch BuildContext build_ctx_data; 6168c81f8b0SPeter Munch build_ctx_data.dim = dim; 6178c81f8b0SPeter Munch build_ctx_data.space_dim = dim; 6188c81f8b0SPeter Munch 6198c81f8b0SPeter Munch CeedQFunctionContextCreate(ceed, &build_ctx); 6208c81f8b0SPeter Munch CeedQFunctionContextSetData( 6218c81f8b0SPeter Munch build_ctx, CEED_MEM_HOST, CEED_USE_POINTER, sizeof(build_ctx_data), &build_ctx_data); 6228c81f8b0SPeter Munch 6238c81f8b0SPeter Munch // 5) create q operation 6248c81f8b0SPeter Munch if (bp <= BPType::BP2) 6258c81f8b0SPeter Munch CeedQFunctionCreateInterior(ceed, 1, f_build_mass, f_build_mass_loc, &qf_build); 6268c81f8b0SPeter Munch else 6278c81f8b0SPeter Munch CeedQFunctionCreateInterior(ceed, 1, f_build_poisson, f_build_poisson_loc, &qf_build); 6288c81f8b0SPeter Munch 6298c81f8b0SPeter Munch CeedQFunctionAddInput(qf_build, "geo", dim * dim, CEED_EVAL_GRAD); 6308c81f8b0SPeter Munch CeedQFunctionAddInput(qf_build, "weights", 1, CEED_EVAL_WEIGHT); 6318c81f8b0SPeter Munch CeedQFunctionAddOutput(qf_build, "qdata", n_components, CEED_EVAL_NONE); 6328c81f8b0SPeter Munch CeedQFunctionSetContext(qf_build, build_ctx); 6338c81f8b0SPeter Munch 6348c81f8b0SPeter Munch // 6) put everything together 6358c81f8b0SPeter Munch CeedOperatorCreate(ceed, qf_build, CEED_QFUNCTION_NONE, CEED_QFUNCTION_NONE, &op_build); 6368c81f8b0SPeter Munch CeedOperatorSetField(op_build, "geo", geo_restriction, geo_basis, CEED_VECTOR_ACTIVE); 6378c81f8b0SPeter Munch CeedOperatorSetField( 6388c81f8b0SPeter Munch op_build, "weights", CEED_ELEMRESTRICTION_NONE, geo_basis, CEED_VECTOR_NONE); 6398c81f8b0SPeter Munch CeedOperatorSetField( 640*fab7d8a4SJeremy L Thompson op_build, "qdata", q_data_restriction, CEED_BASIS_NONE, CEED_VECTOR_ACTIVE); 6418c81f8b0SPeter Munch 6428c81f8b0SPeter Munch CeedOperatorApply(op_build, node_coords, q_data, CEED_REQUEST_IMMEDIATE); 6438c81f8b0SPeter Munch 6448c81f8b0SPeter Munch CeedOperatorDestroy(&op_build); 6458c81f8b0SPeter Munch CeedQFunctionDestroy(&qf_build); 6468c81f8b0SPeter Munch CeedQFunctionContextDestroy(&build_ctx); 6478c81f8b0SPeter Munch CeedElemRestrictionDestroy(&geo_restriction); 6488c81f8b0SPeter Munch CeedVectorDestroy(&node_coords); 6498c81f8b0SPeter Munch CeedElemRestrictionDestroy(&q_data_restriction); 6508c81f8b0SPeter Munch CeedVectorSyncArray(q_data, CEED_MEM_HOST); 6518c81f8b0SPeter Munch CeedVectorDestroy(&q_data); 6528c81f8b0SPeter Munch CeedBasisDestroy(&geo_basis); 6538c81f8b0SPeter Munch 6548c81f8b0SPeter Munch return weights; 6558c81f8b0SPeter Munch } 6568c81f8b0SPeter Munch 6578c81f8b0SPeter Munch /** 6588c81f8b0SPeter Munch * Mapping object passed to the constructor. 6598c81f8b0SPeter Munch */ 6608c81f8b0SPeter Munch const Mapping<dim> &mapping; 6618c81f8b0SPeter Munch 6628c81f8b0SPeter Munch /** 6638c81f8b0SPeter Munch * DoFHandler object passed to the constructor. 6648c81f8b0SPeter Munch */ 6658c81f8b0SPeter Munch const DoFHandler<dim> &dof_handler; 6668c81f8b0SPeter Munch 6678c81f8b0SPeter Munch /** 6688c81f8b0SPeter Munch * Constraints object passed to the constructor. 6698c81f8b0SPeter Munch */ 6708c81f8b0SPeter Munch const AffineConstraints<Number> &constraints; 6718c81f8b0SPeter Munch 6728c81f8b0SPeter Munch /** 6738c81f8b0SPeter Munch * Quadrature rule object passed to the constructor. 6748c81f8b0SPeter Munch */ 6758c81f8b0SPeter Munch const Quadrature<dim> &quadrature; 6768c81f8b0SPeter Munch 6778c81f8b0SPeter Munch /** 6788c81f8b0SPeter Munch * Selected BP. 6798c81f8b0SPeter Munch */ 6808c81f8b0SPeter Munch const BPType bp; 6818c81f8b0SPeter Munch 6828c81f8b0SPeter Munch /** 6838c81f8b0SPeter Munch * Resource name. 6848c81f8b0SPeter Munch */ 6858c81f8b0SPeter Munch const std::string resource; 6868c81f8b0SPeter Munch 6878c81f8b0SPeter Munch /** 6888c81f8b0SPeter Munch * Partitioner for distributed vectors. 6898c81f8b0SPeter Munch */ 6908c81f8b0SPeter Munch std::shared_ptr<Utilities::MPI::Partitioner> partitioner; 6918c81f8b0SPeter Munch 6928c81f8b0SPeter Munch /** 6938c81f8b0SPeter Munch * libCEED data structures. 6948c81f8b0SPeter Munch */ 6958c81f8b0SPeter Munch Ceed ceed; 6968c81f8b0SPeter Munch CeedBasis sol_basis; 6978c81f8b0SPeter Munch CeedElemRestriction sol_restriction; 6988c81f8b0SPeter Munch CeedElemRestriction q_data_restriction; 6998c81f8b0SPeter Munch std::vector<double> weights; 7008c81f8b0SPeter Munch CeedVector q_data; 7018c81f8b0SPeter Munch std::array<CeedInt, 3> strides; 7028c81f8b0SPeter Munch BuildContext build_ctx_data; 7038c81f8b0SPeter Munch CeedQFunctionContext build_ctx; 7048c81f8b0SPeter Munch CeedQFunction qf_apply; 7058c81f8b0SPeter Munch CeedOperator op_apply; 7068c81f8b0SPeter Munch 7078c81f8b0SPeter Munch /** 7088c81f8b0SPeter Munch * Temporal (tempral) vectors. 7098c81f8b0SPeter Munch * 7108c81f8b0SPeter Munch * @note Only needed for multiple components. 7118c81f8b0SPeter Munch */ 7128c81f8b0SPeter Munch mutable VectorType src_tmp; 7138c81f8b0SPeter Munch mutable VectorType dst_tmp; 7148c81f8b0SPeter Munch }; 7158c81f8b0SPeter Munch 7168c81f8b0SPeter Munch 7178c81f8b0SPeter Munch 7188c81f8b0SPeter Munch template <int dim, typename Number> 7198c81f8b0SPeter Munch class OperatorDealii : public OperatorBase<Number> 7208c81f8b0SPeter Munch { 7218c81f8b0SPeter Munch public: 7228c81f8b0SPeter Munch using VectorType = typename OperatorBase<Number>::VectorType; 7238c81f8b0SPeter Munch 7248c81f8b0SPeter Munch /** 7258c81f8b0SPeter Munch * Constructor. 7268c81f8b0SPeter Munch */ 7278c81f8b0SPeter Munch OperatorDealii(const Mapping<dim> &mapping, 7288c81f8b0SPeter Munch const DoFHandler<dim> &dof_handler, 7298c81f8b0SPeter Munch const AffineConstraints<Number> &constraints, 7308c81f8b0SPeter Munch const Quadrature<dim> &quadrature, 7318c81f8b0SPeter Munch const BPType &bp) 7328c81f8b0SPeter Munch : mapping(mapping) 7338c81f8b0SPeter Munch , dof_handler(dof_handler) 7348c81f8b0SPeter Munch , constraints(constraints) 7358c81f8b0SPeter Munch , quadrature(quadrature) 7368c81f8b0SPeter Munch , bp(bp) 7378c81f8b0SPeter Munch { 7388c81f8b0SPeter Munch reinit(); 7398c81f8b0SPeter Munch } 7408c81f8b0SPeter Munch 7418c81f8b0SPeter Munch /** 7428c81f8b0SPeter Munch * Destructor. 7438c81f8b0SPeter Munch */ 7448c81f8b0SPeter Munch ~OperatorDealii() = default; 7458c81f8b0SPeter Munch 7468c81f8b0SPeter Munch /** 7478c81f8b0SPeter Munch * Initialized internal data structures, particularly, MatrixFree. 7488c81f8b0SPeter Munch */ 7498c81f8b0SPeter Munch void 7508c81f8b0SPeter Munch reinit() override 7518c81f8b0SPeter Munch { 7528c81f8b0SPeter Munch // configure MatrixFree 7538c81f8b0SPeter Munch typename MatrixFree<dim, Number>::AdditionalData additional_data; 7548c81f8b0SPeter Munch additional_data.tasks_parallel_scheme = 7558c81f8b0SPeter Munch MatrixFree<dim, Number>::AdditionalData::TasksParallelScheme::none; 7568c81f8b0SPeter Munch 7578c81f8b0SPeter Munch // create MatrixFree 7588c81f8b0SPeter Munch matrix_free.reinit(mapping, dof_handler, constraints, quadrature, additional_data); 7598c81f8b0SPeter Munch } 7608c81f8b0SPeter Munch 7618c81f8b0SPeter Munch /** 7628c81f8b0SPeter Munch * Matrix-vector product. 7638c81f8b0SPeter Munch */ 7648c81f8b0SPeter Munch void 7658c81f8b0SPeter Munch vmult(VectorType &dst, const VectorType &src) const override 7668c81f8b0SPeter Munch { 7678c81f8b0SPeter Munch if (dof_handler.get_fe().n_components() == 1) 7688c81f8b0SPeter Munch { 7698c81f8b0SPeter Munch matrix_free.cell_loop(&OperatorDealii::do_cell_integral_range<1>, this, dst, src, true); 7708c81f8b0SPeter Munch } 7718c81f8b0SPeter Munch else 7728c81f8b0SPeter Munch { 7738c81f8b0SPeter Munch AssertThrow(dof_handler.get_fe().n_components() == dim, ExcInternalError()); 7748c81f8b0SPeter Munch 7758c81f8b0SPeter Munch matrix_free.cell_loop(&OperatorDealii::do_cell_integral_range<dim>, this, dst, src, true); 7768c81f8b0SPeter Munch } 7778c81f8b0SPeter Munch } 7788c81f8b0SPeter Munch 7798c81f8b0SPeter Munch /** 7808c81f8b0SPeter Munch * Initialize vector. 7818c81f8b0SPeter Munch */ 7828c81f8b0SPeter Munch void 7838c81f8b0SPeter Munch initialize_dof_vector(VectorType &vec) const override 7848c81f8b0SPeter Munch { 7858c81f8b0SPeter Munch matrix_free.initialize_dof_vector(vec); 7868c81f8b0SPeter Munch } 7878c81f8b0SPeter Munch 7888c81f8b0SPeter Munch /** 7898c81f8b0SPeter Munch * Compute inverse of diagonal. 7908c81f8b0SPeter Munch */ 7918c81f8b0SPeter Munch void 7928c81f8b0SPeter Munch compute_inverse_diagonal(VectorType &diagonal) const override 7938c81f8b0SPeter Munch { 7948c81f8b0SPeter Munch this->initialize_dof_vector(diagonal); 7958c81f8b0SPeter Munch 7968c81f8b0SPeter Munch if (dof_handler.get_fe().n_components() == 1) 7978c81f8b0SPeter Munch { 7988c81f8b0SPeter Munch MatrixFreeTools::compute_diagonal(matrix_free, 7998c81f8b0SPeter Munch diagonal, 8008c81f8b0SPeter Munch &OperatorDealii::do_cell_integral_local<1>, 8018c81f8b0SPeter Munch this); 8028c81f8b0SPeter Munch } 8038c81f8b0SPeter Munch else 8048c81f8b0SPeter Munch { 8058c81f8b0SPeter Munch AssertThrow(dof_handler.get_fe().n_components() == dim, ExcInternalError()); 8068c81f8b0SPeter Munch 8078c81f8b0SPeter Munch MatrixFreeTools::compute_diagonal(matrix_free, 8088c81f8b0SPeter Munch diagonal, 8098c81f8b0SPeter Munch &OperatorDealii::do_cell_integral_local<dim>, 8108c81f8b0SPeter Munch this); 8118c81f8b0SPeter Munch } 8128c81f8b0SPeter Munch 8138c81f8b0SPeter Munch for (auto &i : diagonal) 8148c81f8b0SPeter Munch i = (std::abs(i) > 1.0e-10) ? (1.0 / i) : 1.0; 8158c81f8b0SPeter Munch } 8168c81f8b0SPeter Munch 8178c81f8b0SPeter Munch private: 8188c81f8b0SPeter Munch /** 8198c81f8b0SPeter Munch * Cell integral without vector access. 8208c81f8b0SPeter Munch */ 8218c81f8b0SPeter Munch template <int n_components> 8228c81f8b0SPeter Munch void 8238c81f8b0SPeter Munch do_cell_integral_local(FEEvaluation<dim, -1, 0, n_components, Number> &phi) const 8248c81f8b0SPeter Munch { 8258c81f8b0SPeter Munch if (bp <= BPType::BP2) // mass matrix 8268c81f8b0SPeter Munch { 8278c81f8b0SPeter Munch phi.evaluate(EvaluationFlags::values); 8288c81f8b0SPeter Munch for (const auto q : phi.quadrature_point_indices()) 8298c81f8b0SPeter Munch phi.submit_value(phi.get_value(q), q); 8308c81f8b0SPeter Munch phi.integrate(EvaluationFlags::values); 8318c81f8b0SPeter Munch } 8328c81f8b0SPeter Munch else // Poisson operator 8338c81f8b0SPeter Munch { 8348c81f8b0SPeter Munch phi.evaluate(EvaluationFlags::gradients); 8358c81f8b0SPeter Munch for (const auto q : phi.quadrature_point_indices()) 8368c81f8b0SPeter Munch phi.submit_gradient(phi.get_gradient(q), q); 8378c81f8b0SPeter Munch phi.integrate(EvaluationFlags::gradients); 8388c81f8b0SPeter Munch } 8398c81f8b0SPeter Munch } 8408c81f8b0SPeter Munch 8418c81f8b0SPeter Munch /** 8428c81f8b0SPeter Munch * Cell integral on a range of cells. 8438c81f8b0SPeter Munch */ 8448c81f8b0SPeter Munch template <int n_components> 8458c81f8b0SPeter Munch void 8468c81f8b0SPeter Munch do_cell_integral_range(const MatrixFree<dim, Number> &matrix_free, 8478c81f8b0SPeter Munch VectorType &dst, 8488c81f8b0SPeter Munch const VectorType &src, 8498c81f8b0SPeter Munch const std::pair<unsigned int, unsigned int> &range) const 8508c81f8b0SPeter Munch { 8518c81f8b0SPeter Munch FEEvaluation<dim, -1, 0, n_components, Number> phi(matrix_free, range); 8528c81f8b0SPeter Munch 8538c81f8b0SPeter Munch for (unsigned cell = range.first; cell < range.second; ++cell) 8548c81f8b0SPeter Munch { 8558c81f8b0SPeter Munch phi.reinit(cell); 8568c81f8b0SPeter Munch phi.read_dof_values(src); // read source vector 8578c81f8b0SPeter Munch do_cell_integral_local(phi); // cell integral 8588c81f8b0SPeter Munch phi.distribute_local_to_global(dst); // write to destination vector 8598c81f8b0SPeter Munch } 8608c81f8b0SPeter Munch } 8618c81f8b0SPeter Munch 8628c81f8b0SPeter Munch /** 8638c81f8b0SPeter Munch * Mapping object passed to the constructor. 8648c81f8b0SPeter Munch */ 8658c81f8b0SPeter Munch const Mapping<dim> &mapping; 8668c81f8b0SPeter Munch 8678c81f8b0SPeter Munch /** 8688c81f8b0SPeter Munch * DoFHandler object passed to the constructor. 8698c81f8b0SPeter Munch */ 8708c81f8b0SPeter Munch const DoFHandler<dim> &dof_handler; 8718c81f8b0SPeter Munch 8728c81f8b0SPeter Munch /** 8738c81f8b0SPeter Munch * Constraints object passed to the constructor. 8748c81f8b0SPeter Munch */ 8758c81f8b0SPeter Munch const AffineConstraints<Number> &constraints; 8768c81f8b0SPeter Munch 8778c81f8b0SPeter Munch /** 8788c81f8b0SPeter Munch * Quadrature rule object passed to the constructor. 8798c81f8b0SPeter Munch */ 8808c81f8b0SPeter Munch const Quadrature<dim> &quadrature; 8818c81f8b0SPeter Munch 8828c81f8b0SPeter Munch /** 8838c81f8b0SPeter Munch * Selected BP. 8848c81f8b0SPeter Munch */ 8858c81f8b0SPeter Munch const BPType bp; 8868c81f8b0SPeter Munch 8878c81f8b0SPeter Munch /** 8888c81f8b0SPeter Munch * MatrixFree object. 8898c81f8b0SPeter Munch */ 8908c81f8b0SPeter Munch MatrixFree<dim, Number> matrix_free; 8918c81f8b0SPeter Munch }; 892