@@ -20,16 +20,17 @@ import ClimaUtilities.TimeVaryingInputs: extrapolation_bc
20
20
import ClimaUtilities. TimeVaryingInputs
21
21
22
22
import ClimaUtilities. TimeManager: ITime, date
23
+ using Dates
23
24
24
25
"""
25
26
InterpolatingTimeVaryingInput0D
26
27
27
28
The constructor for InterpolatingTimeVaryingInput0D is not supposed to be used directly, unless you
28
29
know what you are doing.
29
30
30
- `times` and `vales ` may have different float types, but they must be the same length, and we
31
+ `times` and `values ` may have different types, but they must be the same length, and we
31
32
assume that they have been sorted to be monotonically increasing in time, without repeated
32
- values for the same timestamp.
33
+ values for the same timestamp. `times` can have elements of type `ITime` or floats
33
34
"""
34
35
struct InterpolatingTimeVaryingInput0D{
35
36
AA1 <: AbstractArray ,
@@ -107,9 +108,13 @@ function TimeVaryingInputs.TimeVaryingInput(
107
108
108
109
if extrapolation_bc (method) isa PeriodicCalendar
109
110
if extrapolation_bc (method) isa PeriodicCalendar{Nothing}
110
- isequispaced (times) || error (
111
- " PeriodicCalendar() boundary condition cannot be used because data is defined at non uniform intervals of time " ,
111
+ if ! isequispaced (
112
+ eltype (times) <: ITime ? [ float .( promote (times ... )) ... ] : times ,
112
113
)
114
+ error (
115
+ " PeriodicCalendar() boundary condition cannot be used because data is defined at non uniform intervals of time" ,
116
+ )
117
+ end
113
118
else
114
119
# We have the period in PeriodicCalendar
115
120
error (
@@ -197,9 +202,18 @@ function TimeVaryingInputs.evaluate!(
197
202
# interpolation between t_init and t_end. In this case, y0 = vals[end], y1 =
198
203
# vals[begin], t1 - t0 = dt, and time - t0 = time - t_end
199
204
if time > t_end
200
- @. dest =
201
- itp. vals[end ] +
202
- (itp. vals[begin ] - itp. vals[end ]) / dt * (time - t_end)
205
+ if time isa ITime
206
+ FT = eltype (itp. vals)
207
+ @. dest =
208
+ itp. vals[end ] + FT (
209
+ (itp. vals[begin ] - itp. vals[end ]) / float (dt) *
210
+ float ((time - t_end)),
211
+ )
212
+ else
213
+ @. dest =
214
+ itp. vals[end ] +
215
+ (itp. vals[begin ] - itp. vals[end ]) / dt * (time - t_end)
216
+ end
203
217
return nothing
204
218
end
205
219
end
213
227
214
228
function TimeVaryingInputs. evaluate! (
215
229
destination,
216
- itp:: InterpolatingTimeVaryingInput0D ,
230
+ itp:: InterpolatingTimeVaryingInput0D{<:AbstractArray{<:Number}} ,
217
231
time:: ITime ,
218
232
args... ;
219
233
kwargs... ,
@@ -227,4 +241,53 @@ function TimeVaryingInputs.evaluate!(
227
241
)
228
242
end
229
243
244
+ function TimeVaryingInputs. evaluate! (
245
+ destination,
246
+ itp:: InterpolatingTimeVaryingInput0D{<:AbstractArray{<:ITime}} ,
247
+ eval_date:: DateTime ,
248
+ args... ;
249
+ kwargs... ,
250
+ )
251
+ t0_date = date (itp. range[1 ])
252
+ diff_ms = eval_date - t0_date
253
+ converted_time =
254
+ ITime (diff_ms. value; period = typeof (diff_ms)(1 ), epoch = t0_date)
255
+ return TimeVaryingInputs. evaluate! (
256
+ destination,
257
+ itp,
258
+ converted_time,
259
+ args... ;
260
+ kwargs... ,
261
+ )
262
+
263
+ end
264
+
265
+ function TimeVaryingInputs. evaluate! (
266
+ destination,
267
+ itp:: InterpolatingTimeVaryingInput0D{<:AbstractArray{<:ITime}} ,
268
+ time:: Number ,
269
+ args... ;
270
+ kwargs... ,
271
+ )
272
+ converted_time = first (promote (ITime (time), itp. range[1 ]))
273
+ return TimeVaryingInputs. evaluate! (
274
+ destination,
275
+ itp,
276
+ converted_time,
277
+ args... ;
278
+ kwargs... ,
279
+ )
280
+
281
+ end
282
+
283
+ TimeVaryingInputs. evaluate! (
284
+ destination,
285
+ itp:: InterpolatingTimeVaryingInput0D{<:AbstractArray{<:Number}} ,
286
+ time:: DateTime ,
287
+ args... ;
288
+ kwargs... ,
289
+ ) = error (
290
+ " Cannot evaluate InterpolatingTimeVaryingInput0D with times as numbers and inputs as DateTime" ,
291
+ )
292
+
230
293
end
0 commit comments