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 <array> 7 : #include <vector> 8 : 9 : #include "coupling/indexing/CellIndex.h" 10 : 11 : // #define DEBUG_FILTER_INTERFACE 12 : 13 : namespace coupling { 14 : namespace filtering { 15 : template <unsigned int dim> class FilterInterface; 16 : } 17 : } // namespace coupling 18 : 19 : /** 20 : * Generic interface for filters that are to be applied to 21 : * coupling::CellContainer before MD to Macro transfer. Implementations can 22 : * be found in coupling/filtering/filters. 23 : * 24 : * If you wish to use a filter that does not alter its input data, i.e that is 25 : * read-only, you want to use coupling::FilterInterfaceReadOnly<dim> instead (as 26 : * provided in header file coupling/filtering/FilterPipelineReadOnly.h). 27 : * Examples for such filters are WriteToFile or Strouhal (in 28 : * coupling/filtering/filters). 29 : * 30 : * @author Felix Maurer 31 : */ 32 : template <unsigned int dim> class coupling::filtering::FilterInterface { 33 : public: 34 : /* 35 : * Filter constructors are called during instanciation of their corresponding 36 : * FilterSequence. You can customize parameterization in 37 : * coupling::FilterSequence::loadFiltersFromXML(...). 38 : */ 39 0 : FilterInterface(const std::vector<coupling::datastructures::CouplingCell<dim>*>& inputCellVector, 40 : const std::vector<coupling::datastructures::CouplingCell<dim>*>& outputCellVector, const std::array<bool, 7> filteredValues, const char* type) 41 : : 42 : 43 0 : _inputCells(inputCellVector), _outputCells(outputCellVector), _type(type) { 44 : // microscopic mass 45 0 : if (filteredValues[0]) { 46 0 : _scalarAccessFunctionPairs.push_back( 47 : {&coupling::datastructures::CouplingCell<dim>::getMicroscopicMass, &coupling::datastructures::CouplingCell<dim>::setMicroscopicMass}); 48 : } 49 : // microscopic momentum 50 0 : if (filteredValues[1]) { 51 0 : _vectorAccessFunctionPairs.push_back( 52 : {&coupling::datastructures::CouplingCell<dim>::getMicroscopicMomentum, &coupling::datastructures::CouplingCell<dim>::setMicroscopicMomentum}); 53 : } 54 : // macroscopic mass 55 0 : if (filteredValues[2]) { 56 0 : _scalarAccessFunctionPairs.push_back( 57 : {&coupling::datastructures::CouplingCell<dim>::getMacroscopicMass, &coupling::datastructures::CouplingCell<dim>::setMacroscopicMass}); 58 : } 59 : // macroscopic momentum 60 0 : if (filteredValues[3]) { 61 0 : _vectorAccessFunctionPairs.push_back( 62 : {&coupling::datastructures::CouplingCell<dim>::getMacroscopicMomentum, &coupling::datastructures::CouplingCell<dim>::setMacroscopicMomentum}); 63 : } 64 : // potential energy 65 0 : if (filteredValues[4]) { 66 0 : _scalarAccessFunctionPairs.push_back( 67 : {&coupling::datastructures::CouplingCell<dim>::getPotentialEnergy, &coupling::datastructures::CouplingCell<dim>::setPotentialEnergy}); 68 : } 69 : // velocity 70 0 : if (filteredValues[5]) { 71 0 : _vectorAccessFunctionPairs.push_back( 72 : {&coupling::datastructures::CouplingCell<dim>::getCurrentVelocity, &coupling::datastructures::CouplingCell<dim>::setCurrentVelocity}); 73 : } 74 : // temperature 75 0 : if (filteredValues[6]) { 76 0 : _scalarAccessFunctionPairs.push_back( 77 : {&coupling::datastructures::CouplingCell<dim>::getTemperature, &coupling::datastructures::CouplingCell<dim>::setTemperature}); 78 : } 79 0 : } 80 : 81 0 : FilterInterface(const char* type) 82 0 : : _type(type) { /* Used by incomplete implementations of FilterInterface. 83 : Should be redesigned via meta class.*/ 84 : } 85 : 86 0 : virtual ~FilterInterface() {}; 87 : 88 : /* 89 : * Applies the filter to all cells that are within the filter's sequence's 90 : * domain. 91 : * 92 : * It is very important that this method provides complete output data, 93 : * i.e uses all elements of _scalarSetters and _vectorSetters on all elements 94 : * of _outputCells. If this is not the case, you dont want to use this 95 : * interface, but rather coupling::FilterInterfaceReadOnly and use its method 96 : * copyInputToOutput(). 97 : */ 98 : virtual void operator()() = 0; 99 : 100 0 : void updateCellData(const std::vector<coupling::datastructures::CouplingCell<dim>*>& new_inputCells, 101 : const std::vector<coupling::datastructures::CouplingCell<dim>*>& new_outputCells) { 102 0 : if (new_inputCells.size() != new_outputCells.size()) 103 0 : throw std::runtime_error("New input-, output-, and indexing vectors must " 104 : "be of identical size."); 105 : 106 0 : _inputCells = new_inputCells; 107 0 : _outputCells = new_outputCells; 108 : 109 : #ifdef DEBUG_FILTER_INTERFACE 110 : std::cout << " FI: Updated cell data." << std::endl; 111 : #endif 112 0 : } 113 : 114 : /* 115 : * Basic Getters/Setters 116 : */ 117 0 : const char* getType() const { return _type; } 118 0 : std::vector<coupling::datastructures::CouplingCell<dim>*> getInputCells() const { return _inputCells; } 119 0 : std::vector<coupling::datastructures::CouplingCell<dim>*> getOutputCells() const { return _outputCells; } 120 : 121 : using CellIndex_T = coupling::indexing::CellIndex<dim, coupling::indexing::IndexTrait::local, coupling::indexing::IndexTrait::md2macro, 122 : coupling::indexing::IndexTrait::noGhost>; 123 : /* 124 : * Advanced Getters/Setters 125 : */ 126 : coupling::datastructures::CouplingCell<dim>* getInputCellOfIndex(const CellIndex_T& index) { 127 : if (index.get() < _inputCells.size) { 128 : return _inputCells[index.get()]; 129 : } else { 130 : std::cout << "Index not found: " << index << std::endl; 131 : throw std::runtime_error("FilterInterface: getInputCellofIndex(): Could not find index."); 132 : } 133 : } 134 : coupling::datastructures::CouplingCell<dim>* getOutputCellOfIndex(const CellIndex_T& index) { 135 : if (index.get() < _outputCells.size) { 136 : return _outputCells[index.get()]; 137 : } else { 138 : std::cout << "Index not found: " << index << std::endl; 139 : throw std::runtime_error("FilterInterface: getOutputCellofIndex(): Could not find index."); 140 : } 141 : } 142 : 143 : /* 144 : * Only used in one scenario: 145 : * - this is at index 0 in FS 146 : * - new filter gets dynamically linked into FS at index 0 147 : * In that case, this was previously getting input from MD but won't be any 148 : * longer. The newly added filter will provide input for this one instead. 149 : */ 150 0 : void setInputCells(const std::vector<coupling::datastructures::CouplingCell<dim>*>& newInputCells) { _inputCells = newInputCells; } 151 : 152 : // Size = number of cells in this filter. 153 : int getSize() const { return _inputCells.size(); } 154 : 155 : /* 156 : * Used by filter implementations to iterate over physical properties stored 157 : * in a CouplingCell. 158 : * 159 : * Examplary usage: 160 : * 'for(auto scalar : _scalarAccessFunctionPairs)' loops over all scalar 161 : * properties (e.g. macro/micro mass, temperate) filtered by this specific 162 : * filter. 163 : */ 164 : struct ScalarAccessFunctionPair { 165 : const double& (coupling::datastructures::CouplingCell<dim>::*get)() const; // getter function pointer 166 : void (coupling::datastructures::CouplingCell<dim>::*set)(const double&); // setter function pointer 167 : }; 168 : struct VectorAccessFunctionPair { 169 : const tarch::la::Vector<dim, double>& (coupling::datastructures::CouplingCell<dim>::*get)() const; 170 : void (coupling::datastructures::CouplingCell<dim>::*set)(const tarch::la::Vector<dim, double>&); 171 : }; 172 : 173 : protected: 174 : /** 175 : * Filters should read from input vector and write to output vector. 176 : * Both vectors use the same indexing by default. 177 : * All unmodified cells of the output vector are implicitly copied from 178 : *their respective input counterpart, i.e it is not mandatory to have any 179 : *output. 180 : */ 181 : std::vector<coupling::datastructures::CouplingCell<dim>*> _inputCells; 182 : std::vector<coupling::datastructures::CouplingCell<dim>*> _outputCells; 183 : 184 : // scalars getters/setters 185 : std::vector<ScalarAccessFunctionPair> _scalarAccessFunctionPairs; 186 : 187 : // vectors getters/setters 188 : std::vector<VectorAccessFunctionPair> _vectorAccessFunctionPairs; 189 : 190 : // unique identifier per filter class 191 : const char* _type; 192 : };