Skip to content

Commit 76e6685

Browse files
authored
Merge pull request #128 from LLNL/redecomp-ghost-proximity
Add tests and fixes for `binning_proximity_scale`
2 parents c9a25fd + 72234e1 commit 76e6685

19 files changed

+880
-109
lines changed

cmake/TribolConfig.cmake

+6-1
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,18 @@ message(STATUS "Configuring Tribol version ${TRIBOL_VERSION_FULL}")
1616
convert_to_native_escaped_file_path(${PROJECT_SOURCE_DIR} TRIBOL_REPO_DIR)
1717
convert_to_native_escaped_file_path(${CMAKE_BINARY_DIR} TRIBOL_BIN_DIR)
1818

19-
# Generate and install config header
19+
# Generate and install config headers
2020
set(TRIBOL_DATA_DIR ${PROJECT_SOURCE_DIR}/data)
2121
tribol_configure_file(${PROJECT_SOURCE_DIR}/src/tribol/config.hpp.in
2222
${PROJECT_BINARY_DIR}/include/tribol/config.hpp)
2323

2424
install(FILES ${PROJECT_BINARY_DIR}/include/tribol/config.hpp DESTINATION include/tribol)
2525

26+
tribol_configure_file(${PROJECT_SOURCE_DIR}/src/shared/config.hpp.in
27+
${PROJECT_BINARY_DIR}/include/shared/config.hpp)
28+
29+
install(FILES ${PROJECT_BINARY_DIR}/include/shared/config.hpp DESTINATION include/shared)
30+
2631
# Set up some paths, preserve existing cache values (if present)
2732
set(TRIBOL_INSTALL_INCLUDE_DIR "include" CACHE STRING "")
2833
set(TRIBOL_INSTALL_CONFIG_DIR "lib" CACHE STRING "")

src/CMakeLists.txt

+5
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@
77
# Set up tribol target
88
#------------------------------------------------------------------------------
99

10+
#------------------------------------------------------------------------------
11+
# add shared
12+
#------------------------------------------------------------------------------
13+
add_subdirectory(shared)
14+
1015
#------------------------------------------------------------------------------
1116
# add redecomp
1217
#------------------------------------------------------------------------------

src/shared/CMakeLists.txt

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# Copyright (c) 2017-2025, Lawrence Livermore National Security, LLC and
2+
# other Tribol Project Developers. See the top-level LICENSE file for details.
3+
#
4+
# SPDX-License-Identifier: (MIT)
5+
6+
## list of headers
7+
set(shared_headers
8+
9+
mesh/MeshBuilder.hpp
10+
)
11+
12+
## list of sources
13+
set(shared_sources
14+
15+
mesh/MeshBuilder.cpp
16+
)
17+
18+
## setup the dependency list for tribol shared library
19+
set(shared_depends mfem)
20+
blt_list_append(TO tribol_depends ELEMENTS blt::mpi IF TRIBOL_USE_MPI )
21+
message(STATUS "Tribol shared library dependencies: ${shared_depends}")
22+
23+
## create the library
24+
blt_add_library(
25+
NAME tribol_shared
26+
SOURCES ${shared_sources}
27+
HEADERS ${shared_headers}
28+
DEPENDS_ON ${shared_depends} ${tribol_device_depends}
29+
FOLDER shared
30+
)
31+
32+
# Add separable compilation flag
33+
if(ENABLE_HIP)
34+
target_compile_options(tribol_shared PRIVATE -fgpu-rdc)
35+
target_compile_options(tribol_shared PRIVATE
36+
$<$<CONFIG:Debug>:
37+
-ggdb
38+
>
39+
)
40+
target_link_options(tribol_shared PRIVATE -fgpu-rdc)
41+
target_link_options(tribol_shared PRIVATE --hip-link)
42+
endif()
43+
44+
# Don't propagate internal dependencies
45+
target_link_libraries(tribol_shared PRIVATE axom::slic)
46+
47+
target_include_directories(tribol_shared PUBLIC
48+
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/src>
49+
$<BUILD_INTERFACE:${CMAKE_BINARY_DIR}/include>
50+
$<INSTALL_INTERFACE:include>
51+
)
52+
53+
## mirror the directory structure on the install
54+
foreach( shared_header ${shared_headers} )
55+
get_filename_component( shared_base_dir ${shared_header} DIRECTORY)
56+
install( FILES ${shared_header}
57+
DESTINATION "include/shared/${shared_base_dir}" )
58+
endforeach()
59+
60+
install(TARGETS tribol_shared
61+
EXPORT tribol-targets
62+
DESTINATION lib
63+
)
64+

