SelectVectorField.cpp
1 /*---------------------------------------------------------------------------*\
2  *
3  * mimmo
4  *
5  * Copyright (C) 2015-2021 OPTIMAD engineering Srl
6  *
7  * -------------------------------------------------------------------------
8  * License
9  * This file is part of mimmo.
10  *
11  * mimmo is free software: you can redistribute it and/or modify it
12  * under the terms of the GNU Lesser General Public License v3 (LGPL)
13  * as published by the Free Software Foundation.
14  *
15  * mimmo is distributed in the hope that it will be useful, but WITHOUT
16  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
18  * License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public License
21  * along with mimmo. If not, see <http://www.gnu.org/licenses/>.
22  *
23 \*---------------------------------------------------------------------------*/
24 
25 #include "SelectField.hpp"
26 #include "SkdTreeUtils.hpp"
27 #include "ExtractFields.hpp"
28 #include <unordered_map>
29 
30 namespace mimmo{
31 
37  m_name = "mimmo.SelectVectorField";
38  m_loc = loc;
39  if(m_loc == MPVLocation::UNDEFINED) m_loc= MPVLocation::POINT;
40 }
41 
46 SelectVectorField::SelectVectorField(const bitpit::Config::Section & rootXML){
47 
48  std::string fallback_name = "ClassNONE";
49  std::string fallback_loc = "-1";
50 
51  std::string input_name = rootXML.get("ClassName", fallback_name);
52  input_name = bitpit::utils::string::trim(input_name);
53 
54  std::string input_loc = rootXML.get("DataLocation", fallback_loc);
55  input_loc = bitpit::utils::string::trim(input_loc);
56 
57  int loc = std::stoi(input_loc);
58  if(loc > 0 && loc < 4){
59  m_loc =static_cast<MPVLocation>(loc);
60  }else{
61  m_loc = MPVLocation::POINT;
62  }
63  m_name = "mimmo.SelectVectorField";
64 
65  if(input_name == "mimmo.SelectVectorField" ){
66  absorbSectionXML(rootXML);
67  }else{
69  };
70 }
71 
76 
81  m_loc = other.m_loc;
82  m_fields = other.m_fields;
83  m_result = other.m_result;
84 }
85 
91 {
92  std::swap(m_loc, x.m_loc);
93  std::swap(m_fields, x.m_fields);
94  //std::swap(m_result, x.m_result);
95  m_result.swap(x.m_result);
97 }
98 
102 void
104  bool built = true;
105  built = (built && createPortIn<std::vector<dmpvecarr3E*>, SelectVectorField>(this, &mimmo::SelectVectorField::setFields, M_VECVECTORFIELDS, true, 1));
106  built = (built && createPortIn<dmpvecarr3E*, SelectVectorField>(this, &mimmo::SelectVectorField::addField, M_VECTORFIELD, true, 1));
107  built = (built && createPortOut<dmpvecarr3E*, SelectVectorField>(this, &mimmo::SelectVectorField::getSelectedField, M_VECTORFIELD));
108 
110  m_arePortsBuilt = built;
111 }
112 
119  return &m_result;
120 }
121 
126 void
127 SelectVectorField::setFields(std::vector<dmpvecarr3E*> fields){
128  m_fields.clear();
129  m_fields.reserve(fields.size());
130  for(dmpvecarr3E * ff : fields){
131  if(!ff) continue;
132  if(ff->getDataLocation() == m_loc && ff->getGeometry()!= nullptr){
133  m_fields.push_back(*ff);
134  }
135  }
136  m_fields.shrink_to_fit();
137 }
138 
143 void
145  if(!field) return;
146  if(field->getDataLocation() == m_loc && field->getGeometry() != nullptr){
147  m_fields.push_back(*field);
148  }
149 }
150 
154 void
156  m_fields.clear();
157  m_result.clear();
159 }
160 
164 void
166 
167  m_result.setName(m_fieldname);
168  write(m_result.getGeometry(), m_result);
169 
170 }
171 
176 bool
177 SelectVectorField::mSelect(){
178 
179  m_result.clear();
180 
181  switch(m_mode) {
182 
184  {
185  //Check if geometry is linked
186  if (getGeometry() == nullptr) return false;
187 
188  //Extract by link to geometry
189  for (const auto & field : m_fields){
190  if (field.getGeometry() == getGeometry()){
191  m_result = field;
192  //geometry, location and name are copied from field.
193  return true;
194  }
195  }
196  break;
197  }
198 
199  case SelectType::NAME:
200  {
201  //Extract by link to geometry
202  for (const auto & field : m_fields){
203  if (field.getName() == getFieldName()){
204  m_result = field;
205  //geometry, location and name are copied from field.
206  return true;
207  }
208  }
209  break;
210  }
211 
212  case SelectType::MAPPING:
213  {
214  //Check if geometry is linked
215  if (getGeometry() == nullptr) return false;
216 
217  //Extract by geometric mapping if active and if no positive match is found.
218  if (getGeometry()->getType() != 3){
219 
220  m_result.setGeometry(getGeometry());
221  m_result.setDataLocation(m_loc);
222 
223  ExtractVectorField * ef = new ExtractVectorField();
224  ef->setGeometry(getGeometry());
225  ef->setMode(ExtractMode::MAPPING);
226  ef->setTolerance(m_tol);
227 
228  //create map for overlapping ids purpose;
229  std::unordered_map<long, int> idRepetition;
230 
231  for (dmpvecarr3E & field : m_fields){
232  ef->setField(&field);
233  bool check = ef->extract();
234  if(!check) continue;
235 
236  dmpvecarr3E * temp = ef->getExtractedField();
237  dmpvecarr3E::iterator itB;
238  auto itE = temp->end();
239  long id;
240  for(itB = temp->begin(); itB != itE; ++itB){
241  id = itB.getId();
242  if(!m_result.exists(id)){
243  m_result.insert(id, *itB);
244  }else{
245  m_result[id] += *itB;
246  if(idRepetition.count(id)>0){
247  ++idRepetition[id];
248  }else{
249  idRepetition[id] = 2;
250  }
251  }
252  }
253  }
254 
255  //resolve overlapping ids by averaging correspondent value;
256 
257  for(auto &itval : idRepetition){
258  m_result[itval.first] /= double(itval.second);
259  }
260 
261  delete ef;
262  return true;
263  }
264  break;
265  }
266 
267  } // end switch mode
268 
269  //if you are here something was wrong.
270  return false;
271 }
272 
278 void SelectVectorField::absorbSectionXML(const bitpit::Config::Section & slotXML, std::string name){
279 
280  BITPIT_UNUSED(name);
281 
282  if(slotXML.hasOption("DataLocation")){
283  std::string input = slotXML.get("DataLocation");
284  input = bitpit::utils::string::trim(input);
285  int temp = -1;
286  if(!input.empty()){
287  std::stringstream ss(input);
288  ss>>temp;
289  }
290  if(int(m_loc) != temp){
291  (*m_log)<<"Error absorbing DataLocation in "<<m_name<<". Class and read locations mismatch"<<std::endl;
292  throw std::runtime_error (m_name + " : xml absorbing failed");
293  }
294  }
295 
296  SelectField::absorbSectionXML(slotXML, name);
297 
298 
299 };
300 
306 void SelectVectorField::flushSectionXML(bitpit::Config::Section & slotXML, std::string name){
307 
308  BITPIT_UNUSED(name);
309  slotXML.set("DataLocation", std::to_string(int(m_loc)));
310  SelectField::flushSectionXML(slotXML, name);
311 };
312 
313 
314 
315 }
void swap(SelectField &) noexcept
Definition: SelectField.cpp:56
void swap(SelectVectorField &) noexcept
#define M_VECVECTORFIELDS
MPVLocation
Define data location for the MimmoPiercedVector field.
void setName(std::string name)
void addField(dmpvecarr3E *field)
void warningXML(bitpit::Logger *log, std::string name)
SelectVectorField is specialized derived class of SelectField to Select a vector field.
#define M_VECTORFIELD
MimmoSharedPointer< MimmoObject > getGeometry() const
virtual void absorbSectionXML(const bitpit::Config::Section &slotXML, std::string name="")
std::string getFieldName()
void write(MimmoSharedPointer< MimmoObject > geometry)
virtual void absorbSectionXML(const bitpit::Config::Section &slotXML, std::string name="")
virtual void flushSectionXML(bitpit::Config::Section &slotXML, std::string name="")
SelectVectorField(MPVLocation loc=MPVLocation::POINT)
void setGeometry(MimmoSharedPointer< MimmoObject > geo)
std::string m_fieldname
void setDataLocation(MPVLocation loc)
SelectField is an abstract executable block class capable of Selecting a field from a list of fields.
Definition: SelectField.hpp:97
MimmoSharedPointer< MimmoObject > getGeometry()
void setFields(std::vector< dmpvecarr3E * > fields)
virtual void flushSectionXML(bitpit::Config::Section &slotXML, std::string name="")
mimmo::MimmoPiercedVector< darray3E > dmpvecarr3E