@@ -112,22 +112,7 @@ function debug(cs_fields::CC.Fields.Field, dir, cs_fields_ref = nothing)
112
112
if field_index <= length (field_names)
113
113
field_name = field_names[field_index]
114
114
field = getproperty (cs_fields, field_name)
115
-
116
- # Copy field onto cpu space if necessary
117
- cpu_field = CC. to_cpu (field)
118
-
119
- # ClimaCoreMakie doesn't support NaNs/Infs, so we substitute them with 100max
120
- FT = CC. Spaces. undertype (axes (cpu_field))
121
- isinvalid = (x) -> isnan (x) || isinf (x)
122
-
123
- field_valid_min, field_valid_max = extrema (map (x -> isinvalid (x) ? FT (0 ) : x, parent (cpu_field)))
124
- map! (x -> isinvalid (x) ? 100 field_valid_max : x, parent (cpu_field), parent (cpu_field))
125
- colorrange =
126
- isapprox (field_valid_min, field_valid_max) ? (field_valid_min - 1 , field_valid_max + 1 ) :
127
- (field_valid_min, field_valid_max)
128
- ax = Makie. Axis (fig[i, j * 2 - 1 ], title = string (field_name) * print_extrema (field))
129
- hm = ClimaCoreMakie. fieldheatmap! (ax, cpu_field, colorrange = colorrange)
130
- Makie. Colorbar (fig[i, j * 2 ], hm)
115
+ _heatmap_cc_field! (fig, field, i, j, field_name)
131
116
end
132
117
end
133
118
Makie. save (joinpath (dir, " debug_coupler.png" ), fig)
@@ -139,27 +124,7 @@ function debug(cs_fields::CC.Fields.Field, dir, cs_fields_ref = nothing)
139
124
if field_index <= length (field_names)
140
125
field_name = field_names[field_index]
141
126
field = getproperty (cs_fields, field_name)
142
- # Copy field onto cpu space if necessary
143
-
144
- cpu_field = CC. to_cpu (field)
145
-
146
- # ClimaCoreMakie doesn't support NaNs/Infs, so we substitute them with 100max
147
- FT = CC. Spaces. undertype (axes (cpu_field))
148
- isinvalid = (x) -> isnan (x) || isinf (x)
149
-
150
- field_valid_min, field_valid_max = extrema (map (x -> isinvalid (x) ? FT (0 ) : x, parent (cpu_field)))
151
- map! (x -> isinvalid (x) ? 100 field_valid_max : x, parent (cpu_field), parent (cpu_field))
152
- colorrange =
153
- isapprox (field_valid_min, field_valid_max) ? (field_valid_min - 1 , field_valid_max + 1 ) :
154
- (field_valid_min, field_valid_max)
155
-
156
- ax = Makie. Axis (fig[i, j * 2 - 1 ], title = string (field_name) * print_extrema (field))
157
- hm = ClimaCoreMakie. fieldheatmap! (
158
- ax,
159
- cpu_field .- getproperty (cs_fields_ref, field_name),
160
- colorrange = colorrange,
161
- )
162
- Makie. Colorbar (fig[i, j * 2 ], hm)
127
+ _heatmap_cc_field! (fig, field, i, j, field_name)
163
128
end
164
129
end
165
130
Makie. save (joinpath (dir, " debug_coupler_anomalies.png" ), fig)
@@ -190,24 +155,7 @@ function debug(sim::Interfacer.ComponentModelSimulation, dir)
190
155
hm = CairoMakie. heatmap! (ax, view (field, :, :, grid. Nz))
191
156
Makie. Colorbar (fig[i, j * 2 ], hm)
192
157
elseif field isa CC. Fields. Field
193
- # Copy field onto cpu space if necessary
194
- cpu_field = CC. to_cpu (field)
195
- if cpu_field isa CC. Fields. ExtrudedCubedSphereSpectralElementField3D
196
- cpu_field = CC. Fields. level (cpu_field, 1 )
197
- end
198
- FT = CC. Spaces. undertype (axes (cpu_field))
199
- vals = CC. Fields. field_values (cpu_field)
200
- isinvalid = (x) -> isnan (x) || isinf (x)
201
- # ClimaCoreMakie doesn't support NaNs or Infs, so we make them
202
- # stand out by replacing them with 100max
203
-
204
- field_valid_min, field_valid_max = extrema (map (x -> isinvalid (x) ? FT (0 ) : x, parent (cpu_field)))
205
- map! (x -> isinvalid (x) ? 100 field_max : x, parent (cpu_field), parent (cpu_field))
206
- colorrange =
207
- isapprox (field_valid_min, field_valid_max) ? (field_valid_min - 1 , field_valid_max + 1 ) :
208
- (field_valid_min, field_valid_max)
209
- hm = ClimaCoreMakie. fieldheatmap! (ax, cpu_field, colorrange = colorrange)
210
- Makie. Colorbar (fig[i, j * 2 ], hm)
158
+ _heatmap_cc_field! (fig, field, i, j, field_name)
211
159
elseif field isa AbstractArray
212
160
lin = Makie. lines! (ax, Array (field))
213
161
end
@@ -216,6 +164,40 @@ function debug(sim::Interfacer.ComponentModelSimulation, dir)
216
164
Makie. save (joinpath (dir, " debug_$(nameof (sim)) .png" ), fig)
217
165
end
218
166
167
+ """
168
+ _heatmap_cc_field!(fig, field::CC.Fields.Field, i, j, field_name)
169
+
170
+ Helper function to plot a heatmap of a ClimaCore field in the given figure at position (i, j).
171
+ If the field is constant, skip plotting it to avoid heatmap errors.
172
+ """
173
+ function _heatmap_cc_field! (fig, field:: CC.Fields.Field , i, j, field_name)
174
+ # Copy field onto cpu space if necessary
175
+ cpu_field = CC. to_cpu (field)
176
+ if cpu_field isa CC. Fields. ExtrudedCubedSphereSpectralElementField3D
177
+ cpu_field = CC. Fields. level (cpu_field, 1 )
178
+ end
179
+
180
+ # ClimaCoreMakie doesn't support NaNs/Infs, so we substitute them with 100max
181
+ FT = CC. Spaces. undertype (axes (cpu_field))
182
+ isinvalid = (x) -> isnan (x) || isinf (x)
183
+ field_valid_min, field_valid_max = extrema (map (x -> isinvalid (x) ? FT (0 ) : x, parent (cpu_field)))
184
+ map! (x -> isinvalid (x) ? 100 field_valid_max : x, parent (cpu_field), parent (cpu_field))
185
+
186
+ # If the values are too small, `isapprox` can't be computed accurately because of floating point precision issues.
187
+ is_toosmall = (x) -> log10 (abs (x)) < log10 (floatmin (Float64)) / 2
188
+
189
+ # If the field is constant, skip plotting it to avoid heatmap errors.
190
+ if isapprox (field_valid_min, field_valid_max) || (is_toosmall (field_valid_min) && is_toosmall (field_valid_max))
191
+ ax = Makie. Axis (fig[i, j * 2 - 1 ], title = string (field_name) * print_extrema (cpu_field))
192
+ else
193
+ colorrange = (field_valid_min, field_valid_max)
194
+ ax = Makie. Axis (fig[i, j * 2 - 1 ], title = string (field_name) * print_extrema (cpu_field))
195
+ hm = ClimaCoreMakie. fieldheatmap! (ax, cpu_field, colorrange = colorrange)
196
+ Makie. Colorbar (fig[i, j * 2 ], hm)
197
+ end
198
+ return nothing
199
+ end
200
+
219
201
"""
220
202
print_extrema(field::CC.Fields.Field)
221
203
0 commit comments