25# ifndef __BITPIT_LEVELSET_BOOLEAN_OBJECT_TPP__
26# define __BITPIT_LEVELSET_BOOLEAN_OBJECT_TPP__
41template<
typename SourceLevelSetObject>
43 : m_operation(operation), m_object(nullptr), m_objectSign(0), m_value(levelSetDefaults::
VALUE)
54template<
typename SourceLevelSetObject>
56 : m_operation(operation), m_object(object), m_objectSign(1), m_value(value)
66template<
typename SourceLevelSetObject>
85 m_value = m_objectSign * value;
93 m_value = m_objectSign * value;
97 if(m_value < - value) {
101 m_value = m_objectSign * value;
109template<
typename SourceLevelSetObject>
117template<
typename SourceLevelSetObject>
125template<
typename SourceLevelSetObject>
143template<
typename SourceLevelSetObject>
148 m_sourceObjects.push_back(source1);
149 m_sourceObjects.push_back(source2);
159template<
typename SourceLevelSetObject>
162 m_operation(op), m_sourceObjects(sourceObjects) {
171template<
typename SourceLevelSetObject>
174 for (
const SourceLevelSetObject *sourceObject : m_sourceObjects) {
175 if (!sourceObject->empty()) {
187template<
typename SourceLevelSetObject>
198template<
typename SourceLevelSetObject>
199LevelSetBooleanResult<SourceLevelSetObject> LevelSetBooleanBaseObject<SourceLevelSetObject>::computeBooleanResult(
long id,
bool signedLevelSet )
const{
201 if (m_sourceObjects.empty()) {
202 return LevelSetBooleanResult<SourceLevelSetObject>(getBooleanOperation());
205 LevelSetBooleanResult<SourceLevelSetObject> result( getBooleanOperation(), m_sourceObjects[0], m_sourceObjects[0]->evalCellValue(
id, signedLevelSet) );
206 for(
size_t n=1; n<m_sourceObjects.size(); ++n){
207 result.update(m_sourceObjects[n], m_sourceObjects[n]->evalCellValue(
id, signedLevelSet));
219template<
typename SourceLevelSetObject>
220LevelSetBooleanResult<SourceLevelSetObject> LevelSetBooleanBaseObject<SourceLevelSetObject>::computeBooleanResult(
const std::array<double,3> &coords,
bool signedLevelSet )
const{
222 if (m_sourceObjects.empty()) {
223 return LevelSetBooleanResult<SourceLevelSetObject>(getBooleanOperation());
226 LevelSetBooleanResult<SourceLevelSetObject> result( getBooleanOperation(), m_sourceObjects[0], m_sourceObjects[0]->evalValue(coords, signedLevelSet) );
227 for(
size_t n=1; n<m_sourceObjects.size(); ++n){
228 result.update(m_sourceObjects[n], m_sourceObjects[n]->evalValue(coords, signedLevelSet));
239template<
typename SourceLevelSetObject>
242 std::size_t nSources = m_sourceObjects.size();
243 for (std::size_t i = 0; i < nSources; ++i) {
244 const SourceLevelSetObject *source = m_sourceObjects[i];
245 if (source == current) {
246 m_sourceObjects[i] = updated;
251 throw std::runtime_error(
"Unable to find the source that should be replaced.");
257template<
typename SourceLevelSetObject>
261 for (
const SourceLevelSetObject *sourceObject : m_sourceObjects) {
264 bool useSourceSign =
false;
266 useSourceSign =
true;
270 useSourceSign =
true;
274 useSourceSign =
true;
279 if (!useSourceSign) {
280 SourceLevelSetObject::fillCellPropagatedSignCache();
286 const VolumeKernel &mesh = *(this->getKernel()->getMesh()) ;
291 typedef typename SourceLevelSetObject::CellCacheCollection::template ValueCache<char> ZoneCache;
292 ZoneCache *propagatedSignCache = this->
template getCellCache<char>(this->m_cellPropagatedSignCacheId);
296 long cellId = cellItr.getId();
298 short cellSign = this->evalValueSign(cellResult.
getValue());
300 propagatedSignCache->insertEntry(cellId,
static_cast<char>(cellSign));
310template<
typename SourceLevelSetObject>
312 return this->evalValueSign(_evalCellValue(
id,
true));
322template<
typename SourceLevelSetObject>
327 if ( !resultObject ) {
341template<
typename SourceLevelSetObject>
346 if ( !resultObject ) {
350 std::array<double,3> gradient = resultObject->
evalCellGradient(
id, signedLevelSet);
351 if (signedLevelSet) {
355 return static_cast<double>(result.getObjectSign()) * gradient;
366template<
typename SourceLevelSetObject>
370 const SourceLevelSetObject *resultObject = result.
getObject();
371 if ( !resultObject ) {
386template<
typename SourceLevelSetObject>
391 if ( !resultObject ) {
395 std::array<double,3> gradient = resultObject->
evalGradient(point, signedLevelSet);
396 if (signedLevelSet) {
400 return static_cast<double>(result.getObjectSign()) * gradient;
410template<
typename SourceLevelSetObject>
411template<
typename data_t,
typename function_t>
413 const function_t &function)
const
417 return function(result) ;
426template<
typename SourceLevelSetObject>
427template<
typename data_t,
typename function_t>
429 const function_t &function)
const
433 return function(result) ;
442template<
typename SourceLevelSetObject>
446 if (m_sourceObjects.empty()) {
451 if (m_sourceObjects.size() == 1) {
452 return m_sourceObjects.front();
468template<
typename SourceLevelSetObject>
472 if (m_sourceObjects.empty()) {
477 if (m_sourceObjects.size() == 1) {
478 return m_sourceObjects.front();
493template<
typename SourceLevelSetObject>
496 return m_sourceObjects;
Base class which deals with boolean operation between two LevelSetObjects.
std::vector< const SourceLevelSetObject * > getSourceObjects() const override
std::array< double, 3 > _evalGradient(const std::array< double, 3 > &point, bool signedLevelSet) const override
const SourceLevelSetObject * getCellReferenceObject(long id) const override
bool empty() const override
double _evalValue(const std::array< double, 3 > &point, bool signedLevelSet) const override
std::array< double, 3 > _evalCellGradient(long id, bool signedLevelSet) const override
LevelSetBooleanBaseObject(int, LevelSetBooleanOperation, const SourceLevelSetObject *, const SourceLevelSetObject *)
const SourceLevelSetObject * getReferenceObject(const std::array< double, 3 > &point) const override
data_t _evalCellFunction(long id, bool signedLevelSet, const function_t &function) const
short _evalCellSign(long id) const override
double _evalCellValue(long id, bool signedLevelSet) const override
data_t _evalFunction(const std::array< double, 3 > &point, bool signedLevelSet, const function_t &function) const
void fillCellPropagatedSignCache() override
void replaceSourceObject(const SourceLevelSetObject *current, const SourceLevelSetObject *updated) override
Allow to evaluate the result of a boolean operation between two LevelSetObjects.
void update(const SourceLevelSetObject *object, double value)
LevelSetBooleanResult(LevelSetBooleanOperation operation)
const SourceLevelSetObject * getObject() const
int getObjectSign() const
Interface class for all objects with respect to whom the levelset function may be computed.
virtual std::array< double, 3 > evalCellGradient(long id, bool signedLevelSet) const
virtual std::array< double, 3 > evalGradient(const std::array< double, 3 > &point, bool signedLevelSet) const
Interface class for all objects, which depend on other LevelSetObjects.
CellConstIterator cellConstBegin() const
CellConstIterator cellConstEnd() const
Iterator for the class PiercedStorage.
The VolumeKernel class provides an interface for defining volume patches.
LevelSetBulkEvaluationMode
@ FULL
Data are cached in the whole domain.
@ SIGN_PROPAGATION
Sign is propagated from the narrow band, no other data will be evaluated.
@ EXACT
Exact data is evaluated.
const std::array< double, 3 > GRADIENT