Skip to content

Commit

Permalink
levelset: allow to evaluate the complement of an object
Browse files Browse the repository at this point in the history
  • Loading branch information
andrea-iob authored and marcocisternino committed Sep 29, 2023
1 parent 1d56601 commit aab4847
Show file tree
Hide file tree
Showing 9 changed files with 945 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/levelset/bitpit_levelset.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
#include "levelSetSegmentationObject.hpp"
#include "levelSetSignedObject.hpp"
#include "levelSetBooleanObject.hpp"
#include "levelSetComplementObject.hpp"
#include "levelSetMaskObject.hpp"

#include "levelSet.hpp"
Expand Down
18 changes: 18 additions & 0 deletions src/levelset/levelSet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,24 @@ void LevelSet::setMesh( VolumeKernel* mesh ) {

}

/*!
* Adds the complement of the specified object.
* Objects can be added to the levelset only after setting the mesh.
* @param[in] sourceId id of source object
* @param[in] id id to be assigned to object. In case default value is passed the insertion order will be used as identifier
* @return identifier of new object
*/
int LevelSet::addObjectComplement( int sourceId, int id ) {

assert(m_kernel && " levelset: setMesh must be called before adding a mask object ");

LevelSetObject *sourceObject = m_objects.at(sourceId).get() ;

std::unique_ptr<LevelSetObject> object = LevelSetObjectFactory::createComplementObject( m_kernel.get(), m_storageType, id, sourceObject ) ;

return registerObject(std::move(object));
};

/*!
* Adds a segmentation object
* Objects can be added to the levelset only after setting the mesh.
Expand Down
2 changes: 2 additions & 0 deletions src/levelset/levelSet.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,8 @@ class LevelSet{

void setMesh( VolumeKernel* ) ;

int addObjectComplement( int, int id=levelSetDefaults::OBJECT ) ;

int addObject( std::unique_ptr<SurfaceKernel> &&, double, int id = levelSetDefaults::OBJECT ) ;
int addObject( SurfaceKernel *, double, int id = levelSetDefaults::OBJECT ) ;
int addObject( std::unique_ptr<SurfUnstructured> &&, double, int id = levelSetDefaults::OBJECT ) ;
Expand Down
229 changes: 229 additions & 0 deletions src/levelset/levelSetComplementObject.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,229 @@
/*---------------------------------------------------------------------------*\
*
* bitpit
*
* Copyright (C) 2015-2021 OPTIMAD engineering Srl
*
* -------------------------------------------------------------------------
* License
* This file is part of bitpit.
*
* bitpit is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License v3 (LGPL)
* as published by the Free Software Foundation.
*
* bitpit is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with bitpit. If not, see <http://www.gnu.org/licenses/>.
*
\*---------------------------------------------------------------------------*/

# include <cassert>

# include "bitpit_IO.hpp"
# include "bitpit_common.hpp"

# include "levelSetObject.hpp"
# include "levelSetProxyObject.hpp"
# include "levelSetComplementObject.hpp"

