chombo-discharge
Loading...
Searching...
No Matches
CD_ScanShopImplem.H
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2021-2026 SINTEF Energy Research
3 *
4 * SPDX-License-Identifier: GPL-3.0-or-later
5 */
6
13#ifndef CD_SCANSHOPIMPLEM_H
14#define CD_SCANSHOPIMPLEM_H
15
16// Std includes
17#include <algorithm>
18
19// Our includes
20#include <CD_ScanShop.H>
21#include <CD_NamespaceHeader.H>
22
23inline int
24ScanShop::getScanSkip(Real a_slack, Real a_dx) const
25{
26 // A signed distance function changes by at most the distance travelled, so no cell centre closer than
27 // a_slack to the evaluated point can cross the threshold. Those cells are passed over. The guard keeps
28 // the skipped distance strictly below a_slack, so a cell exactly a_slack away is still evaluated.
29 if (!m_distanceSkip || a_slack <= 0.0) {
30 return 0;
31 }
32
33 int skip = static_cast<int>(a_slack / a_dx);
34
35 if (skip * a_dx >= a_slack) {
36 skip--;
37 }
38
39 return std::max(skip, 0);
40}
41
42inline bool
43ScanShop::isRegular(Box a_box, const RealVect& a_probLo, Real a_dx) const
44{
45 CH_TIME("ScanShop::isRegular(Box, RealVect, Real)");
46
47 // Short-circuit search over the box: a direct index loop with early return rather than a BoxLoops::loop,
48 // since BoxLoops::loop cannot break early and m_baseIF->value(...) is expensive.
49 const Real halfDiagonal = 0.5 * a_dx * sqrt(SpaceDim);
50
51#if CH_SPACEDIM == 3
52 for (int k = a_box.smallEnd(2); k <= a_box.bigEnd(2); k++) {
53#endif
54 for (int j = a_box.smallEnd(1); j <= a_box.bigEnd(1); j++) {
55 for (int i = a_box.smallEnd(0); i <= a_box.bigEnd(0); i++) {
56 const RealVect point = a_probLo + a_dx * (0.5 * RealVect::Unit + RealVect(IntVect(D_DECL(i, j, k))));
57 const Real value = m_baseIF->value(point);
58
59 if (value >= -halfDiagonal) {
60 return false;
61 }
62
63 i += this->getScanSkip(-value - halfDiagonal, a_dx);
64 }
65 }
66#if CH_SPACEDIM == 3
67 }
68#endif
69
70 return true;
71}
72
73inline bool
74ScanShop::isCovered(Box a_box, const RealVect& a_probLo, Real a_dx) const
75{
76 CH_TIME("ScanShop::isCovered(Box, RealVect, Real)");
77
78 // Short-circuit search over the box: a direct index loop with early return rather than a BoxLoops::loop,
79 // since BoxLoops::loop cannot break early and m_baseIF->value(...) is expensive.
80 const Real halfDiagonal = 0.5 * a_dx * sqrt(SpaceDim);
81
82#if CH_SPACEDIM == 3
83 for (int k = a_box.smallEnd(2); k <= a_box.bigEnd(2); k++) {
84#endif
85 for (int j = a_box.smallEnd(1); j <= a_box.bigEnd(1); j++) {
86 for (int i = a_box.smallEnd(0); i <= a_box.bigEnd(0); i++) {
87 const RealVect point = a_probLo + a_dx * (0.5 * RealVect::Unit + RealVect(IntVect(D_DECL(i, j, k))));
88 const Real value = m_baseIF->value(point);
89
90 if (value <= halfDiagonal) {
91 return false;
92 }
93
94 i += this->getScanSkip(value - halfDiagonal, a_dx);
95 }
96 }
97#if CH_SPACEDIM == 3
98 }
99#endif
100
101 return true;
102}
103
104inline std::vector<std::pair<Box, int>>
105ScanShop::getSortedBoxesAndTypes(const Vector<Box>& a_boxes, const Vector<int>& a_types) const
106{
107
108 std::vector<std::pair<Box, int>> sortedBoxesAndTypes;
109
110 for (int i = 0; i < a_boxes.size(); i++) {
111 sortedBoxesAndTypes.emplace_back(std::make_pair(a_boxes[i], a_types[i]));
112 }
113
114 auto comparator = [](const std::pair<Box, int>& a, const std::pair<Box, int>& b) -> bool {
115 return a.first < b.first;
116 };
117
118 std::sort(sortedBoxesAndTypes.begin(), sortedBoxesAndTypes.end(), comparator);
119
120 return sortedBoxesAndTypes;
121}
122
123#endif
124
125#include <CD_NamespaceFooter.H>
Declare a class geometry generation (ScanShop) that uses the signed distance function for optimizatio...
bool m_distanceSkip
Whether or not the box scan may skip cells using the implicit function value as a distance.
Definition CD_ScanShop.H:179
int getScanSkip(Real a_slack, Real a_dx) const
Number of cells along the scan line that can be passed over without evaluating the implicit function.
Definition CD_ScanShopImplem.H:24
bool isRegular(Box a_box, const RealVect &a_probLo, Real a_dx) const
Check if every point in input box is regular.
Definition CD_ScanShopImplem.H:43
std::vector< std::pair< Box, int > > getSortedBoxesAndTypes(const Vector< Box > &a_boxes, const Vector< int > &a_types) const
Sort boxes lexicographically.
Definition CD_ScanShopImplem.H:105
const BaseIF * m_baseIF
Implicit function used to generate geometries.
Definition CD_ScanShop.H:199
bool isCovered(Box a_box, const RealVect &a_probLo, Real a_dx) const
Check if every point in box is covered.
Definition CD_ScanShopImplem.H:74