Line data Source code
1 : // Member functions of coupling::filtering::FilterJunction
2 :
3 : template <unsigned int dim, std::size_t inputc>
4 0 : int coupling::filtering::FilterJunction<dim, inputc>::loadFiltersFromXML(
5 : tinyxml2::XMLElement* sequenceNode) { // in our case "junctionNode" would be more precise
6 0 : if (!sequenceNode)
7 : return EXIT_FAILURE;
8 :
9 : // null if junction is empty
10 0 : tinyxml2::XMLElement* currJunctorNode = sequenceNode->FirstChildElement();
11 :
12 0 : std::array<std::vector<coupling::datastructures::CouplingCell<dim>*>, inputc> inputCellVector = _inputCellVector_parted;
13 0 : std::array<std::vector<coupling::datastructures::CouplingCell<dim>*>, inputc> outputCellVector = _cellVector2_parted;
14 : #ifdef DEBUG_FILTER_PIPELINE
15 : std::cout << PRINT_PREFIX() << "Initializing junctor objects." << std::endl;
16 : #endif
17 :
18 : // Keep track of this for each indivial input partition.
19 0 : [[maybe_unused]] bool firstIteration[inputc] = {true};
20 :
21 0 : while (currJunctorNode) {
22 :
23 : // All Junctors must implement one of the {X,Y}-Junctor interfaces, each of
24 : // which implement FilterInterface.
25 0 : coupling::filtering::FilterInterface<dim>* newjunctor = nullptr;
26 :
27 : // TODO: reduce per-junctor customization: generalize!
28 : // ###############################################################
29 : // This is where you have to define how to handle each junctor individually.
30 :
31 : // NLM
32 0 : if (std::strcmp(currJunctorNode->Value(), "NLM") == 0) {
33 :
34 : // Optional parameters
35 0 : int inputp_unfiltered = 0; // default
36 0 : tarch::configuration::ParseConfiguration::readIntOptional(inputp_unfiltered, currJunctorNode, "input-unfiltered");
37 0 : int inputp_prefiltered = 1; // default
38 0 : tarch::configuration::ParseConfiguration::readIntOptional(inputp_prefiltered, currJunctorNode, "input-filtered");
39 0 : int outputp = 0; // default
40 0 : tarch::configuration::ParseConfiguration::readIntOptional(outputp, currJunctorNode, "output");
41 :
42 : // check for invalid partition indexes
43 0 : for (auto p : {inputp_unfiltered, inputp_prefiltered, outputp}) {
44 0 : if (p < 0) {
45 0 : std::cout << PRINT_PREFIX() << "ERROR: Negative input or output lane index specified in XML:" << p << std::endl;
46 0 : return EXIT_FAILURE;
47 : }
48 0 : if (p >= (int)inputc) {
49 0 : std::cout << PRINT_PREFIX() << "ERROR: Input or output lane index specified in XML (" << p << ") is too large!" << std::endl;
50 0 : return EXIT_FAILURE;
51 : }
52 : }
53 :
54 : // Mandatory parameters
55 : int tws;
56 0 : if (currJunctorNode->QueryIntAttribute("time-window-size", &tws)) {
57 0 : std::cout << "ERROR: NLM filter misses attribute time-window-size in "
58 : "config file."
59 0 : << std::endl;
60 0 : exit(EXIT_FAILURE);
61 : }
62 0 : if (tws <= 2) {
63 0 : std::cout << "ERROR: NLM: time-window-size must be greater than two." << std::endl;
64 0 : exit(EXIT_FAILURE);
65 : }
66 : double sigsq;
67 0 : if (currJunctorNode->QueryDoubleAttribute("sigsq", &sigsq)) {
68 0 : std::cout << "ERROR: NLM filter misses attribute sigsq in config file." << std::endl;
69 0 : exit(EXIT_FAILURE);
70 : }
71 0 : if (sigsq < 0) {
72 0 : std::cout << "ERROR: NLM: sigsq must be greater than zero." << std::endl;
73 0 : exit(EXIT_FAILURE);
74 : }
75 : double hsq;
76 0 : if (currJunctorNode->QueryDoubleAttribute("hsq", &hsq)) {
77 0 : std::cout << "ERROR: NLM filter misses attribute hsq in config file." << std::endl;
78 0 : exit(EXIT_FAILURE);
79 : }
80 0 : if (hsq < 0) {
81 0 : std::cout << "ERROR: NLM: hsq must be greater than zero." << std::endl;
82 0 : exit(EXIT_FAILURE);
83 : }
84 :
85 : // Optional parameters
86 0 : double sigsq_rel = -1;
87 0 : tarch::configuration::ParseConfiguration::readDoubleOptional(sigsq_rel, currJunctorNode, "sigsq_rel");
88 0 : if (sigsq_rel > 1) {
89 0 : std::cout << "ERROR: NLM: sigsq_rel must be 0 <= sigsq_rel <= 1" << std::endl;
90 0 : exit(EXIT_FAILURE);
91 : }
92 0 : if (sigsq_rel >= 0) {
93 0 : std::cout << "INFO: NLM: sigsq adaptivity enabled, target value = " << sigsq_rel * 100 << " % " << std::endl;
94 : }
95 :
96 0 : double hsq_rel = -1;
97 0 : tarch::configuration::ParseConfiguration::readDoubleOptional(hsq_rel, currJunctorNode, "hsq_rel");
98 0 : if (hsq_rel > 1) {
99 0 : std::cout << "ERROR: NLM: hsq_rel must be 0 <= hsq_rel <= 1" << std::endl;
100 0 : exit(EXIT_FAILURE);
101 : }
102 0 : if (hsq_rel >= 0) {
103 0 : std::cout << "INFO: NLM: hsq adaptivity enabled, target value = " << hsq_rel * 100 << " % " << std::endl;
104 : }
105 :
106 : // Instantiation
107 0 : newjunctor = new coupling::filtering::NLM<dim, coupling::indexing::IndexTrait::local>(
108 0 : inputCellVector[inputp_unfiltered], inputCellVector[inputp_prefiltered], outputCellVector[outputp],
109 : coupling::filtering::FilterSequence<dim>::_filteredValues, tws, sigsq, sigsq_rel, hsq, hsq_rel);
110 :
111 : // TODO: generalize this for arbitrary junctors?
112 : // Swapping for output partition
113 0 : if (firstIteration[outputp]) {
114 0 : inputCellVector[outputp] = _cellVector1_parted[outputp];
115 0 : firstIteration[outputp] = false;
116 : }
117 0 : inputCellVector[outputp].swap(outputCellVector[outputp]);
118 : }
119 : // ###############################################################
120 :
121 : // Unknown junctor identifier
122 : else {
123 0 : std::cout << "ERROR: Filter-Junction does not recognize junctor called " << currJunctorNode->Value() << std::endl;
124 : return EXIT_FAILURE;
125 : }
126 :
127 0 : coupling::filtering::FilterSequence<dim>::_filters.push_back(newjunctor);
128 0 : currJunctorNode = currJunctorNode->NextSiblingElement();
129 : }
130 :
131 : #ifdef DEBUG_FILTER_JUNCTIONS
132 : std::cout << PRINT_PREFIX();
133 : printOutputCellVector();
134 : #endif
135 :
136 : return 0;
137 0 : }
|