ExtractLongField.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 "ExtractFields.hpp"
26 #include "SkdTreeUtils.hpp"
27 
28 namespace mimmo{
29 
34  m_name = "mimmo.ExtractLongField";
35 }
36 
41 ExtractLongField::ExtractLongField(const bitpit::Config::Section & rootXML){
42 
43  std::string fallback_name = "ClassNONE";
44  std::string input_name = rootXML.get("ClassName", fallback_name);
45  input_name = bitpit::utils::string::trim(input_name);
46 
47  m_name = "mimmo.ExtractLongField";
48 
49  if(input_name == "mimmo.ExtractLongField"){
50  absorbSectionXML(rootXML);
51  }else{
53  };
54 }
55 
60 
61 
67  m_field = other.m_field;
68  m_result = other.m_result;
69 }
70 
77  m_field = other.m_field;
78  m_result = other.m_result;
79  return *this;
80 };
81 
87 {
88  m_field.swap(x.m_field);
89  m_result.swap(x.m_result);
91 };
92 
93 
97 void
99 
101 
102  bool built = m_arePortsBuilt;
103  built = (built && createPortIn<MimmoPiercedVector<long>*, ExtractLongField>(this, &mimmo::ExtractLongField::setField, M_LONGFIELD, true));
104  built = (built && createPortOut<MimmoPiercedVector<long>*, ExtractLongField>(this, &mimmo::ExtractLongField::getExtractedField, M_LONGFIELD));
105 
106  m_arePortsBuilt = built;
107 }
108 
115  return &m_result;
116 }
117 
124  return m_field;
125 }
126 
131 void
133  if(!field) return;
134  m_field = *field;
135 }
136 
140 void
142  m_field.clear();
143  m_result.clear();
145 }
146 
150 void
152 
153  m_result.setName("field");
154  write(m_result.getGeometry(), m_result);
155 
156 }
157 
162 bool
164 
165  if (getGeometry() == nullptr || m_field.getGeometry() == nullptr) return false;
166  //checking internal ids coherence of the field.
167  if(!m_field.checkDataIdsCoherence()) return false;
168 
169  mimmo::MPVLocation refLoc = m_field.getDataLocation();
171 
172  m_result.clear();
173  m_result.setDataLocation(refLoc);
174 
175  switch(m_mode){
176  case ExtractMode::ID :
177  extractID(refLoc);
178  m_result.setGeometry(getGeometry());
179  break;
180 
181  case ExtractMode::PID :
182  extractPID(refLoc);
183  m_result.setGeometry(m_field.getGeometry());
184  break;
185 
186  case ExtractMode::MAPPING :
187  extractMapping(refLoc);
188  m_result.setGeometry(getGeometry());
189  break;
190 
191  default :
192  assert(false && "unrecognized field location");
193  break;
194  }
195 
196  return true;
197 
198 }
199 
205 void ExtractLongField::extractID(mimmo::MPVLocation loc){
206 
207  switch(loc){
209  for (const auto & ID : getGeometry()->getVertices().getIds()){
210  if (m_field.exists(ID)){
211  m_result.insert(ID, m_field[ID]);
212  }
213  }
214  break;
216  for (const auto & ID : getGeometry()->getCells().getIds()){
217  if (m_field.exists(ID)){
218  m_result.insert(ID, m_field[ID]);
219  }
220  }
221  break;
223  getGeometry()->updateInterfaces();
224  for (const auto & ID : getGeometry()->getInterfaces().getIds()){
225  if (m_field.exists(ID)){
226  m_result.insert(ID, m_field[ID]);
227  }
228  }
229  break;
230  default:
231  //do nothing
232  break;
233  }
234 }
235 
241 void ExtractLongField::extractPID(mimmo::MPVLocation loc){
242  //Extract by PIDs
243  livector1D commonPID;
244  {
245  std::unordered_set<long> pidTarget = getGeometry()->getPIDTypeList();
246  std::unordered_set<long> pidLinked = m_field.getGeometry()->getPIDTypeList();
247  std::set<long> unionPID(pidTarget.begin(), pidTarget.end());
248  unionPID.insert(pidLinked.begin(), pidLinked.end());
249  for(auto val: unionPID){
250  if(pidLinked.count(val) && pidTarget.count(val)){
251  commonPID.push_back(val);
252  }
253  }
254  }
255  livector1D cellExtracted = m_field.getGeometry()->extractPIDCells(commonPID);
256 
257  switch(loc){
259  {
260  livector1D vertExtracted = m_field.getGeometry()->getVertexFromCellList(cellExtracted);
261  for (const auto & ID : vertExtracted){
262  if (m_field.exists(ID)){
263  m_result.insert(ID, m_field[ID]);
264  }
265  }
266  }
267  break;
269  for (const auto & ID : cellExtracted){
270  if (m_field.exists(ID)){
271  m_result.insert(ID, m_field[ID]);
272  }
273  }
274  break;
276  {
277  livector1D interfExtracted = m_field.getGeometry()->getInterfaceFromCellList(cellExtracted);
278  for (const auto & ID : interfExtracted){
279  if (m_field.exists(ID)){
280  m_result.insert(ID, m_field[ID]);
281  }
282  }
283  }
284  break;
285  default:
286  //do nothing
287  break;
288  }
289 }
290 
296 void ExtractLongField::extractMapping(mimmo::MPVLocation loc){
297 
298  m_field.getGeometry()->buildSkdTree();
299  getGeometry()->buildSkdTree();
300 #if MIMMO_ENABLE_MPI
301  livector1D cellExtracted = mimmo::skdTreeUtils::selectByGlobalPatch(m_field.getGeometry()->getSkdTree(), getGeometry()->getSkdTree(), m_tol);
302 #else
303  livector1D cellExtracted = mimmo::skdTreeUtils::selectByPatch(m_field.getGeometry()->getSkdTree(), getGeometry()->getSkdTree(), m_tol);
304 #endif
305 
306  switch(loc){
308  {
309  livector1D vertExtracted = getGeometry()->getVertexFromCellList(cellExtracted);
310  for (const auto & ID : vertExtracted){
311  if (m_field.exists(ID)){
312  m_result.insert(ID, m_field[ID]);
313  }
314  }
315  }
316  break;
318  for (const auto & ID : cellExtracted){
319  if (m_field.exists(ID)){
320  m_result.insert(ID, m_field[ID]);
321  }
322  }
323  break;
325  {
326  livector1D interfExtracted = getGeometry()->getInterfaceFromCellList(cellExtracted);
327  for (const auto & ID : interfExtracted){
328  if (m_field.exists(ID)){
329  m_result.insert(ID, m_field[ID]);
330  }
331  }
332  }
333  break;
334  default:
335  //do nothing
336  break;
337  }
338 }
339 
340 }
#define M_LONGFIELD
void swap(ExtractLongField &x) noexcept
void swap(ExtractField &x) noexcept
ExtractLongField & operator=(const ExtractLongField &other)
void setField(MimmoPiercedVector< long > *field)
MPVLocation
Define data location for the MimmoPiercedVector field.
void setName(std::string name)
std::vector< long > livector1D
ExtractField is an abstract executable block class for extracting/restricting an input field defined ...
void warningXML(bitpit::Logger *log, std::string name)
MimmoSharedPointer< MimmoObject > getGeometry() const
void write(MimmoSharedPointer< MimmoObject > geometry)
ExtractField & operator=(const ExtractField &other)
MimmoPiercedVector< long > getOriginalField()
std::vector< long > selectByPatch(bitpit::PatchSkdTree *selection, bitpit::PatchSkdTree *target, double tol)
void setGeometry(MimmoSharedPointer< MimmoObject > geo)
void setDataLocation(MPVLocation loc)
virtual void absorbSectionXML(const bitpit::Config::Section &slotXML, std::string name="")
MimmoPiercedVector< long > * getExtractedField()
MimmoSharedPointer< MimmoObject > getGeometry()
ExtractLongField is specialized derived class of ExtractField to extract a scalar field of long.