namespace bitpit {

/*!
* \class LevelSetComplementObject
* \ingroup levelset
*
* \brief Class that allows to evaluate the complement of a LevelSetObjects.
*/

/*!
* Constructor.
*
* \param[in] id identifier of object
* \param[in] source pointer to source object
*/
LevelSetComplementObject::LevelSetComplementObject(int id, const LevelSetObject *source)
: LevelSetProxyObject(id),
m_sourceObject(source)
{
}

/*!
* Copy constructor.
*
* Assigns same id to new object;
* \param[in] other object to be copied
*/
LevelSetComplementObject::LevelSetComplementObject(const LevelSetComplementObject &other)
: LevelSetProxyObject(other),
m_sourceObject(other.m_sourceObject)
{
}

/*!
* Returns LevelSetInfo.
*
* \param[in] id cell id
* \return LevelSetInfo
*/
LevelSetInfo LevelSetComplementObject::getLevelSetInfo(long id) const
{
return LevelSetInfo(getValue(id), getGradient(id));
}

/*!
* Get the levelset value.
*
* \param[in] id cell id
* \return levelset value in cell
*/
double LevelSetComplementObject::getLS(long id) const
{
return getValue(id);
}

/*!
* Get the levelset value.
*
* \param[in] id cell id
* \return levelset value in cell
*/
double LevelSetComplementObject::getValue(long id) const
{
return (- m_sourceObject->getValue(id));
}

/*!
* Get the levelset gradient.
*
* \param[in] id cell id
* \return levelset gradient in cell
*/
std::array<double,3> LevelSetComplementObject::getGradient(long id) const
{
return (- 1. * m_sourceObject->getGradient(id));
}

/*!
* Computes the LevelSetInfo in a point.
*
* \param[in] coords point coordinates
* \return LevelSetInfo
*/
LevelSetInfo LevelSetComplementObject::computeLevelSetInfo(const std::array<double,3> &coords) const
{
LevelSetInfo levelSetInfo = m_sourceObject->computeLevelSetInfo(coords);
levelSetInfo.value *= -1.;
levelSetInfo.gradient *= -1.;

return levelSetInfo;
}

/*!
* Replace a source object.
*
* \param[in] current current source object
* \param[in] updated updated source object
*/
void LevelSetComplementObject::replaceSourceObject(const LevelSetObject *current, const LevelSetObject *updated)
{
if (current != m_sourceObject) {
throw std::runtime_error("Unable to find the source that should be replaced.");
}

m_sourceObject = updated;
}

/*!
* Clones the object.
*
* \return pointer to cloned object
*/
LevelSetComplementObject* LevelSetComplementObject::clone() const
{
return new LevelSetComplementObject(*this);
}

/*!
* Gets the surface normal at the projection point.
*
* \param[in] id cell index
* \return closest part
*/
std::array<double,3> LevelSetComplementObject::getNormal(long id) const
{
return (-1. * m_sourceObject->getNormal(id));
}

/*!
* Gets the closest part index.
*
* \param[in] id cell index
* \return closest part
*/
int LevelSetComplementObject::getPart(long id) const
{
return m_sourceObject->getPart(id);
}

/*!
* Get surface feature size.
*
* \param[in] id cell index
* \return characteristic size
*/
double LevelSetComplementObject::getSurfaceFeatureSize(long id) const
{
return m_sourceObject->getSurfaceFeatureSize(id);
}

/*!
* Get the smallest surface feature size.
*
* \return characteristic size
*/
double LevelSetComplementObject::getMinSurfaceFeatureSize() const
{
return m_sourceObject->getMinSurfaceFeatureSize();
}

/*!
* Get the largest surface feature size.
*
* \return characteristic size
*/
double LevelSetComplementObject::getMaxSurfaceFeatureSize() const
{
return m_sourceObject->getMaxSurfaceFeatureSize();
}

/*!
* Get the object that defines the levelset information for the specified cell.
*
* \param[in] id cell index
* \return The object that defines the levelset information for the specified
* cell.
*/
const LevelSetObject * LevelSetComplementObject::getReferenceObject(long id) const
{
BITPIT_UNUSED(id);

return m_sourceObject;
}

/*!
* Get all objects that compose the boolean object.
*
* \return pointers to all primary objects involved in the definition of the
* boolean object levelset information.
*/
std::vector<const LevelSetObject *> LevelSetComplementObject::getSourceObjects() const
{
return std::vector<const LevelSetObject *>(1, m_sourceObject);
}

}
74 changes: 74 additions & 0 deletions src/levelset/levelSetComplementObject.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
/*---------------------------------------------------------------------------*\
*
* bitpit
*
* Copyright (C) 2015-2021 OPTIMAD engineering Srl
*
* -------------------------------------------------------------------------
* License
* This file is part of bitpit.
*
* bitpit is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License v3 (LGPL)
* as published by the Free Software Foundation.
*
* bitpit is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
* License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with bitpit. If not, see <http://www.gnu.org/licenses/>.
*
\*---------------------------------------------------------------------------*/

