Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Construct shapes in memory and support more shapes #1436

Merged
merged 58 commits into from
Jan 14, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
04c3971
Add const to input arguments to assure they are not changed.
gunney1 Jul 19, 2024
7bd74e5
Preliminary ability to generate shape in memory.
gunney1 Jul 31, 2024
88e8222
Add 2 more checks and exit with number of failures found.
gunney1 Jul 31, 2024
126934b
Fix bug that fails to apply GeometryOperators that are not composites.
gunney1 Aug 1, 2024
03b3f07
Add optional scaling to test the use of geometry operator.
gunney1 Aug 1, 2024
2cbfb3c
Add analytical sphere test and factor out code to generate discrete s…
gunney1 Aug 6, 2024
758b7ab
Remove obsolete code from Shaper.
gunney1 Aug 7, 2024
711b29a
Some name changes to fit accepted terminology.
gunney1 Aug 8, 2024
63358e9
Add SOR, cylinder and cone to in-memory shaping.
gunney1 Aug 8, 2024
cf58388
Small changes to comments.
gunney1 Aug 9, 2024
e3e8974
Implement arbitrary locations for VOR (not always on x-axis).
gunney1 Aug 10, 2024
381a75a
Add hexahedron shaping (in-memory only for now, not through klee).
gunney1 Aug 11, 2024
931d1ba
Set DiscreteShape default behavior for adaptive refinement of SOR.
gunney1 Aug 13, 2024
4bee170
Fix mesh pointers that get passed into classes then deleted.
gunney1 Aug 13, 2024
b409d47
Get in-memory shaping working on rzansel host execution.
gunney1 Aug 13, 2024
e5ac6bd
Enable multi-policy testing for in-memory shaping.
gunney1 Aug 14, 2024
df21a07
Merge remote-tracking branch 'gh/develop' into feature/gunney/constru…
gunney1 Aug 20, 2024
6815047
Support single tet shape in in-memory shaping.
gunney1 Aug 30, 2024
ae8bfb2
Support plane shape.
gunney1 Sep 1, 2024
d51a85f
Merge remote-tracking branch 'gh/develop' into feature/gunney/constru…
gunney1 Sep 30, 2024
382313e
Make some groups and views const where they are not modified.
gunney1 Oct 2, 2024
d73df72
More robust way to get temporary unique Group name.
gunney1 Oct 2, 2024
933e4e3
Change parameter ordering.
gunney1 Oct 2, 2024
42bf676
Rename memory-blueprint format to blueprint-tet and add checks
gunney1 Oct 2, 2024
6585fa2
Factor out code to shorten a method for readability.
gunney1 Oct 2, 2024
408b427
Reformat.
gunney1 Oct 2, 2024
39232fd
Check for valid sidre Group in cases where it's required.
gunney1 Oct 2, 2024
7507658
Temporary work-around for data re-allocation crash in docker tests.
gunney1 Oct 6, 2024
d9a7fc3
Autoformat and change parameter comment.
gunney1 Oct 6, 2024
8d6db24
Temporarily disable a sanity check that causes weird crash in
gunney1 Oct 9, 2024
848a449
Fix error in non-Umpire build.
gunney1 Oct 9, 2024
5c76ae5
In-memory shaping example requires RAJA, so disable if no raja.
gunney1 Oct 9, 2024
ec440d6
Merge remote-tracking branch 'gh/develop' into feature/gunney/constru…
gunney1 Oct 10, 2024
8b38891
Fix non-umpire build.
gunney1 Oct 11, 2024
c17f102
Undo the work-around for the (now fixed) Umpire reallocate crash.
gunney1 Oct 11, 2024
6bc441d
Comment changes from code review.
gunney1 Oct 11, 2024
4b8d9f3
Remove support for reading in MFEM mesh in the new test.
gunney1 Oct 14, 2024
8f12aa9
Remove unused code (for sampling shaping) in the new test.
gunney1 Oct 14, 2024
4b99328
Re-enable blueprint check on input mesh.
gunney1 Oct 14, 2024
9af7adf
Minor changes from code review comments.
gunney1 Oct 21, 2024
370ba11
Merge remote-tracking branch 'gh/develop' into feature/gunney/constru…
gunney1 Nov 5, 2024
d290616
Merge remote-tracking branch 'gh/develop' into feature/gunney/constru…
gunney1 Nov 6, 2024
fa54103
Remove redundant line left in by merge.
gunney1 Nov 6, 2024
ac42dc5
Add test option "all" to test multiple shapes and let more shape resp…
gunney1 Nov 25, 2024
72e8769
Remove need to enter explicit mesh dimension.
gunney1 Nov 26, 2024
7cb17c6
Add TODO note about problems with using huge tets to represent plane.
gunney1 Nov 26, 2024
6a497aa
Autoformat.
gunney1 Nov 26, 2024
1b87370
Tweak shapes to make them about the same size.
gunney1 Nov 26, 2024
a2e185c
Change fake material name to match shape name.
gunney1 Dec 30, 2024
b3db9b4
Merge remote-tracking branch 'gh/develop' into feature/gunney/constru…
gunney1 Dec 30, 2024
fbb5a9e
Remove verifying user mesh is a blueprint tet mesh.
gunney1 Jan 3, 2025
9ec6b08
Autoformat.
gunney1 Jan 3, 2025
582a459
Merge remote-tracking branch 'gh/develop' into feature/gunney/constru…
gunney1 Jan 3, 2025
eb1cf6f
Update RELEASE-NOTES.
gunney1 Jan 8, 2025
eb226ee
Merge remote-tracking branch 'gh/develop' into feature/gunney/constru…
gunney1 Jan 8, 2025
69b57cc
Changes from code review.
gunney1 Jan 13, 2025
563358c
More changes from code review.
gunney1 Jan 14, 2025
8dbe147
Merge remote-tracking branch 'gh/develop' into feature/gunney/constru…
gunney1 Jan 14, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add SOR, cylinder and cone to in-memory shaping.
  • Loading branch information
