A test for the parallel radial basis function 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 target_comm);
static void source_main(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 != 2) {
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(split_comm);
else source_main(split_comm);
MPI_Comm_free(&split_comm);
xt_finalize();
MPI_Finalize();
return TEST_EXIT_CODE;
}
static void source_main(MPI_Comm source_comm) {
int my_source_rank;
MPI_Comm_rank(source_comm, &my_source_rank);
double coordinates_x[] = {-2.0, -1.0, 0.0, 1.0, 2.0};
double coordinates_y[] = {-2.0, -1.0, 0.0, 1.0, 2.0};
size_t const num_cells[2] = {4,4};
size_t local_start[2] = {0,0};
size_t local_count[2] = {4,4};
int with_halo = 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, local_count, with_halo);
size_t num_src_fields = sizeof(src_fields) / sizeof(src_fields[0]);
NULL};
for (size_t i = 0; i < 2; ++i) {
{
double ref_src_data[25] = {0,1,2,3,4,
1,2,3,4,5,
2,3,4,5,6,
3,4,5,6,7,
4,5,6,7,8};
++collection_idx) {
src_data[collection_idx] =
xmalloc(1 *
sizeof(**src_data));
src_data[collection_idx][0] =
src_data[collection_idx][0][i] =
ref_src_data[i] + (double)(collection_idx * 9);
}
++collection_idx) {
free(src_data[collection_idx][0]);
free(src_data[collection_idx]);
}
free(src_data);
}
}
}
}
static void target_main(MPI_Comm target_comm) {
double coordinates_x[] = {-1.5,-0.5,0.5,1.5};
double coordinates_y[] = {-1.5,-0.5,0.5,1.5};
double cell_coordinates_x[] = {-1.0,0.0,1.0};
double cell_coordinates_y[] = {-1.0,0.0,1.0};
size_t const num_cells[2] = {3,3};
size_t local_start[2] = {0,0};
size_t local_count[2] = {3,3};
int with_halo = 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;
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);
size_t num_src_fields = sizeof(src_fields) / sizeof(src_fields[0]);
NULL};
for (size_t i = 0; i < 2; ++i) {
{
double ref_tgt_field[9] = {2,3,4, 3,4,5, 4,5,6};
++collection_idx) {
tgt_data[collection_idx] =
for (size_t j = 0; j < 9; ++j) tgt_data[collection_idx][j] = -1.0;
}
++collection_idx)
for (size_t j = 0, offset = collection_idx * 9;
if (fabs((ref_tgt_field[j] + (double)offset) -
tgt_data[collection_idx][j]) > 1e-3)
PUT_ERR("wrong interpolation result");
++collection_idx)
free(tgt_data[collection_idx]);
free(tgt_data);
}
}
}
}
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)
int main(int argc, char **argv)
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_RBF
radial basis functions
#define YAC_INTERP_RBF_MAX_SEARCH_DISTANCE_DEFAULT
#define YAC_INTERP_RBF_SCALE_DEFAULT
void yac_interp_weights_delete(struct yac_interp_weights *weights)
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, char const *yaxt_exchanger_name)
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[]
struct yac_basic_grid ** grids
double(* yac_coordinate_pointer)[3]