Skip to content

Commit 8960877

Browse files
committed
Scalar fields are plotted at the correct location
Interpolation of scalar field is now turned off by default to avoid giving the impression that the run is better resolved than it is. `field.plot_scalar` now exploits walls location by default to draw scalar fields as they are in FV: a value is assigned to a cell delimited by those walls. This eliminates the need for an extra layer to close the spherical annulus. Note that this extra layer is needed when plotting a smoothed field with the Gouraud shading as the later cannot exploit walls locations.
1 parent ff99561 commit 8960877

File tree

3 files changed

+30
-21
lines changed

3 files changed

+30
-21
lines changed

stagpy/config.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ def _index_collection(arg):
104104
('shift', Conf(None, True, None, {'type': int},
105105
False, 'shift plot horizontally')),
106106
('timelabel', switch_opt(False, None, 'add label with time')),
107-
('interpolate', switch_opt(True, None, 'apply Gouraud shading')),
107+
('interpolate', switch_opt(False, None, 'apply Gouraud shading')),
108108
('colorbar', switch_opt(True, None, 'add color bar to plot')),
109109
('ix', Conf(None, True, None, {'type': int},
110110
False, 'x-index of slice for 3D fields')),

stagpy/field.py

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,14 @@
1313
from .stagyydata import StagyyData
1414

1515

16-
# The location is off for vertical velocities they have an extra
16+
# The location is off for vertical velocities: they have an extra
1717
# point in (x,y) instead of z in the output
1818

1919

20-
def _threed_extract(step, var):
20+
def _threed_extract(step, var, walls=False):
2121
"""Return suitable slices and coords for 3D fields."""
2222
is_vector = not valid_field_var(var)
23+
hwalls = is_vector or walls
2324
i_x = conf.field.ix
2425
i_y = conf.field.iy
2526
i_z = conf.field.iz
@@ -30,18 +31,18 @@ def _threed_extract(step, var):
3031
if i_x is None and i_y is None and i_z is None:
3132
i_x = 0
3233
if i_x is not None:
33-
xcoord = step.geom.y_walls if is_vector else step.geom.y_centers
34-
ycoord = step.geom.z_centers
34+
xcoord = step.geom.y_walls if hwalls else step.geom.y_centers
35+
ycoord = step.geom.z_walls if walls else step.geom.z_centers
3536
i_y = i_z = slice(None)
3637
varx, vary = var + '2', var + '3'
3738
elif i_y is not None:
38-
xcoord = step.geom.x_walls if is_vector else step.geom.x_centers
39-
ycoord = step.geom.z_centers
39+
xcoord = step.geom.x_walls if hwalls else step.geom.x_centers
40+
ycoord = step.geom.z_walls if walls else step.geom.z_centers
4041
i_x = i_z = slice(None)
4142
varx, vary = var + '1', var + '3'
4243
else:
43-
xcoord = step.geom.x_walls if is_vector else step.geom.x_centers
44-
ycoord = step.geom.y_walls if is_vector else step.geom.y_centers
44+
xcoord = step.geom.x_walls if hwalls else step.geom.x_centers
45+
ycoord = step.geom.y_walls if hwalls else step.geom.y_centers
4546
i_x = i_y = slice(None)
4647
varx, vary = var + '1', var + '2'
4748
if is_vector:
@@ -66,7 +67,7 @@ def valid_field_var(var):
6667
return var in phyvars.FIELD or var in phyvars.FIELD_EXTRA
6768

6869

69-
def get_meshes_fld(step, var):
70+
def get_meshes_fld(step, var, walls=False):
7071
"""Return scalar field along with coordinates meshes.
7172
7273
Only works properly in 2D geometry and 3D cartesian.
@@ -75,23 +76,24 @@ def get_meshes_fld(step, var):
7576
step (:class:`~stagpy.stagyydata._Step`): a step of a StagyyData
7677
instance.
7778
var (str): scalar field name.
79+
walls (bool): consider the walls as the relevant mesh.
7880
Returns:
7981
tuple of :class:`numpy.array`: xmesh, ymesh, fld
8082
2D arrays containing respectively the x position, y position, and
8183
the value of the requested field.
8284
"""
8385
fld = step.fields[var]
84-
is_vector = (fld.shape[0] != step.geom.nxtot or
85-
fld.shape[1] != step.geom.nytot)
86+
hwalls = (walls or fld.shape[0] != step.geom.nxtot or
87+
fld.shape[1] != step.geom.nytot)
8688
if step.geom.threed and step.geom.cartesian:
87-
(xcoord, ycoord), fld = _threed_extract(step, var)
89+
(xcoord, ycoord), fld = _threed_extract(step, var, walls)
8890
elif step.geom.twod_xz:
89-
xcoord = step.geom.x_walls if is_vector else step.geom.x_centers
90-
ycoord = step.geom.z_centers
91+
xcoord = step.geom.x_walls if hwalls else step.geom.x_centers
92+
ycoord = step.geom.z_walls if walls else step.geom.z_centers
9193
fld = fld[:, 0, :, 0]
9294
else: # twod_yz
93-
xcoord = step.geom.y_walls if is_vector else step.geom.y_centers
94-
ycoord = step.geom.z_centers
95+
xcoord = step.geom.y_walls if hwalls else step.geom.y_centers
96+
ycoord = step.geom.z_walls if walls else step.geom.z_centers
9597
if step.geom.curvilinear:
9698
pmesh, rmesh = np.meshgrid(xcoord, ycoord, indexing='ij')
9799
xmesh, ymesh = rmesh * np.cos(pmesh), rmesh * np.sin(pmesh)
@@ -172,7 +174,16 @@ def plot_scalar(step, var, field=None, axis=None, **extra):
172174
raise NotAvailableError(
173175
'plot_scalar not implemented for 3D spherical geometry')
174176

175-
xmesh, ymesh, fld = get_meshes_fld(step, var)
177+
xmesh, ymesh, fld = get_meshes_fld(step, var,
178+
walls=not conf.field.interpolate)
179+
if conf.field.interpolate and \
180+
step.geom.spherical and step.geom.twod_yz and \
181+
fld.shape[0] == step.geom.nytot:
182+
# add one point to close spherical annulus
183+
xmesh = np.concatenate((xmesh, xmesh[:1]), axis=0)
184+
ymesh = np.concatenate((ymesh, ymesh[:1]), axis=0)
185+
newline = (fld[:1] + fld[-1:]) / 2
186+
fld = np.concatenate((fld, newline), axis=0)
176187
xmin, xmax = xmesh.min(), xmesh.max()
177188
ymin, ymax = ymesh.min(), ymesh.max()
178189

stagpy/stagyyparsers.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -656,9 +656,7 @@ def _get_field(xdmf_file, data_item):
656656
shp = _get_dim(data_item)
657657
h5file, group = data_item.text.strip().split(':/', 1)
658658
# Field on yin is named <var>_XXXXX_YYYYY, on yang is <var>2XXXXX_YYYYY.
659-
# This splitting is done to protect against that and <var> possibly
660-
# containing a 2.
661-
numeral_part = group.split('2')[-1]
659+
numeral_part = group[-11:]
662660
icore = int(numeral_part.split('_')[-2]) - 1
663661
fld = None
664662
try:

0 commit comments

Comments
 (0)