LCOV - code coverage report
Current view: top level - fem/libceed - coefficient.cpp (source / functions) Coverage Total Hit
Test: Palace Coverage Report Lines: 100.0 % 36 36
Test Date: 2025-10-23 22:45:05 Functions: 100.0 % 2 2
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 "coefficient.hpp"
       5              : 
       6              : #include <mfem.hpp>
       7              : #include "fem/libceed/ceed.hpp"
       8              : #include "models/materialoperator.hpp"
       9              : 
      10              : #include "fem/qfunctions/coeff/coeff_qf.h"
      11              : 
      12              : namespace palace::ceed
      13              : {
      14              : 
      15              : namespace
      16              : {
      17              : 
      18              : inline auto CoeffDim(int dim)
      19              : {
      20         9934 :   return dim * dim;
      21              : }
      22              : 
      23              : inline void MakeDiagonalCoefficient(int dim, CeedIntScalar *mat_coeff, CeedScalar a,
      24              :                                     CeedInt k)
      25              : {
      26              :   const int coeff_dim = CoeffDim(dim);
      27       189742 :   for (int i = 0; i < coeff_dim; i++)
      28              :   {
      29       161769 :     mat_coeff[coeff_dim * k + i].second = 0.0;
      30              :   }
      31        91600 :   for (int di = 0; di < dim; ++di)
      32              :   {
      33        63627 :     const int idx = di * (dim + 1);
      34        63627 :     mat_coeff[coeff_dim * k + idx].second = a;
      35              :   }
      36              : }
      37              : 
      38              : inline auto *AttrMat(CeedIntScalar *ctx)
      39              : {
      40              :   return ctx + 1;
      41              : }
      42              : 
      43              : inline auto *MatCoeff(CeedIntScalar *ctx)
      44              : {
      45       206974 :   const CeedInt num_attr = ctx[0].first;
      46       212519 :   return ctx + 2 + num_attr;
      47              : }
      48              : 
      49              : }  // namespace
      50              : 
      51        15479 : std::vector<CeedIntScalar> PopulateCoefficientContext(int dim,
      52              :                                                       const MaterialPropertyCoefficient *Q,
      53              :                                                       bool transpose, double a)
      54              : {
      55        15479 :   if (!Q)
      56              :   {
      57              :     // No attributes are stored in the map from attributes to material property coefficient,
      58              :     // indicating that all attributes map to the same identity coefficient.
      59         5545 :     std::vector<CeedIntScalar> ctx(2 + CoeffDim(dim), {0});
      60         5545 :     ctx[0].first = 0;
      61         5545 :     ctx[1].first = 1;
      62              :     MakeDiagonalCoefficient(dim, MatCoeff(ctx.data()), a, 0);
      63              :     return ctx;
      64              :   }
      65              : 
      66              :   // Material property coefficients might be empty if all attributes map to zero
      67              :   // coefficient.
      68              :   const auto &attr_mat = Q->GetAttributeToMaterial();
      69              :   const auto &mat_coeff = Q->GetMaterialProperties();
      70         9934 :   MFEM_VERIFY(attr_mat.Size() > 0, "Empty attributes for MaterialPropertyCoefficient!");
      71         9934 :   MFEM_VERIFY(attr_mat.Max() < mat_coeff.SizeK(),
      72              :               "Invalid attribute material property for MaterialPropertyCoefficient ("
      73              :                   << attr_mat.Max() << " vs. " << mat_coeff.SizeK() << ")!");
      74         9934 :   MFEM_VERIFY(mat_coeff.SizeI() == mat_coeff.SizeJ() &&
      75              :                   (mat_coeff.SizeI() == 1 || mat_coeff.SizeI() == dim),
      76              :               "Dimension mismatch for MaterialPropertyCoefficient and libCEED integrator!");
      77              : 
      78              :   // Map unassigned attributes to zero material property coefficient (the last material
      79              :   // property is reserved for zero).
      80              :   const int coeff_dim = CoeffDim(dim);
      81         9934 :   std::vector<CeedIntScalar> ctx(2 + attr_mat.Size() + coeff_dim * (mat_coeff.SizeK() + 1));
      82         9934 :   ctx[0].first = attr_mat.Size();
      83              :   const int zero_mat = mat_coeff.SizeK();
      84       144538 :   for (int i = 0; i < attr_mat.Size(); i++)
      85              :   {
      86       134604 :     const int k = attr_mat[i];
      87       269208 :     AttrMat(ctx.data())[i].first = (k < 0) ? zero_mat : k;
      88              :   }
      89              : 
      90              :   // Copy material properties.
      91         9934 :   ctx[1 + attr_mat.Size()].first = mat_coeff.SizeK() + 1;
      92        49436 :   for (int k = 0; k < mat_coeff.SizeK(); k++)
      93              :   {
      94        39502 :     if (mat_coeff.SizeI() == 1)
      95              :     {
      96              :       // Copy as diagonal matrix coefficient.
      97        22428 :       MakeDiagonalCoefficient(dim, MatCoeff(ctx.data()), a * mat_coeff(0, 0, k), k);
      98              :     }
      99              :     else
     100              :     {
     101        61824 :       for (int dj = 0; dj < dim; ++dj)
     102              :       {
     103       166056 :         for (int di = 0; di < dim; ++di)
     104              :         {
     105              :           // Column-major ordering.
     106       121306 :           const int idx = transpose ? (di * dim) + dj : (dj * dim) + di;
     107       121306 :           MatCoeff(ctx.data())[coeff_dim * k + idx].second = a * mat_coeff(di, dj, k);
     108              :         }
     109              :       }
     110              :     }
     111              :   }
     112        73174 :   for (int d = 0; d < coeff_dim; d++)
     113              :   {
     114        63240 :     MatCoeff(ctx.data())[coeff_dim * zero_mat + d].second = 0.0;
     115              :   }
     116              : 
     117              :   return ctx;
     118              : }
     119              : 
     120              : std::vector<CeedIntScalar>
     121           72 : PopulateCoefficientContext(int dim_mass, const MaterialPropertyCoefficient *Q_mass, int dim,
     122              :                            const MaterialPropertyCoefficient *Q, bool transpose_mass,
     123              :                            bool transpose, double a_mass, double a)
     124              : {
     125              :   // Mass coefficient comes first, then the other one for the QFunction.
     126           72 :   auto ctx_mass = PopulateCoefficientContext(dim_mass, Q_mass, transpose_mass, a_mass);
     127           72 :   auto ctx = PopulateCoefficientContext(dim, Q, transpose, a);
     128           72 :   ctx_mass.insert(ctx_mass.end(), ctx.begin(), ctx.end());
     129           72 :   return ctx_mass;
     130              : }
     131              : 
     132              : }  // namespace palace::ceed
        

Generated by: LCOV version 2.0-1