gunney1 committed Aug 8, 2024
commit 63358e9505c1a5a2c40ece10ec093df0f975a6b3
22 changes: 21 additions & 1 deletion src/axom/klee/Geometry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -45,16 +45,36 @@ Geometry::Geometry(const TransformableGeometryProperties &startProperties,
}

Geometry::Geometry(const TransformableGeometryProperties &startProperties,
const axom::primal::Sphere<double, 3>& sphere,
const Sphere3D& sphere,
axom::IndexType levelOfRefinement,
std::shared_ptr<GeometryOperator const> operator_)
: m_startProperties(startProperties)
, m_format("sphere3D")
, m_path()
, m_meshGroup(nullptr)
, m_topology()
, m_levelOfRefinement(levelOfRefinement)
, m_sphere(sphere)
, m_operator(std::move(operator_))
{
}

Geometry::Geometry(const TransformableGeometryProperties &startProperties,
const axom::Array<double, 2>& discreteFunction,
const Point3D& vorBase,
const Vector3D& vorDirection,
axom::IndexType levelOfRefinement,
std::shared_ptr<GeometryOperator const> operator_)
: m_startProperties(startProperties)
, m_format("vor3D")
, m_path()
, m_meshGroup(nullptr)
, m_topology()
, m_levelOfRefinement(levelOfRefinement)
, m_sphere()
, m_discreteFunction(discreteFunction)
, m_vorBase(vorBase)
, m_vorDirection(vorDirection)
, m_operator(std::move(operator_))
{
}
Expand Down
72 changes: 53 additions & 19 deletions src/axom/klee/Geometry.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,12 @@ inline bool operator!=(const TransformableGeometryProperties &lhs,
class Geometry
{
public:
using Point3D = axom::primal::Point<double, 3>;
using Vector3D = axom::primal::Vector<double, 3>;
using Sphere3D = axom::primal::Sphere<double, 3>;

/**
* Create a new Geometry object based on a file representation.
* Create a Geometry object based on a file representation.
*
* \param startProperties the transformable properties before any
* operators are applied
Expand All @@ -71,7 +75,7 @@ class Geometry
std::shared_ptr<GeometryOperator const> operator_);

/**
* Create a new Geometry object based on a blueprint tetrahedral mesh.
* Create a Geometry object based on a blueprint tetrahedral mesh.
*
* \param startProperties the transformable properties before any
* operators are applied
Expand All @@ -88,7 +92,7 @@ class Geometry
std::shared_ptr<GeometryOperator const> operator_);

/**
* Create a new sphere Geometry object.
* Create a sphere Geometry object.
*
* \param startProperties the transformable properties before any
* operators are applied
Expand All @@ -104,16 +108,42 @@ class Geometry
axom::IndexType levelOfRefinement,
std::shared_ptr<GeometryOperator const> operator_);

/**
* Create a volume-of-revolution (VOR) Geometry object.
*
* \param startProperties the transformable properties before any
* operators are applied
* \param discreteFunction Discrete function describing the surface
* of revolution.
* \param vorBase Coordinates of the base of the VOR.
* \param vorDirection VOR axis, in the direction of increasing z.
* \param levelOfRefinement Number of refinement levels to use for
* discretizing the sphere.
* \param operator_ a possibly null operator to apply to the geometry.
*
* The \c discreteFunction should be an Nx2 array, interpreted as
* (z,r) pairs, where z is the axial distance and r is the radius.
* The \c vorBase coordinates corresponds to z=0.
* \c vorAxis should point in the direction of increasing z.
*
* \internal TODO: Is this the simplex requirement overly restrictive?
gunney1 marked this conversation as resolved.
Show resolved Hide resolved
*/
Geometry(const TransformableGeometryProperties &startProperties,
const axom::Array<double, 2>& discreteFunction,
const Point3D& vorBase,
const Vector3D& vorDirection,
axom::IndexType levelOfRefinement,
std::shared_ptr<GeometryOperator const> operator_);

/**
* Get the format in which the geometry is specified.
*
* Values are:
* - "c2c" = C2C file
* - "proe" = ProE file
* - "memory-blueprint" = Blueprint tetrahedral mesh in memory
* - "memory-xy" = discretized 2D, non-negative function as an
* array of points in memory
* - "sphere3D" = 3D sphere, as \c primal::Sphere<double,3>
* - "vor3D" = 3D volume of revolution.
* - "cone3D" = 3D cone, as \c primal::Cone<double,3>
* "cylinder3D" = 3D cylinder, as \c primal::Cylinder<double,3>
*
Expand Down Expand Up @@ -202,6 +232,14 @@ class Geometry
return m_sphere;
}

/**
@brief Get the discrete function.
*/
axom::ArrayView<const double, 2> getDiscreteFunction() const
{
return m_discreteFunction.view();
}

private:
TransformableGeometryProperties m_startProperties;

Expand All @@ -217,24 +255,20 @@ class Geometry
//!@brief Topology of the blueprint simplex mesh, if it's in memory.
std::string m_topology;

//!@brief The analytical sphere, if used.
axom::primal::Sphere<double, 3> m_sphere;

#if 0
//!@brief The analytical cylinder, if used.
axom::primal::Sphere<double, 3> m_cylinder;

//!@brief The analytical cone, if used.
axom::primal::Sphere<double, 3> m_cone;

//!@brief The discrete 2D curve, if used.
axom::Array<primal::Point<double, 2> m_discreteFunction;
#endif

//!@brief Level of refinement for discretizing analytical shapes
// and surfaces of revolutions.
axom::IndexType m_levelOfRefinement = 0;

//!@brief The analytical sphere, if used.
Sphere3D m_sphere;

/*!
@brief The discrete 2D function, as an Nx2 array, if used.
*/
axom::Array<double, 2> m_discreteFunction;
Point3D m_vorBase;
Vector3D m_vorDirection;

std::shared_ptr<const GeometryOperator> m_operator;
};

Expand Down
64 changes: 59 additions & 5 deletions src/axom/quest/DiscreteShape.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,12 +103,13 @@ std::shared_ptr<mint::Mesh> DiscreteShape::createMeshRepresentation()
{
if (m_meshRep) { return m_meshRep; }

using TetMesh = axom::mint::UnstructuredMesh<axom::mint::Topology::SINGLE_SHAPE>;

const axom::klee::Geometry& geometry = m_shape.getGeometry();
const auto& geometryFormat = geometry.getFormat();

if (geometryFormat == "memory-blueprint")
{
// TODO: For readability, move most of this into a function.
// Put the in-memory geometry in m_meshRep.
axom::sidre::Group* inputGroup = geometry.getBlueprintMesh();
axom::sidre::Group* rootGroup = inputGroup->getDataStore()->getRoot();
Expand Down Expand Up @@ -171,11 +172,10 @@ std::shared_ptr<mint::Mesh> DiscreteShape::createMeshRepresentation()
}
});

