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

Add apf::smoothCAPAnisoSizes #455

Merged
merged 4 commits into from
Sep 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
31 changes: 24 additions & 7 deletions apf_cap/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ if(NOT ENABLE_CAPSTONE)
return()
endif()

include(CMakePushCheckState)
include(CheckIncludeFileCXX)
cmake_policy(SET CMP0075 NEW) # Observe CMAKE_REQUIRED_LIBRARIES.

#Sources & Headers
set(SOURCES apfCAP.cc)
set(HEADERS apfCAP.h)
Expand All @@ -16,14 +20,27 @@ add_library(apf_cap ${SOURCES})
target_link_libraries(apf_cap PUBLIC apf gmi_cap)
target_link_libraries(apf_cap PUBLIC capstone_module
framework_testing)
target_include_directories(apf_cap PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<INSTALL_INTERFACE:include>
)

#directory containing apf_simConfig.h
target_include_directories(apf_cap PRIVATE
$<BUILD_INTERFACE:${CMAKE_CURRENT_BINARY_DIR}>)
set(CMAKE_CXX_OLD_STANDARD "${CMAKE_CXX_STANDARD}")
cmake_push_check_state(RESET)
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_REQUIRED_LIBRARIES "framework_meshing")
check_include_file_cxx("CreateMG_SizingMetricTool.h" HAVE_CAPSTONE_SIZINGMETRICTOOL)
cmake_pop_check_state()
set(CMAKE_CXX_STANDARD "${CMAKE_CXX_OLD_STANDARD}")

if(HAVE_CAPSTONE_SIZINGMETRICTOOL)
target_compile_definitions(apf_cap PRIVATE HAVE_CAPSTONE_SIZINGMETRICTOOL)
target_link_libraries(apf_cap PRIVATE framework_meshing)
target_compile_features(apf_cap PRIVATE cxx_std_14)
endif()

include(GNUInstallDirs)

target_include_directories(apf_cap PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)

scorec_export_library(apf_cap)

Expand Down
78 changes: 78 additions & 0 deletions apf_cap/apfCAP.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,14 @@
#include <gmi.h>
#include <gmi_cap.h>
#include <cstdlib>
#include <mth.h>
#include <pcu_util.h>
#include <algorithm>
#include <lionPrint.h>

#ifdef HAVE_CAPSTONE_SIZINGMETRICTOOL
#include <CreateMG_SizingMetricTool.h>
#endif

namespace apf {

Expand Down Expand Up @@ -942,5 +947,78 @@ Mesh2* createMesh(MeshDatabaseInterface* mdb, GeometryDatabaseInterface* gdb)
return m;
}

bool has_smoothCAPAnisoSizes(void) noexcept {
#ifdef HAVE_CAPSTONE_SIZINGMETRICTOOL
return true;
#else
return false;
#endif
}

