Loading...
Searching...
No Matches
levelSetObject.tpp
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# ifndef __BITPIT_LEVELSET_OBJECT_TPP__
26# define __BITPIT_LEVELSET_OBJECT_TPP__
27
28namespace bitpit {
29
39template<typename value_t>
41{
43 if (cacheMode == LevelSetCacheMode::NONE) {
44 return nullptr;
45 }
46
47 std::size_t cacheId = getFieldCellCacheId(field);
48
49 return getCellCache<value_t>(cacheId);
50}
51
60template<typename value_t>
62{
64 return nullptr;
65 }
66
67 return (*m_cellCacheCollection)[cacheId].getCache<value_t>();
68}
69
78template<typename value_t>
79std::size_t LevelSetObject::createFieldCellCache(LevelSetField field, std::size_t cacheId)
80{
81 // Create cache
83 if (cacheMode != LevelSetCacheMode::NONE) {
84 LevelSetFillIn expectedFillIn;
86 expectedFillIn = LevelSetFillIn::DENSE;
87 } else {
88 expectedFillIn = LevelSetFillIn::SPARSE;
89 }
90
91 cacheId = createCellCache<value_t>(expectedFillIn, cacheId);
92 } else {
94 }
95
96 // Update field properties
97 std::size_t fieldIndex = static_cast<std::size_t>(field);
98 m_cellFieldCacheIds[fieldIndex] = cacheId;
99
100 return cacheId;
101}
102
111template<typename value_t>
112std::size_t LevelSetObject::createCellCache(LevelSetFillIn expectedFillIn, std::size_t cacheId)
113{
114 if (dynamic_cast<const LevelSetCartesianKernel *>(m_kernel)){
115 if (expectedFillIn == LevelSetFillIn::DENSE) {
116 cacheId = m_cellCacheCollection->insert<LevelSetCartesianKernel::CellDenseCacheContainer<value_t>>(cacheId);
117 } else if (expectedFillIn == LevelSetFillIn::SPARSE) {
118 cacheId = m_cellCacheCollection->insert<LevelSetCartesianKernel::CellSparseCacheContainer<value_t>>(cacheId);
119 } else {
120 BITPIT_UNREACHABLE("The fill in type is not supported!");
121 throw std::runtime_error("The fill in type is not supported!");
122 }
123 } else if (dynamic_cast<const LevelSetOctreeKernel *>(m_kernel)){
124 if (expectedFillIn == LevelSetFillIn::DENSE) {
125 cacheId = m_cellCacheCollection->insert<LevelSetOctreeKernel::CellDenseCacheContainer<value_t>>(cacheId);
126 } else if (expectedFillIn == LevelSetFillIn::SPARSE) {
127 cacheId = m_cellCacheCollection->insert<LevelSetOctreeKernel::CellSparseCacheContainer<value_t>>(cacheId);
128 } else {
129 BITPIT_UNREACHABLE("The fill in type is not supported!");
130 throw std::runtime_error("The fill in type is not supported!");
131 }
132 } else if (dynamic_cast<const LevelSetUnstructuredKernel *>(m_kernel)){
133 if (expectedFillIn == LevelSetFillIn::DENSE) {
134 cacheId = m_cellCacheCollection->insert<LevelSetUnstructuredKernel::CellDenseCacheContainer<value_t>>(cacheId);
135 } else if (expectedFillIn == LevelSetFillIn::SPARSE) {
136 cacheId = m_cellCacheCollection->insert<LevelSetUnstructuredKernel::CellSparseCacheContainer<value_t>>(cacheId);
137 } else {
138 BITPIT_UNREACHABLE("The fill in type is not supported!");
139 throw std::runtime_error("The fill in type is not supported!");
140 }
141 } else {
142 BITPIT_UNREACHABLE("The kernel type is not supported!");
143 throw std::runtime_error("The kernel type is not supported!");
144 }
145
146 return cacheId;
147}
148
163template<typename value_t, typename evaluator_t, typename fallback_t>
164void LevelSetObject::flushVTKOutputData(std::fstream &stream, VTKFormat format, LevelSetField field,
165 const evaluator_t evaluator, const fallback_t fallback) const
166{
167 LevelSetCacheMode fieldCacheMode = getFieldCellCacheMode(field);
168 switch (fieldCacheMode) {
169
171 {
173 for (const Cell &cell : m_kernel->getMesh()->getVTKCellWriteRange()) {
174 long cellId = cell.getId();
175 if (cache->contains(cellId)) {
176 flushValue(stream, format, evaluator(cellId));
177 } else {
178 flushValue(stream, format, fallback(cellId));
179 }
180 }
181
182 break;
183 }
184
186 {
187 for (const Cell &cell : m_kernel->getMesh()->getVTKCellWriteRange()) {
188 long cellId = cell.getId();
189 if (isCellInNarrowBand(cellId)) {
190 flushValue(stream, format, evaluator(cellId));
191 } else {
192 flushValue(stream, format, fallback(cellId));
193 }
194 }
195
196 break;
197 }
198
200 {
201 for (const Cell &cell : m_kernel->getMesh()->getVTKCellWriteRange()) {
202 long cellId = cell.getId();
203 flushValue(stream, format, evaluator(cellId));
204 }
205
206 break;
207 }
208
209 default:
210 {
211 for (const Cell &cell : m_kernel->getMesh()->getVTKCellWriteRange()) {
212 long cellId = cell.getId();
213 flushValue(stream, format, fallback(cellId));
214 }
215
216 break;
217 }
218
219 }
220}
221
235template<typename value_t, typename evaluator_t, typename fallback_t>
236value_t LevelSetObject::evalCellFieldCached(LevelSetField field, long id, const evaluator_t &evaluator, const fallback_t &fallback) const
237{
238 // Try fetching the field from the cache
239 CellCacheCollection::ValueCache<value_t> *cache = getFieldCellCache<value_t>(field);
240 if (cache) {
241 typename CellCacheCollection::ValueCache<value_t>::Entry cacheEntry = cache->findEntry(id);
242 if (cacheEntry.isValid()) {
243 return *cacheEntry;
244 }
245 }
246
247 // Evaluate the field
248 value_t value = evalCellField<value_t>(field, id, evaluator, fallback);
249
250 // Update the cache
251 fillFieldCellCache(field, id, value);
252
253 // Return the value
254 return value;
256
266template<typename value_t, typename evaluator_t, typename fallback_t>
267value_t LevelSetObject::evalCellField(LevelSetField field, long id, const evaluator_t &evaluator, const fallback_t &fallback) const
268{
269 BITPIT_UNUSED(field);
270
271 // Get cell location
272 LevelSetCellLocation cellLocation = getCellLocation(id);
273
274 // Early return if the zone has not been detected
275 if (cellLocation == LevelSetCellLocation::UNKNOWN) {
276 return evaluator(id);
277 }
278
279 // Early return if the fallback value should be returned
280 if (cellLocation == LevelSetCellLocation::BULK) {
281 if (m_cellBulkEvaluationMode != LevelSetBulkEvaluationMode::EXACT) {
282 return fallback(id);
283 }
284 }
285
286 // Return the value
287 return evaluator(id);
288}
289
301template<typename value_t>
302void LevelSetObject::fillFieldCellCache(LevelSetField field, long id, const value_t &value) const
303{
304 // Early return if no cache is associated with the field
305 LevelSetCacheMode levelsetCacheMode = getFieldCellCacheMode(field);
306 if (levelsetCacheMode == LevelSetCacheMode::NONE) {
307 return;
308 }
309
310 // Early return if the cache doesn't need to be updated
311 //
312 // There are some cases were the cache doesn't need to be updated:
313 // - cells outside the narrow band should not be added to caches in "narrow band" mode.
314 //
315 // If the zone of the cell has not been detected, it's not possible to check the aforementioned
316 // conditions. In this case the cache can be updated only if it is operating in "full" mode and
317 // the bulk is evaluated using an exact method.
318 LevelSetCellLocation cellLocation = getCellLocation(id);
319 if (cellLocation == LevelSetCellLocation::UNKNOWN) {
320 if (levelsetCacheMode != LevelSetCacheMode::FULL) {
321 return;
322 }
323
325 return;
326 }
327 } else if (cellLocation == LevelSetCellLocation::BULK) {
328 if (levelsetCacheMode == LevelSetCacheMode::NARROW_BAND) {
329 return;
330 }
331 }
332
333 // Update the cache
334 CellCacheCollection::ValueCache<value_t> *cache = getFieldCellCache<value_t>(field);
335 cache->insertEntry(id, value);
336}
337
338}
339
340#endif
The Cell class defines the cells.
Definition cell.hpp:42
The class LevelSetCache is the base class for defining caches.
Implements LevelSetKernel for cartesian meshes.
virtual VolumeKernel * getMesh() const
LevelSetFillIn getExpectedFillIn() const
CellCacheCollection::ValueCache< value_t > * getCellCache(std::size_t cacheId) const
LevelSetBulkEvaluationMode getCellBulkEvaluationMode() const
void fillFieldCellCache(LevelSetField field, const std::vector< long > &cellIds)
LevelSetKernel * m_kernel
std::size_t createCellCache(LevelSetFillIn expectedFillIn, std::size_t cacheId=CellCacheCollection::NULL_CACHE_ID)
std::size_t getFieldCellCacheId(LevelSetField field) const
CellCacheCollection::ValueCache< value_t > * getFieldCellCache(LevelSetField field) const
LevelSetCacheMode getFieldCellCacheMode(LevelSetField field) const
LevelSetCellLocation getCellLocation(long id) const
virtual bool isCellInNarrowBand(long id) const
value_t evalCellFieldCached(LevelSetField field, long id, const evaluator_t &evaluator, const fallback_t &fallback) const
virtual void flushVTKOutputData(std::fstream &stream, VTKFormat format, LevelSetField field) const
value_t evalCellField(LevelSetField field, long id, const evaluator_t &evaluator, const fallback_t &fallback) const
virtual std::size_t createFieldCellCache(LevelSetField field, std::size_t cacheId=CellCacheCollection::NULL_CACHE_ID)
Implements LevelSetKernel for octree meshes.
Implements LevelSetKernel for unstructured meshes.
The class LevelSetCache is the base class for defining caches that store values.
const CellConstRange getVTKCellWriteRange() const
void flushValue(std::fstream &, VTKFormat, const T &value) const
VTKFormat
Definition VTK.hpp:92
#define BITPIT_UNREACHABLE(str)
Definition compiler.hpp:53
#define BITPIT_UNUSED(variable)
Definition compiler.hpp:63
@ NARROW_BAND
Data are cached only inside the narrow band.
@ NONE
No caching will be performed.
@ FULL
Data are cached in the whole domain.
@ ON_DEMAND
Data are cached only where explicitly evaluated.
@ UNKNOWN
Unknown location.
@ EXACT
Exact data is evaluated.
--- layout: doxygen_footer ---