# ifndef __BITPIT_LEVELSET_COMPLEMENT_OBJECT_HPP__
# define __BITPIT_LEVELSET_COMPLEMENT_OBJECT_HPP__

# include <array>

# include "levelSetCommon.hpp"
# include "levelSetProxyObject.hpp"

namespace bitpit{

class LevelSetObject ;
class LevelSetProxyObject ;

class LevelSetComplementObject: public LevelSetProxyObject {

private:
const LevelSetObject* m_sourceObject; /**< Pointers to source object */

protected:
void replaceSourceObject(const LevelSetObject *current, const LevelSetObject *updated) override ;

public:
LevelSetComplementObject(int id, const LevelSetObject*);
LevelSetComplementObject(const LevelSetComplementObject &);

LevelSetComplementObject* clone() const override;

LevelSetInfo getLevelSetInfo(long ) const override;
double getLS(long ) const override;
double getValue(long ) const override;
std::array<double,3> getGradient(long ) const override;

std::array<double,3> getNormal(long ) const override;
int getPart(long ) const override;
double getSurfaceFeatureSize(long ) const override;

LevelSetInfo computeLevelSetInfo(const std::array<double,3> &) const override;

double getMinSurfaceFeatureSize() const override;
double getMaxSurfaceFeatureSize() const override;

const LevelSetObject * getReferenceObject( long ) const override;

std::vector<const LevelSetObject *> getSourceObjects() const override;

};

}

#endif
4 changes: 4 additions & 0 deletions src/levelset/levelSetObjectFactory.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

#include "levelSetBooleanObject.hpp"
#include "levelSetCartesianKernel.hpp"
#include "levelSetComplementObject.hpp"
#include "levelSetImmutableObject.hpp"
#include "levelSetMaskObject.hpp"
#include "levelSetOctreeKernel.hpp"
Expand All @@ -40,6 +41,9 @@ class LevelSetObjectFactory {
template<typename... Args>
static std::unique_ptr<LevelSetObject> createBooleanObject(const LevelSetKernel *kernel, LevelSetStorageType storageType, Args&&... args);

template<typename... Args>
static std::unique_ptr<LevelSetObject> createComplementObject(const LevelSetKernel *kernel, LevelSetStorageType storageType, Args&&... args);

template<template<typename> class narrow_band_cache_t>
static std::unique_ptr<LevelSetObject> createImmutableObject(const LevelSetKernel *kernel, LevelSetStorageType storageType, LevelSetObject *source);

Expand Down
16 changes: 16 additions & 0 deletions src/levelset/levelSetObjectFactory.tpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,22 @@ std::unique_ptr<LevelSetObject> LevelSetObjectFactory::createBooleanObject(const
return std::unique_ptr<LevelSetObject>(new LevelSetBooleanObject(std::forward<Args>(args)...));
}

/*!
* Create a new complement object for the specified kernel.
*
* \param kernel is the kernel
* \param storageType is the storage type
* \param args are the arguments that will be forwarded to the constructor
*/
template<typename... Args>
std::unique_ptr<LevelSetObject> LevelSetObjectFactory::createComplementObject(const LevelSetKernel *kernel, LevelSetStorageType storageType, Args&&... args)
{
BITPIT_UNUSED(kernel);
BITPIT_UNUSED(storageType);

return std::unique_ptr<LevelSetObject>(new LevelSetComplementObject(std::forward<Args>(args)...));
}

/*!
* Create a new immutable object for the specified kernel.
*
Expand Down
1 change: 1 addition & 0 deletions test/integration_tests/levelset/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ list(APPEND TESTS "test_levelset_00005")
list(APPEND TESTS "test_levelset_00006")
list(APPEND TESTS "test_levelset_00007")
list(APPEND TESTS "test_levelset_00008")
list(APPEND TESTS "test_levelset_00009")
if (BITPIT_ENABLE_MPI)
list(APPEND TESTS "test_levelset_parallel_00001:3")
list(APPEND TESTS "test_levelset_parallel_00002:3")
Expand Down
Loading

0 comments on commit aab4847

Please sign in to comment.