src/shared/config.hpp.in

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Copyright (c) 2017-2025, Lawrence Livermore National Security, LLC and
2+
// other Tribol Project Developers. See the top-level LICENSE file for details.
3+
//
4+
// SPDX-License-Identifier: (MIT)
5+
6+
#ifndef SHARED_CONFIG_HPP_
7+
#define SHARED_CONFIG_HPP_
8+
9+
/*
10+
* Note: Use only C-style comments in this file
11+
* since it might be included from a C file
12+
*/
13+
14+
/*
15+
* Build information
16+
*/
17+
#cmakedefine TRIBOL_USE_MPI
18+
19+
#endif /* SHARED_CONFIG_HPP_ */

src/shared/mesh/MeshBuilder.cpp

+166
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
#include "MeshBuilder.hpp"
2+
3+
#include "axom/slic.hpp"
4+
#include "axom/primal.hpp"
5+
6+
namespace shared {
7+
8+
MeshBuilder MeshBuilder::Unify( std::initializer_list<MeshBuilder> meshes )
9+
{
10+
std::vector<mfem::Mesh*> mesh_list;
11+
mesh_list.reserve( meshes.size() );
12+
for ( auto& mesh : meshes ) {
13+
// NOTE: the const cast is because the constructor requires a non-const mesh, even though the data is copied and not
14+
// altered
15+
mesh_list.push_back( &const_cast<mfem::Mesh&>( *mesh ) );
16+
}
17+
return mfem::Mesh( mesh_list.data(), mesh_list.size() );
18+
}
19+
20+
MeshBuilder MeshBuilder::SquareMesh( int n_x_els, int n_y_els )
21+
{
22+
return mfem::Mesh::MakeCartesian2D( n_x_els, n_y_els, mfem::Element::QUADRILATERAL );
23+
}
24+
25+
MeshBuilder MeshBuilder::CubeMesh( int n_x_els, int n_y_els, int n_z_els )
26+
{
27+
return mfem::Mesh::MakeCartesian3D( n_x_els, n_y_els, n_z_els, mfem::Element::HEXAHEDRON );
28+
}
29+
30+
MeshBuilder MeshBuilder::HypercubeMesh( int dim, int n_els )
31+
{
32+
switch ( dim ) {
33+
case 1:
34+
return mfem::Mesh::MakeCartesian1D( n_els );
35+
case 2:
36+
return mfem::Mesh::MakeCartesian2D( n_els, n_els, mfem::Element::QUADRILATERAL );
37+
case 3:
38+
return mfem::Mesh::MakeCartesian3D( n_els, n_els, n_els, mfem::Element::HEXAHEDRON );
39+
default:
40+
SLIC_ERROR_ROOT( "Mesh dimension must be between 1 and 3." );
41+
return mfem::Mesh();
42+
}
43+
}
44+
45+
MeshBuilder::MeshBuilder( mfem::Mesh&& mesh ) : mesh_{ std::move( mesh ) } { mesh_.EnsureNodes(); }
46+
47+
MeshBuilder&& MeshBuilder::translate( std::initializer_list<double> dx )
48+
{
49+
SLIC_ERROR_ROOT_IF( static_cast<int>( dx.size() ) != mesh_.SpaceDimension(), "Invalid size for dx" );
50+
auto& coords = *mesh_.GetNodes();
51+
for ( int d = 0; d < mesh_.SpaceDimension(); ++d ) {
52+
for ( int i = 0; i < mesh_.GetNV(); ++i ) {
53+
auto vdof = coords.FESpace()->DofToVDof( i, d );
54+
coords[vdof] += *( dx.begin() + d );
55+
}
56+
}
57+
return std::move( *this );
58+
}
59+
60+
MeshBuilder&& MeshBuilder::updateAttrib( int old_attrib, int new_attrib )
61+
{
62+
for ( int i = 0; i < mesh_.GetNE(); ++i ) {
63+
if ( mesh_.GetAttribute( i ) == old_attrib ) {
64+
mesh_.SetAttribute( i, new_attrib );
65+
}
66+
}
67+
// add the new attribute to the mesh's list of attributes
68+
auto old_attrib_idx = mesh_.attributes.Find( old_attrib );
69+
if ( old_attrib_idx >= 0 ) {
70+
mesh_.attributes[old_attrib_idx] = new_attrib;
71+
}
72+
mesh_.attributes.Sort();
73+
mesh_.attributes.Unique();
74+
return std::move( *this );
75+
}
76+
77+
MeshBuilder&& MeshBuilder::bdrAttribInfo()
78+
{
79+
for ( int i{ 0 }; i < mesh_.bdr_attributes.Size(); ++i ) {
80+
auto current_attrib = mesh_.bdr_attributes[i];
81+
auto num_elems = 0;
82+
auto attrib_bbox = axom::primal::BoundingBox<double, 3>();
83+
for ( int j = 0; j < mesh_.GetNBE(); ++j ) {
84+
if ( mesh_.GetBdrAttribute( j ) == current_attrib ) {
85+
num_elems++;
86+
mfem::Array<int> bdr_dofs;
87+
mesh_.GetNodes()->FESpace()->GetBdrElementDofs( j, bdr_dofs );
88+
for ( int k{ 0 }; k < bdr_dofs.Size(); ++k ) {
89+
axom::primal::Point<double, 3> vert;
90+
for ( int d{ 0 }; d < mesh_.SpaceDimension(); ++d ) {
91+
auto vdof = mesh_.GetNodes()->FESpace()->DofToVDof( bdr_dofs[k], d );
92+
vert[d] = ( *mesh_.GetNodes() )[vdof];
93+
}
94+
attrib_bbox.addPoint( vert );
95+
}
96+
}
97+
}
98+
if ( num_elems > 0 ) {
99+
std::cout << "Boundary attribute " << current_attrib << std::endl;
100+
std::cout << " Number of elements: " << num_elems << std::endl;
101+
std::cout << " Min coordinate: " << attrib_bbox.getMin() << std::endl;
102+
std::cout << " Max coordinate: " << attrib_bbox.getMax() << std::endl;
103+
std::cout << " Coordinate range: " << attrib_bbox.range() << std::endl;
104+
}
105+
}
106+
return std::move( *this );
107+
}
108+
109+
MeshBuilder&& MeshBuilder::updateBdrAttrib( int old_attrib, int new_attrib )
110+
{
111+
for ( int i = 0; i < mesh_.GetNBE(); ++i ) {
112+
if ( mesh_.GetBdrAttribute( i ) == old_attrib ) {
113+
mesh_.SetBdrAttribute( i, new_attrib );
114+
}
115+
}
116+
// add the new boundary attribute to the mesh's list of boundary attributes
117+
auto old_attrib_idx = mesh_.bdr_attributes.Find( old_attrib );
118+
if ( old_attrib_idx >= 0 ) {
119+
mesh_.bdr_attributes[old_attrib_idx] = new_attrib;
120+
}
121+
mesh_.bdr_attributes.Sort();
122+
mesh_.bdr_attributes.Unique();
123+
return std::move( *this );
124+
}
125+
126+
MeshBuilder::operator mfem::Mesh*() { return &mesh_; }
127+
128+
MeshBuilder::operator const mfem::Mesh*() const { return &mesh_; }
129+
130+
MeshBuilder::operator mfem::Mesh&() { return mesh_; }
131+
132+
MeshBuilder::operator const mfem::Mesh&() const { return mesh_; }
133+
134+
ParMeshBuilder::ParMeshBuilder( MPI_Comm comm, MeshBuilder&& mesh ) : pmesh_{ comm, mesh } {}
135+
136+
ParMeshBuilder&& ParMeshBuilder::setNodesFEColl( mfem::H1_FECollection fe_coll )
137+
{
138+
mfem::FiniteElementCollection* fe_coll_ptr = fe_coll.Clone( fe_coll.GetOrder() );
139+
mfem::ParFiniteElementSpace* fe_space =
140+
new mfem::ParFiniteElementSpace( &pmesh_, fe_coll_ptr, pmesh_.SpaceDimension() );
141+
pmesh_.SetNodalFESpace( fe_space );
142+
pmesh_.GetNodes()->MakeOwner( fe_coll_ptr );
143+
return std::move( *this );
144+
}
145+
146+
mfem::ParGridFunction& ParMeshBuilder::getNodes()
147+
{
148+
// static_cast should be OK; MeshBuilder meshes always have Nodes so this won't be null and this should never be a
149+
// GridFunction
150+
return *static_cast<mfem::ParGridFunction*>( pmesh_.GetNodes() );
151+
}
152+
153+
const mfem::ParGridFunction& ParMeshBuilder::getNodes() const
154+
{
155+
// static_cast should be OK; MeshBuilder meshes always have Nodes so this won't be null and this should never be a
156+
// GridFunction
157+
return *static_cast<const mfem::ParGridFunction*>( pmesh_.GetNodes() );
158+
}
159+
160+
mfem::ParFiniteElementSpace& ParMeshBuilder::getNodesFESpace() { return *getNodes().ParFESpace(); }
161+
162+
const mfem::ParFiniteElementSpace& ParMeshBuilder::getNodesFESpace() const { return *getNodes().ParFESpace(); }
163+
164+
ParMeshBuilder::operator const mfem::ParMesh&() const { return pmesh_; }
165+
166+
} // namespace shared

0 commit comments

Comments
 (0)