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>(inputCellVector[inputp_unfiltered], inputCellVector[inputp_prefiltered], outputCellVector[outputp], 108 0 : coupling::filtering::FilterSequence<dim>::_filteredValues, tws, sigsq, sigsq_rel, hsq, hsq_rel); 109 : 110 : // TODO: generalize this for arbitrary junctors? 111 : // Swapping for output partition 112 0 : if (firstIteration[outputp]) { 113 0 : inputCellVector[outputp] = _cellVector1_parted[outputp]; 114 0 : firstIteration[outputp] = false; 115 : } 116 0 : inputCellVector[outputp].swap(outputCellVector[outputp]); 117 : } 118 : // ############################################################### 119 : 120 : // Unknown junctor identifier 121 : else { 122 0 : std::cout << "ERROR: Filter-Junction does not recognize junctor called " << currJunctorNode->Value() << std::endl; 123 : return EXIT_FAILURE; 124 : } 125 : 126 0 : coupling::filtering::FilterSequence<dim>::_filters.push_back(newjunctor); 127 0 : currJunctorNode = currJunctorNode->NextSiblingElement(); 128 : } 129 : 130 : #ifdef DEBUG_FILTER_JUNCTIONS 131 : std::cout << PRINT_PREFIX(); 132 : printOutputCellVector(); 133 : #endif 134 : 135 : return 0; 136 0 : }