LCOV - code coverage report
Current view: top level - coupling/filtering/filters - FilterFromFunction.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 46 0.0 %
Date: 2025-06-25 11:26:37 Functions: 0 4 0.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 1.14