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

Test add linear axis aligned geometry test #914

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
7 changes: 4 additions & 3 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ libt8_installed_headers_cmesh = \
src/t8_cmesh/t8_cmesh_examples.h \
src/t8_cmesh/t8_cmesh_geometry.h \
src/t8_cmesh/t8_cmesh_helpers.h \
src/t8_cmesh/t8_cmesh_cad.hxx
src/t8_cmesh/t8_cmesh_cad.hxx \
src/t8_cmesh/t8_cmesh_types.h \
src/t8_cmesh/t8_cmesh_stash.h
libt8_installed_headers_data = \
src/t8_data/t8_shmem.h src/t8_data/t8_containers.h
libt8_installed_headers_forest = \
Expand Down Expand Up @@ -88,9 +90,8 @@ libt8_installed_headers_default_tet =
libt8_installed_headers_default_prism =
libt8_installed_headers_default_pyramid =
libt8_internal_headers = \
src/t8_cmesh/t8_cmesh_trees.h src/t8_cmesh/t8_cmesh_partition.h \
src/t8_geometry/t8_geometry_handler.hxx \
src/t8_cmesh/t8_cmesh_stash.h src/t8_cmesh/t8_cmesh_trees.h \
src/t8_cmesh/t8_cmesh_types.h src/t8_cmesh/t8_cmesh_partition.h \
src/t8_cmesh/t8_cmesh_copy.h \
src/t8_cmesh/t8_cmesh_offset.h \
src/t8_vtk/t8_vtk_polydata.hxx \
Expand Down
2 changes: 1 addition & 1 deletion src/t8_geometry/t8_geometry_helpers.c
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ t8_geom_compute_linear_axis_aligned_geometry (t8_eclass_t tree_class, const doub
const size_t offset_domain_dim = i_coord * T8_ECLASS_MAX_DIM;
for (int i_dim = 0; i_dim < T8_ECLASS_MAX_DIM; ++i_dim) {
out_coords[offset_domain_dim + i_dim] = tree_vertices[i_dim];
out_coords[offset_domain_dim + i_dim] += ref_coords[offset_tree_dim] * vector[i_dim];
out_coords[offset_domain_dim + i_dim] += ref_coords[offset_tree_dim + i_dim] * vector[i_dim];
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,88 +25,142 @@
*/

#include <test/t8_gtest_macros.hxx>
#include <test/t8_geometry/t8_gtest_geometry_macros.hxx>
#include <test/t8_gtest_custom_assertion.hxx>
#include <gtest/gtest.h>
#include <t8_eclass.h>
#include <t8_cmesh.hxx>
#include <t8_cmesh/t8_cmesh_examples.h>
#include <t8_geometry/t8_geometry.h>
#include <t8_geometry/t8_geometry_implementations/t8_geometry_linear.hxx>
#include <t8_geometry/t8_geometry_implementations/t8_geometry_linear_axis_aligned.hxx>
#include <t8_element.h>

t8_cmesh_t
t8_geometry_testing_tree_from_class (const t8_eclass_t eclass)
{
t8_cmesh_t cmesh;
t8_cmesh_init (&cmesh);
const int num_vertices = t8_eclass_num_vertices[eclass];
double *vertices = T8_ALLOC (double, T8_ECLASS_MAX_DIM *num_vertices);
for (int i_vertex = 0; i_vertex < num_vertices; ++i_vertex) {
for (int dim = 0; dim < T8_ECLASS_MAX_DIM; ++dim) {
vertices[i_vertex * T8_ECLASS_MAX_DIM + dim] = t8_element_corner_ref_coords[eclass][i_vertex][dim];
class geometry_test: public testing::TestWithParam<std::tuple<int, t8_eclass>> {
public:
static void
SetUpTestSuite ()
{
seed = time (NULL); /* RNG seed */
}
static int seed;

protected:
void
SetUp () override
{
const int geom_int = std::get<0> (GetParam ());
eclass = std::get<1> (GetParam ());
t8_cmesh_init (&cmesh);
if (geom_int == T8_GEOMETRY_TYPE_LINEAR_AXIS_ALIGNED
&& !(eclass == T8_ECLASS_LINE || eclass == T8_ECLASS_QUAD || eclass == T8_ECLASS_HEX)) {
GTEST_SKIP ();
}

const int num_vertices = t8_eclass_num_vertices[eclass];
t8_cmesh_set_tree_class (cmesh, 0, eclass);
double *vertices = T8_ALLOC_ZERO (double, num_vertices *T8_ECLASS_MAX_DIM);
for (int i_vertex = 0; i_vertex < num_vertices; ++i_vertex) {
for (int dim = 0; dim < T8_ECLASS_MAX_DIM; ++dim) {
vertices[i_vertex * T8_ECLASS_MAX_DIM + dim] = t8_element_corner_ref_coords[eclass][i_vertex][dim];
}
}
switch (geom_int) {
case T8_GEOMETRY_TYPE_LINEAR:
geom = new t8_geometry_linear (t8_eclass_to_dimension[eclass]);
t8_cmesh_register_geometry<t8_geometry_linear> (cmesh, t8_eclass_to_dimension[eclass]);
break;
case T8_GEOMETRY_TYPE_LINEAR_AXIS_ALIGNED:
geom = new t8_geometry_linear_axis_aligned (t8_eclass_to_dimension[eclass]);
/* Copy last vertex to the second position*/
vertices[3] = vertices[3 * (num_vertices - 1)];
vertices[4] = vertices[3 * (num_vertices - 1) + 1];
vertices[5] = vertices[3 * (num_vertices - 1) + 2];

t8_cmesh_register_geometry<t8_geometry_linear_axis_aligned> (cmesh, t8_eclass_to_dimension[eclass]);
break;
default:
break;
}
t8_cmesh_set_tree_vertices (cmesh, 0, vertices, t8_eclass_num_vertices[eclass]);
t8_cmesh_commit (cmesh, sc_MPI_COMM_WORLD);
T8_FREE (vertices);
}
t8_cmesh_set_tree_class (cmesh, 0, eclass);
t8_cmesh_register_geometry<t8_geometry_linear> (cmesh, t8_eclass_to_dimension[eclass]);
t8_cmesh_set_tree_vertices (cmesh, 0, vertices, t8_eclass_num_vertices[eclass]);
t8_cmesh_commit (cmesh, sc_MPI_COMM_WORLD);
T8_FREE (vertices);
return cmesh;
}
void
TearDown () override
{
t8_cmesh_unref (&cmesh);
}
t8_eclass_t eclass;
t8_geometry_with_vertices *geom;
t8_cmesh_t cmesh;
#ifdef T8_ENABLE_LESS_TESTS
const int num_points = 1000;
#else
const int num_points = 10000;
#endif
};

/* Check whether the linear geometry map is correct.
* We create a cmesh of one tree and unit element
int geometry_test::seed;

/* Check whether the linear axis aligned geometry map is correct.
* We create a cmesh of one tree and unit line, quad or hex
* geometry. We then create random points in a reference tree and
* check whether the evaluation is correct. */
TEST_P (geometry_test, cmesh_geometry_linear)
TEST_P (geometry_test, cmesh_geometry)
{
/* TODO: Add a test for the jacobian, as soon as its implemented. */

t8_debugf ("Testing linear geometry evaluation.\n");

/* Create random points in [0,1]^d and check if they are mapped correctly. */
t8_geometry_linear linear_geom (t8_eclass_to_dimension[eclass]);
t8_cmesh_t cmesh;

double point[3];
double point_mapped[3];
const int seed = 0; /* RNG seed */
const t8_geometry_c *cmesh_geom;

cmesh = t8_geometry_testing_tree_from_class (eclass);

/* Double check that the geometry is the linear geometry. */
/* Double check that the geometry is the linear axis aligned geometry. */
cmesh_geom = t8_cmesh_get_tree_geometry (cmesh, 0);
ASSERT_TRUE (cmesh_geom != NULL) << "Could not get cmesh's geometry.";
int has_same_name = cmesh_geom->t8_geom_get_name () == linear_geom.t8_geom_get_name ();
ASSERT_EQ (has_same_name, 1) << "cmesh's geometry is not the linear geometry.";
ASSERT_EQ (cmesh_geom->t8_geom_get_hash (), geom->t8_geom_get_hash ())
<< "cmesh's geometry is not the expected geometry.";

srand (seed);
for (int ipoint = 0; ipoint < num_points; ++ipoint) {
double point[3] = { 0 };
/* Compute random coordinates in [0,1].
* These are seen as reference coordinates in the single
* cmesh tree. Our geometry will map them into the physical
* space. Since this space is also [0,1] and the cmesh only
* has one tree, the mapped coordinates must be the same as the
* reference coordinates. */
point[0] = (double) rand () / RAND_MAX;
point[1] = (double) rand () / RAND_MAX;
point[2] = (double) rand () / RAND_MAX;
for (int idim = 0; idim < t8_eclass_to_dimension[eclass]; ++idim) {
point[idim] = (double) rand () / RAND_MAX;
}

/* Evaluate the geometry */
t8_geometry_evaluate (cmesh, 0, point, 1, point_mapped);
/* Check that the first dim coordinates are the same */
int idim;
for (idim = 0; idim < t8_eclass_to_dimension[eclass]; ++idim) {
ASSERT_NEAR (point[idim], point_mapped[idim], T8_PRECISION_SQRT_EPS) << "Linear geometry computed wrong value.";
}
/* Check that the remaining entries are 0. */
for (; idim < 3; ++idim) {
ASSERT_EQ (point_mapped[idim], 0) << "Linear geometry computed wrong value.";
}
EXPECT_VEC3_EQ (point, point_mapped, T8_PRECISION_SQRT_EPS);
}
/* Destroy the cmesh */
t8_cmesh_destroy (&cmesh);
}

INSTANTIATE_TEST_SUITE_P (t8_gtest_geometry, geometry_test, AllEclasses);
auto print_test = [] (const testing::TestParamInfo<std::tuple<int, t8_eclass>> &info) {
std::string name;
const int geom_int = std::get<0> (info.param);
const t8_eclass_t eclass = std::get<1> (info.param);
switch (geom_int) {
case T8_GEOMETRY_TYPE_LINEAR:
name = std::string ("linear_geometry_");
break;
case T8_GEOMETRY_TYPE_LINEAR_AXIS_ALIGNED:
name = std::string ("linear_axis_aligned_geometry_");
break;
default:
name = std::string ("geometry_not_allowed_");
break;
}
name += std::string (t8_eclass_to_string[eclass]);
return name;
};

INSTANTIATE_TEST_SUITE_P (
t8_gtest_geometry, geometry_test,
::testing::Combine (::testing::Values (T8_GEOMETRY_TYPE_LINEAR, T8_GEOMETRY_TYPE_LINEAR_AXIS_ALIGNED), AllEclasses),
print_test);
47 changes: 0 additions & 47 deletions test/t8_geometry/t8_gtest_geometry_macros.hxx
Original file line number Diff line number Diff line change
@@ -1,47 +0,0 @@
/*
This file is part of t8code.
t8code is a C library to manage a collection (a forest) of multiple
connected adaptive space-trees of general element classes in parallel.

Copyright (C) 2024 the developers

t8code is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

t8code is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with t8code; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

/** \file t8_gtest_geometry_macros.hxx
* This file contains macros and base classes for geometry tests.
*/

#include <gtest/gtest.h>
#include <t8_eclass.h>

class geometry_test: public testing::TestWithParam<t8_eclass_t> {
protected:
void
SetUp () override
{
eclass = GetParam ();
}
void
TearDown () override
{
}
t8_eclass_t eclass;
#ifdef T8_ENABLE_LESS_TESTS
const int num_points = 1000;
#else
const int num_points = 10000;
#endif
};