LCOV - code coverage report
Current view: top level - fem/libceed - integrator.cpp (source / functions) Coverage Total Hit
Test: Palace Coverage Report Lines: 55.8 % 215 120
Test Date: 2025-10-23 22:45:05 Functions: 70.0 % 10 7
Legend: Lines: hit not hit

            Line data    Source code
       1              : // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
       2              : // SPDX-License-Identifier: Apache-2.0
       3              : 
       4              : #include "integrator.hpp"
       5              : 
       6              : #include <string>
       7              : #include <ceed/backend.h>
       8              : #include <mfem.hpp>
       9              : #include "utils/diagnostic.hpp"
      10              : 
      11              : PalacePragmaDiagnosticPush
      12              : PalacePragmaDiagnosticDisableUnused
      13              : 
      14              : #include "fem/qfunctions/apply_qf.h"
      15              : #include "fem/qfunctions/geom_qf.h"
      16              : 
      17              : PalacePragmaDiagnosticPop
      18              : 
      19              : namespace palace::ceed
      20              : {
      21              : 
      22              : namespace
      23              : {
      24              : 
      25        15407 : void AddQFunctionActiveInputs(unsigned int ops, Ceed ceed, CeedBasis basis,
      26              :                               CeedQFunction qf, std::string name = "u")
      27              : {
      28              :   // Add inputs or outputs with evaluation modes for the active vector of a QFunction.
      29              :   CeedInt num_comp;
      30        15407 :   PalaceCeedCall(ceed, CeedBasisGetNumComponents(basis, &num_comp));
      31        15407 :   if (ops & EvalMode::None)
      32              :   {
      33            0 :     PalaceCeedCall(ceed, CeedQFunctionAddInput(qf, name.c_str(), num_comp, CEED_EVAL_NONE));
      34              :   }
      35        15407 :   if (ops & EvalMode::Interp)
      36              :   {
      37              :     CeedInt q_comp;
      38         8878 :     PalaceCeedCall(ceed,
      39              :                    CeedBasisGetNumQuadratureComponents(basis, CEED_EVAL_INTERP, &q_comp));
      40         8878 :     PalaceCeedCall(
      41              :         ceed, CeedQFunctionAddInput(qf, name.c_str(), num_comp * q_comp, CEED_EVAL_INTERP));
      42              :   }
      43        15407 :   if (ops & EvalMode::Grad)
      44              :   {
      45              :     CeedInt q_comp;
      46         4226 :     PalaceCeedCall(ceed,
      47              :                    CeedBasisGetNumQuadratureComponents(basis, CEED_EVAL_GRAD, &q_comp));
      48        12678 :     PalaceCeedCall(ceed, CeedQFunctionAddInput(qf, (std::string("grad_") + name).c_str(),
      49              :                                                num_comp * q_comp, CEED_EVAL_GRAD));
      50              :   }
      51        15407 :   if (ops & EvalMode::Div)
      52              :   {
      53              :     CeedInt q_comp;
      54          582 :     PalaceCeedCall(ceed,
      55              :                    CeedBasisGetNumQuadratureComponents(basis, CEED_EVAL_DIV, &q_comp));
      56         1746 :     PalaceCeedCall(ceed, CeedQFunctionAddInput(qf, (std::string("div_") + name).c_str(),
      57              :                                                num_comp * q_comp, CEED_EVAL_DIV));
      58              :   }
      59        15407 :   if (ops & EvalMode::Curl)
      60              :   {
      61              :     CeedInt q_comp;
      62         1793 :     PalaceCeedCall(ceed,
      63              :                    CeedBasisGetNumQuadratureComponents(basis, CEED_EVAL_CURL, &q_comp));
      64         5379 :     PalaceCeedCall(ceed, CeedQFunctionAddInput(qf, (std::string("curl_") + name).c_str(),
      65              :                                                num_comp * q_comp, CEED_EVAL_CURL));
      66              :   }
      67        15407 : }
      68              : 
      69        15407 : void AddQFunctionActiveOutputs(unsigned int ops, Ceed ceed, CeedBasis basis,
      70              :                                CeedQFunction qf, std::string name = "v")
      71              : {
      72              :   // Add inputs or outputs with evaluation modes for the active vector of a QFunction.
      73              :   CeedInt num_comp;
      74        15407 :   PalaceCeedCall(ceed, CeedBasisGetNumComponents(basis, &num_comp));
      75        15407 :   if (ops & EvalMode::None)
      76              :   {
      77            0 :     PalaceCeedCall(ceed,
      78              :                    CeedQFunctionAddOutput(qf, name.c_str(), num_comp, CEED_EVAL_NONE));
      79              :   }
      80        15407 :   if (ops & EvalMode::Interp)
      81              :   {
      82              :     CeedInt q_comp;
      83        10244 :     PalaceCeedCall(ceed,
      84              :                    CeedBasisGetNumQuadratureComponents(basis, CEED_EVAL_INTERP, &q_comp));
      85        10244 :     PalaceCeedCall(ceed, CeedQFunctionAddOutput(qf, name.c_str(), num_comp * q_comp,
      86              :                                                 CEED_EVAL_INTERP));
      87              :   }
      88        15407 :   if (ops & EvalMode::Grad)
      89              :   {
      90              :     CeedInt q_comp;
      91         2860 :     PalaceCeedCall(ceed,
      92              :                    CeedBasisGetNumQuadratureComponents(basis, CEED_EVAL_GRAD, &q_comp));
      93         8580 :     PalaceCeedCall(ceed, CeedQFunctionAddOutput(qf, (std::string("grad_") + name).c_str(),
      94              :                                                 num_comp * q_comp, CEED_EVAL_GRAD));
      95              :   }
      96        15407 :   if (ops & EvalMode::Div)
      97              :   {
      98              :     CeedInt q_comp;
      99          582 :     PalaceCeedCall(ceed,
     100              :                    CeedBasisGetNumQuadratureComponents(basis, CEED_EVAL_DIV, &q_comp));
     101         1746 :     PalaceCeedCall(ceed, CeedQFunctionAddOutput(qf, (std::string("div_") + name).c_str(),
     102              :                                                 num_comp * q_comp, CEED_EVAL_DIV));
     103              :   }
     104        15407 :   if (ops & EvalMode::Curl)
     105              :   {
     106              :     CeedInt q_comp;
     107         1793 :     PalaceCeedCall(ceed,
     108              :                    CeedBasisGetNumQuadratureComponents(basis, CEED_EVAL_CURL, &q_comp));
     109         5379 :     PalaceCeedCall(ceed, CeedQFunctionAddOutput(qf, (std::string("curl_") + name).c_str(),
     110              :                                                 num_comp * q_comp, CEED_EVAL_CURL));
     111              :   }
     112        15407 : }
     113              : 
     114        30814 : void AddOperatorActiveFields(unsigned int ops, Ceed ceed, CeedElemRestriction restr,
     115              :                              CeedBasis basis, CeedOperator op, const std::string &name,
     116              :                              CeedVector v)
     117              : {
     118              :   // Set active input or output vector fields of an operator.
     119        30814 :   if (ops & EvalMode::None)
     120              :   {
     121            0 :     PalaceCeedCall(ceed, CeedOperatorSetField(op, name.c_str(), restr, CEED_BASIS_NONE, v));
     122              :   }
     123        30814 :   if (ops & EvalMode::Interp)
     124              :   {
     125        19122 :     PalaceCeedCall(ceed, CeedOperatorSetField(op, name.c_str(), restr, basis, v));
     126              :   }
     127        30814 :   if (ops & EvalMode::Grad)
     128              :   {
     129        21258 :     PalaceCeedCall(ceed, CeedOperatorSetField(op, (std::string("grad_") + name).c_str(),
     130              :                                               restr, basis, v));
     131              :   }
     132        30814 :   if (ops & EvalMode::Div)
     133              :   {
     134         3492 :     PalaceCeedCall(ceed, CeedOperatorSetField(op, (std::string("div_") + name).c_str(),
     135              :                                               restr, basis, v));
     136              :   }
     137        30814 :   if (ops & EvalMode::Curl)
     138              :   {
     139        10758 :     PalaceCeedCall(ceed, CeedOperatorSetField(op, (std::string("curl_") + name).c_str(),
     140              :                                               restr, basis, v));
     141              :   }
     142        30814 : }
     143              : 
     144              : void AddOperatorActiveInputFields(unsigned int ops, Ceed ceed, CeedElemRestriction restr,
     145              :                                   CeedBasis basis, CeedOperator op, std::string name = "u",
     146              :                                   CeedVector v = CEED_VECTOR_ACTIVE)
     147              : {
     148        15407 :   AddOperatorActiveFields(ops, ceed, restr, basis, op, name, v);
     149        15407 : }
     150              : 
     151              : void AddOperatorActiveOutputFields(unsigned int ops, Ceed ceed, CeedElemRestriction restr,
     152              :                                    CeedBasis basis, CeedOperator op, std::string name = "v",
     153              :                                    CeedVector v = CEED_VECTOR_ACTIVE)
     154              : {
     155        15407 :   AddOperatorActiveFields(ops, ceed, restr, basis, op, name, v);
     156        15407 : }
     157              : 
     158            0 : std::vector<CeedInt> QuadratureDataSetup(unsigned int ops, Ceed ceed,
     159              :                                          CeedElemRestriction restr, CeedBasis basis,
     160              :                                          CeedVector *q_data,
     161              :                                          CeedElemRestriction *q_data_restr)
     162              : {
     163              :   // Operator application at each quadrature point should be square, so just use the inputs
     164              :   // and ignore the outputs.
     165              :   CeedInt num_comp;
     166            0 :   PalaceCeedCall(ceed, CeedBasisGetNumComponents(basis, &num_comp));
     167              : 
     168              :   std::vector<CeedInt> active_input_sizes;
     169            0 :   if (ops & EvalMode::None)
     170              :   {
     171              :     active_input_sizes.push_back(num_comp);
     172              :   }
     173            0 :   if (ops & EvalMode::Interp)
     174              :   {
     175              :     CeedInt q_comp;
     176            0 :     PalaceCeedCall(ceed,
     177              :                    CeedBasisGetNumQuadratureComponents(basis, CEED_EVAL_INTERP, &q_comp));
     178            0 :     active_input_sizes.push_back(num_comp * q_comp);
     179              :   }
     180            0 :   if (ops & EvalMode::Grad)
     181              :   {
     182              :     CeedInt q_comp;
     183            0 :     PalaceCeedCall(ceed,
     184              :                    CeedBasisGetNumQuadratureComponents(basis, CEED_EVAL_GRAD, &q_comp));
     185            0 :     active_input_sizes.push_back(num_comp * q_comp);
     186              :   }
     187            0 :   if (ops & EvalMode::Div)
     188              :   {
     189              :     CeedInt q_comp;
     190            0 :     PalaceCeedCall(ceed,
     191              :                    CeedBasisGetNumQuadratureComponents(basis, CEED_EVAL_DIV, &q_comp));
     192            0 :     active_input_sizes.push_back(num_comp * q_comp);
     193              :   }
     194            0 :   if (ops & EvalMode::Curl)
     195              :   {
     196              :     CeedInt q_comp;
     197            0 :     PalaceCeedCall(ceed,
     198              :                    CeedBasisGetNumQuadratureComponents(basis, CEED_EVAL_CURL, &q_comp));
     199            0 :     active_input_sizes.push_back(num_comp * q_comp);
     200              :   }
     201              : 
     202              :   CeedInt num_elem, num_qpts, q_data_size = 0;
     203            0 :   PalaceCeedCall(ceed, CeedElemRestrictionGetNumElements(restr, &num_elem));
     204            0 :   PalaceCeedCall(ceed, CeedBasisGetNumQuadraturePoints(basis, &num_qpts));
     205            0 :   for (auto size : active_input_sizes)
     206              :   {
     207            0 :     q_data_size += size * size;
     208              :   }
     209              : 
     210            0 :   PalaceCeedCall(
     211              :       ceed, CeedVectorCreate(ceed, (CeedSize)num_elem * num_qpts * q_data_size, q_data));
     212            0 :   PalaceCeedCall(
     213              :       ceed, CeedElemRestrictionCreateStrided(ceed, num_elem, num_qpts, q_data_size,
     214              :                                              (CeedSize)num_elem * num_qpts * q_data_size,
     215              :                                              CEED_STRIDES_BACKEND, q_data_restr));
     216              : 
     217            0 :   return active_input_sizes;
     218              : }
     219              : 
     220            0 : void QuadratureDataAssembly(const std::vector<CeedInt> &qf_active_sizes,
     221              :                             const CeedQFunctionInfo &info, Ceed ceed,
     222              :                             CeedElemRestriction trial_restr, CeedElemRestriction test_restr,
     223              :                             CeedBasis trial_basis, CeedBasis test_basis, CeedVector q_data,
     224              :                             CeedElemRestriction q_data_restr, CeedOperator *op)
     225              : {
     226              :   // Assemble the quadrature data, destroy the operator, and create a new one for the
     227              :   // actual operator application.
     228            0 :   PalaceCeedCall(ceed,
     229              :                  CeedOperatorApply(*op, CEED_VECTOR_NONE, q_data, CEED_REQUEST_IMMEDIATE));
     230            0 :   PalaceCeedCall(ceed, CeedOperatorDestroy(op));
     231              : 
     232            0 :   MFEM_VERIFY(!qf_active_sizes.empty() && qf_active_sizes.size() <= 2,
     233              :               "Invalid number of active QFunction input/output fields ("
     234              :                   << qf_active_sizes.size() << ")!");
     235              :   CeedQFunction apply_qf;
     236            0 :   CeedInt qf_size_1 = qf_active_sizes[0],
     237            0 :           qf_size_2 = (qf_active_sizes.size() > 1) ? qf_active_sizes[1] : 0;
     238            0 :   switch (10 * qf_size_1 + qf_size_2)
     239              :   {
     240              :     case 1:
     241              :     case 10:
     242            0 :       PalaceCeedCall(ceed, CeedQFunctionCreateInterior(
     243              :                                ceed, 1, f_apply_1,
     244              :                                PalaceQFunctionRelativePath(f_apply_1_loc), &apply_qf));
     245              :       break;
     246              :     case 2:
     247              :     case 20:
     248            0 :       PalaceCeedCall(ceed, CeedQFunctionCreateInterior(
     249              :                                ceed, 1, f_apply_2,
     250              :                                PalaceQFunctionRelativePath(f_apply_2_loc), &apply_qf));
     251              :       break;
     252              :     case 3:
     253              :     case 30:
     254            0 :       PalaceCeedCall(ceed, CeedQFunctionCreateInterior(
     255              :                                ceed, 1, f_apply_3,
     256              :                                PalaceQFunctionRelativePath(f_apply_3_loc), &apply_qf));
     257              :       break;
     258              :     case 22:
     259            0 :       PalaceCeedCall(ceed, CeedQFunctionCreateInterior(
     260              :                                ceed, 1, f_apply_22,
     261              :                                PalaceQFunctionRelativePath(f_apply_22_loc), &apply_qf));
     262              :       break;
     263              :     case 33:
     264            0 :       PalaceCeedCall(ceed, CeedQFunctionCreateInterior(
     265              :                                ceed, 1, f_apply_33,
     266              :                                PalaceQFunctionRelativePath(f_apply_33_loc), &apply_qf));
     267              :       break;
     268              :     case 12:
     269            0 :       PalaceCeedCall(ceed, CeedQFunctionCreateInterior(
     270              :                                ceed, 1, f_apply_12,
     271              :                                PalaceQFunctionRelativePath(f_apply_12_loc), &apply_qf));
     272              :       break;
     273              :     case 13:
     274            0 :       PalaceCeedCall(ceed, CeedQFunctionCreateInterior(
     275              :                                ceed, 1, f_apply_13,
     276              :                                PalaceQFunctionRelativePath(f_apply_13_loc), &apply_qf));
     277              :       break;
     278              :     case 21:
     279            0 :       PalaceCeedCall(ceed, CeedQFunctionCreateInterior(
     280              :                                ceed, 1, f_apply_21,
     281              :                                PalaceQFunctionRelativePath(f_apply_21_loc), &apply_qf));
     282              :       break;
     283              :     case 31:
     284            0 :       PalaceCeedCall(ceed, CeedQFunctionCreateInterior(
     285              :                                ceed, 1, f_apply_31,
     286              :                                PalaceQFunctionRelativePath(f_apply_31_loc), &apply_qf));
     287              :       break;
     288            0 :     default:
     289            0 :       MFEM_ABORT("Invalid number of QFunction input/output components ("
     290              :                  << qf_size_1 << ", " << qf_size_2 << ")!");
     291              :       apply_qf = nullptr;  // Silence compiler warning
     292              :   }
     293              : 
     294              :   // Inputs/outputs.
     295              :   {
     296              :     CeedInt q_data_size;
     297            0 :     PalaceCeedCall(ceed, CeedElemRestrictionGetNumComponents(q_data_restr, &q_data_size));
     298            0 :     PalaceCeedCall(ceed,
     299              :                    CeedQFunctionAddInput(apply_qf, "q_data", q_data_size, CEED_EVAL_NONE));
     300              :   }
     301            0 :   AddQFunctionActiveInputs(info.trial_ops, ceed, trial_basis, apply_qf);
     302            0 :   AddQFunctionActiveOutputs(info.test_ops, ceed, test_basis, apply_qf);
     303              : 
     304              :   // Create the actual operator.
     305            0 :   PalaceCeedCall(ceed, CeedOperatorCreate(ceed, apply_qf, nullptr, nullptr, op));
     306            0 :   PalaceCeedCall(ceed, CeedQFunctionDestroy(&apply_qf));
     307              : 
     308            0 :   PalaceCeedCall(
     309              :       ceed, CeedOperatorSetField(*op, "q_data", q_data_restr, CEED_BASIS_NONE, q_data));
     310            0 :   AddOperatorActiveInputFields(info.trial_ops, ceed, trial_restr, trial_basis, *op);
     311            0 :   AddOperatorActiveOutputFields(info.test_ops, ceed, test_restr, test_basis, *op);
     312              : 
     313            0 :   PalaceCeedCall(ceed, CeedOperatorCheckReady(*op));
     314            0 : }
     315              : 
     316              : }  // namespace
     317              : 
     318        12191 : int CeedGeometryDataGetSpaceDimension(CeedElemRestriction geom_data_restr, CeedInt dim,
     319              :                                       CeedInt *space_dim)
     320              : {
     321        12191 :   if (space_dim)
     322              :   {
     323              :     Ceed ceed;
     324              :     CeedInt geom_data_size;
     325        12191 :     PalaceCeedCallBackend(CeedElemRestrictionGetCeed(geom_data_restr, &ceed));
     326        12191 :     PalaceCeedCall(ceed,
     327              :                    CeedElemRestrictionGetNumComponents(geom_data_restr, &geom_data_size));
     328        12191 :     *space_dim = (geom_data_size - 2) / dim;
     329              :     MFEM_ASSERT(2 + (*space_dim) * dim == geom_data_size,
     330              :                 "Invalid size for geometry quadrature data!");
     331              :   }
     332        12191 :   return CEED_ERROR_SUCCESS;
     333              : }
     334              : 
     335        54674 : void AssembleCeedGeometryData(Ceed ceed, CeedElemRestriction mesh_restr,
     336              :                               CeedBasis mesh_basis, CeedVector mesh_nodes,
     337              :                               CeedElemRestriction attr_restr, CeedBasis attr_basis,
     338              :                               CeedVector elem_attr, CeedVector geom_data,
     339              :                               CeedElemRestriction geom_data_restr)
     340              : {
     341              :   CeedInt dim, space_dim, num_qpts;
     342        54674 :   PalaceCeedCall(ceed, CeedBasisGetDimension(mesh_basis, &dim));
     343        54674 :   PalaceCeedCall(ceed, CeedBasisGetNumComponents(mesh_basis, &space_dim));
     344        54674 :   PalaceCeedCall(ceed, CeedBasisGetNumQuadraturePoints(mesh_basis, &num_qpts));
     345              : 
     346              :   // Create the QFunction that computes the quadrature data.
     347              :   CeedQFunction build_qf;
     348        54674 :   switch (10 * space_dim + dim)
     349              :   {
     350              :     case 22:
     351        14963 :       PalaceCeedCall(ceed, CeedQFunctionCreateInterior(
     352              :                                ceed, 1, f_build_geom_factor_22,
     353              :                                PalaceQFunctionRelativePath(f_build_geom_factor_22_loc),
     354              :                                &build_qf));
     355              :       break;
     356              :     case 33:
     357        13504 :       PalaceCeedCall(ceed, CeedQFunctionCreateInterior(
     358              :                                ceed, 1, f_build_geom_factor_33,
     359              :                                PalaceQFunctionRelativePath(f_build_geom_factor_33_loc),
     360              :                                &build_qf));
     361              :       break;
     362              :     case 21:
     363        11232 :       PalaceCeedCall(ceed, CeedQFunctionCreateInterior(
     364              :                                ceed, 1, f_build_geom_factor_21,
     365              :                                PalaceQFunctionRelativePath(f_build_geom_factor_21_loc),
     366              :                                &build_qf));
     367              :       break;
     368              :     case 32:
     369        14975 :       PalaceCeedCall(ceed, CeedQFunctionCreateInterior(
     370              :                                ceed, 1, f_build_geom_factor_32,
     371              :                                PalaceQFunctionRelativePath(f_build_geom_factor_32_loc),
     372              :                                &build_qf));
     373              :       break;
     374            0 :     default:
     375            0 :       MFEM_ABORT("Invalid value of (dim, space_dim) = ("
     376              :                  << dim << ", " << space_dim << ") for geometry factor quadrature data!");
     377              :       build_qf = nullptr;  // Silence compiler warning
     378              :   }
     379              : 
     380              :   // Inputs/outputs.
     381        54674 :   PalaceCeedCall(ceed, CeedQFunctionAddInput(build_qf, "attr", 1, CEED_EVAL_INTERP));
     382        54674 :   PalaceCeedCall(ceed, CeedQFunctionAddInput(build_qf, "q_w", 1, CEED_EVAL_WEIGHT));
     383        54674 :   PalaceCeedCall(
     384              :       ceed, CeedQFunctionAddInput(build_qf, "grad_x", space_dim * dim, CEED_EVAL_GRAD));
     385              :   {
     386              :     CeedInt geom_data_size;
     387        54674 :     PalaceCeedCall(ceed,
     388              :                    CeedElemRestrictionGetNumComponents(geom_data_restr, &geom_data_size));
     389        54674 :     MFEM_VERIFY(geom_data_size == 2 + space_dim * dim,
     390              :                 "Insufficient storage for geometry quadrature data!");
     391        54674 :     PalaceCeedCall(ceed, CeedQFunctionAddOutput(build_qf, "geom_data", geom_data_size,
     392              :                                                 CEED_EVAL_NONE));
     393              :   }
     394              : 
     395              :   // Create the operator that builds the quadrature data.
     396              :   CeedOperator build_op;
     397        54674 :   PalaceCeedCall(ceed, CeedOperatorCreate(ceed, build_qf, nullptr, nullptr, &build_op));
     398        54674 :   PalaceCeedCall(ceed, CeedQFunctionDestroy(&build_qf));
     399              : 
     400        54674 :   PalaceCeedCall(ceed,
     401              :                  CeedOperatorSetField(build_op, "attr", attr_restr, attr_basis, elem_attr));
     402        54674 :   PalaceCeedCall(ceed, CeedOperatorSetField(build_op, "q_w", CEED_ELEMRESTRICTION_NONE,
     403              :                                             mesh_basis, CEED_VECTOR_NONE));
     404        54674 :   PalaceCeedCall(ceed, CeedOperatorSetField(build_op, "grad_x", mesh_restr, mesh_basis,
     405              :                                             CEED_VECTOR_ACTIVE));
     406        54674 :   PalaceCeedCall(ceed, CeedOperatorSetField(build_op, "geom_data", geom_data_restr,
     407              :                                             CEED_BASIS_NONE, CEED_VECTOR_ACTIVE));
     408              : 
     409        54674 :   PalaceCeedCall(ceed, CeedOperatorCheckReady(build_op));
     410              : 
     411              :   // Compute the quadrature data for the operator.
     412        54674 :   PalaceCeedCall(
     413              :       ceed, CeedOperatorApply(build_op, mesh_nodes, geom_data, CEED_REQUEST_IMMEDIATE));
     414        54674 :   PalaceCeedCall(ceed, CeedOperatorDestroy(&build_op));
     415        54674 : }
     416              : 
     417        15407 : void AssembleCeedOperator(const CeedQFunctionInfo &info, void *ctx, std::size_t ctx_size,
     418              :                           Ceed ceed, CeedElemRestriction trial_restr,
     419              :                           CeedElemRestriction test_restr, CeedBasis trial_basis,
     420              :                           CeedBasis test_basis, CeedVector geom_data,
     421              :                           CeedElemRestriction geom_data_restr, CeedOperator *op)
     422              : {
     423              :   // If we are going to be assembling the quadrature data, construct the storage vector for
     424              :   // it (to be owned by the operator).
     425        15407 :   CeedVector q_data = nullptr;
     426        15407 :   CeedElemRestriction q_data_restr = nullptr;
     427              :   std::vector<CeedInt> qf_active_sizes;
     428        15407 :   if (info.assemble_q_data)
     429              :   {
     430            0 :     qf_active_sizes = QuadratureDataSetup(info.trial_ops, ceed, trial_restr, trial_basis,
     431              :                                           &q_data, &q_data_restr);
     432              :   }
     433              : 
     434              :   // Create the QFunction that defines the action of the operator (or its setup).
     435              :   CeedQFunction apply_qf;
     436        15407 :   PalaceCeedCall(ceed, CeedQFunctionCreateInterior(ceed, 1, info.apply_qf,
     437              :                                                    info.apply_qf_path.c_str(), &apply_qf));
     438              : 
     439              :   CeedQFunctionContext apply_ctx;
     440        15407 :   PalaceCeedCall(ceed, CeedQFunctionContextCreate(ceed, &apply_ctx));
     441        15407 :   PalaceCeedCall(ceed, CeedQFunctionContextSetData(apply_ctx, CEED_MEM_HOST,
     442              :                                                    CEED_COPY_VALUES, ctx_size, ctx));
     443        15407 :   PalaceCeedCall(ceed, CeedQFunctionSetContext(apply_qf, apply_ctx));
     444        15407 :   PalaceCeedCall(ceed, CeedQFunctionContextDestroy(&apply_ctx));
     445              : 
     446              :   // Inputs/outputs.
     447              :   {
     448              :     CeedInt geom_data_size;
     449        15407 :     PalaceCeedCall(ceed,
     450              :                    CeedElemRestrictionGetNumComponents(geom_data_restr, &geom_data_size));
     451        15407 :     PalaceCeedCall(
     452              :         ceed, CeedQFunctionAddInput(apply_qf, "geom_data", geom_data_size, CEED_EVAL_NONE));
     453              :   }
     454        15407 :   if (info.trial_ops & EvalMode::Weight)
     455              :   {
     456         1157 :     PalaceCeedCall(ceed, CeedQFunctionAddInput(apply_qf, "q_w", 1, CEED_EVAL_WEIGHT));
     457              :   }
     458        15407 :   MFEM_VERIFY(!(info.test_ops & EvalMode::Weight),
     459              :               "CeedOperator should not have quadrature weight output!");
     460        15407 :   if (!info.assemble_q_data)
     461              :   {
     462        15407 :     AddQFunctionActiveInputs(info.trial_ops, ceed, trial_basis, apply_qf);
     463        30814 :     AddQFunctionActiveOutputs(info.test_ops, ceed, test_basis, apply_qf);
     464              :   }
     465              :   else
     466              :   {
     467              :     CeedInt q_data_size;
     468            0 :     PalaceCeedCall(ceed, CeedElemRestrictionGetNumComponents(q_data_restr, &q_data_size));
     469            0 :     PalaceCeedCall(ceed,
     470              :                    CeedQFunctionAddOutput(apply_qf, "q_data", q_data_size, CEED_EVAL_NONE));
     471              :   }
     472              : 
     473              :   // Create the operator.
     474        15407 :   PalaceCeedCall(ceed, CeedOperatorCreate(ceed, apply_qf, nullptr, nullptr, op));
     475        15407 :   PalaceCeedCall(ceed, CeedQFunctionDestroy(&apply_qf));
     476              : 
     477        15407 :   PalaceCeedCall(ceed, CeedOperatorSetField(*op, "geom_data", geom_data_restr,
     478              :                                             CEED_BASIS_NONE, geom_data));
     479        15407 :   if (info.trial_ops & EvalMode::Weight)
     480              :   {
     481         1157 :     PalaceCeedCall(ceed, CeedOperatorSetField(*op, "q_w", CEED_ELEMRESTRICTION_NONE,
     482              :                                               trial_basis, CEED_VECTOR_NONE));
     483              :   }
     484        15407 :   if (!info.assemble_q_data)
     485              :   {
     486        15407 :     AddOperatorActiveInputFields(info.trial_ops, ceed, trial_restr, trial_basis, *op);
     487        30814 :     AddOperatorActiveOutputFields(info.test_ops, ceed, test_restr, test_basis, *op);
     488              :   }
     489              :   else
     490              :   {
     491            0 :     PalaceCeedCall(ceed, CeedOperatorSetField(*op, "q_data", q_data_restr, CEED_BASIS_NONE,
     492              :                                               CEED_VECTOR_ACTIVE));
     493              :   }
     494              : 
     495        15407 :   PalaceCeedCall(ceed, CeedOperatorCheckReady(*op));
     496              : 
     497              :   // Assemble the quadrature data and create the actual operator.
     498        15407 :   if (info.assemble_q_data)
     499              :   {
     500            0 :     QuadratureDataAssembly(qf_active_sizes, info, ceed, trial_restr, test_restr,
     501              :                            trial_basis, test_basis, q_data, q_data_restr, op);
     502              : 
     503              :     // Cleanup (these are now owned by the operator).
     504            0 :     PalaceCeedCall(ceed, CeedElemRestrictionDestroy(&q_data_restr));
     505            0 :     PalaceCeedCall(ceed, CeedVectorDestroy(&q_data));
     506              :   }
     507        15407 : }
     508              : 
     509         1254 : void AssembleCeedInterpolator(Ceed ceed, CeedElemRestriction trial_restr,
     510              :                               CeedElemRestriction test_restr, CeedBasis interp_basis,
     511              :                               CeedOperator *op, CeedOperator *op_t)
     512              : {
     513              :   // Create the QFunction that defines the action of the operator (only an identity as
     514              :   // element dof multiplicity is handled outside of libCEED).
     515              :   CeedQFunction apply_qf, apply_qf_t;
     516         1254 :   PalaceCeedCall(ceed, CeedQFunctionCreateIdentity(ceed, 1, CEED_EVAL_INTERP,
     517              :                                                    CEED_EVAL_NONE, &apply_qf));
     518         1254 :   PalaceCeedCall(ceed, CeedQFunctionCreateIdentity(ceed, 1, CEED_EVAL_NONE,
     519              :                                                    CEED_EVAL_INTERP, &apply_qf_t));
     520              : 
     521              :   // Create the operator.
     522         1254 :   PalaceCeedCall(ceed, CeedOperatorCreate(ceed, apply_qf, nullptr, nullptr, op));
     523         1254 :   PalaceCeedCall(ceed, CeedQFunctionDestroy(&apply_qf));
     524              : 
     525         1254 :   PalaceCeedCall(ceed, CeedOperatorSetField(*op, "input", trial_restr, interp_basis,
     526              :                                             CEED_VECTOR_ACTIVE));
     527         1254 :   PalaceCeedCall(ceed, CeedOperatorSetField(*op, "output", test_restr, CEED_BASIS_NONE,
     528              :                                             CEED_VECTOR_ACTIVE));
     529              : 
     530         1254 :   PalaceCeedCall(ceed, CeedOperatorCheckReady(*op));
     531              : 
     532              :   // Create the transpose operator.
     533         1254 :   PalaceCeedCall(ceed, CeedOperatorCreate(ceed, apply_qf_t, nullptr, nullptr, op_t));
     534         1254 :   PalaceCeedCall(ceed, CeedQFunctionDestroy(&apply_qf_t));
     535              : 
     536         1254 :   PalaceCeedCall(ceed, CeedOperatorSetField(*op_t, "input", test_restr, CEED_BASIS_NONE,
     537              :                                             CEED_VECTOR_ACTIVE));
     538         1254 :   PalaceCeedCall(ceed, CeedOperatorSetField(*op_t, "output", trial_restr, interp_basis,
     539              :                                             CEED_VECTOR_ACTIVE));
     540              : 
     541         1254 :   PalaceCeedCall(ceed, CeedOperatorCheckReady(*op_t));
     542         1254 : }
     543              : 
     544            0 : void AssembleCeedElementErrorIntegrator(
     545              :     const CeedQFunctionInfo &info, void *ctx, std::size_t ctx_size, Ceed ceed,
     546              :     CeedVector input1, CeedVector input2, CeedElemRestriction input1_restr,
     547              :     CeedElemRestriction input2_restr, CeedBasis input1_basis, CeedBasis input2_basis,
     548              :     CeedElemRestriction mesh_elem_restr, CeedVector geom_data,
     549              :     CeedElemRestriction geom_data_restr, CeedOperator *op)
     550              : {
     551            0 :   MFEM_VERIFY(!info.assemble_q_data,
     552              :               "Quadrature interpolator does not support quadrature data assembly!");
     553              : 
     554              :   // Create basis for summing contributions from all quadrature points on the element.
     555              :   CeedInt num_qpts;
     556            0 :   PalaceCeedCall(ceed, CeedBasisGetNumQuadraturePoints(input1_basis, &num_qpts));
     557              :   CeedBasis mesh_elem_basis;
     558              :   {
     559              :     // Note: ceed::GetCeedTopology(CEED_TOPOLOGY_LINE) == 1.
     560            0 :     mfem::Vector Bt(num_qpts), Gt(num_qpts), qX(num_qpts), qW(num_qpts);
     561            0 :     Bt = 1.0;
     562            0 :     Gt = 0.0;
     563            0 :     qX = 0.0;
     564            0 :     qW = 0.0;
     565            0 :     PalaceCeedCall(ceed, CeedBasisCreateH1(ceed, CEED_TOPOLOGY_LINE, 1, 1, num_qpts,
     566              :                                            Bt.GetData(), Gt.GetData(), qX.GetData(),
     567              :                                            qW.GetData(), &mesh_elem_basis));
     568              :   }
     569              : 
     570              :   // Create the QFunction that defines the action of the operator.
     571              :   CeedQFunction apply_qf;
     572            0 :   PalaceCeedCall(ceed, CeedQFunctionCreateInterior(ceed, 1, info.apply_qf,
     573              :                                                    info.apply_qf_path.c_str(), &apply_qf));
     574              : 
     575              :   CeedQFunctionContext apply_ctx;
     576            0 :   PalaceCeedCall(ceed, CeedQFunctionContextCreate(ceed, &apply_ctx));
     577            0 :   PalaceCeedCall(ceed, CeedQFunctionContextSetData(apply_ctx, CEED_MEM_HOST,
     578              :                                                    CEED_COPY_VALUES, ctx_size, ctx));
     579            0 :   PalaceCeedCall(ceed, CeedQFunctionSetContext(apply_qf, apply_ctx));
     580            0 :   PalaceCeedCall(ceed, CeedQFunctionContextDestroy(&apply_ctx));
     581              : 
     582              :   // Inputs/outputs. "Test" operations are the operations for the second input vector.
     583              :   {
     584              :     CeedInt geom_data_size;
     585            0 :     PalaceCeedCall(ceed,
     586              :                    CeedElemRestrictionGetNumComponents(geom_data_restr, &geom_data_size));
     587            0 :     PalaceCeedCall(
     588              :         ceed, CeedQFunctionAddInput(apply_qf, "geom_data", geom_data_size, CEED_EVAL_NONE));
     589              :   }
     590            0 :   if (info.trial_ops & EvalMode::Weight)
     591              :   {
     592            0 :     PalaceCeedCall(ceed, CeedQFunctionAddInput(apply_qf, "q_w", 1, CEED_EVAL_WEIGHT));
     593              :   }
     594            0 :   AddQFunctionActiveInputs(info.trial_ops, ceed, input1_basis, apply_qf, "u_1");
     595            0 :   AddQFunctionActiveInputs(info.test_ops, ceed, input2_basis, apply_qf, "u_2");
     596            0 :   PalaceCeedCall(ceed, CeedQFunctionAddOutput(apply_qf, "v", 1, CEED_EVAL_INTERP));
     597              : 
     598              :   // Create the operator.
     599            0 :   PalaceCeedCall(ceed, CeedOperatorCreate(ceed, apply_qf, nullptr, nullptr, op));
     600            0 :   PalaceCeedCall(ceed, CeedQFunctionDestroy(&apply_qf));
     601              : 
     602            0 :   PalaceCeedCall(ceed, CeedOperatorSetField(*op, "geom_data", geom_data_restr,
     603              :                                             CEED_BASIS_NONE, geom_data));
     604            0 :   if (info.trial_ops & EvalMode::Weight)
     605              :   {
     606            0 :     PalaceCeedCall(ceed, CeedOperatorSetField(*op, "q_w", CEED_ELEMRESTRICTION_NONE,
     607              :                                               input1_basis, CEED_VECTOR_NONE));
     608              :   }
     609            0 :   AddOperatorActiveInputFields(info.trial_ops, ceed, input1_restr, input1_basis, *op, "u_1",
     610              :                                input1);
     611            0 :   AddOperatorActiveInputFields(info.test_ops, ceed, input2_restr, input2_basis, *op, "u_2",
     612              :                                input2);
     613            0 :   PalaceCeedCall(ceed, CeedOperatorSetField(*op, "v", mesh_elem_restr, mesh_elem_basis,
     614              :                                             CEED_VECTOR_ACTIVE));
     615              : 
     616            0 :   PalaceCeedCall(ceed, CeedOperatorCheckReady(*op));
     617              : 
     618              :   // Cleanup (this is now owned by the operator).
     619            0 :   PalaceCeedCall(ceed, CeedBasisDestroy(&mesh_elem_basis));
     620            0 : }
     621              : 
     622              : }  // namespace palace::ceed
        

Generated by: LCOV version 2.0-1