This example show how to set up a YAC instance. It uses three processes.
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include "tests.h"
#include "test_common.h"
#include "dist_grid_utils.h"
#include "weight_file_common.h"
#include "grid_file_common.h"
static void compute_weights_callback(
double const tgt_coords[3], int src_cell_id, size_t src_cell_idx,
int const ** global_results_points, double ** result_weights,
int main(
int argc,
char** argv) {
MPI_Init(NULL, NULL);
xt_initialize(MPI_COMM_WORLD);
int rank, size;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
if (size != 3) {
PUT_ERR("ERROR: wrong number of processes\n");
return TEST_EXIT_CODE;
}
if (argc != 2) {
PUT_ERR("ERROR: missing config file directory");
xt_finalize();
MPI_Finalize();
return TEST_EXIT_CODE;
}
{
{
char * yaml_filename =
strcat(
strcpy(
malloc(strlen(argv[1]) + 32), argv[1]), "instance_test_1_1.yaml");
free(yaml_filename);
}
{
char const * component_names[2] = {"comp_1", "comp_2"};
instance, &(component_names[rank >> 1]), 1);
size_t num_vertices[2] = {2,2};
int cyclic[2] = {0,0};
double coordinates_x[3][2] = {{0,1},{1,2},{0.5,1.5}};
double coordinates_y[3][2] = {{0,1},{0,1},{0,1}};
yac_int global_cell_ids [3][1] = {{0},{1},{0}};
yac_int global_corner_ids[3][4] = {{0,1,3,4},{1,2,4,5},{0,1,2,3}};
int cell_core_mask[1] = {1};
num_vertices, cyclic, coordinates_x[rank], coordinates_y[rank]);
grid_data.
cell_ids = TO_POINTER(global_cell_ids[rank]);
grid_data.
vertex_ids = TO_POINTER(global_corner_ids[rank]);
char * grid_name[2] = {"grid1", "grid2"};
interp_fields[0].coordinates_idx = SIZE_MAX;
interp_fields[0].masks_idx = SIZE_MAX;
instance, "field_1", component_names[rank >> 1], grid,
interp_fields, 1, collection_size, timestep_iso8601);
char * yaml_filename =
strcat(
strcpy(
malloc(strlen(argv[1]) + 32), argv[1]), "instance_test_1_1.yaml");
char const * grid_filename = "instance_test_1_1_grid2.nc";
free(yaml_filename);
MPI_Barrier(MPI_COMM_WORLD);
if (rank == 0) {
unlink("comp_1.err");
unlink("comp_2.err");
unlink("comp_1.log");
unlink("comp_2.log");
check_grid_file(
grid_filename, "grid2", 1, 4,
(double[]){0,0,1,1}, (double[]){0.5,1.5,1.5,0.5}, NULL, NULL,
(
yac_int[]){0}, (
int[]){1}, NULL, NULL, NULL, NULL);
unlink(grid_filename);
}
MPI_Barrier(MPI_COMM_WORLD);
}
}
{
{
char const * component_names[3] = {"comp_1", "comp_2", "comp_3"};
instance, &(component_names[rank]), 1);
size_t num_vertices[2] = {2,2};
int cyclic[2] = {0,0};
double coordinates_x[2] = {0,1};
double coordinates_y[2] = {0,1};
yac_int global_corner_ids[4] = {0,1,2,3};
int cell_core_mask[1] = {1};
grid_data.
cell_ids = TO_POINTER(global_cell_ids);
grid_data.
vertex_ids = TO_POINTER(global_corner_ids);
char * grid_name[3] = {"grid1", "grid2", "grid3"};
interp_fields[0].coordinates_idx = SIZE_MAX;
interp_fields[0].masks_idx = SIZE_MAX;
char * field_name[3] = {"field_1", "field_2", "field_3"};
instance, field_name[rank], component_names[0], grid,
interp_fields, 1, collection_size, timestep_iso8601);
instance, field_name[(rank + 2) % 3], component_names[rank], grid,
interp_fields, 1, collection_size, timestep_iso8601);
char * yaml_filename =
strcat(
strcpy(
malloc(strlen(argv[1]) + 32), argv[1]), "instance_test_1_2.yaml");
free(yaml_filename);
}
}
{
{
char const * component_names[3] = {"comp_1", "comp_2", "comp_3"};
instance, &(component_names[rank]), 1);
size_t num_vertices[2] = {2,2};
int cyclic[2] = {0,0};
double coordinates_x[2] = {0,1};
double coordinates_y[2] = {0,1};
yac_int global_corner_ids[4] = {0,1,2,3};
int cell_core_mask[1] = {1};
grid_data.
cell_ids = TO_POINTER(global_cell_ids);
grid_data.
vertex_ids = TO_POINTER(global_corner_ids);
char * grid_name[3] = {"grid1", "grid2", "grid3"};
interp_fields[0].coordinates_idx = SIZE_MAX;
interp_fields[0].masks_idx = SIZE_MAX;
char * field_name[6] = {"field_1", "field_2", "field_3",
"field_4", "field_5", "field_6"};
instance, field_name[rank], component_names[rank], grid,
interp_fields, 1, collection_size, timestep_iso8601);
instance, field_name[(rank + 2) % 3], component_names[rank], grid,
interp_fields, 1, collection_size, timestep_iso8601);
instance, field_name[rank + 3], component_names[rank], grid,
interp_fields, 1, collection_size, timestep_iso8601);
instance, field_name[((rank + 2) % 3) + 3], component_names[rank], grid,
interp_fields, 1, collection_size, timestep_iso8601);
char * yaml_filename =
strcat(
strcpy(
malloc(strlen(argv[1]) + 32), argv[1]), "instance_test_1_3.yaml");
free(yaml_filename);
}
}
{
{
char const * component_names[3] = {"comp_1", "comp_2", "comp_3"};
instance, &(component_names[rank]), 1);
size_t num_vertices[2] = {2,2};
int cyclic[2] = {0,0};
double coordinates_x[2] = {0,1};
double coordinates_y[2] = {0,1};
yac_int global_corner_ids[4] = {0,1,2,3};
int cell_core_mask[1] = {1};
grid_data.
cell_ids = TO_POINTER(global_cell_ids);
grid_data.
vertex_ids = TO_POINTER(global_corner_ids);
char * grid_name[3] = {"grid1", "grid2", "grid3"};
interp_fields[0].coordinates_idx = SIZE_MAX;
interp_fields[0].masks_idx = SIZE_MAX;
instance, "field_1", component_names[rank], grid,
interp_fields, 1, collection_size, timestep_iso8601);
char * yaml_filename =
strcat(
strcpy(
malloc(strlen(argv[1]) + 32), argv[1]), "instance_test_1_4.yaml");
free(yaml_filename);
}
}
{
{
char const * component_names[3] = {"comp_1", "comp_2", "comp_3"};
instance, &(component_names[rank]), 1);
size_t num_vertices[2] = {5,5};
int cyclic[2] = {0,0};
double coordinates_x[5] = {0,1,2,3,4};
double coordinates_y[5] = {0,1,2,3,4};
char * grid_name[3] = {"grid1", "grid2", "grid3"};
interp_fields[0].coordinates_idx = SIZE_MAX;
interp_fields[0].masks_idx = SIZE_MAX;
instance, "field_1", component_names[rank], grid,
interp_fields, 1, collection_size, timestep_iso8601);
char * yaml_filename =
strcat(
strcpy(
malloc(strlen(argv[1]) + 32), argv[1]), "instance_test_1_5.yaml");
free(yaml_filename);
}
}
{
{
char const * component_names[2] = {"comp_1", "comp_2"};
instance, &(component_names[rank >> 1]), 1);
size_t num_vertices[2] = {2,2};
int cyclic[2] = {0,0};
double coordinates_x[3][2] = {{0,1},{1,2},{0.5,1.5}};
double coordinates_y[3][2] = {{0,1},{0,1},{0,1}};
yac_int global_cell_ids [3][1] = {{0},{1},{0}};
yac_int global_corner_ids[3][4] = {{0,1,3,4},{1,2,4,5},{0,1,2,3}};
int cell_core_mask[1] = {1};
num_vertices, cyclic, coordinates_x[rank], coordinates_y[rank]);
grid_data.
cell_ids = TO_POINTER(global_cell_ids[rank]);
grid_data.
vertex_ids = TO_POINTER(global_corner_ids[rank]);
char * grid_name[2] = {"grid1", "grid2"};
interp_fields[0].coordinates_idx = SIZE_MAX;
interp_fields[0].masks_idx = SIZE_MAX;
char * weight_file_name = "test_instance_parallel1_weight_file.nc";
if (rank == 0) unlink(weight_file_name);
instance, "field_1", component_names[rank >> 1], grid,
interp_fields, 1, collection_size, timestep_iso8601);
char * yaml_filename =
strcat(
strcpy(
malloc(strlen(argv[1]) + 32), argv[1]), "instance_test_1_6.yaml");
free(yaml_filename);
MPI_Barrier(MPI_COMM_WORLD);
if (rank == 0) {
if (access(weight_file_name, F_OK ) == -1)
PUT_ERR("weight file is missing\n");
unlink(weight_file_name);
}
}
}
{
{
char const * component_names[2] = {"comp_1", "comp_2"};
instance, &(component_names[rank >> 1]), 1);
size_t num_vertices[2] = {2,2};
int cyclic[2] = {0,0};
double coordinates_x[3][2] = {{0,1},{1,2},{0.5,1.5}};
double coordinates_y[3][2] = {{0,1},{0,1},{0,1}};
yac_int global_cell_ids [3][1] = {{0},{1},{0}};
yac_int global_corner_ids[3][4] = {{0,1,3,4},{1,2,4,5},{0,1,2,3}};
int cell_core_mask[1] = {1};
num_vertices, cyclic, coordinates_x[rank], coordinates_y[rank]);
grid_data.
cell_ids = TO_POINTER(global_cell_ids[rank]);
grid_data.
vertex_ids = TO_POINTER(global_corner_ids[rank]);
char * grid_name[2] = {"grid1", "grid2"};
interp_fields[0].coordinates_idx = SIZE_MAX;
interp_fields[0].masks_idx = SIZE_MAX;
char * field_name[3] = {"field_1", "field_2", "field_3"};
char * weight_file_name[3] =
{NULL, "test_instance_parallel1_weight_file_1.nc",
"test_instance_parallel1_weight_file_2.nc"};
char * yaml_filename =
strcat(
strcpy(
malloc(strlen(argv[1]) + 32), argv[1]), "instance_test_1_7.yaml");
free(yaml_filename);
for (unsigned i = 0; i < 3; ++i) {
if ((rank == 0) && (weight_file_name[i] != NULL))
unlink(weight_file_name[i]);
instance, field_name[i], component_names[rank >> 1], grid,
interp_fields, 1, collection_size, timestep_iso8601);
}
MPI_Barrier(MPI_COMM_WORLD);
if (rank == 0) {
for (unsigned i = 0; i < 3; ++i) {
if (weight_file_name[i] == NULL) continue;
if (access(weight_file_name[i], F_OK ) == -1)
PUT_ERR("weight file is missing\n");
unlink(weight_file_name[i]);
}
}
}
}
{
{
char const * component_names[1] = {"comp_1"};
size_t num_vertices[2] = {2,2};
int cyclic[2] = {0,0};
double coordinates_x[3][2] = {{0,1},{1,2},{2,3}};
double coordinates_y[3][2] = {{0,1},{0,1},{0,1}};
yac_int global_cell_ids [3][1] = {{0},{1},{2}};
yac_int global_corner_ids[3][4] = {{0,1,4,5},{1,2,5,6},{2,3,6,7}};
int cell_core_mask[1] = {1};
num_vertices, cyclic, coordinates_x[rank], coordinates_y[rank]);
grid_data.
cell_ids = TO_POINTER(global_cell_ids[rank]);
grid_data.
vertex_ids = TO_POINTER(global_corner_ids[rank]);
char * grid_name[1] = {"grid1"};
interp_fields[0].coordinates_idx = SIZE_MAX;
interp_fields[0].masks_idx = SIZE_MAX;
char * field_name[3] = {"field_1", "field_2", "field_3"};
for (unsigned i = 0; i < 3; ++i)
instance, field_name[i], component_names[0], grid,
interp_fields, 1, collection_size, timestep_iso8601);
char * yaml_filename =
strcat(
strcpy(
malloc(strlen(argv[1]) + 32), argv[1]), "instance_test_1_8.yaml");
free(yaml_filename);
}
}
{
{
int comp_idx = rank >> 1;
char const * component_names[2] = {"comp_1", "comp_2"};
instance, &(component_names[comp_idx]), 1);
double coordinates_x[5] = {0.0,1.0,2.0,3.0,4.0};
double coordinates_y[5] = {0.0,1.0,2.0,3.0,4.0};
size_t const num_cells[2] = {4,4};
size_t local_start[3][2] = {{0,0},{2,0}, {0,0}};
size_t local_count[3][2] = {{2,4},{2,4}, {4,4}};
int with_halo = 0;
for (
size_t i = 0; i < 5; ++i) coordinates_x[i] *=
YAC_RAD;
for (
size_t i = 0; i < 5; ++i) coordinates_y[i] *=
YAC_RAD;
yac_generate_basic_grid_data_reg2d(
local_start[rank], local_count[rank], with_halo);
char * grid_name[2] = {"grid1", "grid2"};
for (
size_t i = 0; i < grid_data.
num_cells; ++i) {
for (size_t j = 0; j < 3; ++j) cell_middle_points[i][j] = 0.0;
for (size_t k = 0; k < 3; ++k)
cell_middle_points[i][k] +=
}
interp_fields[0].coordinates_idx = SIZE_MAX;
interp_fields[0].masks_idx = SIZE_MAX;
interp_fields[1].coordinates_idx =
interp_fields[1].masks_idx = SIZE_MAX;
free(cell_middle_points);
char const * weight_file_name = "instance_test_1_9.nc";
if (rank == 0) {
int src_indices[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
int tgt_indices[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
double weights[] = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15};
size_t num_links = 16;
unsigned num_src_fields = 1;
int num_links_per_field[1] = {num_links};
int * tgt_id_fixed = NULL;
size_t num_fixed_tgt = 0;
double * fixed_values = NULL;
int * num_tgt_per_fixed_value = NULL;
size_t num_fixed_values = 0;
write_weight_file(
weight_file_name, src_indices, tgt_indices, weights, num_links,
src_locations, num_src_fields, num_links_per_field, tgt_id_fixed,
num_fixed_tgt, fixed_values, num_tgt_per_fixed_value,
num_fixed_values, tgt_location, grid_name[0], grid_name[1]);
}
if (comp_idx == 0)
compute_weights_callback, NULL, "compute_weights_callback");
char * field_name[] = {"AVG_ARITHMETIC",
"AVG_DIST",
"AVG_BARY",
"4NN_ARITHMETIC",
"4NN_DIST",
"4NN_GAUSS",
"HCSBB",
"RBF_4_GAUSS",
"FIXED",
"SPMAP",
"CONSERV_FRACAREA",
"CONSERV_DESTAREA",
"CONSERV2ND",
"USER_FILE",
"CREEP",
"USER_CALLBACK"};
size_t const field_count = 16;
for (size_t i = 0; i < 9; ++i)
instance, field_name[i], component_names[comp_idx], grid,
&(interp_fields[0]), 1, collection_size, timestep_iso8601);
for (size_t i = 9; i < 15; ++i)
instance, field_name[i], component_names[comp_idx], grid,
&(interp_fields[1]), 1, collection_size, timestep_iso8601);
if (comp_idx == 0) {
for (size_t i = 15; i < field_count; ++i)
instance, field_name[i], component_names[comp_idx], grid,
&(interp_fields[0]), 2, collection_size, timestep_iso8601);
} else {
for (size_t i = 15; i < field_count; ++i)
instance, field_name[i], component_names[comp_idx], grid,
&(interp_fields[0]), 1, collection_size, timestep_iso8601);
}
char * yaml_filename =
strcat(
strcpy(
malloc(strlen(argv[1]) + 32), argv[1]), "instance_test_1_9.yaml");
free(yaml_filename);
if (rank == 0) unlink(weight_file_name);
}
}
{
{
size_t num_vertices[2] = {2,2};
int cyclic[2] = {0,0};
double coordinates_x[3][2] = {{0,1},{1,2},{0.5,1.5}};
double coordinates_y[3][2] = {{0,1},{0,1},{0,1}};
yac_int global_cell_ids [3][1] = {{0},{1},{0}};
yac_int global_corner_ids[3][4] = {{0,1,3,4},{1,2,4,5},{0,1,2,3}};
int cell_core_mask[1] = {1};
num_vertices, cyclic, coordinates_x[rank], coordinates_y[rank]);
grid_data.
cell_ids = TO_POINTER(global_cell_ids[rank]);
grid_data.
vertex_ids = TO_POINTER(global_corner_ids[rank]);
char * grid_name[2] = {"grid1", "grid2"};
for (int i = 0; i < 2; ++i) {
char const * component_names[2] = {"comp_1", "comp_2"};
instance, &(component_names[rank >> 1]), 1);
if ((rank >> 1) == i) {
interp_fields[0].coordinates_idx = SIZE_MAX;
interp_fields[0].masks_idx = SIZE_MAX;
instance, "field", component_names[rank >> 1], grid,
interp_fields, 1, collection_size, timestep_iso8601);
}
char * yaml_filename =
strcat(
strcpy(
malloc(strlen(argv[1]) + 32), argv[1]), "instance_test_1_10.yaml");
free(yaml_filename);
}
}
}
xt_finalize();
MPI_Finalize();
return TEST_EXIT_CODE;
}
static void compute_weights_callback(
double const tgt_coords[3], int src_cell_id, size_t src_cell_idx,
int const ** global_results_points, double ** result_weights,
for (size_t i = 0; i < 2; ++i) {
global_results_points[i] = NULL;
result_weights[i] = NULL;
result_count[i] = 0;
}
}
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(struct yac_basic_grid *grid, enum yac_location location, yac_coordinate_pointer coordinates, size_t count)
void yac_basic_grid_delete(struct yac_basic_grid *grid)
struct yac_basic_grid_data yac_generate_basic_grid_data_reg_2d_deg(size_t nbr_vertices[2], int cyclic[2], double *lon_vertices, double *lat_vertices)
void yac_yaml_read_coupling(struct yac_couple_config *couple_config, const char *yaml_filename, int parse_flags)
int const YAC_YAML_PARSER_DEFAULT
default parse flags (YAML format)
char const * yac_time_to_ISO(char const *time, enum yac_time_unit_type time_unit)
void yac_couple_config_grid_set_output_filename(struct yac_couple_config *couple_config, char const *grid_name, const char *output_filename)
struct yac_couple_config * yac_couple_config_new()
int main(int argc, char **argv)
static void normalise_vector(double v[])
void yac_instance_delete(struct yac_instance *instance)
void yac_instance_setup(struct yac_instance *instance, struct yac_basic_grid **grids, size_t num_grids)
struct yac_instance * yac_instance_new(MPI_Comm comm)
struct coupling_field * yac_instance_add_field(struct yac_instance *instance, char const *field_name, char const *comp_name, struct yac_basic_grid *grid, struct yac_interp_field *interp_fields, size_t num_interp_fields, int collection_size, char const *timestep)
void yac_instance_set_couple_config(struct yac_instance *instance, struct yac_couple_config *couple_config)
void yac_instance_def_components(struct yac_instance *instance, char const **comp_names, size_t num_comps)
struct yac_couple_config * yac_instance_get_couple_config(struct yac_instance *instance)
yac_coordinate_pointer vertex_coordinates
size_t * cell_to_vertex_offsets
int * num_vertices_per_cell
enum yac_location location
void yac_cadd_compute_weights_callback(yac_func_compute_weights compute_weights_callback, void *user_data, char const *key)
void yac_cdef_calendar(int calendar)
int const YAC_PROLEPTIC_GREGORIAN
double(* yac_coordinate_pointer)[3]