// TODO: Set this up with sidre::Group to have data on device.
axom::mint::UnstructuredMesh<axom::mint::Topology::SINGLE_SHAPE>* tetMesh = nullptr;
TetMesh* tetMesh = nullptr;
if (m_sidreGroup != nullptr)
{
tetMesh = new axom::mint::UnstructuredMesh<axom::mint::Topology::SINGLE_SHAPE>(
tetMesh = new TetMesh(
3,
axom::mint::CellType::TET,
m_sidreGroup,
Expand All @@ -184,7 +184,7 @@ std::shared_ptr<mint::Mesh> DiscreteShape::createMeshRepresentation()
}
else
{
tetMesh = new axom::mint::UnstructuredMesh<axom::mint::Topology::SINGLE_SHAPE>(
tetMesh = new TetMesh(
3,
axom::mint::CellType::TET,
nodeCount,
Expand All @@ -196,6 +196,60 @@ std::shared_ptr<mint::Mesh> DiscreteShape::createMeshRepresentation()

applyTransforms();
}
if (geometryFormat == "vor3D")
{
// Construct the tet m_meshRep from the volume-of-revolution.
auto& vorGeom = m_shape.getGeometry();
const auto& discreteFcn = vorGeom.getDiscreteFunction();

// Generate the Octahedra
axom::Array<OctType> octs;
int octCount = 0;
axom::ArrayView<Point2D> polyline((Point2D*)discreteFcn.data(),
discreteFcn.shape()[0]);
const bool good = axom::quest::discretize<axom::SEQ_EXEC>(
polyline,
int(polyline.size()),
m_shape.getGeometry().getLevelOfRefinement(),
octs,
octCount);
SLIC_ASSERT(good);

// Dump discretized octs as a tet mesh
axom::mint::Mesh* mesh;
axom::quest::mesh_from_discretized_polyline(
octs.view(),
octCount,
polyline.size() - 1,
mesh);

if (m_sidreGroup)
{
auto* tetMesh = static_cast<TetMesh*>(mesh);
// Don't directly use tetMesh, because we want the data in Sidre.
axom::mint::UnstructuredMesh<axom::mint::SINGLE_SHAPE>*
siMesh = new axom::mint::UnstructuredMesh<axom::mint::SINGLE_SHAPE>(
tetMesh->getDimension(),
tetMesh->getCellType(),
m_sidreGroup,
tetMesh->getTopologyName(),
tetMesh->getCoordsetName(),
tetMesh->getNumberOfNodes(),
tetMesh->getNumberOfCells());
siMesh->appendNodes( tetMesh->getCoordinateArray(0)
, tetMesh->getCoordinateArray(1)
, tetMesh->getCoordinateArray(2)
, tetMesh->getNumberOfNodes() );
siMesh->appendCells( tetMesh->getCellNodesArray()
, tetMesh->getNumberOfCells() );
m_meshRep.reset(siMesh);
} else {
m_meshRep.reset(mesh);
}

// Transform the coordinates of the linearized mesh.
applyTransforms();
}

if (m_meshRep)
{
Expand Down
2 changes: 1 addition & 1 deletion src/axom/quest/Discretize.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ bool discretize(const SphereType& s,
* This routine initializes an Array, \a out.
*/
template <typename ExecSpace>
bool discretize(const axom::Array<Point2D>& polyline,
bool discretize(const axom::ArrayView<Point2D>& polyline,
int len,
int levels,
axom::Array<OctType>& out,
Expand Down
23 changes: 13 additions & 10 deletions src/axom/quest/IntersectionShaper.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,7 @@ class IntersectionShaper : public Shaper
using Point3D = primal::Point<double, 3>;
using TetrahedronType = primal::Tetrahedron<double, 3>;
using SegmentMesh = mint::UnstructuredMesh<mint::SINGLE_SHAPE>;
using TetMesh = mint::UnstructuredMesh<mint::SINGLE_SHAPE>;

using RuntimePolicy = axom::runtime_policy::Policy;

Expand Down Expand Up @@ -610,21 +611,15 @@ class IntersectionShaper : public Shaper

std::string shapeFormat = shape.getGeometry().getFormat();

// C2C mesh is not discretized into tets, but all others are.
if(shapeFormat == "c2c")
{
prepareC2CCells<ExecSpace>();
}

else if(shapeFormat == "proe")
{
prepareTetCells<ExecSpace>();
}

else if(shapeFormat == "memory-blueprint" || shapeFormat == "sphere3D")
else if(surfaceMeshIsTet())
{
prepareTetCells<ExecSpace>();
}

else
{
SLIC_ERROR(
Expand Down Expand Up @@ -1492,8 +1487,8 @@ class IntersectionShaper : public Shaper
AXOM_ANNOTATE_SCOPE("runShapeQuery");
const std::string shapeFormat = shape.getGeometry().getFormat();

// Testing separate workflow for Pro/E
if(shapeFormat == "proe" || shapeFormat == "memory-blueprint" || shapeFormat == "sphere3D")
// C2C mesh is not discretized into tets, but all others are.
if(surfaceMeshIsTet())
{
switch(m_execPolicy)
{
Expand Down Expand Up @@ -2029,6 +2024,14 @@ class IntersectionShaper : public Shaper
return volFrac;
}

bool surfaceMeshIsTet() const {
bool isTet = m_surfaceMesh != nullptr &&
m_surfaceMesh->getDimension() == 3 &&
!m_surfaceMesh->hasMixedCellTypes() &&
m_surfaceMesh->getCellType() == mint::TET;
return isTet;
}

private:
RuntimePolicy m_execPolicy {RuntimePolicy::seq};
int m_level {DEFAULT_CIRCLE_REFINEMENT_LEVEL};
Expand Down
2 changes: 1 addition & 1 deletion src/axom/quest/Shaper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ bool Shaper::isValidFormat(const std::string& format) const
{
return (format == "stl" || format == "proe" || format == "c2c" ||
format == "memory-blueprint" || format == "sphere3D" ||
format == "none");
format == "vor3D" || format == "none");
}

void Shaper::loadShape(const klee::Shape& shape)
Expand Down
2 changes: 1 addition & 1 deletion src/axom/quest/detail/Discretize_detail.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,7 @@ namespace quest
* This routine initializes an Array pointed to by \a out.
*/
template <typename ExecSpace>
bool discretize(const axom::Array<Point2D> &polyline,
bool discretize(const axom::ArrayView<Point2D> &polyline,
int pointcount,
int levels,
axom::Array<OctType> &out,
Expand Down
5 changes: 3 additions & 2 deletions src/axom/quest/examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -252,15 +252,16 @@ if(AXOM_ENABLE_MPI AND MFEM_FOUND AND MFEM_USE_MPI
if(AXOM_ENABLE_TESTS AND AXOM_DATA_DIR)
# 3D shaping tests. No 2D shaping in this feature, at least for now.
set(_nranks 1)
set(_testshapes "tet" "sphere")
set(_testshapes "tetmesh" "sphere" "cyl" "cone" "vor")
foreach(_testshape ${_testshapes})
set(_testname "quest_shape_in_memory_${_testshape}")
axom_add_test(
NAME ${_testname}
COMMAND quest_shape_in_memory_ex
--testShape ${_testshape}
--method intersection --refinements 2
--scale 0.75 0.75 0.75
inline_mesh --min -1 -1 -1 --max 5 5 5 --res 20 20 20 -d 3
inline_mesh --min -2 -2 -2 --max 4 4 4 --res 20 20 20 -d 3
NUM_MPI_TASKS ${_nranks})
endforeach()
endif()
Expand Down
Loading