1+ #include " geometrycentral/surface/embedded_geometry_interface.h"
2+ #include " geometrycentral/surface/meshio.h"
3+ #include " geometrycentral/surface/vertex_position_geometry.h"
4+
5+ #include " load_test_meshes.h"
6+
7+ #include " gtest/gtest.h"
8+
9+ #include < iostream>
10+ #include < string>
11+
12+ using namespace geometrycentral ;
13+ using namespace geometrycentral ::surface;
14+
15+ class PolygonMeshSuite : public MeshAssetSuite {};
16+
17+ /* Test that the lumped mass matrices correspond with their unlumped versions. */
18+ TEST_F (PolygonMeshSuite, MassLumpingTest) {
19+
20+ double epsilon = 1e-8 ;
21+ for (MeshAsset& a : allMeshes ()) {
22+ a.printThyName ();
23+ SurfaceMesh& mesh = *a.mesh ;
24+ VertexPositionGeometry& geometry = *a.geometry ;
25+
26+ geometry.requireSimplePolygonVertexLumpedMassMatrix ();
27+ geometry.requireSimplePolygonVertexGalerkinMassMatrix ();
28+
29+ SparseMatrix<double > Mt = geometry.simplePolygonVertexGalerkinMassMatrix .transpose ();
30+ SparseMatrix<double >& M = geometry.simplePolygonVertexLumpedMassMatrix ;
31+ for (size_t i = 0 ; i < mesh.nVertices (); i++) {
32+ double rowSum = 0 .;
33+ for (SparseMatrix<double >::InnerIterator it (Mt, i); it; ++it) {
34+ rowSum += it.value ();
35+ }
36+ EXPECT_LT (std::abs (rowSum - M.coeffRef (i, i)), epsilon);
37+ }
38+
39+ geometry.unrequireSimplePolygonVertexLumpedMassMatrix ();
40+ geometry.unrequireSimplePolygonVertexGalerkinMassMatrix ();
41+ }
42+ }
43+
44+ /* Check that polygon Laplacians and mass matrices coincide with simplicial versions on a triangle mesh. */
45+ TEST_F (PolygonMeshSuite, TriangularTest) {
46+
47+ double epsilon = 1e-8 ;
48+ for (MeshAsset& a : triangularMeshes ()) {
49+ a.printThyName ();
50+ SurfaceMesh& mesh = *a.mesh ;
51+ VertexPositionGeometry& geometry = *a.geometry ;
52+
53+ geometry.requireVertexGalerkinMassMatrix ();
54+ geometry.requireVertexLumpedMassMatrix ();
55+ geometry.requireCotanLaplacian ();
56+ geometry.requireSimplePolygonLaplacian ();
57+ geometry.requireSimplePolygonVertexLumpedMassMatrix ();
58+ geometry.requireSimplePolygonVertexGalerkinMassMatrix ();
59+ geometry.requirePolygonLaplacian ();
60+ geometry.requirePolygonVertexLumpedMassMatrix ();
61+
62+ double L = geometry.cotanLaplacian .norm ();
63+ double Mg = geometry.vertexGalerkinMassMatrix .norm ();
64+ double Ml = geometry.vertexLumpedMassMatrix .norm ();
65+
66+ EXPECT_LT ((geometry.simplePolygonLaplacian - geometry.cotanLaplacian ).norm () / L, epsilon);
67+ EXPECT_LT ((geometry.polygonLaplacian - geometry.cotanLaplacian ).norm () / L, epsilon);
68+ EXPECT_LT ((geometry.simplePolygonVertexGalerkinMassMatrix - geometry.vertexGalerkinMassMatrix ).norm () / Mg,
69+ epsilon);
70+ EXPECT_LT ((geometry.simplePolygonVertexLumpedMassMatrix - geometry.vertexLumpedMassMatrix ).norm () / Ml, epsilon);
71+ EXPECT_LT ((geometry.polygonVertexLumpedMassMatrix - geometry.vertexLumpedMassMatrix ).norm () / Ml, epsilon);
72+
73+ geometry.unrequireVertexGalerkinMassMatrix ();
74+ geometry.unrequireVertexLumpedMassMatrix ();
75+ geometry.unrequireCotanLaplacian ();
76+ geometry.unrequireSimplePolygonLaplacian ();
77+ geometry.unrequireSimplePolygonVertexLumpedMassMatrix ();
78+ geometry.unrequireSimplePolygonVertexGalerkinMassMatrix ();
79+ geometry.unrequirePolygonLaplacian ();
80+ geometry.unrequirePolygonVertexLumpedMassMatrix ();
81+ }
82+ }
83+
84+ /* Check that Laplacian can be assembled as expected from DEC operators. */
85+ TEST_F (PolygonMeshSuite, DECTest) {
86+
87+ double epsilon = 1e-8 ;
88+ for (MeshAsset& a : allMeshes ()) {
89+ a.printThyName ();
90+ SurfaceMesh& mesh = *a.mesh ;
91+ VertexPositionGeometry& geometry = *a.geometry ;
92+
93+ geometry.requirePolygonDECOperators ();
94+ geometry.requirePolygonLaplacian ();
95+
96+ SparseMatrix<double >& L = geometry.polygonLaplacian ;
97+ SparseMatrix<double >& h0 = geometry.polygonHodge0 ;
98+ SparseMatrix<double >& h0Inv = geometry.polygonHodge0Inverse ;
99+ SparseMatrix<double >& h1 = geometry.polygonHodge1 ;
100+ SparseMatrix<double >& h2 = geometry.polygonHodge2 ;
101+ SparseMatrix<double >& h2Inv = geometry.polygonHodge2Inverse ;
102+ SparseMatrix<double >& d0 = geometry.polygonD0 ;
103+ SparseMatrix<double >& d1 = geometry.polygonD1 ;
104+ EXPECT_LT ((L - d0.transpose () * h1 * d0).norm (), epsilon);
105+
106+ if (mesh.isTriangular ()) {
107+ geometry.requireDECOperators ();
108+ EXPECT_LT ((h0 - geometry.hodge0 ).norm (), epsilon);
109+ EXPECT_LT ((h2 - geometry.hodge2 ).norm (), epsilon);
110+ geometry.unrequireDECOperators ();
111+ }
112+
113+ geometry.unrequirePolygonDECOperators ();
114+ geometry.unrequirePolygonLaplacian ();
115+ }
116+ }
0 commit comments