Loading...
Searching...
No Matches
adaption.cpp
1/*---------------------------------------------------------------------------*\
2 *
3 * bitpit
4 *
5 * Copyright (C) 2015-2021 OPTIMAD engineering Srl
6 *
7 * -------------------------------------------------------------------------
8 * License
9 * This file is part of bitpit.
10 *
11 * bitpit 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 * bitpit 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 bitpit. If not, see <http://www.gnu.org/licenses/>.
22 *
23\*---------------------------------------------------------------------------*/
24
25#include <unordered_map>
26#include <unordered_set>
27
28#include "patch_kernel.hpp"
29
30namespace bitpit {
31
37namespace adaption
38{
39
79{
80 m_cachedTypes.insert(adaption::TYPE_DELETION);
81 m_cachedTypes.insert(adaption::TYPE_CREATION);
82 m_cachedTypes.insert(adaption::TYPE_PARTITION_RECV);
83 m_cachedTypes.insert(adaption::TYPE_PARTITION_SEND);
84}
85
93const std::vector<Info> & InfoCollection::data() const noexcept
94{
95 return m_collection;
96}
97
105std::vector<Info> & InfoCollection::data() noexcept
106{
107 return m_collection;
108}
109
116{
117 m_collection.emplace_back();
118
119 return m_collection.size() - 1;
120}
121
135std::size_t InfoCollection::create(Type type, Entity entity, int rank)
136{
137 infoData_t infoData = infoData_t(type, entity, rank);
138 bool useCache = (m_cachedTypes.count(type) > 0);
139
140 if (useCache) {
141 if (m_cache.count(infoData) > 0) {
142 return m_cache.at(infoData);
143 }
144 }
145
146 m_collection.emplace_back(type, entity, rank);
147
148 std::size_t id = m_collection.size() - 1;
149 if (useCache) {
150 m_cache.insert({{infoData, id}});
151 }
152 return id;
153}
154
162Info & InfoCollection::at(std::size_t n)
163{
164 if (n >= m_collection.size()) {
165 throw std::out_of_range("Requested adaption info is not in the collection");
166 }
167
168 return (*this)[n];
169}
170
178const Info & InfoCollection::at(std::size_t n) const
179{
180 if (n >= m_collection.size()) {
181 throw std::out_of_range("Requested adaption info is not in the collection");
182 }
183
184 return (*this)[n];
185}
186
194{
195 return m_collection[id];
196}
197
204const Info & InfoCollection::operator[](std::size_t id) const
205{
206 return m_collection[id];
207}
208
217std::vector<Info> InfoCollection::dump()
218{
219 std::vector<Info> exportedCollection;
220 exportedCollection.swap(m_collection);
221
222 m_cache.clear();
223
224 return exportedCollection;
225}
226
227}
228
241 : m_patch(nullptr)
242{
243}
244
251 : m_patch(patch)
252{
253}
254
260const std::vector<long> & FlatMapping::getNumbering() const
261{
262 return m_numbering;
263}
264
270const std::vector<long> & FlatMapping::getMapping() const
271{
272 return m_mapping;
273}
274
290
297 : FlatMapping(patch)
298{
299 m_numbering.reserve(m_patch->getCellCount());
300 m_mapping.reserve(m_patch->getCellCount());
301
302 long flatId = -1;
303 for (const auto &cell : m_patch->getCells()) {
304 flatId++;
305
306 m_numbering.emplace_back();
307 long &cellId = m_numbering.back();
308 cellId = cell.getId();
309
310 m_mapping.emplace_back();
311 long &cellMapping = m_mapping.back();
312 cellMapping = flatId;
313 }
314}
315
322void CellFlatMapping::update(const std::vector<adaption::Info> &adaptionData)
323{
324 // Previous number of cells
325 long nPreviousCells = m_numbering.size();
326
327 // Current number of cells
328 long nCurrentCells = m_patch->getCellCount();
329
330 // Find the first change
331 long firstChangedFlatId = std::min(nCurrentCells, nPreviousCells);
332 long firstChangedId = m_patch->getCells().getSizeMarker(firstChangedFlatId, Element::NULL_ID);
333 for (auto &adaptionInfo : adaptionData) {
334 if (adaptionInfo.entity != adaption::ENTITY_CELL) {
335 continue;
336 }
337
338 for (const auto &currentId : adaptionInfo.current) {
339 long currentFlatId = m_patch->getCells().evalFlatIndex(currentId);
340 if (currentFlatId < firstChangedFlatId) {
341 firstChangedId = currentId;
342 firstChangedFlatId = currentFlatId;
343 }
344 }
345 }
346
347 // The mapping, until the flat id with the first change, is a no-op mapping
348 m_mapping.resize(nCurrentCells);
349 for (long flatId = 0; flatId < firstChangedFlatId; ++flatId) {
350 m_mapping[flatId] = flatId;
351 }
352
353 // If there are no changes the mapping is already updated
354 if (firstChangedId < 0) {
355 return;
356 }
357
358 // List of cells that have been deleted
359 std::unordered_set<long> removedIds;
360 for (auto &adaptionInfo : adaptionData) {
361 if (adaptionInfo.entity != adaption::ENTITY_CELL) {
362 continue;
363 }
364
365 for (const auto &previousId : adaptionInfo.previous) {
366 removedIds.insert(previousId);
367 }
368 }
369 long nRemovedCells = removedIds.size();
370
371 // Create a mapping between cell ids and previous flat ids
372 std::unordered_map<long, long> previousFlatIds;
373 std::unordered_map<long, long> removedFlatIds;
374 previousFlatIds.reserve(nCurrentCells - firstChangedFlatId - nRemovedCells);
375 removedFlatIds.reserve(nRemovedCells);
376 for (long previousFlatId = firstChangedFlatId; previousFlatId < nPreviousCells; ++previousFlatId) {
377 long previousId = m_numbering[previousFlatId];
378 if (removedIds.count(previousId) > 0) {
379 removedFlatIds.insert({{previousId, previousFlatId}});
380 } else {
381 previousFlatIds.insert({{previousId, previousFlatId}});
382 }
383 }
384
385 // Add to the mapping the added cells
386 for (auto &adaptionInfo : adaptionData) {
387 if (adaptionInfo.entity != adaption::ENTITY_CELL) {
388 continue;
389 }
390
391 // Ancestor flat index of the added cells
392 long ancestorFlatId;
393 if (adaptionInfo.previous.size() > 0) {
394 ancestorFlatId = removedFlatIds.at(adaptionInfo.previous[0]);
395 } else {
396 ancestorFlatId = -1;
397 }
398
399 // Mapping of the added cells
400 for (const auto &currentId : adaptionInfo.current) {
401 previousFlatIds.insert({{currentId, ancestorFlatId}});
402 }
403 }
404
405 std::unordered_map<long, long>().swap(removedFlatIds);
406
407 // Update numbering and mapping past the flat id with the first change
408 m_numbering.resize(nCurrentCells);
409 auto cellIterator = m_patch->getCells().find(firstChangedId);
410 for (long flatId = firstChangedFlatId; flatId < nCurrentCells; ++flatId) {
411 long cellId = cellIterator->getId();
412
413 m_numbering[flatId] = cellId;
414 m_mapping[flatId] = previousFlatIds[cellId];
415
416 cellIterator++;
417 }
418}
419
420}
void update(const std::vector< adaption::Info > &adaptionData) override
Definition adaption.cpp:322
The FlatMapping class allows to generate a mapping between an id-base numeration to a continuous-inde...
Definition adaption.hpp:113
const std::vector< long > & getMapping() const
Definition adaption.cpp:270
const std::vector< long > & getNumbering() const
Definition adaption.cpp:260
The PatchKernel class provides an interface for defining patches.
PiercedVector< Cell > & getCells()
virtual long getCellCount() const
const std::vector< Info > & data() const noexcept
Definition adaption.cpp:93
Info & operator[](std::size_t id)
Definition adaption.cpp:193
std::vector< Info > dump()
Definition adaption.cpp:217
Info & at(std::size_t id)
Definition adaption.cpp:162
The Info struct defines the information associated to an adaption.
Definition adaption.hpp:63
--- layout: doxygen_footer ---