Skip to content

Commit

Permalink
Merge branch 'pvidal_296-create-a-patch-class-and-sample-patch-geomet…
Browse files Browse the repository at this point in the history
…ries' into 'main'

Resolve "Create a Patch class and sample patch geometries"

Closes #296

See merge request gysela-developpers/gyselalibxx!599
  • Loading branch information
EmilyBourne committed Jul 26, 2024
1 parent 63bb162 commit 12a6a20
Show file tree
Hide file tree
Showing 11 changed files with 473 additions and 99 deletions.
1 change: 1 addition & 0 deletions src/multipatch/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@


add_subdirectory(connectivity)
add_subdirectory(interfaces)
add_subdirectory(spline)

2 changes: 2 additions & 0 deletions src/multipatch/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

The `multipatch` folder contains all the code describing methods and classes which are specific to a multipatch geometry. It is broken up into the following sub-folders:

- [connectivity](./connectivity/README.md) - Defines structures and methods to describe patches and how they are connected to one another.

- [interface](./interfaces/README.md) - Defines structures and methods for sticking patches together.

- [spline](./spline/README.md) - Defines structures and methods to deal with different splines on every patches.
11 changes: 11 additions & 0 deletions src/multipatch/connectivity/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@


add_library("multipatch_connectivity" INTERFACE)
target_include_directories("multipatch_connectivity"
INTERFACE
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>"
)
target_link_libraries("multipatch_connectivity" INTERFACE
DDC::DDC
)
add_library("gslx::multipatch_connectivity" ALIAS "multipatch_connectivity")
15 changes: 15 additions & 0 deletions src/multipatch/connectivity/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Multipatch connectivity

## Patch tag
The tag Patch refers to a single 2D patch geometry. The tag contains aliases (or shortcuts) to the DDC geometry elements, such as:

* Grids (or points sequence along one dimension) on both dimensions (`Grid1` and `Grid2`);
* Associated continuous dimensions (`Dim1` and `Dim2`);
* Dimensions for B-splines coefficients (`Bsplines1` and `Bsplines2`);
* Coordinates of objects represented on the dimensions (`Coord1`, `Coord2` and `Coord12`);
* The type which describes the index of a grid point (e.g. `Idx1`);
* The type which describes a distance between grid points (e.g. `IdxStep1`);
* The type which describes the index range of a grid (e.g. `IdxRange1`).
* The type which describes the index range of a spline coefficients grid (e.g. `BSIdxRange1`).

The domain defined on this patch is called *logical domain*.
78 changes: 78 additions & 0 deletions src/multipatch/connectivity/patch.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
// SPDX-License-Identifier: MIT

#pragma once

#include <ddc/ddc.hpp>

/**
* @brief Base tag for a patch.
* @tparam T Variadic template parameter allowing us to use Patch struct
* for different numbers of dimensions.
*/
template <class... T>
struct Patch;

/**
* @brief Tag for a patch.
*
* @tparam grid1 Grid on the first logical dimension associated to the patch.
* @tparam grid2 Grid on the second logical dimension associated to the patch.
* @tparam bsplines_dim1 Bspline dimension defined on the first logical continuous dimension associated to the patch.
* @tparam bsplines_dim2 Bspline dimension defined on the second logical continuous dimension associated to the patch.
*/
template <class grid1, class grid2, class bsplines_dim1, class bsplines_dim2>
struct Patch<grid1, grid2, bsplines_dim1, bsplines_dim2>
{
/// @brief The number of dimensions of the patch.
static int constexpr n_dims = 2;

/// @brief Grid on the first logical dimension.
using Grid1 = grid1;
/// @brief Grid on the second logical dimension.
using Grid2 = grid2;

/// @brief First continuous dimension.
using Dim1 = typename grid1::continuous_dimension_type;
/// @brief Second continuous dimension.
using Dim2 = typename grid2::continuous_dimension_type;

/// @brief B-splines defined along the first dimension.
using BSplines1 = bsplines_dim1;
/// @brief B-splines defined along the second dimension.
using BSplines2 = bsplines_dim2;

/// @brief Coordinate type on the first continuous dimension.
using Coord1 = ddc::Coordinate<Dim1>;
/// @brief Coordinate type on the second continuous dimension.
using Coord2 = ddc::Coordinate<Dim2>;
/// @brief Coordinate type on the 2D continuous domain.
using Coord12 = ddc::Coordinate<Dim1, Dim2>;

/// @brief 1D index of a grid point along the first dimension.
using Idx1 = ddc::DiscreteElement<Grid1>;
/// @brief 1D index of a grid point along the second dimension.
using Idx2 = ddc::DiscreteElement<Grid2>;
/// @brief 2D index of a grid point along the first and second dimensions.
using Idx12 = ddc::DiscreteElement<Grid1, Grid2>;

/// @brief 1D index step between grid points along the first dimension.
using IdxStep1 = ddc::DiscreteVector<Grid1>;
/// @brief 1D index step between grid points along the second dimension.
using IdxStep2 = ddc::DiscreteVector<Grid2>;
/// @brief 2D index step between grid points along the first and second dimensions.
using IdxStep12 = ddc::DiscreteVector<Grid1, Grid2>;

/// @brief Index range of a grids over the first dimension.
using IdxRange1 = ddc::DiscreteDomain<Grid1>;
/// @brief Index range of a grids over the second dimension.
using IdxRange2 = ddc::DiscreteDomain<Grid2>;
/// @brief Index range of a grids over the first and second dimension.
using IdxRange12 = ddc::DiscreteDomain<Grid1, Grid2>;

/// @brief Index range of a grids over the first spline dimension.
using BSIdxRange1 = ddc::DiscreteDomain<BSplines1>;
/// @brief Index range of a grids over the second spline dimension.
using BSIdxRange2 = ddc::DiscreteDomain<BSplines2>;
/// @brief Index range of a grids over the first and second spline dimension.
using BSIdxRange12 = ddc::DiscreteDomain<BSplines1, BSplines2>;
};
4 changes: 4 additions & 0 deletions tests/multipatch/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,15 @@ PUBLIC
GTest::gtest
GTest::gmock