bool smoothCAPAnisoSizes(apf::Mesh2* mesh, std::string analysis,
apf::Field* scales, apf::Field* frames) {
#ifdef HAVE_CAPSTONE_SIZINGMETRICTOOL
apf::MeshCAP* m = dynamic_cast<apf::MeshCAP*>(mesh);
if (!m) {
lion_eprint(1, "ERROR: smoothCAPAnisoSizes: mesh is not an apf::MeshCAP*\n");
return false;
}
std::vector<Metric6> sizing6(m->count(0));
apf::Matrix3x3 Q;
apf::Vector3 H;
apf::MeshIterator* it = m->begin(0);
for (apf::MeshEntity* e = m->iterate(it); e; e = m->iterate(it)) {
apf::getVector(scales, e, 0, H);
apf::getMatrix(frames, e, 0, Q);
apf::Matrix3x3 L(H[0], 0, 0, 0, H[1], 0, 0, 0, H[2]);
apf::Matrix3x3 t = Q * L * apf::invert(Q);
size_t id;
MG_API_CALL(m->getMesh(), get_id(fromEntity(e), id));
PCU_DEBUG_ASSERT(id != 0);
--id;
sizing6[id][0] = t[0][0];
sizing6[id][1] = t[0][1];
sizing6[id][2] = t[0][2];
sizing6[id][3] = t[1][1];
sizing6[id][4] = t[1][2];
sizing6[id][5] = t[2][2];
}
m->end(it);
auto smooth_tool = get_sizing_metric_tool(m->getMesh()->get_context(),
"CreateSmoothingBase");
if (smooth_tool == nullptr) {
lion_eprint(1, "ERROR: Unable to find \"CreateSmoothingBase\"\n");
return false;
}
smooth_tool->set_context(m->getMesh()->get_context());
M_MModel mmodel;
MG_API_CALL(m->getMesh(), get_current_model(mmodel));
smooth_tool->set_metric(mmodel, "sizing6", sizing6);
std::vector<Metric6> ometric;
smooth_tool->smooth_metric(mmodel, analysis, "sizing6", ometric);
it = m->begin(0);
for (apf::MeshEntity* e = m->iterate(it); e; e = m->iterate(it)) {
size_t id;
MG_API_CALL(m->getMesh(), get_id(fromEntity(e), id));
PCU_DEBUG_ASSERT(id != 0);
--id;
const Metric6& m = ometric[id];
apf::Matrix3x3 t(m[0], m[1], m[2],
m[1], m[3], m[4],
m[2], m[4], m[5]);
PCU_DEBUG_ASSERT(apf::eigen(t, &Q[0], &H[0]) == 3);
apf::setMatrix(frames, e, 0, Q);
apf::setVector(scales, e, 0, H);
}
m->end(it);
return true;
#else
(void) mesh;
(void) analysis;
(void) scales;
(void) frames;
apf::fail("smoothCAPAnisoSizes: Capstone does not have SizingMetricTool.");
#endif
}

}//namespace apf
25 changes: 25 additions & 0 deletions apf_cap/apfCAP.h
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,31 @@ class MeshCAP : public Mesh2
std::vector<TagCAP*> tags;
};

/**
* \brief Test for smoothCAPAnisoSizes support.
*
* \return A boolean indicating whether support was compiled. False indicates
* the call would fail.
*
* \details smoothCAPAnisoSizes is only compiled if support for the underlying
* call is detected in the version of Capstone apf_cap was compiled
* against. Otherwise the call will always apf::fail. Use this
* function to programmatically test for the capability.
*/
bool has_smoothCAPAnisoSizes(void) noexcept;

/**
* \brief Use the SizingMetricTool to smooth a size field on a Capstone mesh.
*
* \param m A Capstone mesh.
* \param analysis The Capstone analysis to use.
* \param frames An apf::Field of apf::Matrix3x3 with orthogonal basis frames.
* \param scales An apf::Field of apf::Vector3 with frame scales (eigenvalues).
* \return A boolean indicating success.
* \pre m must be an apf::MeshCAP.
*/
bool smoothCAPAnisoSizes(apf::Mesh2* m, std::string analysis,
apf::Field* frames, apf::Field* scales);

}//namespace apf

Expand Down
3 changes: 3 additions & 0 deletions test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,9 @@ endif()
if(ENABLE_CAPSTONE)
util_exe_func(capVol capVol.cc)
target_include_directories(capVol PRIVATE "${PROJECT_SOURCE_DIR}/capstone_clis")
if(HAVE_CAPSTONE_SIZINGMETRICTOOL)
util_exe_func(cap_smooth cap_smooth.cc)
endif()
endif()

# send all the newly added utility executable targets
Expand Down
8 changes: 8 additions & 0 deletions test/cap_smooth.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#include <pcu_util.h>
#include <apfCAP.h>

int main (void) {
PCU_ALWAYS_ASSERT(apf::has_smoothCAPAnisoSizes());
// FIXME: Test apf::smoothCAPAnisoSizes.
return 0;
}
3 changes: 3 additions & 0 deletions test/testing.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -895,4 +895,7 @@ if(ENABLE_CAPSTONE)
mpi_test(capVolWing 1 ./capVol -vg 2 ${MESHES}/cap/wing_surf_only.cre)
mpi_test(capVolCube 1 ./capVol -vg 3 ${MESHES}/cap/cube_surf_only.cre)
mpi_test(capVolCyl2 1 ./capVol -vg 4 ${MESHES}/cap/cyl_surf_only.cre)
if(HAVE_CAPSTONE_SIZINGMETRICTOOL)
mpi_test(cap_smooth 1 ./cap_smooth)
endif()
endif()