YAC 3.12.0
Yet Another Coupler
Loading...
Searching...
No Matches
dist_grid_utils.c
Go to the documentation of this file.
1// Copyright (c) 2024 The YAC Authors
2//
3// SPDX-License-Identifier: BSD-3-Clause
4
5#ifdef HAVE_CONFIG_H
6// Get the definition of the 'restrict' keyword.
7#include "config.h"
8#endif
9
10#include <stdlib.h>
11#include <string.h>
12
13#include "dist_grid_utils.h"
14#include "ppm/ppm_xfuncs.h"
15#include "geometry.h"
16
19 size_t idx;
20 int mask;
21 double coord[3];
22};
23
24struct temp_edge {
26 size_t idx;
27 int mask;
30};
31
34};
35
36struct temp_cell {
38 int mask;
41};
42
44 size_t num_global_cells, struct temp_cell * global_cells,
45 size_t num_global_vertices, struct temp_corner * global_vertices,
46 size_t num_global_edges, struct temp_edge * global_edges,
47 size_t num_local_cells, size_t * local_cell_indices, int with_halo) {
48
49 for (size_t i = 0; i < num_global_cells; ++i) global_cells[i].mask = 2;
50 for (size_t i = 0; i < num_global_vertices; ++i) global_vertices[i].mask = 2;
51 for (size_t i = 0; i < num_global_edges; ++i) global_edges[i].mask = 2;
52
53 for (size_t i = 0; i < num_local_cells; ++i) {
54 struct temp_cell * curr_cell = global_cells + local_cell_indices[i];
55 curr_cell->mask = 1;
56 for (size_t j = 0; j < curr_cell->num_corners; ++j) {
57 global_vertices[curr_cell->data[j].corner_idx].mask = 1;
58 global_edges[curr_cell->data[j].edge_idx].mask = 1;
59 }
60 }
61
62 if (with_halo) {
63 for (size_t i = 0; i < num_global_cells; ++i) {
64 if (global_cells[i].mask == 1) continue;
65 int mask_flag = 0;
66 for (size_t j = 0; j < global_cells[i].num_corners; ++j)
67 if (global_vertices[global_cells[i].data[j].corner_idx].mask == 1)
68 mask_flag = 1;
69 if (mask_flag) {
70 global_cells[i].mask = 0;
71 for (size_t j = 0; j < global_cells[i].num_corners; ++j) {
72 if (global_vertices[global_cells[i].data[j].corner_idx].mask == 2)
73 global_vertices[global_cells[i].data[j].corner_idx].mask = 0;
74 if (global_edges[global_cells[i].data[j].edge_idx].mask == 2)
75 global_edges[global_cells[i].data[j].edge_idx].mask = 0;
76 }
77 }
78 }
79 }
80
81 size_t num_cells = 0;
82 size_t num_vertices = 0;
83 size_t num_edges = 0;
84 size_t num_vertices_per_cell_sum = 0;
85
86 for (size_t i = 0; i < num_global_cells; ++i) {
87 if (global_cells[i].mask != 2) {
88 ++num_cells;
89 num_vertices_per_cell_sum += global_cells[i].num_corners;
90 }
91 }
92 for (size_t i = 0; i < num_global_vertices; ++i)
93 if (global_vertices[i].mask != 2) ++num_vertices;
94 for (size_t i = 0; i < num_global_edges; ++i)
95 if (global_edges[i].mask != 2) ++num_edges;
96
97 yac_coordinate_pointer vertex_coordinates =
98 xmalloc(num_vertices * sizeof(*vertex_coordinates));
99 yac_int * cell_ids = xmalloc(num_cells * sizeof(*cell_ids));
100 yac_int * vertex_ids = xmalloc(num_vertices * sizeof(*vertex_ids));
101 yac_int * edge_ids = xmalloc(num_edges * sizeof(*edge_ids));
102 int * core_cell_mask = xmalloc(num_cells * sizeof(*core_cell_mask));
103 int * core_vertex_mask = xmalloc(num_vertices * sizeof(*core_vertex_mask));
104 int * core_edge_mask = xmalloc(num_edges * sizeof(*core_edge_mask));
105 int * num_vertices_per_cell = xmalloc(num_cells * sizeof(*num_vertices_per_cell));
106 int * num_cells_per_vertex = xcalloc(num_vertices, sizeof(*num_cells_per_vertex));
107 size_t * cell_to_vertex = xmalloc(num_vertices_per_cell_sum * sizeof(*cell_to_vertex));
108 size_t * cell_to_vertex_offsets = xmalloc(num_cells * sizeof(*cell_to_vertex_offsets));
109 size_t * cell_to_edge = xmalloc(num_vertices_per_cell_sum * sizeof(*cell_to_edge));;
110 size_t * cell_to_edge_offsets = cell_to_vertex_offsets;
111 size_t * vertex_to_cell = xmalloc(num_vertices_per_cell_sum * sizeof(*vertex_to_cell));
112 size_t * vertex_to_cell_offsets = xmalloc((num_vertices+1) * sizeof(*vertex_to_cell_offsets));
113 yac_size_t_2_pointer edge_to_vertex = xmalloc(num_edges * sizeof(*edge_to_vertex));
114 enum yac_edge_type * edge_type = xmalloc(num_edges * sizeof(*edge_type));
115
116 for (size_t i = 0, j = 0; i < num_global_vertices; ++i) {
117 if (global_vertices[i].mask != 2) {
118 global_vertices[i].idx = j;
119 for (int k = 0; k < 3; ++k)
120 vertex_coordinates[j][k] = global_vertices[i].coord[k];
121 vertex_ids[j] = global_vertices[i].id;
122 core_vertex_mask[j] = global_vertices[i].mask;
123 ++j;
124 }
125 }
126 for (size_t i = 0, j = 0; i < num_global_edges; ++i) {
127 if (global_edges[i].mask != 2) {
128 global_edges[i].idx = j;
129 edge_ids[j] = global_edges[i].id;
130 core_edge_mask[j] = global_edges[i].mask;
131 edge_type[j] = global_edges[i].type;
132 edge_to_vertex[j][0] = global_vertices[global_edges[i].vertex_idx[0]].idx;
133 edge_to_vertex[j][1] = global_vertices[global_edges[i].vertex_idx[1]].idx;
134 ++j;
135 }
136 }
137 for (size_t i = 0, j = 0, l = 0; i < num_global_cells; ++i) {
138 if (global_cells[i].mask != 2) {
139 cell_ids[j] = global_cells[i].id;
140 core_cell_mask[j] = global_cells[i].mask;
141 size_t num_corners = global_cells[i].num_corners;
142 num_vertices_per_cell[j] = num_corners;
143 for (size_t k = 0; k < num_corners; ++k, ++l) {
144 cell_to_vertex[l] =
145 global_vertices[global_cells[i].data[k].corner_idx].idx;
146 cell_to_edge[l] =
147 global_edges[global_cells[i].data[k].edge_idx].idx;
148 }
149 ++j;
150 }
151 }
152
153 for (size_t i = 0, k = 0; i < num_cells; ++i)
154 for (int j = 0; j < num_vertices_per_cell[i]; ++j, ++k)
155 num_cells_per_vertex[cell_to_vertex[k]]++;
156
157 for (size_t i = 0, accu = 0; i < num_cells; ++i) {
158 cell_to_vertex_offsets[i] = accu;
159 accu += num_vertices_per_cell[i];
160 }
161
162 vertex_to_cell_offsets[0] = 0;
163 for (size_t i = 0, accu = 0; i < num_vertices; ++i) {
164 vertex_to_cell_offsets[i+1] = accu;
165 accu += num_cells_per_vertex[i];
166 }
167 for (size_t i = 0, k = 0; i < num_cells; ++i)
168 for (int j = 0; j < num_vertices_per_cell[i]; ++j, ++k)
169 vertex_to_cell[vertex_to_cell_offsets[cell_to_vertex[k]+1]++] = i;
170
172
173 grid_data.vertex_coordinates = vertex_coordinates;
174 grid_data.cell_ids = cell_ids;
175 grid_data.vertex_ids = vertex_ids;
176 grid_data.edge_ids = edge_ids;
177 grid_data.num_cells = num_cells;
178 grid_data.num_vertices = num_vertices;
179 grid_data.num_edges = num_edges;
180 grid_data.core_cell_mask = core_cell_mask;
181 grid_data.core_vertex_mask = core_vertex_mask;
182 grid_data.core_edge_mask = core_edge_mask;
184 grid_data.num_cells_per_vertex = num_cells_per_vertex;
186 grid_data.cell_to_vertex_offsets = cell_to_vertex_offsets;
187 grid_data.cell_to_edge = cell_to_edge;
188 grid_data.cell_to_edge_offsets = cell_to_edge_offsets;
189 grid_data.vertex_to_cell = vertex_to_cell;
190 grid_data.vertex_to_cell_offsets = vertex_to_cell_offsets;
191 grid_data.edge_to_vertex = edge_to_vertex;
192 grid_data.edge_type = edge_type;
193 grid_data.num_total_cells = num_cells;
194 grid_data.num_total_vertices = num_vertices;
195 grid_data.num_total_edges = num_edges;
196
197 return grid_data;
198}
199
201 double const * global_coords_x, double const * global_coords_y,
202 size_t const num_global_cells_[2], size_t const local_start[2],
203 size_t const local_count[2], int with_halo) {
204
205 size_t num_global_cells = num_global_cells_[0] * num_global_cells_[1];
206 size_t num_global_vertices =
207 (num_global_cells_[0] + 1) * (num_global_cells_[1] + 1);
208 size_t num_global_edges =
209 (num_global_cells_[0] + 1) * num_global_cells_[1] +
210 (num_global_cells_[1] + 1) * num_global_cells_[0];
211
212 struct temp_cell_data * cell_data =
213 xmalloc(4 * num_global_cells * sizeof(*cell_data));
214 struct temp_cell * global_cells =
215 xmalloc(num_global_cells * sizeof(*global_cells));
216 struct temp_corner * global_corners =
217 xmalloc(num_global_vertices * sizeof(*global_corners));
218 struct temp_edge * global_edges =
219 xmalloc(num_global_edges * sizeof(*global_edges));
220
221 for (size_t i = 0; i < num_global_cells; ++i) {
222
223 struct temp_cell * curr_cell = global_cells + i;
224 curr_cell->id = i;
225 curr_cell->num_corners = 4;
226 curr_cell->data = cell_data + 4 * i;
227
228 size_t y_index = i / num_global_cells_[0];
229 size_t x_index = i - y_index * num_global_cells_[0];
230
231 curr_cell->data[0].corner_idx = y_index * (num_global_cells_[0] + 1) + x_index;
232 curr_cell->data[1].corner_idx = y_index * (num_global_cells_[0] + 1) + x_index + 1;
233 curr_cell->data[2].corner_idx = (y_index + 1) * (num_global_cells_[0] + 1) + x_index + 1;
234 curr_cell->data[3].corner_idx = (y_index + 1) * (num_global_cells_[0] + 1) + x_index;
235
236 curr_cell->data[0].edge_idx = (2 * num_global_cells_[0] + 1) * y_index + 2 * x_index;
237 curr_cell->data[1].edge_idx = curr_cell->data[0].edge_idx + 3 - (x_index+1 == num_global_cells_[0]);
238 if (y_index+1 == num_global_cells_[1])
239 curr_cell->data[2].edge_idx = (2 * num_global_cells_[0] + 1) * (y_index + 1) + x_index;
240 else
241 curr_cell->data[2].edge_idx = curr_cell->data[0].edge_idx + 2 * num_global_cells_[0] + 1;
242 curr_cell->data[3].edge_idx = curr_cell->data[0].edge_idx + 1;
243 }
244 for (size_t i = 0; i < num_global_vertices; ++i) {
245 global_corners[i].id = i;
246 size_t y_index = i / (num_global_cells_[0] + 1);
247 LLtoXYZ(global_coords_x[i - y_index * (num_global_cells_[0] + 1)],
248 global_coords_y[y_index], &(global_corners[i].coord[0]));
249 }
250 for (size_t i = 0; i < num_global_edges; ++i) {
251
252 global_edges[i].id = i;
253
254 size_t y_index = i / (2*num_global_cells_[0]+1);
255 size_t x_index = i - y_index * (2*num_global_cells_[0]+1);
256 if (y_index == num_global_cells_[1]) {
257 global_edges[i].type = YAC_LAT_CIRCLE_EDGE;
258 x_index *= 2;
259 } else if (x_index == 2*num_global_cells_[0]) {
260 global_edges[i].type = YAC_LON_CIRCLE_EDGE;
261 ++x_index;
262 } else global_edges[i].type = (x_index&1)?YAC_LON_CIRCLE_EDGE:YAC_LAT_CIRCLE_EDGE;
263 global_edges[i].vertex_idx[0] =
264 x_index / 2 + y_index * (num_global_cells_[0] + 1);
265 global_edges[i].vertex_idx[1] =
266 global_edges[i].vertex_idx[0] + 1 + ((x_index & 1)?num_global_cells_[0]:0);
267 }
268
269 size_t num_local_cells = local_count[0] * local_count[1];
270 size_t * local_cell_indices =
271 xmalloc(num_local_cells * sizeof(*local_cell_indices));
272 for (size_t i = 0, k = 0; i < local_count[1]; ++i)
273 for (size_t j = 0; j < local_count[0]; ++j, ++k)
274 local_cell_indices[k] =
275 j + local_start[0] + (i + local_start[1]) * num_global_cells_[0];
276
279 num_global_cells, global_cells,
280 num_global_vertices, global_corners,
281 num_global_edges, global_edges,
282 num_local_cells, local_cell_indices, with_halo);
283
284 free(local_cell_indices);
285 free(global_edges);
286 free(global_corners);
287 free(global_cells);
288 free(cell_data);
289
290 return grid_data;
291}
292
294 char const * name, double const * coordinates_x,
295 double const * coordinates_y, size_t const num_cells[2],
296 size_t const local_start[2], size_t const local_count[2], int with_halo) {
297
298 return
300 name,
303 local_start, local_count, with_halo));
304}
struct yac_basic_grid * yac_basic_grid_new(char const *name, struct yac_basic_grid_data grid_data)
Definition basic_grid.c:50
static struct yac_basic_grid_data generate_local_grid_data(size_t num_global_cells, struct temp_cell *global_cells, size_t num_global_vertices, struct temp_corner *global_vertices, size_t num_global_edges, struct temp_edge *global_edges, size_t num_local_cells, size_t *local_cell_indices, int with_halo)
struct yac_basic_grid_data yac_generate_basic_grid_data_reg2d(double const *global_coords_x, double const *global_coords_y, size_t const num_global_cells_[2], size_t const local_start[2], size_t const local_count[2], int with_halo)
struct yac_basic_grid * yac_generate_basic_grid_reg2d(char const *name, double const *coordinates_x, double const *coordinates_y, size_t const num_cells[2], size_t const local_start[2], size_t const local_count[2], int with_halo)
yac_edge_type
Definition grid_cell.h:12
@ YAC_LAT_CIRCLE_EDGE
latitude circle
Definition grid_cell.h:14
@ YAC_LON_CIRCLE_EDGE
longitude circle
Definition grid_cell.h:15
add versions of standard API functions not returning on error
#define xcalloc(nmemb, size)
Definition ppm_xfuncs.h:64
#define xmalloc(size)
Definition ppm_xfuncs.h:66
size_t num_corners
struct temp_cell_data * data
double coord[3]
yac_int vertex_idx[2]
enum yac_edge_type type
yac_coordinate_pointer vertex_coordinates
size_t * vertex_to_cell_offsets
yac_size_t_2_pointer edge_to_vertex
enum yac_edge_type * edge_type
size_t * cell_to_vertex_offsets
int * cell_to_vertex
double * data
double coordinates_x[]
size_t num_cells[2]
double coordinates_y[]
static int mask[16]
char const * name
Definition toy_scrip.c:114
static void LLtoXYZ(double lon, double lat, double p_out[])
Definition toy_scrip.c:587
YAC_INT yac_int
Definition yac_types.h:15
size_t(* yac_size_t_2_pointer)[2]
Definition yac_types.h:23
double(* yac_coordinate_pointer)[3]
Definition yac_types.h:19