SelectScalarField.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.SelectScalarField";
38  m_loc = loc;
39  if(m_loc == MPVLocation::UNDEFINED) m_loc= MPVLocation::POINT;
40 }
41 
46 SelectScalarField::SelectScalarField(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 
64  m_name = "mimmo.SelectScalarField";
65 
66  if(input_name == "mimmo.SelectScalarField"){
67  absorbSectionXML(rootXML);
68  }else{
70  };
71 }
72 
77 
82  m_loc = other.m_loc;
83  m_fields = other.m_fields;
84  m_result = other.m_result;
85 }
86 
92 {
93  std::swap(m_loc, x.m_loc);
94  std::swap(m_fields, x.m_fields);
95  //std::swap(m_result, x.m_result);
96  m_result.swap(x.m_result);
98 }
99 
103 void
105  bool built = true;
106  built = (built && createPortIn<std::vector<dmpvector1D*>, SelectScalarField>(this, &mimmo::SelectScalarField::setFields, M_VECSCALARFIELDS, true, 1));
107  built = (built && createPortIn<dmpvector1D*, SelectScalarField>(this, &mimmo::SelectScalarField::addField, M_SCALARFIELD, true, 1));
108  built = (built && createPortOut<dmpvector1D*, SelectScalarField>(this, &mimmo::SelectScalarField::getSelectedField, M_SCALARFIELD));
109 
111  m_arePortsBuilt = built;
112 }
113 
118 dmpvector1D *
120  return &m_result;
121 }
122 
127 void
128 SelectScalarField::setFields(std::vector<dmpvector1D*> fields){
129  m_fields.clear();
130  m_fields.reserve(fields.size());
131  for(dmpvector1D * ff : fields){
132  if(!ff) continue;
133  if(ff->getDataLocation() == m_loc && ff->getGeometry()!= nullptr){
134  m_fields.push_back(*ff);
135  }
136  }
137  m_fields.shrink_to_fit();
138 }
139 
144 void
146  if(!field) return;
147  if(field->getDataLocation() == m_loc && field->getGeometry() != nullptr){
148  m_fields.push_back(*field);
149  }
150 
151 }
152 
156 void
158  m_fields.clear();
159  m_result.clear();
161 }
162 
166 void
168 
169  m_result.setName(m_fieldname);
170  write(m_result.getGeometry(), m_result);
171 
172 }
173 
178 bool
179 SelectScalarField::mSelect(){
180 
181  m_result.clear();
182 
183  switch(m_mode) {
184 
186  {
187  //Check if geometry is linked
188  if (getGeometry() == nullptr) return false;
189 
190  //Extract by link to geometry
191  for (const auto & field : m_fields){
192  if (field.getGeometry() == getGeometry()){
193  m_result = field;
194  //geometry, location and name are copied from field.
195  return true;
196  }
197  }
198  break;
199  }
200 
201  case SelectType::NAME:
202  {
203  //Extract by link to geometry
204  for (const auto & field : m_fields){
205  if (field.getName() == getFieldName()){
206  m_result = field;
207  //geometry, location and name are copied from field.
208  return true;
209  }
210  }
211  break;
212  }
213 
214  case SelectType::MAPPING:
215  {
216  //Check if geometry is linked
217  if (getGeometry() == nullptr) return false;
218 
219  //Extract by geometric mapping if active and if no positive match is found.
220  if (getGeometry()->getType() != 3){
221 
222  m_result.setGeometry(getGeometry());
223  m_result.setDataLocation(m_loc);
224 
225  ExtractScalarField * ef = new ExtractScalarField();
226  ef->setGeometry(getGeometry());
227  ef->setMode(ExtractMode::MAPPING);
228  ef->setTolerance(m_tol);
229 
230  //create map for overlapping ids purpose;
231  std::unordered_map<long, int> idRepetition;
232 
233  for (dmpvector1D & field : m_fields){
234  ef->setField(&field);
235  bool check = ef->extract();
236  if(!check) continue;
237 
238  dmpvector1D * temp = ef->getExtractedField();
239  dmpvector1D::iterator itB;
240  auto itE = temp->end();
241  long id;
242  for(itB = temp->begin(); itB != itE; ++itB){
243  id = itB.getId();
244  if(!m_result.exists(id)){
245  m_result.insert(id, *itB);
246  }else{
247  m_result[id] += *itB;
248  if(idRepetition.count(id)>0){
249  ++idRepetition[id];
250  }else{
251  idRepetition[id] = 2;
252  }
253  }
254  }
255  }
256 
257  //resolve overlapping ids by averaging correspondent value;
258 
259  for(auto &itval : idRepetition){
260  m_result[itval.first] /= double(itval.second);
261  }
262 
263  delete ef;
264  return true;
265  }
266  break;
267  }
268 
269  } // end switch mode
270 
271  //if you are here something was wrong.
272  return false;
273 }
274 
280 void SelectScalarField::absorbSectionXML(const bitpit::Config::Section & slotXML, std::string name){
281 
282  BITPIT_UNUSED(name);
283 
284  if(slotXML.hasOption("DataLocation")){
285  std::string input = slotXML.get("DataLocation");
286  input = bitpit::utils::string::trim(input);
287  int temp = -1;
288  if(!input.empty()){
289  std::stringstream ss(input);
290  ss>>temp;
291  }
292  if(int(m_loc) != temp){
293  (*m_log)<<"Error absorbing DataLocation in "<<m_name<<". Class and read locations mismatch"<<std::endl;
294  throw std::runtime_error (m_name + " : xml absorbing failed");
295  }
296  }
297 
298  SelectField::absorbSectionXML(slotXML, name);
299 
300 
301 };
302 
308 void SelectScalarField::flushSectionXML(bitpit::Config::Section & slotXML, std::string name){
309 
310  BITPIT_UNUSED(name);
311  slotXML.set("DataLocation", std::to_string(int(m_loc)));
312  SelectField::flushSectionXML(slotXML, name);
313 };
314 
315 
316 }
void swap(SelectField &) noexcept
Definition: SelectField.cpp:56
void addField(dmpvector1D *field)
MPVLocation
Define data location for the MimmoPiercedVector field.
void setName(std::string name)
void warningXML(bitpit::Logger *log, std::string name)
void swap(SelectScalarField &) noexcept
SelectScalarField is specialized derived class of SelectField to Select a scalar field.
virtual void absorbSectionXML(const bitpit::Config::Section &slotXML, std::string name="")
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 flushSectionXML(bitpit::Config::Section &slotXML, std::string name="")
mimmo::MimmoPiercedVector< double > dmpvector1D
void setGeometry(MimmoSharedPointer< MimmoObject > geo)
std::string m_fieldname
SelectScalarField(MPVLocation loc=MPVLocation::POINT)
void setDataLocation(MPVLocation loc)
#define M_SCALARFIELD
#define M_VECSCALARFIELDS
SelectField is an abstract executable block class capable of Selecting a field from a list of fields.
Definition: SelectField.hpp:97
MimmoSharedPointer< MimmoObject > getGeometry()
virtual void flushSectionXML(bitpit::Config::Section &slotXML, std::string name="")
void setFields(std::vector< dmpvector1D * > fields)