gslx::multipatch_connectivity
gslx::multipatch_geometries
gslx::multipatch_interface
)
target_compile_definitions("${test_name_gtest}" PUBLIC)
gtest_discover_tests("${test_name_gtest}" DISCOVERY_MODE PRE_TEST)



add_subdirectory(geometries)
add_subdirectory(spline)

143 changes: 44 additions & 99 deletions tests/multipatch/coord_transformation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,119 +4,62 @@

#include <gtest/gtest.h>

#include "2patches_2d_non_periodic_uniform.hpp"
#include "coord_transformation.hpp"
#include "edge.hpp"
#include "interface.hpp"

namespace {
// Continuous dimension of patch 1
struct RDimX1
{
static bool constexpr PERIODIC = false;
};

struct RDimY1
{
static bool constexpr PERIODIC = false;
};

// Continuous dimension of patch 2
struct RDimX2
{
static bool constexpr PERIODIC = false;
};

struct RDimY2
{
static bool constexpr PERIODIC = false;
};


using CoordX1 = ddc::Coordinate<RDimX1>;
using CoordY1 = ddc::Coordinate<RDimY1>;
using CoordX2 = ddc::Coordinate<RDimX2>;
using CoordY2 = ddc::Coordinate<RDimY2>;

// Discrete dimensions
struct IDimX1 : ddc::UniformPointSampling<RDimX1>
{
};
struct IDimY1 : ddc::UniformPointSampling<RDimY1>
{
};
struct IDimX2 : ddc::UniformPointSampling<RDimX2>
{
};
struct IDimY2 : ddc::UniformPointSampling<RDimY2>
{
};

using IndexX1 = ddc::DiscreteElement<IDimX1>;
using IndexY1 = ddc::DiscreteElement<IDimY1>;
using IndexX2 = ddc::DiscreteElement<IDimX2>;
using IndexY2 = ddc::DiscreteElement<IDimY2>;


using IVectX1 = ddc::DiscreteVector<IDimX1>;
using IVectY1 = ddc::DiscreteVector<IDimY1>;
using IVectX2 = ddc::DiscreteVector<IDimX2>;
using IVectY2 = ddc::DiscreteVector<IDimY2>;

using IDomainX1 = ddc::DiscreteDomain<IDimX1>;
using IDomainY1 = ddc::DiscreteDomain<IDimY1>;
using IDomainX2 = ddc::DiscreteDomain<IDimX2>;
using IDomainY2 = ddc::DiscreteDomain<IDimY2>;
#include "patch.hpp"


namespace {
class CoordinateTransformationTest : public ::testing::Test
{
private:
static constexpr IVectX1 x1_size = IVectX1(10);
static constexpr IVectY1 y1_size = IVectY1(10);
static constexpr Patch1::IdxStep1 x1_size = Patch1::IdxStep1(10);
static constexpr Patch1::IdxStep2 y1_size = Patch1::IdxStep2(10);

static constexpr IVectX2 x2_size = IVectX2(10);
static constexpr IVectY2 y2_size = IVectY2(10);
static constexpr Patch2::IdxStep1 x2_size = Patch2::IdxStep1(10);
static constexpr Patch2::IdxStep2 y2_size = Patch2::IdxStep2(10);

protected:
IDomainX1 const domain_x1;
IDomainY1 const domain_y1;
Patch1::IdxRange1 const idx_range_x1;
Patch1::IdxRange2 const idx_range_y1;

IDomainX2 const domain_x2;
IDomainY2 const domain_y2;
Patch2::IdxRange1 const idx_range_x2;
Patch2::IdxRange2 const idx_range_y2;

public:
CoordinateTransformationTest()
: domain_x1(IndexX1(0), x1_size)
, domain_y1(IndexY1(0), y1_size)
, domain_x2(IndexX2(0), x2_size)
, domain_y2(IndexY2(0), y2_size) {};
: idx_range_x1(Patch1::Idx1(0), x1_size)
, idx_range_y1(Patch1::Idx2(0), y1_size)
, idx_range_x2(Patch2::Idx1(0), x2_size)
, idx_range_y2(Patch2::Idx2(0), y2_size) {};

static void SetUpTestSuite()
{
// Creating of meshes and supports ...........................................................
// Patch 1
CoordX1 const x1_min(0.0);
CoordX1 const x1_max(2.0);
Patch1::Coord1 const x1_min(0.0);
Patch1::Coord1 const x1_max(2.0);

CoordY1 const y1_min(2.5);
CoordY1 const y1_max(7.0);
Patch1::Coord2 const y1_min(2.5);
Patch1::Coord2 const y1_max(7.0);

ddc::init_discrete_space<IDimX1>(IDimX1::init(x1_min, x1_max, x1_size));
ddc::init_discrete_space<IDimY1>(IDimY1::init(y1_min, y1_max, y1_size));
ddc::init_discrete_space<GridX1>(GridX1::init(x1_min, x1_max, x1_size));
ddc::init_discrete_space<GridY1>(GridY1::init(y1_min, y1_max, y1_size));

// Patch 2
CoordX2 const x2_min(1.0);
CoordX2 const x2_max(3.0);
Patch2::Coord1 const x2_min(1.0);
Patch2::Coord1 const x2_max(3.0);

CoordY2 const y2_min(-4.0);
CoordY2 const y2_max(-3.5);
Patch2::Coord2 const y2_min(-4.0);
Patch2::Coord2 const y2_max(-3.5);

ddc::init_discrete_space<IDimX2>(IDimX2::init(x2_min, x2_max, x2_size));
ddc::init_discrete_space<IDimY2>(IDimY2::init(y2_min, y2_max, y2_size));
ddc::init_discrete_space<GridX2>(GridX2::init(x2_min, x2_max, x2_size));
ddc::init_discrete_space<GridY2>(GridY2::init(y2_min, y2_max, y2_size));
}
};


} // namespace


Expand All @@ -125,54 +68,56 @@ TEST_F(CoordinateTransformationTest, InvertedOrientation)
{
// --- TEST 1 ---
// Creating interfaces .......................................................................
Edge<IDimX1> edge_1 = {1, domain_x1, BACK};
Edge<IDimX2> edge_2 = {2, domain_x2, FRONT};
Edge<GridX1> edge_1 = {1, idx_range_x1, BACK};
Edge<GridX2> edge_2 = {2, idx_range_x2, FRONT};

Interface<IDimX1, IDimX2> interface = {edge_1, edge_2, false};
Interface<GridX1, GridX2> interface = {edge_1, edge_2, false};

// Coordinate transformation .................................................................
EdgeCoordinatesTransformation coord_transformation(interface);

CoordX1 test_coord_x1(1.5);
CoordX2 test_coord_x2(coord_transformation(test_coord_x1));
Patch1::Coord1 test_coord_x1(1.5);
Patch2::Coord1 test_coord_x2(coord_transformation(test_coord_x1));

EXPECT_NEAR(double(test_coord_x2), 1.5, 1e-14);
}



TEST_F(CoordinateTransformationTest, StickingDifferentDimensions)
{
// --- TEST 2 ---
// Creating interfaces .......................................................................
Edge<IDimX1> edge_1 = {1, domain_x1, BACK};
Edge<IDimY2> edge_2 = {2, domain_y2, FRONT};
Edge<GridX1> edge_1 = {1, idx_range_x1, BACK};
Edge<GridY2> edge_2 = {2, idx_range_y2, FRONT};

Interface<IDimX1, IDimY2> interface = {edge_1, edge_2, true};
Interface<GridX1, GridY2> interface = {edge_1, edge_2, true};

// Coordinate transformation .................................................................
EdgeCoordinatesTransformation coord_transformation(interface);

CoordX1 test_coord_x1(0.7);
CoordY2 test_coord_y2(coord_transformation(test_coord_x1));
Patch1::Coord1 test_coord_x1(0.7);
Patch2::Coord2 test_coord_y2(coord_transformation(test_coord_x1));

EXPECT_NEAR(double(test_coord_y2), -3.825, 1e-14);
}



TEST_F(CoordinateTransformationTest, ReverseTransformation)
{
// --- TEST 3 ---
// Creating interfaces .......................................................................
Edge<IDimX1> edge_1 = {1, domain_x1, BACK};
Edge<IDimX2> edge_2 = {2, domain_x2, FRONT};
Edge<GridX1> edge_1 = {1, idx_range_x1, BACK};
Edge<GridX2> edge_2 = {2, idx_range_x2, FRONT};

Interface<IDimX1, IDimX2> interface = {edge_1, edge_2, false};
Interface<GridX1, GridX2> interface = {edge_1, edge_2, false};

// Coordinate transformation .................................................................
EdgeCoordinatesTransformation coord_transformation(interface);

CoordX2 test_coord_x2(1.5);
CoordX1 test_coord_x1 = coord_transformation(test_coord_x2);
Patch2::Coord1 test_coord_x2(1.5);
Patch1::Coord1 test_coord_x1 = coord_transformation(test_coord_x2);

EXPECT_NEAR(double(test_coord_x1), 1.5, 1e-14);
}
Loading

0 comments on commit 12a6a20

Please sign in to comment.