Skip to content

Commit 912a7dd

Browse files
committed
test: add cap native adapt test
- test/capNativeAdapt.cc: similar to simxAnisoAdapt, add utility to run native capstone adaptation for testing/timing purposes. - test/CMakeLists.txt: add capNativeAdapt. - apf_cap/apfCAP.h: add loadCapSizingFileMetrics to facilitate loading sizing/vmap files. - apf_cap/apfCAPsizing.cc (load_file): add error checking for file open failure. - (loadCapSizingFileMetrics): refactor file loading/remapping part of loadCapSizingFile into this function. doesn't require writing new code and allows me to keep the SFINAE load_file function limited to apfCAPsizing.cc Signed-off-by: Aiden Woodruff <[email protected]>
1 parent 32c246e commit 912a7dd

File tree

4 files changed

+156
-10
lines changed

4 files changed

+156
-10
lines changed

apf_cap/apfCAP.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,19 @@ bool loadCapSizing(
211211
const char* scales, const char* frames
212212
);
213213

214+
/**
215+
* \brief Load metrics from a sizing file and vmap file.
216+
*
217+
* \param m An apf Capstone mesh
218+
* \param sizingFile The name of the bulk sizing file
219+
* \param vmapFile The name of the vmap file
220+
* \param sizing6 A vector to fill with bulk sizing metrics
221+
*/
222+
void loadCapSizingFileMetrics(
223+
apf::Mesh2* m, const std::string& sizingFile, const std::string& vmapFile,
224+
std::vector<CreateMG::Metric6>& sizing6
225+
);
226+
214227
/**
215228
* \brief Load Capstone bulk sizing into apf::Fields from a sizing file.
216229
*

apf_cap/apfCAPsizing.cc

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#include "apfCAP.h"
22

3+
#include <exception>
34
#include <fstream>
5+
#include <stdexcept>
46

57
#include <apf.h>
68
#include <apfMesh2.h>
@@ -20,6 +22,9 @@ typename std::enable_if<std::is_trivially_copyable<T>::value, void>::type
2022
load_file(const std::string& fname, std::vector<T>& data) {
2123
try {
2224
std::ifstream file(fname, std::ios::in | std::ios::binary);
25+
if (!file.is_open()) {
26+
throw std::runtime_error("failed to open file `" + fname + "`");
27+
}
2328
T val;
2429
while (file) {
2530
file.read(reinterpret_cast<char*>(std::addressof(val)), sizeof(T));
@@ -96,17 +101,10 @@ bool loadCapSizing(
96101
return loadCapSizing(m, sizing, scalesField, framesField);
97102
}
98103

99-
bool loadCapSizingFile(
104+
void loadCapSizingFileMetrics(
100105
apf::Mesh2* m, const std::string& sizingFile, const std::string& vmapFile,
101-
apf::Field* scales, apf::Field* frames,
102-
bool smooth, const std::string& analysis
106+
std::vector<CreateMG::Metric6>& sizing6
103107
) {
104-
if (smooth && !has_smoothCapAnisoSizes()) {
105-
lion_eprint(1,
106-
"WARNING: loadCapSizingFile: smoothing requested but apf_cap was"
107-
" compiled without support for smoothing\n");
108-
return false;
109-
}
110108
std::vector<size_t> vmap;
111109
std::vector<double> sizing;
112110
load_file(vmapFile, vmap);
@@ -125,14 +123,29 @@ bool loadCapSizingFile(
125123
fail("loadCapSizingFile: loaded invalid vmap");
126124
}
127125
// Copy sizefield to Metric6
128-
std::vector<CreateMG::Metric6> sizing6(vmap[0]);
126+
sizing6.resize(vmap[0]);
129127
for (size_t si = 0, vi = 1; vi < vmap.size(); ++vi) {
130128
size_t tid = vmap[vi];
131129
PCU_DEBUG_ASSERT(tid != 0);
132130
for (size_t j = 0; j < 6; ++j, ++si) {
133131
sizing6[tid - 1][j] = sizing[si];
134132
}
135133
}
134+
}
135+
136+
bool loadCapSizingFile(
137+
apf::Mesh2* m, const std::string& sizingFile, const std::string& vmapFile,
138+
apf::Field* scales, apf::Field* frames,
139+
bool smooth, const std::string& analysis
140+
) {
141+
if (smooth && !has_smoothCapAnisoSizes()) {
142+
lion_eprint(1,
143+
"WARNING: loadCapSizingFile: smoothing requested but apf_cap was"
144+
" compiled without support for smoothing\n");
145+
return false;
146+
}
147+
std::vector<CreateMG::Metric6> sizing6;
148+
loadCapSizingFileMetrics(m, sizingFile, vmapFile, sizing6);
136149
if (smooth) {
137150
std::vector<CreateMG::Metric6> ometric;
138151
if (!doSmoothing(m, analysis, sizing6, ometric)) return false;

test/CMakeLists.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,12 @@ if(PUMI_ENABLE_CAPSTONE)
229229
util_exe_func(capAdapt capAdapt.cc)
230230
util_exe_func(capProbe capProbe.cc)
231231
util_exe_func(capLoadSome capLoadSome.cc)
232+
if(PUMI_HAS_CAPSTONE_SIZINGMETRICTOOL)
233+
util_exe_func(capNativeAdapt capNativeAdapt.cc)
234+
target_link_libraries(capNativeAdapt
235+
framework_application framework_mesh framework_meshing
236+
)
237+
endif()
232238
endif()
233239

234240
# send all the newly added utility executable targets

test/capNativeAdapt.cc

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
#include <exception>
2+
#include <string>
3+
#include <vector>
4+
5+
#include <PCU.h>
6+
#include <apf.h>
7+
#include <apfCAP.h>
8+
#include <apfMesh2.h>
9+
#include <lionPrint.h>
10+
#include <gmi_cap.h>
11+
#include <pcu_util.h>
12+
13+
#include <CreateMG_AppProcessor.h>
14+
#include <CreateMG_Framework_Mesh.h>
15+
#include <CreateMG_Function.h>
16+
#include <CreateMG_SizingMetricTool.h>
17+
18+
namespace {
19+
20+
/** \brief Print nested exceptions. */
21+
void print_exception(const std::exception& e, int level = 0);
22+
23+
} // namespace
24+
25+
int main(int argc, char* argv[]) {
26+
lion_set_verbosity(1);
27+
pcu::Init(&argc, &argv);
28+
try {
29+
pcu::PCU PCU;
30+
if (argc < 4) {
31+
std::cerr << "USAGE: " << argv[0] << " <in.cre> <out.cre> <sizing.dat>"
32+
" <in.vmap>" << std::endl;
33+
throw 1;
34+
}
35+
36+
const char *creFile = argv[1], *outFile = argv[2], *sizingFile = argv[3],
37+
*vmapFile = argv[4];
38+
39+
gmi_cap_start();
40+
gmi_register_cap();
41+
try {
42+
gmi_model* model = gmi_cap_load(creFile);
43+
apf::Mesh2* mesh = apf::createCapMesh(model, &PCU);
44+
try {
45+
auto mdbi = apf::exportCapNative(mesh);
46+
auto ctx = mdbi->get_context();
47+
auto proc = CreateMG::get_context_processor(ctx);
48+
auto fn = CreateMG::get_function(ctx, "AdaptMesh");
49+
CreateMG::M_MModel mmodel;
50+
MG_API_CALL(mdbi, get_current_model(mmodel));
51+
CreateMG::set_input(fn, "MeshModel", mmodel);
52+
// CreateMG::set_input(fn, "Analysis", mmodel);
53+
auto sTool = CreateMG::get_sizing_metric_tool(
54+
ctx, "CreateSmoothingBase"
55+
);
56+
PCU_ALWAYS_ASSERT(sTool);
57+
sTool->set_context(ctx);
58+
std::vector<CreateMG::Metric6> sizing6;
59+
apf::loadCapSizingFileMetrics(mesh, sizingFile, vmapFile, sizing6);
60+
sTool->set_metric(mmodel, "sizing6", sizing6);
61+
CreateMG::set_input(fn, "TensorData", "sizing6");
62+
// DiscreteCurvature, Complexity, MaxComplexity
63+
auto t0 = pcu::Time();
64+
if (proc->execute(fn) != CreateMG::STATUS_OK) {
65+
std::cerr << "ERROR: failed to adapt mesh" << std::endl;
66+
throw 1;
67+
}
68+
auto t1 = pcu::Time();
69+
std::cout << "Capstone AdaptMesh ran in " << t1 - t0 << std::endl;
70+
CreateMG::get_output(fn, "Output", mmodel);
71+
std::string oname;
72+
MG_API_CALL(mdbi, get_model_name(mmodel, oname));
73+
apf::Mesh2* omesh = apf::createCapMesh(model, oname.c_str(), &PCU);
74+
apf::disownCapModel(omesh);
75+
apf::writeVtkFiles((std::string(outFile) + ".vtk").c_str(), omesh);
76+
gmi_cap_write(model, outFile);
77+
apf::destroyMesh(omesh);
78+
} catch (...) {
79+
apf::destroyMesh(mesh);
80+
std::rethrow_exception(std::current_exception());
81+
}
82+
apf::destroyMesh(mesh);
83+
} catch (const std::exception& e) {
84+
if (PCU.Self() == 0) {
85+
std::cerr << "ERROR: ";
86+
print_exception(e);
87+
}
88+
gmi_cap_stop();
89+
throw 1;
90+
} catch (...) {
91+
gmi_cap_stop();
92+
throw 1;
93+
}
94+
gmi_cap_stop();
95+
} catch (...) {
96+
pcu::Finalize();
97+
return 1;
98+
}
99+
pcu::Finalize();
100+
return 0;
101+
}
102+
103+
namespace {
104+
105+
void print_exception(const std::exception& e, int level) {
106+
std::cerr << std::string(level * 2, ' ') << e.what() << '\n';
107+
try {
108+
std::rethrow_if_nested(e);
109+
} catch (const std::exception& nestedE) {
110+
print_exception(nestedE, level + 1);
111+
} catch (...) {}
112+
}
113+
114+
} // namespace

0 commit comments

Comments
 (0)