Skip to content

Commit 4da7a51

Browse files
committed
CG and PCG to heat geodesics
1 parent 8982873 commit 4da7a51

1 file changed

Lines changed: 68 additions & 18 deletions

File tree

apps/Heat/heat.cu

Lines changed: 68 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,14 @@
99
#include <limits>
1010

1111
#include "rxmesh/geometry_util.cuh"
12-
#include "rxmesh/matrix/cudss_cholesky_solver.h"
1312
#include "rxmesh/reduce_handle.h"
1413
#include "rxmesh/rxmesh_static.h"
1514
#include "rxmesh/util/timer.h"
1615

16+
#include "rxmesh/matrix/cg_solver.h"
17+
#include "rxmesh/matrix/cudss_cholesky_solver.h"
18+
#include "rxmesh/matrix/pcg_solver.h"
19+
1720
using namespace rxmesh;
1821

1922
int main(int argc, char** argv)
@@ -22,10 +25,13 @@ int main(int argc, char** argv)
2225

2326
CLI::App app{"Heat geodesics (Crane et al. 2017)"};
2427

25-
std::string mesh_path = STRINGIFY(INPUT_DIR) "sphere3.obj";
26-
uint32_t device_id = 0;
27-
uint32_t source_vid = 0;
28-
T t_factor = 1.0f;
28+
std::string mesh_path = STRINGIFY(INPUT_DIR) "sphere3.obj";
29+
uint32_t device_id = 0;
30+
uint32_t source_vid = 0;
31+
T t_factor = 1.0f;
32+
int cg_max_iter = 10000;
33+
std::string solver = "cudss";
34+
2935

3036
app.add_option("-i,--input", mesh_path, "Input OBJ mesh file")
3137
->default_val(mesh_path);
@@ -37,17 +43,37 @@ int main(int argc, char** argv)
3743
t_factor,
3844
"Heat time-step multiplier on h^2 (default 1)")
3945
->default_val(1.0f);
46+
app.add_option("-c,--cg_max_iter", cg_max_iter, "Max #iter for CG solver")
47+
->default_val(cg_max_iter);
48+
app.add_option("-l,--solver",
49+
solver,
50+
"Solver. Only cudss, cg, and pcg are supported")
51+
->default_val(solver);
4052

4153
try {
4254
app.parse(argc, argv);
4355
} catch (const CLI::ParseError& e) {
4456
return app.exit(e);
4557
}
46-
4758
rx_init(device_id);
4859

49-
RXMeshStatic rx(mesh_path);
60+
RXMESH_INFO("input = {}", mesh_path);
61+
RXMESH_INFO("device_id = {}", device_id);
62+
RXMESH_INFO("source_vid = {}", source_vid);
63+
RXMESH_INFO("solver = {}", solver);
64+
RXMESH_INFO("cg_max_iter = {}", cg_max_iter);
65+
66+
if (solver != "pcg" && solver != "cg" && solver != "cudss") {
67+
RXMESH_ERROR(
68+
"Unuspported solver option {}. Supported options are cudss, cg, "
69+
"and pcg",
70+
solver);
71+
return EXIT_FAILURE;
72+
}
5073

74+
75+
RXMeshStatic rx(mesh_path);
76+
5177
auto coords = *rx.get_input_vertex_coordinates();
5278

5379
const uint32_t num_vertices = rx.get_num_vertices();
@@ -164,10 +190,21 @@ int main(int argc, char** argv)
164190

165191

166192
// 4) solve A_heat*u = rhs
167-
cuDSSCholeskySolver<SparseMatrix<T>> heat_solver(&A_heat);
168-
heat_solver.pre_solve(rx, rhs, phi_or_u);
169-
heat_solver.solve(rhs, phi_or_u);
170-
193+
if (solver == "cudss") {
194+
cuDSSCholeskySolver<SparseMatrix<T>> heat_solver(&A_heat);
195+
heat_solver.pre_solve(rx, rhs, phi_or_u);
196+
heat_solver.solve(rhs, phi_or_u);
197+
}
198+
if (solver == "pcg") {
199+
PCGSolver<T> heat_solver(A_heat, 1, cg_max_iter);
200+
heat_solver.pre_solve(rhs, phi_or_u);
201+
heat_solver.solve(rhs, phi_or_u);
202+
}
203+
if (solver == "cg") {
204+
CGSolver<T> heat_solver(A_heat, 1, cg_max_iter);
205+
heat_solver.pre_solve(rhs, phi_or_u);
206+
heat_solver.solve(rhs, phi_or_u);
207+
}
171208

172209
// 5) Per-face X = -grad(u) / |grad(u)|.
173210
// For a triangle (p0, p1, p2) with face normal N:
@@ -250,26 +287,39 @@ int main(int argc, char** argv)
250287

251288

252289
// 7) Solve L phi = div(X)
253-
cuDSSCholeskySolver<SparseMatrix<T>> poisson_solver(&L);
254290
phi_or_u.reset(0, DEVICE);
255-
poisson_solver.pre_solve(rx, rhs, phi_or_u);
256-
poisson_solver.solve(rhs, phi_or_u);
291+
if (solver == "cudss") {
292+
cuDSSCholeskySolver<SparseMatrix<T>> poisson_solver(&L);
293+
poisson_solver.pre_solve(rx, rhs, phi_or_u);
294+
poisson_solver.solve(rhs, phi_or_u);
295+
}
296+
if (solver == "pcg") {
297+
PCGSolver<T> poisson_solver(L, 1, cg_max_iter);
298+
poisson_solver.pre_solve(rhs, phi_or_u);
299+
poisson_solver.solve(rhs, phi_or_u);
300+
}
301+
if (solver == "cg") {
302+
CGSolver<T> poisson_solver(L, 1, cg_max_iter);
303+
poisson_solver.pre_solve(rhs, phi_or_u);
304+
poisson_solver.solve(rhs, phi_or_u);
305+
}
257306

258307

259308
// Distance = phi - phi(source)
260309
rx.for_each_vertex(DEVICE, [=] __device__(const VertexHandle vh) mutable {
261310
dist(vh, 0) = phi_or_u(vh, 0) - phi_or_u(source_handle, 0);
262311
});
263-
dist.move(DEVICE, HOST);
312+
dist.move(DEVICE, HOST);
264313

265314
timer.stop();
266315

267316
RXMESH_INFO("Heat Geodesics took {} (ms)", timer.elapsed_millis());
268317
#if USE_POLYSCOPE
318+
auto ps_geo =
319+
rx.get_polyscope_mesh()->addVertexScalarQuantity("geodesic", dist);
320+
ps_geo->setEnabled(true);
269321

270-
rx.get_polyscope_mesh()
271-
->addVertexScalarQuantity("geodesic", dist)
272-
->setEnabled(true);
322+
ps_geo->setIsolinesEnabled(true);
273323
polyscope::show();
274324
#endif
275325

0 commit comments

Comments
 (0)