xref: /libCEED/examples/deal.II/bps-kokkos.cc (revision a44bca27e5d331f553a82497b0c34f31883da506)
1*d416dc2bSJeremy L Thompson // ---------------------------------------------------------------------
2*d416dc2bSJeremy L Thompson //
3*d416dc2bSJeremy L Thompson // Copyright (C) 2023 by the deal.II authors
4*d416dc2bSJeremy L Thompson //
5*d416dc2bSJeremy L Thompson // This file is part of the deal.II library.
6*d416dc2bSJeremy L Thompson //
7*d416dc2bSJeremy L Thompson // The deal.II library is free software; you can use it, redistribute
8*d416dc2bSJeremy L Thompson // it, and/or modify it under the terms of the GNU Lesser General
9*d416dc2bSJeremy L Thompson // Public License as published by the Free Software Foundation; either
10*d416dc2bSJeremy L Thompson // version 2.1 of the License, or (at your option) any later version.
11*d416dc2bSJeremy L Thompson // The full text of the license can be found in the file LICENSE.md at
12*d416dc2bSJeremy L Thompson // the top level directory of deal.II.
13*d416dc2bSJeremy L Thompson //
14*d416dc2bSJeremy L Thompson //  Authors: Peter Munch, Martin Kronbichler
15*d416dc2bSJeremy L Thompson //
16*d416dc2bSJeremy L Thompson // ---------------------------------------------------------------------
17*d416dc2bSJeremy L Thompson 
18*d416dc2bSJeremy L Thompson // deal.II includes
19*d416dc2bSJeremy L Thompson #include <deal.II/base/conditional_ostream.h>
20*d416dc2bSJeremy L Thompson #include <deal.II/base/mpi.h>
21*d416dc2bSJeremy L Thompson #include <deal.II/base/parameter_handler.h>
22*d416dc2bSJeremy L Thompson #include <deal.II/base/quadrature_lib.h>
23*d416dc2bSJeremy L Thompson 
24*d416dc2bSJeremy L Thompson #include <deal.II/distributed/shared_tria.h>
25*d416dc2bSJeremy L Thompson #include <deal.II/distributed/tria.h>
26*d416dc2bSJeremy L Thompson 
27*d416dc2bSJeremy L Thompson #include <deal.II/dofs/dof_handler.h>
28*d416dc2bSJeremy L Thompson #include <deal.II/dofs/dof_renumbering.h>
29*d416dc2bSJeremy L Thompson 
30*d416dc2bSJeremy L Thompson #include <deal.II/fe/fe_nothing.h>
31*d416dc2bSJeremy L Thompson #include <deal.II/fe/fe_q.h>
32*d416dc2bSJeremy L Thompson #include <deal.II/fe/fe_system.h>
33*d416dc2bSJeremy L Thompson #include <deal.II/fe/fe_tools.h>
34*d416dc2bSJeremy L Thompson #include <deal.II/fe/fe_values.h>
35*d416dc2bSJeremy L Thompson #include <deal.II/fe/mapping_q1.h>
36*d416dc2bSJeremy L Thompson 
37*d416dc2bSJeremy L Thompson #include <deal.II/grid/grid_generator.h>
38*d416dc2bSJeremy L Thompson 
39*d416dc2bSJeremy L Thompson #include <deal.II/lac/affine_constraints.h>
40*d416dc2bSJeremy L Thompson #include <deal.II/lac/precondition.h>
41*d416dc2bSJeremy L Thompson #include <deal.II/lac/solver_cg.h>
42*d416dc2bSJeremy L Thompson 
43*d416dc2bSJeremy L Thompson // boost
44*d416dc2bSJeremy L Thompson #include <boost/algorithm/string.hpp>
45*d416dc2bSJeremy L Thompson 
46*d416dc2bSJeremy L Thompson #include <sstream>
47*d416dc2bSJeremy L Thompson 
48*d416dc2bSJeremy L Thompson // include operators
49*d416dc2bSJeremy L Thompson #include "bps-ceed.h"
50*d416dc2bSJeremy L Thompson #include "bps-kokkos.h"
51*d416dc2bSJeremy L Thompson 
52*d416dc2bSJeremy L Thompson // Test cases
53*d416dc2bSJeremy L Thompson //TESTARGS(name="BP1") --resource {ceed_resource} --bp BP1 --fe_degree 2 --print_timings 0
54*d416dc2bSJeremy L Thompson //TESTARGS(name="BP4") --resource {ceed_resource} --bp BP4 --fe_degree 1 --print_timings 0
55*d416dc2bSJeremy L Thompson 
56*d416dc2bSJeremy L Thompson /**
57*d416dc2bSJeremy L Thompson  * Relevant parameters.
58*d416dc2bSJeremy L Thompson  */
59*d416dc2bSJeremy L Thompson struct Parameters
60*d416dc2bSJeremy L Thompson {
61*d416dc2bSJeremy L Thompson   BPType       bp                   = BPType::BP5;
62*d416dc2bSJeremy L Thompson   unsigned int n_global_refinements = 1;
63*d416dc2bSJeremy L Thompson   unsigned int fe_degree            = 2;
64*d416dc2bSJeremy L Thompson   bool         print_timings        = true;
65*d416dc2bSJeremy L Thompson   std::string  libCEED_resource     = "/cpu/self";
66*d416dc2bSJeremy L Thompson 
67*d416dc2bSJeremy L Thompson   bool
parseParameters68*d416dc2bSJeremy L Thompson   parse(int argc, char *argv[])
69*d416dc2bSJeremy L Thompson   {
70*d416dc2bSJeremy L Thompson     if (argc == 1 && (std::string(argv[0]) == "--help"))
71*d416dc2bSJeremy L Thompson       {
72*d416dc2bSJeremy L Thompson         std::cout << "Usage: ./bp [OPTION]..." << std::endl;
73*d416dc2bSJeremy L Thompson         std::cout << std::endl;
74*d416dc2bSJeremy L Thompson         std::cout << "--bp             name of benchmark (BP1-BP6)" << std::endl;
75*d416dc2bSJeremy L Thompson         std::cout << "--n_refinements  number of refinements (0-)" << std::endl;
76*d416dc2bSJeremy L Thompson         std::cout << "--fe_degree      polynomial degree (1-)" << std::endl;
77*d416dc2bSJeremy L Thompson         std::cout << "--print_timings  name of benchmark (0, 1)" << std::endl;
78*d416dc2bSJeremy L Thompson         std::cout << "--resource       name of resource (e.g., /cpu/self/avx/blocked)" << std::endl;
79*d416dc2bSJeremy L Thompson 
80*d416dc2bSJeremy L Thompson         return true;
81*d416dc2bSJeremy L Thompson       }
82*d416dc2bSJeremy L Thompson 
83*d416dc2bSJeremy L Thompson     AssertThrow(argc % 2 == 0, ExcInternalError());
84*d416dc2bSJeremy L Thompson 
85*d416dc2bSJeremy L Thompson     while (argc > 0)
86*d416dc2bSJeremy L Thompson       {
87*d416dc2bSJeremy L Thompson         std::string label(argv[0]);
88*d416dc2bSJeremy L Thompson 
89*d416dc2bSJeremy L Thompson         if ("--bp" == label)
90*d416dc2bSJeremy L Thompson           {
91*d416dc2bSJeremy L Thompson             std::string bp_string(argv[1]);
92*d416dc2bSJeremy L Thompson 
93*d416dc2bSJeremy L Thompson             if (bp_string == "BP1")
94*d416dc2bSJeremy L Thompson               bp = BPType::BP1;
95*d416dc2bSJeremy L Thompson             else if (bp_string == "BP2")
96*d416dc2bSJeremy L Thompson               bp = BPType::BP2;
97*d416dc2bSJeremy L Thompson             else if (bp_string == "BP3")
98*d416dc2bSJeremy L Thompson               bp = BPType::BP3;
99*d416dc2bSJeremy L Thompson             else if (bp_string == "BP4")
100*d416dc2bSJeremy L Thompson               bp = BPType::BP4;
101*d416dc2bSJeremy L Thompson             else if (bp_string == "BP5")
102*d416dc2bSJeremy L Thompson               bp = BPType::BP5;
103*d416dc2bSJeremy L Thompson             else if (bp_string == "BP6")
104*d416dc2bSJeremy L Thompson               bp = BPType::BP6;
105*d416dc2bSJeremy L Thompson             else
106*d416dc2bSJeremy L Thompson               AssertThrow(false, ExcInternalError());
107*d416dc2bSJeremy L Thompson           }
108*d416dc2bSJeremy L Thompson         else if ("--n_refinements" == label)
109*d416dc2bSJeremy L Thompson           {
110*d416dc2bSJeremy L Thompson             n_global_refinements = std::atoi(argv[1]);
111*d416dc2bSJeremy L Thompson           }
112*d416dc2bSJeremy L Thompson         else if ("--fe_degree" == label)
113*d416dc2bSJeremy L Thompson           {
114*d416dc2bSJeremy L Thompson             fe_degree = std::atoi(argv[1]);
115*d416dc2bSJeremy L Thompson           }
116*d416dc2bSJeremy L Thompson         else if ("--print_timings" == label)
117*d416dc2bSJeremy L Thompson           {
118*d416dc2bSJeremy L Thompson             print_timings = std::atoi(argv[1]);
119*d416dc2bSJeremy L Thompson           }
120*d416dc2bSJeremy L Thompson         else if ("--resource" == label)
121*d416dc2bSJeremy L Thompson           {
122*d416dc2bSJeremy L Thompson             libCEED_resource = std::string(argv[1]);
123*d416dc2bSJeremy L Thompson           }
124*d416dc2bSJeremy L Thompson         else
125*d416dc2bSJeremy L Thompson           {
126*d416dc2bSJeremy L Thompson             AssertThrow(false, ExcNotImplemented());
127*d416dc2bSJeremy L Thompson           }
128*d416dc2bSJeremy L Thompson 
129*d416dc2bSJeremy L Thompson 
130*d416dc2bSJeremy L Thompson         argc -= 2;
131*d416dc2bSJeremy L Thompson         argv += 2;
132*d416dc2bSJeremy L Thompson       }
133*d416dc2bSJeremy L Thompson 
134*d416dc2bSJeremy L Thompson     return false;
135*d416dc2bSJeremy L Thompson   }
136*d416dc2bSJeremy L Thompson };
137*d416dc2bSJeremy L Thompson 
138*d416dc2bSJeremy L Thompson 
139*d416dc2bSJeremy L Thompson 
140*d416dc2bSJeremy L Thompson int
main(int argc,char * argv[])141*d416dc2bSJeremy L Thompson main(int argc, char *argv[])
142*d416dc2bSJeremy L Thompson {
143*d416dc2bSJeremy L Thompson   Utilities::MPI::MPI_InitFinalize mpi_initialization(argc, argv, 1);
144*d416dc2bSJeremy L Thompson 
145*d416dc2bSJeremy L Thompson   Parameters params;
146*d416dc2bSJeremy L Thompson   if (params.parse(argc - 1, argv + 1))
147*d416dc2bSJeremy L Thompson     return 0;
148*d416dc2bSJeremy L Thompson 
149*d416dc2bSJeremy L Thompson   ConditionalOStream pout(std::cout, Utilities::MPI::this_mpi_process(MPI_COMM_WORLD) == 0);
150*d416dc2bSJeremy L Thompson 
151*d416dc2bSJeremy L Thompson   //  configuration
152*d416dc2bSJeremy L Thompson   const BPType bp = params.bp;
153*d416dc2bSJeremy L Thompson 
154*d416dc2bSJeremy L Thompson   using Number                     = double;
155*d416dc2bSJeremy L Thompson   using VectorType                 = LinearAlgebra::distributed::Vector<Number, MemorySpace::Default>;
156*d416dc2bSJeremy L Thompson   const unsigned int dim           = 2;
157*d416dc2bSJeremy L Thompson   const unsigned int fe_degree     = params.fe_degree;
158*d416dc2bSJeremy L Thompson   const unsigned int n_q_points    = (bp <= BPType::BP4) ? (fe_degree + 2) : (fe_degree + 1);
159*d416dc2bSJeremy L Thompson   const unsigned int n_refinements = params.n_global_refinements;
160*d416dc2bSJeremy L Thompson   const unsigned int n_components =
161*d416dc2bSJeremy L Thompson     (bp == BPType::BP1 || bp == BPType::BP3 || bp == BPType::BP5) ? 1 : dim;
162*d416dc2bSJeremy L Thompson 
163*d416dc2bSJeremy L Thompson   // create mapping, quadrature, fe, mesh, ...
164*d416dc2bSJeremy L Thompson   MappingQ1<dim> mapping;
165*d416dc2bSJeremy L Thompson   QGauss<dim>    quadrature(n_q_points);
166*d416dc2bSJeremy L Thompson   FESystem<dim>  fe(FE_Q<dim>(fe_degree), n_components);
167*d416dc2bSJeremy L Thompson 
168*d416dc2bSJeremy L Thompson #ifdef DEAL_II_WITH_P4EST
169*d416dc2bSJeremy L Thompson   parallel::distributed::Triangulation<dim> tria(MPI_COMM_WORLD);
170*d416dc2bSJeremy L Thompson #else
171*d416dc2bSJeremy L Thompson   Triangulation<dim> tria;
172*d416dc2bSJeremy L Thompson #endif
173*d416dc2bSJeremy L Thompson 
174*d416dc2bSJeremy L Thompson   GridGenerator::hyper_cube(tria);
175*d416dc2bSJeremy L Thompson   tria.refine_global(n_refinements);
176*d416dc2bSJeremy L Thompson 
177*d416dc2bSJeremy L Thompson   DoFHandler<dim> dof_handler(tria);
178*d416dc2bSJeremy L Thompson   dof_handler.distribute_dofs(fe);
179*d416dc2bSJeremy L Thompson 
180*d416dc2bSJeremy L Thompson   DoFRenumbering::support_point_wise(dof_handler);
181*d416dc2bSJeremy L Thompson 
182*d416dc2bSJeremy L Thompson   AffineConstraints<Number> constraints;
183*d416dc2bSJeremy L Thompson 
184*d416dc2bSJeremy L Thompson   if (!(bp == BPType::BP1 || bp == BPType::BP2))
185*d416dc2bSJeremy L Thompson     {
186*d416dc2bSJeremy L Thompson       // for stiffness matrix
187*d416dc2bSJeremy L Thompson       DoFTools::make_zero_boundary_constraints(dof_handler, constraints);
188*d416dc2bSJeremy L Thompson       constraints.close();
189*d416dc2bSJeremy L Thompson     }
190*d416dc2bSJeremy L Thompson 
191*d416dc2bSJeremy L Thompson   const auto test = [&](const std::string &label, const auto &op) {
192*d416dc2bSJeremy L Thompson     (void)label;
193*d416dc2bSJeremy L Thompson 
194*d416dc2bSJeremy L Thompson     // initialize vector
195*d416dc2bSJeremy L Thompson     VectorType u, v;
196*d416dc2bSJeremy L Thompson     op.initialize_dof_vector(u);
197*d416dc2bSJeremy L Thompson     op.initialize_dof_vector(v);
198*d416dc2bSJeremy L Thompson     u = 1.0;
199*d416dc2bSJeremy L Thompson 
200*d416dc2bSJeremy L Thompson     constraints.set_zero(u);
201*d416dc2bSJeremy L Thompson 
202*d416dc2bSJeremy L Thompson     // perform matrix-vector product
203*d416dc2bSJeremy L Thompson     op.vmult(v, u);
204*d416dc2bSJeremy L Thompson 
205*d416dc2bSJeremy L Thompson     // create solver
206*d416dc2bSJeremy L Thompson     ReductionControl reduction_control(100, 1e-20, 1e-6);
207*d416dc2bSJeremy L Thompson 
208*d416dc2bSJeremy L Thompson     // create preconditioner
209*d416dc2bSJeremy L Thompson     DiagonalMatrix<VectorType> diagonal_matrix;
210*d416dc2bSJeremy L Thompson     op.compute_inverse_diagonal(diagonal_matrix.get_vector());
211*d416dc2bSJeremy L Thompson 
212*d416dc2bSJeremy L Thompson     std::chrono::time_point<std::chrono::system_clock> now;
213*d416dc2bSJeremy L Thompson 
214*d416dc2bSJeremy L Thompson     bool not_converged = false;
215*d416dc2bSJeremy L Thompson 
216*d416dc2bSJeremy L Thompson     try
217*d416dc2bSJeremy L Thompson       {
218*d416dc2bSJeremy L Thompson         // solve problem
219*d416dc2bSJeremy L Thompson         SolverCG<VectorType> solver(reduction_control);
220*d416dc2bSJeremy L Thompson         now = std::chrono::system_clock::now();
221*d416dc2bSJeremy L Thompson         solver.solve(op, v, u, diagonal_matrix);
222*d416dc2bSJeremy L Thompson       }
223*d416dc2bSJeremy L Thompson     catch (const SolverControl::NoConvergence &)
224*d416dc2bSJeremy L Thompson       {
225*d416dc2bSJeremy L Thompson         pout << "Error: solver failed to converge with" << std::endl;
226*d416dc2bSJeremy L Thompson         not_converged = true;
227*d416dc2bSJeremy L Thompson       }
228*d416dc2bSJeremy L Thompson 
229*d416dc2bSJeremy L Thompson 
230*d416dc2bSJeremy L Thompson     const auto time =
231*d416dc2bSJeremy L Thompson       std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::system_clock::now() - now)
232*d416dc2bSJeremy L Thompson         .count() /
233*d416dc2bSJeremy L Thompson       1e9;
234*d416dc2bSJeremy L Thompson 
235*d416dc2bSJeremy L Thompson 
236*d416dc2bSJeremy L Thompson     if (params.print_timings || not_converged)
237*d416dc2bSJeremy L Thompson       {
238*d416dc2bSJeremy L Thompson         pout << label << ": " << reduction_control.last_step() << " " << v.l2_norm() << " "
239*d416dc2bSJeremy L Thompson              << (params.print_timings ? time : 0.0) << std::endl;
240*d416dc2bSJeremy L Thompson       }
241*d416dc2bSJeremy L Thompson   };
242*d416dc2bSJeremy L Thompson 
243*d416dc2bSJeremy L Thompson   // create and test the libCEED operator
244*d416dc2bSJeremy L Thompson   OperatorCeed<dim, Number, MemorySpace::Default> op_ceed(
245*d416dc2bSJeremy L Thompson     mapping, dof_handler, constraints, quadrature, bp, params.libCEED_resource);
246*d416dc2bSJeremy L Thompson   test("ceed", op_ceed);
247*d416dc2bSJeremy L Thompson 
248*d416dc2bSJeremy L Thompson   // create and test a native deal.II operator
249*d416dc2bSJeremy L Thompson   OperatorDealii<dim, Number> op_dealii(mapping, dof_handler, constraints, quadrature, bp);
250*d416dc2bSJeremy L Thompson   test("dealii", op_dealii);
251*d416dc2bSJeremy L Thompson }
252