Skip to content

Commit

Permalink
Merge pull request #455 from SCOREC/apw/cap_smooth
Browse files Browse the repository at this point in the history
Add apf::smoothCAPAnisoSizes
  • Loading branch information
cwsmith authored Sep 23, 2024
2 parents 7cd7647 + ecc2e72 commit 3e6ecac
Show file tree
Hide file tree
Showing 6 changed files with 141 additions and 7 deletions.
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()

0 comments on commit 3e6ecac

Please sign in to comment.