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"
|