LCOV - code coverage report
Current view: top level - src/userobjects - NekBinnedSideIntegral.C (source / functions) Hit Total Coverage
Test: neams-th-coe/cardinal: be601f Lines: 55 66 83.3 %
Date: 2025-07-15 20:50:38 Functions: 6 7 85.7 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /********************************************************************/
       2             : /*                  SOFTWARE COPYRIGHT NOTIFICATION                 */
       3             : /*                             Cardinal                             */
       4             : /*                                                                  */
       5             : /*                  (c) 2021 UChicago Argonne, LLC                  */
       6             : /*                        ALL RIGHTS RESERVED                       */
       7             : /*                                                                  */
       8             : /*                 Prepared by UChicago Argonne, LLC                */
       9             : /*               Under Contract No. DE-AC02-06CH11357               */
      10             : /*                With the U. S. Department of Energy               */
      11             : /*                                                                  */
      12             : /*             Prepared by Battelle Energy Alliance, LLC            */
      13             : /*               Under Contract No. DE-AC07-05ID14517               */
      14             : /*                With the U. S. Department of Energy               */
      15             : /*                                                                  */
      16             : /*                 See LICENSE for full restrictions                */
      17             : /********************************************************************/
      18             : 
      19             : #ifdef ENABLE_NEK_COUPLING
      20             : 
      21             : #include "NekBinnedSideIntegral.h"
      22             : #include "NekInterface.h"
      23             : 
      24             : registerMooseObject("CardinalApp", NekBinnedSideIntegral);
      25             : 
      26             : InputParameters
      27         113 : NekBinnedSideIntegral::validParams()
      28             : {
      29         113 :   InputParameters params = NekSideSpatialBinUserObject::validParams();
      30         113 :   params.addClassDescription(
      31             :       "Compute the spatially-binned side integral of a field over a boundary of the NekRS mesh");
      32         113 :   return params;
      33           0 : }
      34             : 
      35          57 : NekBinnedSideIntegral::NekBinnedSideIntegral(const InputParameters & parameters)
      36          57 :   : NekSideSpatialBinUserObject(parameters)
      37             : {
      38          56 :   if (_fixed_mesh)
      39          56 :     computeBinVolumes();
      40          56 : }
      41             : 
      42             : void
      43          56 : NekBinnedSideIntegral::getBinVolumes()
      44             : {
      45          56 :   resetPartialStorage();
      46             : 
      47          56 :   mesh_t * mesh = nekrs::entireMesh();
      48          56 :   const auto & sgeo = nekrs::getSgeo();
      49             : 
      50       92688 :   for (int i = 0; i < mesh->Nelements; ++i)
      51             :   {
      52      648424 :     for (int j = 0; j < mesh->Nfaces; ++j)
      53             :     {
      54      555792 :       int face_id = mesh->EToB[i * mesh->Nfaces + j];
      55      555792 :       if (std::find(_boundary.begin(), _boundary.end(), face_id) != _boundary.end())
      56             :       {
      57       38472 :         int offset = i * mesh->Nfaces * mesh->Nfp + j * mesh->Nfp;
      58      625224 :         for (int v = 0; v < mesh->Nfp; ++v)
      59             :         {
      60      586752 :           Point p = nekPoint(i, j, v);
      61      586752 :           unsigned int b = bin(p);
      62      586752 :           _bin_partial_values[b] += sgeo[mesh->Nsgeo * (offset + v) + WSJID];
      63      586752 :           _bin_partial_counts[b]++;
      64             :         }
      65             :       }
      66             :     }
      67             :   }
      68             : 
      69             :   // sum across all processes
      70          56 :   MPI_Allreduce(
      71             :       _bin_partial_values, _bin_volumes, _n_bins, MPI_DOUBLE, MPI_SUM, platform->comm.mpiComm);
      72          56 :   MPI_Allreduce(
      73             :       _bin_partial_counts, _bin_counts, _n_bins, MPI_INT, MPI_SUM, platform->comm.mpiComm);
      74             : 
      75             :   // dimensionalize
      76         272 :   for (unsigned int i = 0; i < _n_bins; ++i)
      77         216 :     nekrs::dimensionalizeArea(_bin_volumes[i]);
      78          56 : }
      79             : 
      80             : void
      81          72 : NekBinnedSideIntegral::binnedSideIntegral(const field::NekFieldEnum & integrand,
      82             :                                           double * total_integral)
      83             : {
      84          72 :   resetPartialStorage();
      85             : 
      86          72 :   mesh_t * mesh = nekrs::entireMesh();
      87          72 :   double (*f)(int) = nekrs::solutionPointer(integrand);
      88          72 :   const auto & sgeo = nekrs::getSgeo();
      89             : 
      90      107936 :   for (int i = 0; i < mesh->Nelements; ++i)
      91             :   {
      92      755048 :     for (int j = 0; j < mesh->Nfaces; ++j)
      93             :     {
      94      647184 :       int face_id = mesh->EToB[i * mesh->Nfaces + j];
      95      647184 :       if (std::find(_boundary.begin(), _boundary.end(), face_id) != _boundary.end())
      96             :       {
      97       39240 :         int offset = i * mesh->Nfaces * mesh->Nfp + j * mesh->Nfp;
      98      638280 :         for (int v = 0; v < mesh->Nfp; ++v)
      99             :         {
     100      599040 :           Point p = nekPoint(i, j, v);
     101      599040 :           unsigned int b = bin(p);
     102      599040 :           _bin_partial_values[b] +=
     103      599040 :               f(mesh->vmapM[offset + v]) * sgeo[mesh->Nsgeo * (offset + v) + WSJID];
     104             :         }
     105             :       }
     106             :     }
     107             :   }
     108             : 
     109             :   // sum across all processes
     110          72 :   MPI_Allreduce(
     111             :       _bin_partial_values, total_integral, _n_bins, MPI_DOUBLE, MPI_SUM, platform->comm.mpiComm);
     112             : 
     113             :   // dimensionalize
     114         368 :   for (unsigned int i = 0; i < _n_bins; ++i)
     115         296 :     nekrs::dimensionalizeSideIntegral(integrand, _bin_volumes[i], total_integral[i]);
     116          72 : }
     117             : 
     118             : Real
     119           0 : NekBinnedSideIntegral::spatialValue(const Point & p, const unsigned int & component) const
     120             : {
     121           0 :   const auto & i = bin(p);
     122           0 :   return _bin_values[i] * _velocity_bin_directions[i](component);
     123             : }
     124             : 
     125             : void
     126          72 : NekBinnedSideIntegral::computeIntegral()
     127             : {
     128             :   // if the mesh is changing, re-compute the areas of the bins
     129          72 :   if (!_fixed_mesh)
     130           0 :     computeBinVolumes();
     131             : 
     132          72 :   if (_field == field::velocity_component)
     133             :   {
     134           0 :     binnedSideIntegral(field::velocity_x, _bin_values_x);
     135           0 :     binnedSideIntegral(field::velocity_y, _bin_values_y);
     136           0 :     binnedSideIntegral(field::velocity_z, _bin_values_z);
     137             : 
     138           0 :     for (unsigned int i = 0; i < num_bins(); ++i)
     139             :     {
     140           0 :       Point velocity(_bin_values_x[i], _bin_values_y[i], _bin_values_z[i]);
     141           0 :       _bin_values[i] = _velocity_bin_directions[i] * velocity;
     142             :     }
     143             :   }
     144             :   else
     145          72 :     binnedSideIntegral(_field, _bin_values);
     146          72 : }
     147             : 
     148             : void
     149          72 : NekBinnedSideIntegral::executeUserObject()
     150             : {
     151          72 :   computeIntegral();
     152          72 : }
     153             : 
     154             : #endif

Generated by: LCOV version 1.14