YAC 3.20.0
Yet Another Coupler
Loading...
Searching...
No Matches
test_interface.py
Go to the documentation of this file.
1#!/usr/bin/env python3
2
3# Copyright (c) 2024 The YAC Authors
4#
5# SPDX-License-Identifier: BSD-3-Clause
6
7
11
12import yac
13from mpi4py import MPI
14import numpy as np
15import os
16import datetime
17
18rank = MPI.COMM_WORLD.rank
19size = MPI.COMM_WORLD.size
20assert size > 1
21
22yac.def_calendar(yac.Calendar.PROLEPTIC_GREGORIAN)
23assert yac.get_calendar() == yac.Calendar.PROLEPTIC_GREGORIAN
24print(yac.version())
25
26# class YAC
27yac_def_instance = yac.YAC(default_instance=True)
28yac_def_instance2 = yac.YAC.default_instance
29yac_from_id = yac.YAC.from_id(yac_def_instance2.instance_id)
30assert yac_def_instance.instance_id == yac_def_instance2.instance_id == yac_from_id.instance_id
31assert yac_def_instance.rank == rank
32assert yac_def_instance.size == size
33assert yac_def_instance.default_instance_id_defined == True
34
35yac_def_instance.set_config_output_file("foo.yaml",
36 yac.ConfigOutputFormat.YAML,
37 yac.ConfigOutputSyncLoc.ENDDEF)
38yac_def_instance.set_grid_output_file("foo_grid", "foo_grid.nc")
39yac_def_instance.set_coordinates_check(True)
40yac_def_instance.set_coordinates_mismatch_is_fatal(True)
41
42del yac_def_instance, yac_def_instance2
43yac_comm = yac.YAC(comm=MPI.COMM_WORLD)
44assert size == yac_comm.size
45assert rank == yac_comm.rank
46del yac_comm
47yac_instance = yac.YAC()
48
49# datetime
50# without timezone
51start_dt = datetime.datetime(
52 year=2020, month=1, day=1, hour=0, minute=0, second=0,
53)
54end_dt = datetime.datetime(
55 year=2020, month=1, day=2, hour=0, minute=0, second=0,
56)
57yac_instance.def_datetime(start_dt, end_dt)
58
59# with UTC (datetime uses Z in isostring to represent utc, not +00:00)
60start_dt = start_dt.replace(tzinfo=datetime.timezone.utc)
61end_dt = end_dt.replace(tzinfo=datetime.timezone.utc)
62yac_instance.def_datetime(start_dt, end_dt)
63
64# raw strings
65# without timezone
66yac_instance.def_datetime("2020-01-01T00:00:00",
67 "2020-01-02T00:00:00")
68# with UTC as Z
69yac_instance.def_datetime("2020-01-01T00:00:00Z",
70 "2020-01-02T00:00:00Z")
71# with UTC as +00:00
72yac_instance.def_datetime("2020-01-01T00:00:00+00:00",
73 "2020-01-02T00:00:00+00:00")
74
75# components
76if rank % 2 == 0:
77 comp1 = yac_instance.predef_comp("comp1")
78 comp2 = yac_instance.def_comp("comp2")
79else:
80 comp1, comp3 = yac_instance.def_comps(["comp1", "comp3"])
81
82assert yac_instance.get_component("comp1").comp_id == comp1.comp_id
83
84assert yac_instance.start_datetime == "2020-01-01T00:00:00.000"
85assert yac_instance.end_datetime == "2020-01-02T00:00:00.000"
86
87assert yac_instance.get_comps_comm(["comp2", "comp3"]).size == size
88assert comp1.comp_comm.size == size
89assert comp1.size == comp1.comp_comm.size
90assert comp1.rank == comp1.comp_comm.rank
91
92
93yac_instance.def_component_metadata("comp1", "COMP_METADATA".encode())
94
95assert set(yac_instance.component_names) == {"comp1", "comp2", "comp3"}
96
97# class Grid
98x = np.array([-1., 0., 1.])
99x.setflags(write=0) # require a const memoryview in Reg2d
100prelim_grid1 = yac_instance.get_grid("grid1")
101grid1 = yac.Reg2dGrid("grid1", x, x)
102assert grid1.grid_id == prelim_grid1.grid_id
103grid1.set_global_index(range(9), yac.Location.CORNER)
104grid1.set_global_index(np.arange(4, dtype=np.intc), yac.Location.CELL)
105print(f"{grid1.compute_grid_cell_areas()=}")
106assert grid1.nbr_cells == 4
107assert grid1.nbr_corners == 9
108assert grid1.nbr_edges == 12
109grid1.set_core_mask([True, False] * 2, yac.Location.CELL)
110points1 = grid1.def_points(
111 yac.Location.CELL, [-0.5, 0.5], [-0.5, 0.5], name="points_grid1")
112assert (
113 points1.points_id ==
114 grid1.get_points(yac.Location.CELL, "points_grid1").points_id
115)
116assert points1.size == grid1.nbr_cells
117points1.set_mask([True] * 4)
118
119yac_instance.def_grid_metadata("grid1", "GRID_METADATA".encode())
120
122 "grid2",
123 [3],
124 [0.0, 1.0, 0.0],
125 [0.0, 0.0, 1.0],
126 [0, 1, 2],
127 use_ll_edges=False,
128)
129prelim_mask1_id = grid2.get_mask(yac.Location.CELL, "mask1").mask_id
130mask1 = grid2.def_mask(yac.Location.CELL, [True], name="mask1")
131assert mask1.mask_id == prelim_mask1_id
132points2 = grid2.def_points(
133 yac.Location.CELL, [0.5], [0.5], name="points_grid2")
134
136 "grid3",
137 [4],
138 [0.0, 1.0, 1.0, 0.0],
139 [0.0, 0.0, 1.0, 1.0],
140 [0, 1, 2, 3],
141 use_ll_edges=True,
142)
143
144grid4 = yac.CloudGrid("grid4",
145 [0.0, 1.0, 1.0, 0.0],
146 [0.0, 0.0, 1.0, 1.0])
147
148points4 = grid4.def_points([0.0, 1.0, 1.0, 0.0],
149 [0.0, 0.0, 1.0, 1.0],
150 name="points_grid4")
151
153 [3],
154 [0.0, 1.0, 0.0],
155 [0.0, 0.0, 1.0],
156 [0, 1, 2],
157 [[0, 1], [1, 2], [2, 0]],
158 use_ll_edges=False,
159 )
160points5 = grid5.def_points(
161 yac.Location.CELL, [0.5], [0.5], name="points_grid5")
162
164 [4],
165 [0.0, 1.0, 1.0, 0.0],
166 [0.0, 0.0, 1.0, 1.0],
167 [0, 1, 2, 3],
168 [[0, 1], [1, 2], [2, 3], [3, 0]],
169 use_ll_edges=True,
170 )
171
172# regular 2d rotated grid
173grid7 = yac.Reg2dGrid("grid7", x, x, north_pole = [3.6, 0.7])
174points7 = grid7.def_points(
175 yac.Location.CELL, [-0.5, 0.5], [-0.5, 0.5], name="points_grid7")
176
177# class Field
178field1 = yac.Field.create("field1", comp1, points1, 3, "1", yac.TimeUnit.MINUTE)
179yac_instance.def_field_metadata(
180 "comp1", "grid1", "field1", "FIELD_METADATA".encode()
181)
182yac_instance.enable_field_frac_mask("comp1", "grid1", "field1", 42.0)
183
185 "field2", comp1, points2, 2, "1", yac.TimeUnit.HOUR, mask1
186)
188 "field3", comp1, points1, 1, "1", yac.TimeUnit.HOUR
189)
191 "field4", comp1, points2, 1, "1", yac.TimeUnit.HOUR, mask1
192)
193
194# class InterpolationStack
196interp.add_nnn(yac.NNNReductionType.AVG, 1, 0.0, 1.0)
197yac.InterpolationStack().add_average(yac.AverageReductionType.AVG_DIST, 1)
198yac.InterpolationStack().add_conservative(
199 1, 1, 1, yac.ConservNormalizationType.FRACAREA
200)
201yac.InterpolationStack().add_rbf()
202yac.InterpolationStack().add_spmap(
203 1.0, 1.0, yac.SPMAPWeightType.AVG, yac.SPMAPScaleType.NONE)
204yac.InterpolationStack().add_hcsbb()
205# interp.add_user_file()
206yac.InterpolationStack().add_fixed(999.0)
207yac.InterpolationStack().add_check("ctor", "search key")
208yac.InterpolationStack().add_creep(42)
209
210yac_instance.def_couple(
211 "comp1",
212 "grid1",
213 "field1",
214 "comp1",
215 "grid2",
216 "field2",
217 "60",
218 yac.TimeUnit.MINUTE,
219 yac.Reduction.TIME_NONE,
220 interp,
221 src_lag=2,
222 yaxt_exchanger_name="irecv_send",
223 collection_selection=[2, 0],
224)
225del interp
226
228 "- nnn:\n n: 1"
229)
230del interp_yaml
231
233 "[{\"nnn\": {\"n\": 1}}]"
234)
235del interp_json
236
237if rank == 0:
238 with open("config.yaml", "w") as f:
239 f.write(
240 """timestep_unit: minute
241coupling:
242 - src_component: comp1
243 src_grid: grid1
244 src_lag: 0
245 tgt_component: comp1
246 tgt_grid: grid2
247 coupling_period: 60
248 time_reduction: none
249 interpolation:
250 - nnn:
251 n: 1
252 field:
253 src: field3
254 tgt: field4
255"""
256 )
257 yac_instance.read_config_yaml("config.yaml")
258 os.remove("config.yaml")
259
260yac_instance.sync_def_comps(["comp1", "comp2", "comp3"])
261yac_instance.sync_def()
262
263assert yac_instance.get_component_metadata("comp1") == "COMP_METADATA"
264assert yac_instance.get_grid_metadata("grid1") == "GRID_METADATA"
265assert (
266 yac_instance.get_field_metadata("comp1", "grid1", "field1")
267 == "FIELD_METADATA"
268)
269
270assert "grid1" in yac_instance.grid_names
271assert "grid1" in yac_instance.get_comp_grid_names("comp1")
272assert "field1" in yac_instance.get_field_names("comp1", "grid1")
273assert yac_instance.get_field_is_defined("comp1", "grid1", "field1")
274assert not yac_instance.get_field_is_defined("comp1", "grid1", "undefined_field")
275assert not yac_instance.get_field_is_defined("comp1", "undefined_grid", "field1")
276assert not yac_instance.get_field_is_defined("undefined_comp", "grid1", "field1")
277field1_id = yac_instance.get_field_id("comp1", "grid1", "field1")
278assert (field1.component_name == "comp1")
279assert (field1.grid_name == "grid1")
280assert (
281 yac_instance.get_field_timestep("comp1", "grid1", "field1")
282 == field1.timestep
283 == "PT01M"
284)
285assert (
286 yac_instance.get_field_role("comp1", "grid1", "field1")
287 == yac.ExchangeType.SOURCE
288)
289assert (yac_instance.get_field_collection_size("comp1", "grid1", "field1")
290 == field1.collection_size
291 == 3)
292assert (
293 yac_instance.get_field_frac_mask_fallback_value("comp1", "grid1", "field1")
294 == 42.0
295)
296assert yac_instance.get_field_source("comp1", "grid2", "field2") == ("comp1", "grid1", "field1")
297
298yac_instance.enddef()
299
300assert (field1.role == yac.ExchangeType.SOURCE ) # it is set only after enddef
301
302data, send_info, recv_info = yac.Field.exchange(field3, field4, np.random.rand(2, 2))
303field1.update()
exchange(cls, send_field, recv_field, send_buf, recv_buf=None, send_frac_mask=None)
Definition yac.pyx:1951
create(cls, str field_name, Component comp, points, collection_size, str timestep, TimeUnit timeunit, masks=None)
Definition yac.pyx:1759
from_string_json(cls, str interp_stack_string)
Definition yac.pyx:2244
from_string_yaml(cls, str interp_stack_string)
Definition yac.pyx:2234
A stuctured 2d Grid.
Definition yac.pyx:1496
An unstuctured 2d Grid.
Definition yac.pyx:1656
Initializies a YAC instance and provides further functionality.
Definition yac.pyx:753
from_id(cls, id)
Definition yac.pyx:810
version()
Definition yac.pyx:2431
get_calendar()
Definition yac.pyx:614
def_calendar(Calendar calendar)
Definition yac.pyx:608