Add InterfaceDerivativeMatrix for conforming meshes - #498
Conversation
Add `SingleInterfaceDerivativesCalculator` operator and tests to compute an interface derivative with the different cases: - Interpolation type: Hermite boundary conditions ; additional interpolation points - Mesh type: uniform ; non-uniform - Formula type: exact ; approximation. - Patch connections: E|E ; E|W ; W|E ; W|W ; E|S See merge request gysela-developpers/gyselalibxx!869 -------------------------------------------- Co-authored-by: Emily Bourne <emily.bourne@epfl.ch>
Add a `SingleInterfaceDerivativeCalculatorCollection` to store a collection of `SingleInterfaceDerivativeCalculator`. Change the template parameters of `SingleInterfaceDerivativeCalculator`. The boundary conditions are now inputs in the constructor. Move useful operators in the test files `single_interface_derivatives_calculator_test.cpp` in a `interface_derivatives_utils.hpp` file. See merge request gysela-developpers/gyselalibxx!874 -------------------------------------------- Co-authored-by: Pauline Vidal <142578924+PaulineVidal@users.noreply.github.com> Co-authored-by: Emily Bourne <emily.bourne@epfl.ch>
Add `SingleInterfaceDerivativesCalculator` operator and tests to compute an interface derivative with the different cases: - Interpolation type: Hermite boundary conditions ; additional interpolation points - Mesh type: uniform ; non-uniform - Formula type: exact ; approximation. - Patch connections: E|E ; E|W ; W|E ; W|W ; E|S See merge request gysela-developpers/gyselalibxx!869 -------------------------------------------- Co-authored-by: Emily Bourne <emily.bourne@epfl.ch>
Add a `SingleInterfaceDerivativeCalculatorCollection` to store a collection of `SingleInterfaceDerivativeCalculator`. Change the template parameters of `SingleInterfaceDerivativeCalculator`. The boundary conditions are now inputs in the constructor. Move useful operators in the test files `single_interface_derivatives_calculator_test.cpp` in a `interface_derivatives_utils.hpp` file. See merge request gysela-developpers/gyselalibxx!874 -------------------------------------------- Co-authored-by: Pauline Vidal <142578924+PaulineVidal@users.noreply.github.com> Co-authored-by: Emily Bourne <emily.bourne@epfl.ch>
…ce_approx_derivative_matrix
Add `SingleInterfaceDerivativesCalculator` operator and tests to compute an interface derivative with the different cases: - Interpolation type: Hermite boundary conditions ; additional interpolation points - Mesh type: uniform ; non-uniform - Formula type: exact ; approximation. - Patch connections: E|E ; E|W ; W|E ; W|W ; E|S See merge request gysela-developpers/gyselalibxx!869 -------------------------------------------- Co-authored-by: Emily Bourne <emily.bourne@epfl.ch>
Add a `SingleInterfaceDerivativeCalculatorCollection` to store a collection of `SingleInterfaceDerivativeCalculator`. Change the template parameters of `SingleInterfaceDerivativeCalculator`. The boundary conditions are now inputs in the constructor. Move useful operators in the test files `single_interface_derivatives_calculator_test.cpp` in a `interface_derivatives_utils.hpp` file. See merge request gysela-developpers/gyselalibxx!874 -------------------------------------------- Co-authored-by: Pauline Vidal <142578924+PaulineVidal@users.noreply.github.com> Co-authored-by: Emily Bourne <emily.bourne@epfl.ch>
…ce_approx_derivative_matrix
Update the `main_pvidal` branch after merge including DDC changes. See merge request gysela-developpers/gyselalibxx!882 --------------------------------------------
|
This PR is failing tests so it has been put back into draft. Please remove the draft status when the tests pass. |
| // Update the derivatives. | ||
| // Change the sign of the derivative on Patch1, if the grid directions desagreed. | ||
| function_and_derivs_1(idx_slice_deriv_1, idx_slice_1) = interface_deriv * sign_1; | ||
| function_and_derivs_2(idx_slice_deriv_2, idx_slice_2) = interface_deriv * sign_2; |
There was a problem hiding this comment.
@EmilyBourne
There is these CI test errors:
Variable 'function_and_derivs_1(idx_slice_deriv_1,idx_slice_1)' is assigned a value that is never used. [unreadVariable]
see https://github.com/gyselax/gyselalibxx/actions/runs/20954118794/job/60214406603?pr=498
However, these lines modify the values pointed by the Field given as input.
…rox_derivative_matrix
| template <class DimOut, class DimIn> | ||
| std::vector<Coord<DimOut>> const convert_dim(std::vector<Coord<DimIn>> const& input_vec) | ||
| { |
There was a problem hiding this comment.
Doesn't this function do the same thing as fill_in?
There was a problem hiding this comment.
It is true they are similar 🤔
Actually I use fill_in to fill in the vectors of global coordinates. The idea is more like an .append(). I use it in the test files to fill in the global vectors with values of the different patches.
E.g.
fill_in(global_points, patch1_points);
fill_in(global_points, patch2_points);
fill_in(global_points, patch3_points);Which in python could be equivalent to
global_points = patch1_points
global_points.append(patch2_points)
global_points.append(patch3_points)It also convert the points to from local coordinates to global coordinates.
Do you think I should rename the operator? I choose fill_in with the idea of filling in a bottle of water.
On the other hand, convert_dim cannot be apply to .append() the vectors.
As it directly returns a vector, I use it to avoid to instantiate a vector.
E.g. (see interface_derivative_matrix_Greville_periodic_test.cpp)
// Patch 2 ...............................................................................
ddc::init_discrete_space<BSplinesX<2>>(break_points_x258);
ddc::init_discrete_space<BSplinesY<2>>(convert_dim<Y<2>, Y<1>>(break_points_y123));
ddc::init_discrete_space<GridX<2>>(interpolation_points_x258);
ddc::init_discrete_space<GridY<2>>(convert_dim<Y<2>, Y<1>>(interpolation_points_y123));
// Patch 3 ...............................................................................
ddc::init_discrete_space<BSplinesX<3>>(break_points_x369);
ddc::init_discrete_space<BSplinesY<3>>(convert_dim<Y<3>, Y<1>>(break_points_y123));
ddc::init_discrete_space<GridX<3>>(interpolation_points_x369);
ddc::init_discrete_space<GridY<3>>(convert_dim<Y<3>, Y<1>>(interpolation_points_y123));
// ...| // The patches are conforming between each other. | ||
| std::vector<Coord<X<1>>> break_points_x147 | ||
| = build_random_non_uniform_break_points(x1_min, x1_max, x1_ncells); | ||
| std::vector<Coord<X<2>>> break_points_x258 | ||
| = build_random_non_uniform_break_points(x2_min, x2_max, x2_ncells); | ||
| std::vector<Coord<X<3>>> break_points_x369 | ||
| = build_random_non_uniform_break_points(x3_min, x3_max, x3_ncells); | ||
|
|
||
| std::vector<Coord<Y<1>>> break_points_y123 | ||
| = build_random_non_uniform_break_points(y1_min, y1_max, y1_ncells); | ||
| std::vector<Coord<Y<4>>> break_points_y456 | ||
| = build_random_non_uniform_break_points(y4_min, y4_max, y4_ncells); | ||
| std::vector<Coord<Y<7>>> break_points_y789 | ||
| = build_random_non_uniform_break_points(y7_min, y7_max, y7_ncells); |
There was a problem hiding this comment.
If the patches use similar coordinate systems is it possible to have:
using Patch3 = Patch<GridX<3>, GridY<1>, BSplinesX<3>, BSplinesY<1>>?
There was a problem hiding this comment.
In the source file, there is
// Sequence of 1D grids in the direction of Grid1D over the patches.
using Grid1DSeq = collect_grids_on_dim_t<
find_patch_t<Grid1D, all_patches>,
Grid1D,
interface_sorted_collection>;
I am not sure about the result with all_patches = (Patch1, Patch2, ..., Patch9) and Grid1D = GridY<1>.
Does it work?
Maybe it could work. I am not sure. To be tested.
There was a problem hiding this comment.
I think we should check this at some point
| return get_function_coefficients_with_sign(function_1, function_2, 1); | ||
| } | ||
|
|
||
| /** | ||
| * @brief Get the linear combination of the function values (c). | ||
| * See @ref get_function_coefficients. | ||
| * @param function_1 Function values at the interpolation points on patch 1. | ||
| * @param function_2 Function values at the interpolation points on patch 2. | ||
| * @return the linear combination of the function values (c). | ||
| */ | ||
| template <class Layout1, class Layout2> | ||
| inline double get_function_coefficients( | ||
| DConstField<IdxRange1DPerp_2, Kokkos::HostSpace, Layout2> const& function_2, | ||
| DConstField<IdxRange1DPerp_1, Kokkos::HostSpace, Layout1> const& function_1) const | ||
| { | ||
| return get_function_coefficients_with_sign(function_1, function_2, 1); |
There was a problem hiding this comment.
Why is sign hard-coded to 1 in these 2 functions?
There was a problem hiding this comment.
To get an interface derivatives, I compute
To get an interface cross-derivatives, I compute
The computed derivatives correspond to the derivatives of an equivalent global spline on the two patches.
In the case of cross-derivatives, we have to be careful that the sign of the
For example,
^^^^^^^^|^^^^^^^^
Patch1 Patch2
can be represented by
^^^^^^^^^^^^^^^^
Global
However, we have a problem with
^^^^^^^^|vvvvvvvv
Patch1 Patch2
because GridY1 and GridY2 do not have the same orientation. By flipping the sign of the derivative on Patch2, this correspond to orientate GridY2 to the same orientation of GridY1 and bring us to the situation1 the problem.
Of course, the change of sign is not needed for the computation of the first derivative, because the function values are not oriented.
Tell me if this part is not enough https://github.com/gyselax/gyselalibxx/tree/pvidal_interface_approx_derivative_matrix/src/multipatch/interface_derivatives

There was a problem hiding this comment.
Of course, the change of sign is not needed for the computation of the first derivative, because the function values are not oriented.
Do you mean 0-th derivative?
There was a problem hiding this comment.
The first derivatives are computed from the "0th derivatives" = function values -> no need of sign flip.
The cross-derivatives are computed from the 1rst derivatives -> need to flip sign if the grid orientations desagree.
There was a problem hiding this comment.
Maybe the name of the operator is confusing?
The exact value of the derivative (of a global spline) is
deriv = a x previous_deriv + b x next_deriv + c
with
or
The coefficient c I called it get_function_coefficient in the first case and get_derivatives_coefficient in the second case, because it is a coefficient computed from the function values or the derivatives in the second case.
| using Interface_1_2 = Interface<EastEdge<1>, WestEdge<2>, true>; | ||
| using Interface_2_3 = Interface<EastEdge<2>, SouthEdge<3>, false>; | ||
|
|
||
| using OutsideInterface1 = Interface<OutsideEdge, WestEdge<1>, true>; | ||
| using OutsideInterface3 = Interface<NorthEdge<3>, OutsideEdge, true>; |
There was a problem hiding this comment.
The boolean refers to the orientation of the parallel grid to the interface.
Here,
Reorganise the InterfaceDerivative tests in order to: - reduce code duplication (reduce overall code quantity) - group decisions (i.e. all choices related to a given patch configuration should be found together)
…_matrix_Greville_periodic_test.cpp
…rox_derivative_matrix
|
Is this PR ready for review again? |

Operator to compute the coupled interface derivatives along a direction with the approximation formula.
Waiting for #499, better to wait for #500.
Please complete the checklist to ensure that all tasks are completed before marking your pull request as ready for review.
All Submissions
New Feature Submissions
Changes to Existing Features
Changes to the CI