A test for the parallel nearest neighbour interpolation method.
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "tests.h"
#include "dist_grid_utils.h"
#include <mpi.h>
#include <yaxt.h>
#include <netcdf.h>
char const src_grid_name[] = "src_grid";
char const tgt_grid_name[] = "tgt_grid";
static void target_main(MPI_Comm global_comm, MPI_Comm target_comm);
static void source_main(MPI_Comm global_comm, MPI_Comm source_comm);
MPI_Init(NULL, NULL);
xt_initialize(MPI_COMM_WORLD);
int comm_rank, comm_size;
MPI_Comm_rank(MPI_COMM_WORLD, &comm_rank);
MPI_Comm_size(MPI_COMM_WORLD, &comm_size);
MPI_Barrier(MPI_COMM_WORLD);
if (comm_size != 5) {
PUT_ERR("ERROR: wrong number of processes");
xt_finalize();
MPI_Finalize();
return TEST_EXIT_CODE;
}
int tgt_flag = comm_rank < 1;
MPI_Comm split_comm;
MPI_Comm_split(MPI_COMM_WORLD, tgt_flag, 0, &split_comm);
if (tgt_flag) target_main(MPI_COMM_WORLD, split_comm);
else source_main(MPI_COMM_WORLD, split_comm);
MPI_Comm_free(&split_comm);
xt_finalize();
MPI_Finalize();
return TEST_EXIT_CODE;
}
static void source_main(MPI_Comm global_comm,
MPI_Comm source_comm) {
int my_source_rank;
MPI_Comm_rank(source_comm, &my_source_rank);
double coordinates_x[] = {0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0};
double coordinates_y[] = {0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0};
size_t const num_cells[2] = {7,7};
size_t local_start[4][2] = {{0,0},{0,2},{3,2},{0,5}};
size_t local_count[4][2] = {{7,2},{3,3},{4,3},{7,2}};
int with_halo = 0;
int global_corner_mask[8][8] = {
{1,1,0,0,0,0,1,1},
{1,0,0,0,0,0,0,1},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{0,0,0,0,0,0,0,0},
{1,1,0,0,0,0,0,0},
{1,1,0,0,0,0,0,0}};
for (
size_t i = 0; i <= num_cells[0]; ++i) coordinates_x[i] *=
YAC_RAD;
for (
size_t i = 0; i <= num_cells[1]; ++i) coordinates_y[i] *=
YAC_RAD;
yac_generate_basic_grid_data_reg2d(
local_start[my_source_rank], local_count[my_source_rank], with_halo);
int * src_corner_mask =
src_corner_mask[i] =
((
int*)(&(global_corner_mask[0][0])))[grid_data.
vertex_ids[i]];
size_t num_src_fields = sizeof(src_fields) / sizeof(src_fields[0]);
for (size_t i = 0; i < 2; ++i) {
{
double * src_field = NULL;
double ** src_fields = &src_field;
free(src_field);
}
}
}
static void target_main(MPI_Comm global_comm,
MPI_Comm target_comm) {
double coordinates_x[] = {0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0};
double coordinates_y[] = {0.0,1.0,2.0,3.0,4.0,5.0,6.0,7.0};
double cell_coordinates_x[] = {0.75,1.75,2.75,3.75,4.75,5.75,6.75};
double cell_coordinates_y[] = {0.75,1.75,2.75,3.75,4.75,5.75,6.75};
size_t const num_cells[2] = {7,7};
size_t local_start[2] = {0,0};
size_t local_count[2] = {7,7};
int with_halo = 0;
int global_cell_mask[7][7] = {
{1,1,1,1,1,1,1},
{1,1,1,1,1,1,1},
{1,1,0,0,0,1,1},
{1,1,0,0,0,1,1},
{1,1,0,0,0,1,1},
{1,1,1,1,1,1,1},
{1,1,1,1,1,1,1}};
for (
size_t i = 0; i <= num_cells[0]; ++i) coordinates_x[i] *=
YAC_RAD;
for (
size_t i = 0; i <= num_cells[1]; ++i) coordinates_y[i] *=
YAC_RAD;
for (size_t i = 0, k = 0; i < num_cells[1]; ++i)
for (size_t j = 0; j < num_cells[0]; ++j, ++k)
cell_coordinates_x[j], cell_coordinates_y[i], cell_coordinates[k]);
yac_generate_basic_grid_data_reg2d(
local_start, local_count, with_halo);
int * tgt_cell_mask =
for (
size_t i = 0; i < grid_data.
num_cells; ++i)
tgt_cell_mask[i] =
((
int*)(&(global_cell_mask[0][0])))[grid_data.
cell_ids[i]];
size_t num_src_fields = sizeof(src_fields) / sizeof(src_fields[0]);
for (size_t i = 0; i < 2; ++i) {
{
double * tgt_field = NULL;
double ref_tgt_field[49] =
{(0+1+8+49)/4.0,(0+1+8+6)/4.0,(0+1+8+6)/4.0,(1+6+7+15)/4.0,
(1+6+7+15)/4.0,(1+6+7+15)/4.0,(1+6+7+15)/4.0,
(0+1+8+49)/4.0,(0+1+8+49)/4.0,(0+1+8+6)/4.0,(1+6+7+15)/4.0,
(1+6+7+15)/4.0,(1+6+7+15)/4.0,(1+6+7+15)/4.0,
(8+1+0+49)/4.0,(8+1+0+49)/4.0,-1,-1,
-1,(1+6+7+15)/4.0,(1+6+7+15)/4.0,
(48+49+8+57)/4.0,(48+49+8+57)/4.0,-1,-1,
-1,(6+7+15+49)/4.0,(6+7+15+49)/4.0,
(48+49+56+57)/4.0,(48+49+56+57)/4.0,-1,-1,
-1,(6+7+15+49)/4.0,(6+7+15+49)/4.0,
(48+49+56+57)/4.0,(48+49+56+57)/4.0,(48+49+56+57)/4.0,(48+49+56+57)/4.0,
(48+49+56+57)/4.0,(48+49+15+57)/4.0,(6+7+15+49)/4.0,
(48+49+56+57)/4.0,(48+49+56+57)/4.0,(48+49+56+57)/4.0,(48+49+56+57)/4.0,
(48+49+56+57)/4.0,(48+49+56+57)/4.0,(49+57+56+15)/4.0};
for (
size_t j = 0; j < grid_data.
num_cells; ++j) tgt_field[j] = -1.0;
for (
size_t j = 0; j < grid_data.
num_cells; ++j)
if (fabs(ref_tgt_field[j] - tgt_field[j]) > 1e-9)
PUT_ERR("wrong interpolation result");
free(tgt_field);
}
}
}
struct yac_basic_grid * yac_basic_grid_new(char const *name, struct yac_basic_grid_data grid_data)
size_t yac_basic_grid_add_coordinates_nocpy(struct yac_basic_grid *grid, enum yac_location location, yac_coordinate_pointer coordinates)
struct yac_basic_grid * yac_basic_grid_empty_new(char const *name)
void yac_basic_grid_delete(struct yac_basic_grid *grid)
size_t yac_basic_grid_add_mask_nocpy(struct yac_basic_grid *grid, enum yac_location location, int const *mask, char const *mask_name)
void yac_dist_grid_pair_delete(struct yac_dist_grid_pair *grid_pair)
struct yac_dist_grid_pair * yac_dist_grid_pair_new(struct yac_basic_grid *grid_a, struct yac_basic_grid *grid_b, MPI_Comm comm)
static void LLtoXYZ_deg(double lon, double lat, double p_out[])
void yac_interp_grid_delete(struct yac_interp_grid *interp_grid)
struct yac_interp_grid * yac_interp_grid_new(struct yac_dist_grid_pair *grid_pair, char const *src_grid_name, char const *tgt_grid_name, size_t num_src_fields, struct yac_interp_field const *src_fields, struct yac_interp_field const tgt_field)
void yac_interp_method_delete(struct interp_method **method)
struct yac_interp_weights * yac_interp_method_do_search(struct interp_method **method, struct yac_interp_grid *interp_grid)
struct interp_method * yac_interp_method_nnn_new(struct yac_nnn_config config)
@ YAC_INTERP_NNN_AVG
average of n source points
struct yac_interpolation * yac_interp_weights_get_interpolation(struct yac_interp_weights *weights, enum yac_interp_weights_reorder_type reorder, size_t collection_size, double frac_mask_fallback_value, double scaling_factor, double scaling_summand)
void yac_interp_weights_delete(struct yac_interp_weights *weights)
yac_interp_weights_reorder_type
@ YAC_MAPPING_ON_TGT
weights will be applied at target processes
@ YAC_MAPPING_ON_SRC
weights will be appied at source processes
void yac_interpolation_execute(struct yac_interpolation *interp, double ***src_fields, double **tgt_field)
void yac_interpolation_delete(struct yac_interpolation *interp)
double const YAC_FRAC_MASK_NO_VALUE
enum yac_location location
struct yac_interp_field tgt_field
struct yac_dist_grid_pair * grid_pair
struct yac_interp_field src_fields[]
int main(int argc, char **argv)
double(* yac_coordinate_pointer)[3]