ICON Community Interface 0.4.0
Loading...
Searching...
No Matches
point_source.py
Go to the documentation of this file.
1"""
2Test plugin for the ICON Community Interface (ComIn)
3
4The point_source plugin shows an example for
5- Requesting a tracer that participates in ICON's turbulence and convection scheme
6- Adding point source emissions to this tracer
7- Using KDTree of scipy to locate the point source
8- Use decomp_domain to check if the point source is local to the PE
9- Updating the tracer with tendencies received from ICON's turbulence and convection scheme
10
11@authors 12/2023 :: ICON Community Interface <comin@icon-model.org>
12
13SPDX-License-Identifier: BSD-3-Clause
14
15Please see the file LICENSE in the root of the source tree for this code.
16Where software is supplied by third parties, it is indicated in the
17headers of the routines.
18"""
19
20import comin
21import numpy as np
22import sys
23from scipy.spatial import KDTree
24
25# request to add point source tracer on all domains
26comin.var_request_add(("pntsrc", -1), False)
27comin.metadata_set(("pntsrc", -1), tracer=True, tracer_turb=True, tracer_conv=True)
28
29# Point source is only added to domain 1
30jg = 1
31msgrank = 0 # Rank that prints messages
32pntsrc_lon = 141.0325
33pntsrc_lat = 37.421389
34
35
36def message(message_string, rank):
37 """Short helper function to print a message on one PE"""
38 if comin.parallel_get_host_mpi_rank() == rank:
39 print(f"ComIn point_source.py: {message_string}", file=sys.stderr)
40
41
42def lonlat2xyz(lon, lat):
43 clat = np.cos(lat)
44 return clat * np.cos(lon), clat * np.sin(lon), np.sin(lat)
45
46
47@comin.register_callback(comin.EP_SECONDARY_CONSTRUCTOR)
49 """Constructor: Get pointers to tracers and descriptive data"""
50 global pntsrc, ddt_pntsrc_turb, ddt_pntsrc_conv
51
52 entry_points = [comin.EP_ATM_ADVECTION_BEFORE, comin.EP_ATM_PHYSICS_BEFORE]
53 pntsrc = comin.var_get(
54 entry_points, ("pntsrc", jg), comin.COMIN_FLAG_READ | comin.COMIN_FLAG_WRITE
55 )
56 # ICON prepends 'ddt_' and appends '_turb'/'_conv' for the respective tendencies
57 entry_points = [comin.EP_ATM_PHYSICS_BEFORE]
58 ddt_pntsrc_turb = comin.var_get(
59 entry_points, ("ddt_pntsrc_turb", jg), comin.COMIN_FLAG_READ
60 )
61 ddt_pntsrc_conv = comin.var_get(
62 entry_points, ("ddt_pntsrc_conv", jg), comin.COMIN_FLAG_READ
63 )
64
65 message("pntsrc_constructor successful", msgrank)
66
67
68@comin.register_callback(comin.EP_ATM_INIT_FINALIZE)
70 global lcontain_pntsrc, jc_loc, jb_loc
71
72 # pntsrc_init is executed outside domain loop
73 # all arrays are for domain 1 only
75 clon = np.asarray(domain.cells.clon)
76 clat = np.asarray(domain.cells.clat)
77 xyz = np.c_[lonlat2xyz(clon.ravel(), clat.ravel())]
78 decomp_domain = np.asarray(domain.cells.decomp_domain)
79
80 tree = KDTree(xyz)
81 dd, ii = tree.query(
82 [lonlat2xyz(np.deg2rad(pntsrc_lon), np.deg2rad(pntsrc_lat))], k=1
83 )
84
85 lcontain_pntsrc = False
86 if decomp_domain.ravel()[ii] == 0:
87 # point found is inside prognostic area
88 # This implicitly assumes that on each other PE, the nearest neighbor is located in the halo zone
89 jc_loc, jb_loc = np.unravel_index(ii, clon.shape)
90 message(
91 f"Min at PE {comin.parallel_get_host_mpi_rank()}, clon={np.rad2deg(clon[jc_loc,jb_loc])}, clat={np.rad2deg(clat[jc_loc,jb_loc])}",
92 comin.parallel_get_host_mpi_rank(),
93 )
94 lcontain_pntsrc = True
95
96
97@comin.register_callback(comin.EP_ATM_ADVECTION_BEFORE)
99 """Emission for pntsrc on domain 1"""
100 if comin.current_get_domain_id() == jg and lcontain_pntsrc:
101 pntsrc_np = np.asarray(pntsrc)
102 pntsrc_np[jc_loc, :, jb_loc, 0, 0] = pntsrc_np[jc_loc, :, jb_loc, 0, 0] + 1.0
103
104
105@comin.register_callback(comin.EP_ATM_PHYSICS_BEFORE)
107 """Update tracer from turb and conv tendencies for domain 1"""
108 if comin.current_get_domain_id() == jg:
109 pntsrc_np = np.asarray(pntsrc)
110 ddt_pntsrc_turb_np = np.asarray(ddt_pntsrc_turb)
111 ddt_pntsrc_conv_np = np.asarray(ddt_pntsrc_conv)
112
113 dtime = comin.descrdata_get_timesteplength(jg)
114 pntsrc_np[:, :, :, 0, 0] = np.maximum(
115 (
116 pntsrc_np[:, :, :, 0, 0]
117 + dtime
118 * (
119 ddt_pntsrc_turb_np[:, :, :, 0, 0]
120 + ddt_pntsrc_conv_np[:, :, :, 0, 0]
121 )
122 ),
123 0.0,
124 )
125
126
127@comin.register_callback(comin.EP_DESTRUCTOR)
129 message("pntsrc_destructor called!", msgrank)
var_get(context, var_descriptor, flag)
get variable object, arguments: [entry point], (name string, domain id), access flag)
Definition comin.py:107
metadata_set(var_descriptor, **kwargs)
sets metadata for a requested field, arguments: name string, domain id, metadata key,...
Definition comin.py:189
descrdata_get_domain(jg)
returns descriptive data for a given domain, arguments: jg
Definition comin.py:167
pntsrc_updatePhysTends()
Update tracer from turb and conv tendencies for domain 1.
pntsrc_constructor()
Constructor: Get pointers to tracers and descriptive data.
pntsrc_emission()
Emission for pntsrc on domain 1.
lonlat2xyz(lon, lat)
message(message_string, rank)
Short helper function to print a message on one PE.