LCOV - code coverage report
Current view: top level - coupling/filtering/filters - FilterFromFunction.h (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 46 0
Test Date: 2026-08-21 15:14:06 Functions: 0.0 % 3 0

            Line data    Source code
       1              : // This file is part of the Mamico project. For conditions of distribution
       2              : // and use, please see the copyright notice in Mamico's main folder, or at
       3              : // www5.in.tum.de/mamico
       4              : 
       5              : #pragma once
       6              : #include "coupling/filtering/interfaces/FilterInterface.h"
       7              : #include <functional>
       8              : 
       9              : namespace coupling {
      10              : namespace filtering {
      11              : template <unsigned int dim> class FilterFromFunction;
      12              : }
      13              : } // namespace coupling
      14              : 
      15              : /*
      16              :  * Extension of FilterInterface.h to allow usage of custom filters using only
      17              :  * two apply functions. Especially ment to be used for application of filters
      18              :  * written in Python.
      19              :  *
      20              :  * Two std::function pointers are required: One for scalar and one for vector
      21              :  * processing.
      22              :  * @author Felix Maurer
      23              :  */
      24              : 
      25              : template <unsigned int dim> class coupling::filtering::FilterFromFunction : public coupling::filtering::FilterInterface<dim> {
      26              : public:
      27            0 :   FilterFromFunction(
      28              :       const std::vector<coupling::datastructures::CouplingCell<dim>*>& inputCellVector,
      29              :       const std::vector<coupling::datastructures::CouplingCell<dim>*>& outputCellVector, std::array<bool, 7> filteredValues,
      30              :       const std::function<std::vector<double>(std::vector<double>, std::vector<std::array<unsigned int, dim>>)>* applyScalar,
      31              :       const std::function<std::vector<std::array<double, dim>>(std::vector<std::array<double, dim>>, std::vector<std::array<unsigned int, dim>>)>* applyVector)
      32            0 :       : coupling::filtering::FilterInterface<dim>(inputCellVector, outputCellVector, filteredValues, "FFF"), _applyScalar(applyScalar),
      33            0 :         _applyVector(applyVector) {
      34              : 
      35            0 :     if (applyScalar == nullptr or applyVector == nullptr)
      36            0 :       throw std::runtime_error("ERROR: FilterFromFunction received nullptr as function pointer!");
      37              : 
      38              :     // cast MaMiCo indexing to std::array
      39            0 :     tarch::la::Vector<dim, int> mamicoIndex;
      40              :     std::array<unsigned int, dim> stlIndex;
      41            0 :     for (unsigned int i = 0; i < inputCellVector.size(); i++) {
      42              :       // interpret position of cell in inputCellVector as linear local
      43              :       // md-to-macro index, then convert it to vector
      44              :       using coupling::indexing::IndexTrait;
      45            0 :       mamicoIndex = coupling::indexing::convertToVector<dim>(I14{i});
      46              : 
      47            0 :       for (unsigned int d = 0; d < dim; d++)
      48            0 :         stlIndex[d] = mamicoIndex[d];
      49            0 :       _stlIndices.push_back(stlIndex);
      50              :     }
      51            0 :   }
      52              : 
      53            0 :   ~FilterFromFunction() {
      54            0 :     delete _applyScalar;
      55            0 :     delete _applyVector;
      56            0 :   }
      57              : 
      58            0 :   void operator()() {
      59            0 :     std::vector<double> input_s;
      60            0 :     std::vector<std::array<double, dim>> input_v;
      61              : 
      62            0 :     input_s.reserve(coupling::filtering::FilterInterface<dim>::_inputCells.size());
      63            0 :     input_v.reserve(coupling::filtering::FilterInterface<dim>::_inputCells.size());
      64              : 
      65              :     /*
      66              :      * SCALAR
      67              :      */
      68            0 :     for (const auto scalarProperty : coupling::filtering::FilterInterface<dim>::_scalarAccessFunctionPairs) {
      69              : 
      70              :       /*
      71              :        * PACK
      72              :        */
      73            0 :       for (auto cell : coupling::filtering::FilterInterface<dim>::_inputCells) {
      74            0 :         input_s.push_back((cell->*scalarProperty.get)());
      75              :       }
      76              : 
      77              :       // std::cout << "Now applying scalar func at: " << _applyScalar <<
      78              :       // std::endl;
      79              :       /*
      80              :        * APPLY
      81              :        *
      82              :        * If the cell vector is emtpy, we skip this step. It would not have any
      83              :        * effect anyway and could cause problems if the apply functions does
      84              :        * cannot handle empty input sets.
      85              :        */
      86            0 :       std::vector<double> output_s = {};
      87            0 :       if (input_s.size() > 0)
      88            0 :         output_s = (*_applyScalar)(input_s, _stlIndices);
      89              : 
      90            0 :       input_s.clear();
      91              : 
      92              :       /*
      93              :        * UNPACK
      94              :        */
      95            0 :       for (unsigned int i = 0; i < coupling::filtering::FilterInterface<dim>::_inputCells.size(); i++) {
      96            0 :         (coupling::filtering::FilterInterface<dim>::_outputCells[i]->*scalarProperty.set)(output_s[i]);
      97              :       }
      98              :     }
      99              : 
     100              :     /*
     101              :      * VECTOR
     102              :      */
     103            0 :     for (const auto vectorProperty : coupling::filtering::FilterInterface<dim>::_vectorAccessFunctionPairs) {
     104              : 
     105              :       // coupling::FilterInterface<dim>::DEBUG_PRINT_CELL_VELOCITY("FFF BEFORE
     106              :       // ");
     107              : 
     108              :       /*
     109              :        * PACK
     110              :        */
     111            0 :       for (auto cell : coupling::filtering::FilterInterface<dim>::_inputCells) {
     112            0 :         tarch::la::Vector<dim, double> mamico_vec = (cell->*vectorProperty.get)();
     113              :         std::array<double, dim> array_vec;
     114            0 :         for (unsigned int d = 0; d < dim; d++)
     115            0 :           array_vec[d] = mamico_vec[d];
     116            0 :         input_v.push_back(array_vec);
     117              :       }
     118              : 
     119              :       // std::cout << "Now applying vector func at: " << _applyVector <<
     120              :       // std::endl;
     121              :       /*
     122              :        * APPLY
     123              :        *
     124              :        * Cf. scalar case.
     125              :        */
     126            0 :       std::vector<std::array<double, dim>> output_v = {};
     127            0 :       if (input_v.size() > 0)
     128            0 :         output_v = (*_applyVector)(input_v, _stlIndices);
     129              : 
     130            0 :       input_v.clear();
     131              : 
     132              :       /*
     133              :        * UNPACK
     134              :        */
     135            0 :       for (unsigned int i = 0; i < coupling::filtering::FilterInterface<dim>::_inputCells.size(); i++) {
     136            0 :         tarch::la::Vector<dim, double> mamico_vec{};
     137            0 :         for (unsigned int d = 0; d < dim; d++)
     138            0 :           mamico_vec[d] = output_v[i][d];
     139            0 :         (coupling::filtering::FilterInterface<dim>::_outputCells[i]->*vectorProperty.set)(mamico_vec);
     140              :       }
     141              : 
     142              :       // coupling::FilterInterface<dim>::DEBUG_PRINT_CELL_VELOCITY("FFF AFTER
     143              :       // ");
     144              :     }
     145            0 :   }
     146              : 
     147              : private:
     148              :   // FFFs use slightly different datastructures for index/cell storage than
     149              :   // other filters
     150              :   std::vector<std::array<unsigned int, dim>> _stlIndices;
     151              : 
     152              :   // this encodes what filter to use
     153              :   const std::function<std::vector<double>(std::vector<double>, std::vector<std::array<unsigned int, dim>>)>* _applyScalar;
     154              :   const std::function<std::vector<std::array<double, dim>>(std::vector<std::array<double, dim>>, std::vector<std::array<unsigned int, dim>>)>* _applyVector;
     155              : };
        

Generated by: LCOV version 2.0-1