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 : 7 : #define DEBUG_FILTER_JUNCTION 8 : 9 : #include "coupling/filtering/sequencing/FilterSequence.h" 10 : 11 : // INCLUDE ALL JUNCTOR HEADERS HERE 12 : #include "coupling/filtering/filters/NLM.h" 13 : #include "coupling/filtering/interfaces/JunctorInterface.h" 14 : 15 : /* 16 : * Generalizes the concept of FilterSequences: A FilterJunction can have more 17 : * than a single input. This allows for seemless integration of FilterJunctions 18 : * into a net of FilterSequences. 19 : * 20 : * 21 : * @todo Support multiple outputs. ("X-Junctions") 22 : * @todo Support dynamically linked filters. 23 : * @author Felix Maurer 24 : */ 25 : 26 : namespace coupling { 27 : namespace filtering { 28 : template <unsigned int dim, std::size_t inputc> class FilterJunction; 29 : } 30 : } // namespace coupling 31 : 32 : template <unsigned int dim, std::size_t inputc> class coupling::filtering::FilterJunction : public coupling::filtering::FilterSequence<dim> { 33 : public: 34 0 : FilterJunction(const char* name, 35 : const std::vector<coupling::datastructures::CouplingCell<dim>*> inputCellVector, // concatenation of numberImput input cell vectors 36 : #if (COUPLING_MD_PARALLEL == COUPLING_MD_YES) 37 : MPI_Comm comm, 38 : #endif 39 : std::array<bool, 7> filteredValues) 40 : : coupling::filtering::FilterSequence<dim>(name, inputCellVector, 41 : #if (COUPLING_MD_PARALLEL == COUPLING_MD_YES) 42 : comm, 43 : #endif 44 0 : filteredValues) { 45 : if (inputc == 0) 46 : throw std::runtime_error("ERROR: Creating FilterJunction with inputc = 0."); 47 : 48 : #ifdef DEBUG_FILTER_JUNCTION 49 0 : std::cout << PRINT_PREFIX() << "This is a FilterJunction. Number of inputs:" << inputc << std::endl; 50 : #endif 51 : 52 : // Partition input vector 53 0 : unsigned int partitionSize = coupling::filtering::FilterSequence<dim>::_inputCellVector.size() / inputc; 54 : 55 0 : for (unsigned int p = 0; p < inputc; p++) { 56 : //_inputCellVector 57 0 : _inputCellVector_parted[p] = std::vector<coupling::datastructures::CouplingCell<dim>*>( 58 0 : coupling::filtering::FilterSequence<dim>::_inputCellVector.begin() + (p * partitionSize), 59 0 : coupling::filtering::FilterSequence<dim>::_inputCellVector.begin() + ((p + 1) * partitionSize)); 60 : #ifdef DEBUG_FILTER_JUNCTION 61 0 : std::cout << PRINT_PREFIX() << "Size of _inputCellVector_parted[" << p << "]: " << _inputCellVector_parted[p].size() << std::endl; 62 : #endif 63 : 64 : //_cellVector1 65 0 : _cellVector1_parted[p] = 66 0 : std::vector<coupling::datastructures::CouplingCell<dim>*>(coupling::filtering::FilterSequence<dim>::_cellVector1.begin() + (p * partitionSize), 67 0 : coupling::filtering::FilterSequence<dim>::_cellVector1.begin() + ((p + 1) * partitionSize)); 68 : #ifdef DEBUG_FILTER_JUNCTION 69 0 : std::cout << PRINT_PREFIX() << "Size of _cellVector1_parted[" << p << "]: " << _cellVector1_parted[p].size() << std::endl; 70 : #endif 71 : 72 : //_cellVector2 73 0 : _cellVector2_parted[p] = 74 0 : std::vector<coupling::datastructures::CouplingCell<dim>*>(coupling::filtering::FilterSequence<dim>::_cellVector2.begin() + (p * partitionSize), 75 0 : coupling::filtering::FilterSequence<dim>::_cellVector2.begin() + ((p + 1) * partitionSize)); 76 : #ifdef DEBUG_FILTER_JUNCTION 77 0 : std::cout << PRINT_PREFIX() << "Size of _cellVector2_parted[" << p << "]: " << _cellVector2_parted[p].size() << std::endl; 78 : #endif 79 : } 80 : 81 0 : coupling::filtering::FilterSequence<dim>::_isModifiable = false; // Dynamic filters are not yet supported. 82 0 : } 83 : 84 : /* 85 : * This member function allows appendance and insertion of filters defined by 86 : * two processing functions to a modifiable sequence at runtime. Index -1 87 : * implies appending. 88 : */ 89 0 : void addFilter( 90 : const std::function<std::vector<double>(std::vector<double>, std::vector<std::array<unsigned int, dim>>)>* applyScalar, 91 : const std::function<std::vector<std::array<double, dim>>(std::vector<std::array<double, dim>>, std::vector<std::array<unsigned int, dim>>)>* applyVector, 92 : int filterIndex = -1) override { 93 : // Do nothing, not yet supported. 94 : #ifdef DEBUG_FILTER_JUNCTION 95 0 : std::cout << PRINT_PREFIX() 96 0 : << "This is a FilterJunction. addFilter(...) is not supported " 97 : "and has no effect." 98 0 : << std::endl; 99 : #endif 100 0 : } 101 : 102 : /* 103 : * This function is very similar to the interface's. Check 104 : * coupling::FilterSequence for more details. 105 : */ 106 : int loadFiltersFromXML(tinyxml2::XMLElement* sequenceNode) override; 107 : 108 : /* 109 : * The first partition of _cellVector1/2 is the main partition. A junction's 110 : * default output is always its main partition. 111 : */ 112 0 : const std::vector<coupling::datastructures::CouplingCell<dim>*>& getOutputCellVector(unsigned int outputIndex = 0) const override { 113 0 : if (outputIndex >= inputc) { 114 0 : std::cout << PRINT_PREFIX() << "ERROR: getOutputCellVector: Requested output index(" << outputIndex << ") too high. (partitions: )" << inputc 115 0 : << std::endl; 116 0 : exit(EXIT_FAILURE); 117 : } 118 : 119 0 : if (coupling::filtering::FilterSequence<dim>::_filters.empty()) 120 0 : std::cout << PRINT_PREFIX() << "Warning: Accessing cell vectors while _filters is empty." << std::endl; 121 0 : if (coupling::filtering::FilterSequence<dim>::_filters.size() % 2 == 0) 122 0 : return _cellVector1_parted[0]; 123 : else 124 0 : return _cellVector2_parted[0]; 125 : } 126 : 127 0 : void printFilters() override { 128 0 : std::cout << "Junctors in junction " << coupling::filtering::FilterSequence<dim>::_name << ": "; 129 0 : for (auto f : coupling::filtering::FilterSequence<dim>::_filters) 130 0 : std::cout << f->getType() << " "; 131 0 : std::cout << std::endl; 132 0 : } 133 : 134 0 : std::string PRINT_PREFIX() const override { 135 0 : return std::string(" FJ(").std::string::append(coupling::filtering::FilterSequence<dim>::_name).std::string::append("): "); 136 : } 137 : 138 : private: 139 : // These must be parted for junction output and junctor in/output. 140 : std::array<std::vector<coupling::datastructures::CouplingCell<dim>*>, inputc> _inputCellVector_parted; 141 : std::array<std::vector<coupling::datastructures::CouplingCell<dim>*>, inputc> _cellVector1_parted; 142 : std::array<std::vector<coupling::datastructures::CouplingCell<dim>*>, inputc> _cellVector2_parted; 143 : }; 144 : 145 : // inlcude implementation 146 : #include "coupling/filtering/sequencing/FilterJunction.cpph"