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

Cmesh parameters with rules #945

Merged
merged 6 commits into from
Feb 22, 2024
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
4 changes: 2 additions & 2 deletions example/remove/t8_example_empty_trees.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,10 @@ t8_strip_of_quads (t8_gloidx_t num_trees, t8_gloidx_t empty_tree, const char **v
{

const double boundary_coords[12] = { 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0 };
const t8_geometry_c *geometry = t8_geometry_linear_axis_aligned_new (2);
const int use_axis_alined = 1;

t8_cmesh_t cmesh
= t8_cmesh_new_hypercube_pad (T8_ECLASS_QUAD, sc_MPI_COMM_WORLD, boundary_coords, num_trees, 1, 0, geometry);
= t8_cmesh_new_hypercube_pad (T8_ECLASS_QUAD, sc_MPI_COMM_WORLD, boundary_coords, num_trees, 1, 0, use_axis_alined);

t8_forest_t forest = t8_forest_new_uniform (cmesh, t8_scheme_new_default_cxx (), 0, 0, sc_MPI_COMM_WORLD);

Expand Down
8 changes: 4 additions & 4 deletions src/t8_cmesh/t8_cmesh_examples.c
Original file line number Diff line number Diff line change
Expand Up @@ -1258,7 +1258,7 @@ t8_cmesh_set_vertices_3D (t8_cmesh_t cmesh, const t8_eclass_t eclass, const doub

t8_cmesh_t
t8_cmesh_new_hypercube_pad (const t8_eclass_t eclass, sc_MPI_Comm comm, const double *boundary, t8_locidx_t polygons_x,
t8_locidx_t polygons_y, t8_locidx_t polygons_z, const t8_geometry_c *geometry)
t8_locidx_t polygons_y, t8_locidx_t polygons_z, const int use_axis_aligned)
{
SC_CHECK_ABORT (eclass != T8_ECLASS_PYRAMID, "Pyramids are not yet supported.");
const int dim = t8_eclass_to_dimension[eclass];
Expand All @@ -1279,7 +1279,7 @@ t8_cmesh_new_hypercube_pad (const t8_eclass_t eclass, sc_MPI_Comm comm, const do
t8_cmesh_t cmesh;
t8_cmesh_init (&cmesh);

const int is_axis_aligned = t8_geom_get_type (geometry) == T8_GEOMETRY_TYPE_LINEAR_AXIS_ALIGNED;
t8_geometry_c *geometry = use_axis_aligned ? t8_geometry_linear_axis_aligned_new (dim) : t8_geometry_linear_new (dim);

t8_cmesh_register_geometry (cmesh, geometry);

Expand All @@ -1295,11 +1295,11 @@ t8_cmesh_new_hypercube_pad (const t8_eclass_t eclass, sc_MPI_Comm comm, const do
/* Set the vertices of all trees. */
if (dim == 3) {
T8_ASSERT (eclass == T8_ECLASS_HEX || eclass == T8_ECLASS_TET || eclass == T8_ECLASS_PRISM);
t8_cmesh_set_vertices_3D (cmesh, eclass, boundary, polygons_x, polygons_y, polygons_z, is_axis_aligned);
t8_cmesh_set_vertices_3D (cmesh, eclass, boundary, polygons_x, polygons_y, polygons_z, use_axis_aligned);
}
else if (dim == 2) {
T8_ASSERT (eclass == T8_ECLASS_QUAD || eclass == T8_ECLASS_TRIANGLE);
t8_cmesh_set_vertices_2D (cmesh, eclass, boundary, polygons_x, polygons_y, is_axis_aligned);
t8_cmesh_set_vertices_2D (cmesh, eclass, boundary, polygons_x, polygons_y, use_axis_aligned);
}
else if (dim == 1) {
T8_ASSERT (eclass == T8_ECLASS_LINE);
Expand Down
2 changes: 1 addition & 1 deletion src/t8_cmesh/t8_cmesh_examples.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ t8_cmesh_new_hypercube (t8_eclass_t eclass, sc_MPI_Comm comm, int do_bcast, int
*/
t8_cmesh_t
t8_cmesh_new_hypercube_pad (const t8_eclass_t eclass, sc_MPI_Comm comm, const double *boundary, t8_locidx_t polygons_x,
t8_locidx_t polygons_y, t8_locidx_t polygons_z, const t8_geometry_c *geometry);
t8_locidx_t polygons_y, t8_locidx_t polygons_z, const int use_axis_aligned);

/** Hybercube with 6 Tets, 6 Prism, 4 Hex.
* \param [in] comm The mpi communicator to be used.
Expand Down
4 changes: 2 additions & 2 deletions test/t8_cmesh/t8_gtest_cmesh_set_join_by_vertices.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -243,8 +243,8 @@ TEST (t8_cmesh_set_join_by_vertices, test_cmesh_set_join_by_vertices)
const double boundary_coords[24] = { 1, 0, 0, 4, 0, 0, 0, 6, 0, 5, 5, 0, -1, -2, 8, 9, 0, 10, 0, 8, 9, 10, 10, 10 };

t8_eclass_t eclass = T8_ECLASS_HEX;
t8_geometry_c *geometry = new t8_geometry_linear (3);
t8_cmesh_t cmesh = t8_cmesh_new_hypercube_pad (eclass, comm, boundary_coords, 2, 2, 2, geometry);
const int use_axis_aligned = 0;
t8_cmesh_t cmesh = t8_cmesh_new_hypercube_pad (eclass, comm, boundary_coords, 2, 2, 2, use_axis_aligned);
test_with_cmesh (cmesh);
t8_cmesh_destroy (&cmesh);
}
Expand Down
6 changes: 4 additions & 2 deletions test/t8_cmesh_generator/t8_cmesh_example_sets.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ along with t8code; if not, write to the Free Software Foundation, Inc.,
#include "test/t8_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_new_from_class_param.hxx"
#include "test/t8_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_new_bigmesh_param.hxx"
#include "test/t8_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_new_comm.hxx"
#include "test/t8_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_new_hypercube_pad.hxx"
#include "test/t8_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_new_hypercube_param.hxx"
#include "test/t8_cmesh_generator/t8_gtest_cmesh_cartestian_product.hxx"
#include "test/t8_cmesh_generator/t8_gtest_cmesh_sum_of_sets.hxx"
Expand All @@ -48,8 +49,9 @@ auto pretty_print_base_example = [] (const testing::TestParamInfo<cmesh_example_
namespace cmesh_list
{
std::vector<example_set *> cart_prod_vec
= { new_from_class::cmesh_example, new_prism_cake::cmesh_example, new_bigmesh::cmesh_example,
new_cmesh_comm::cmesh_example, new_hypercube_cmesh::cmesh_example, new_hypercube_cmesh::cmesh_example_pyra };
= { new_from_class::cmesh_example, new_prism_cake::cmesh_example, new_bigmesh::cmesh_example,
new_cmesh_comm::cmesh_example, new_hypercube_pad::cmesh_example, new_hypercube_cmesh::cmesh_example,
new_hypercube_cmesh::cmesh_example_pyra };

cmesh_sum_of_sets cmesh_sums (cart_prod_vec);

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/*
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.
*/

#ifndef T8_CMESH_NEW_HYPERCUBE_PAD
#define T8_CMESH_NEW_HYPERCUBE_PAD

#include "test/t8_cmesh_generator/t8_gtest_cmesh_cartestian_product.hxx"
#include "test/t8_cmesh_generator/t8_cmesh_parametrized_examples/t8_cmesh_params.hxx"
#include <t8_cmesh/t8_cmesh_examples.h>

namespace new_hypercube_pad
{
std::function<t8_cmesh_t (const t8_eclass_t, sc_MPI_Comm, const double *, t8_locidx_t, t8_locidx_t, t8_locidx_t,
const int)>
hyper_pad = t8_cmesh_new_hypercube_pad;

std::string
make_param_string (const t8_eclass_t eclass, sc_MPI_Comm comm, const double *boundary, t8_locidx_t polygons_x,
t8_locidx_t polygons_y, t8_locidx_t polygons_z, const int use_axis_aligned)
{
std::string delimiter = std::string ("_");
std::string geometry = use_axis_aligned ? std::string ("AxisAligned") : std::string ("LinearGeom");

std::string params = delimiter + t8_eclass_to_string[eclass] + delimiter + cmesh_params::comm_to_string (comm)
+ delimiter + std::string ("BoundsNotPrinted") + delimiter + std::to_string (polygons_x)
+ delimiter + std::to_string (polygons_y) + delimiter + std::to_string (polygons_z) + delimiter
+ geometry;

return params;
}
std::function<std::string (const t8_eclass_t, sc_MPI_Comm, const double *, t8_locidx_t, t8_locidx_t, t8_locidx_t,
const int)>
make_param_string_wrapper = make_param_string;

inline bool
rule (const t8_eclass_t eclass, sc_MPI_Comm comm, const double *boundary, t8_locidx_t polygons_x,
t8_locidx_t polygons_y, t8_locidx_t polygons_z, const int use_axis_aligned)
{
const int dim = t8_eclass_to_dimension[eclass];
if (dim == 0 && (polygons_x > 1 || polygons_y > 1 || polygons_z > 1))
return false;
if (dim == 1 && (polygons_y > 1 || polygons_z > 1))
return false;
if (dim == 2 && polygons_z > 1)
return false;
if ((eclass != T8_ECLASS_HEX && use_axis_aligned) || (eclass != T8_ECLASS_QUAD && use_axis_aligned))
return false;
if (eclass == T8_ECLASS_PYRAMID)
return false;
return true;
}

std::function<bool (const t8_eclass_t, sc_MPI_Comm, const double *, t8_locidx_t, t8_locidx_t, t8_locidx_t, const int)>
rule_wrapper = rule;

example_set *cmesh_example = (example_set *) new cmesh_cartesian_product_with_rules<
decltype (cmesh_params::all_eclasses.begin ()), decltype (cmesh_params::my_comms.begin ()),
decltype (cmesh_params::boundaries.begin ()), decltype (cmesh_params::elems_per_dim.begin ()),
decltype (cmesh_params::elems_per_dim.begin ()), decltype (cmesh_params::elems_per_dim.begin ()),
decltype (cmesh_params::use_axis_aligned.begin ())> (
std::make_pair (cmesh_params::eclasses.begin (), cmesh_params::eclasses.end ()),
std::make_pair (cmesh_params::my_comms.begin (), cmesh_params::my_comms.end ()),
std::make_pair (cmesh_params::boundaries.begin (), cmesh_params::boundaries.end ()),
std::make_pair (cmesh_params::elems_per_dim.begin (), cmesh_params::elems_per_dim.end ()),
std::make_pair (cmesh_params::elems_per_dim.begin (), cmesh_params::elems_per_dim.end ()),
std::make_pair (cmesh_params::elems_per_dim.begin (), cmesh_params::elems_per_dim.end ()),
std::make_pair (cmesh_params::use_axis_aligned.begin (), cmesh_params::use_axis_aligned.end ()), hyper_pad,
make_param_string_wrapper, rule_wrapper, "t8_cmesh_new_hypercube_pad_");
} // namespace new_hypercube_pad

#endif /* T8_CMESH_NEW_HYPERCUBE_PAD */
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,20 @@ along with t8code; if not, write to the Free Software Foundation, Inc.,
* File to store the parameters that are used for our parameterized cmesh-tests
*/

#ifndef T8_CMESH_PARAMS_HXX
#define T8_CMESH_PARAMS_HXX
#include <t8_eclass.h>
#include <vector>
#include <numeric>
#include <algorithm>

#ifndef T8_CMESH_PARAMS_HXX
#define T8_CMESH_PARAMS_HXX
#include <t8_geometry/t8_geometry_base.hxx>
#include <t8_geometry/t8_geometry_implementations/t8_geometry_linear.hxx>
#include <t8_geometry/t8_geometry_implementations/t8_geometry_linear_axis_aligned.hxx>

namespace cmesh_params
{
std::string
comm_to_string (const sc_MPI_Comm& comm)
comm_to_string (const sc_MPI_Comm &comm)
{
int mpi_ret;
sc_MPI_Comm_compare (comm, sc_MPI_COMM_WORLD, &mpi_ret);
Expand All @@ -53,8 +55,16 @@ filled_vector (const size_t size, int start)
return tmp;
}

const double cube_bounds[24] = { 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1 };

std::vector<const double *> boundaries = { cube_bounds };

std::vector<int> use_axis_aligned = { 0, 1 };

std::vector<int> large_mesh = filled_vector (20, 500);

std::vector<int> elems_per_dim = filled_vector (5, 1);

std::vector<sc_MPI_Comm> my_comms = { sc_MPI_COMM_WORLD };
std::vector<t8_eclass_t> eclasses = { T8_ECLASS_VERTEX, T8_ECLASS_LINE, T8_ECLASS_QUAD, T8_ECLASS_TRIANGLE,
T8_ECLASS_HEX, T8_ECLASS_TET, T8_ECLASS_PRISM, T8_ECLASS_PYRAMID };
Expand Down
57 changes: 50 additions & 7 deletions test/t8_cmesh_generator/t8_gtest_cmesh_cartestian_product.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -172,24 +172,37 @@ increment (const B& begins, std::pair<T, T>& r, std::pair<TT, TT>&... rr)
return false;
}

template <typename... Args>
inline bool
no_rule (Args... params)
{
return true;
}

/**
* Fill a vector with tuples, based on pairs of iterators. The iterators are used
* to create the tuples according to the cartesian product.
*
* @tparam OutputIterator
* @tparam Iter
* \param out An OutputIterator that will be filled
* \param ranges Pairs of ranges
* \param[in, out] out An OutputIterator that will be filled
* \param[in] rule A function that returns true if a parameter combination is permissible, false otherwise
* \param[in] ranges Pairs of ranges
*/
template <typename OutputIterator, typename... Iter>
void
cartesian_product (OutputIterator out, std::pair<Iter, Iter>... ranges)
cartesian_product (OutputIterator out, std::function<bool (typename Iter::value_type...)> rule,
std::pair<Iter, Iter>... ranges)
{
const auto begins = std::make_tuple (ranges.first...);
out = { *ranges.first... };
while (!increment (begins, ranges...)) {
if (rule (*ranges.first...)) {
out = { *ranges.first... };
}
while (!increment (begins, ranges...)) {
if (rule (*ranges.first...)) {
out = { *ranges.first... };
}
}
}

/**
Expand All @@ -208,8 +221,9 @@ class cmesh_cartesian_product_params: example_set {
std::function<std::string (const typename Iter::value_type&...)> param_to_string,
std::string name)
{
std::function<bool (typename Iter::value_type...)> no_rule_wrapper = no_rule<typename Iter::value_type...>;
std::vector<std::tuple<typename Iter::value_type...>> cart_prod;
cartesian_product (std::back_inserter (cart_prod), ranges...);
cartesian_product (std::back_inserter (cart_prod), no_rule_wrapper, ranges...);
for (int iparam_set = 0; (long unsigned int) iparam_set < cart_prod.size (); iparam_set++) {
std::tuple<typename Iter::value_type...> param = cart_prod[iparam_set];
cmesh_example_base* next_example
Expand All @@ -224,8 +238,9 @@ class cmesh_cartesian_product_params: example_set {
std::function<std::string (const typename Iter::value_type&...)> param_to_string,
std::vector<std::string> names)
{
std::function<bool (typename Iter::value_type...)> no_rule_wrapper = no_rule<typename Iter::value_type...>;
std::vector<std::tuple<typename Iter::value_type...>> cart_prod;
cartesian_product (std::back_inserter (cart_prod), ranges...);
cartesian_product (std::back_inserter (cart_prod), no_rule_wrapper, ranges...);
T8_ASSERT (cmesh_functions.size () == names.size ());
for (int ifunction = 0; (long unsigned int) ifunction < cmesh_functions.size (); ifunction++) {
for (int iparam_set = 0; (long unsigned int) iparam_set < cart_prod.size (); iparam_set++) {
Expand All @@ -239,4 +254,32 @@ class cmesh_cartesian_product_params: example_set {
}
};

/**
* Variadic template class that creates \ref base_example based on the cartesian product
* of the input parameters.
*
* @tparam Iter
*/
template <class... Iter>
class cmesh_cartesian_product_with_rules: example_set {
public:
cmesh_cartesian_product_with_rules () {};

cmesh_cartesian_product_with_rules (std::pair<Iter, Iter>... ranges,
std::function<t8_cmesh_t (typename Iter::value_type...)> cmesh_function,
std::function<std::string (const typename Iter::value_type&...)> param_to_string,
std::function<bool (typename Iter::value_type...)> rule, std::string name)
{
std::vector<std::tuple<typename Iter::value_type...>> cart_prod;
cartesian_product (std::back_inserter (cart_prod), rule, ranges...);
for (int iparam_set = 0; (long unsigned int) iparam_set < cart_prod.size (); iparam_set++) {
std::tuple<typename Iter::value_type...> param = cart_prod[iparam_set];
cmesh_example_base* next_example
= (cmesh_example_base*) new cmesh_example_with_parameter<typename Iter::value_type...> (cmesh_function, param,
param_to_string, name);
example_all_combination.push_back (next_example);
}
}
};

#endif /* T8_GTEST_CMESH_CREATOR_BASE_HXX */
5 changes: 1 addition & 4 deletions test/t8_geometry/t8_gtest_point_inside.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,6 @@ class geometry_point_inside: public testing::TestWithParam<std::tuple<t8_eclass,
eclass = std::get<0> (GetParam ());
level = std::get<1> (GetParam ());
use_axis_aligned_geom = std::get<2> (GetParam ());
const int dim = t8_eclass_to_dimension[eclass];

/* Construct a cube coarse mesh */
if (use_axis_aligned_geom && (eclass == T8_ECLASS_LINE || eclass == T8_ECLASS_QUAD || eclass == T8_ECLASS_HEX)) {
Expand All @@ -148,8 +147,7 @@ class geometry_point_inside: public testing::TestWithParam<std::tuple<t8_eclass,
1, 1, 1
};
/* clang-format on */
geometry = new t8_geometry_linear_axis_aligned (dim);
cmesh = t8_cmesh_new_hypercube_pad (eclass, sc_MPI_COMM_WORLD, boundaries, 1, 1, 1, geometry);
cmesh = t8_cmesh_new_hypercube_pad (eclass, sc_MPI_COMM_WORLD, boundaries, 1, 1, 1, use_axis_aligned_geom);
}
else {
cmesh = t8_cmesh_new_from_class (eclass, sc_MPI_COMM_WORLD);
Expand All @@ -162,7 +160,6 @@ class geometry_point_inside: public testing::TestWithParam<std::tuple<t8_eclass,
t8_eclass_t eclass;
int level;
int use_axis_aligned_geom;
t8_geometry_c *geometry;
t8_cmesh_t cmesh;
};

Expand Down