@@ -201,71 +201,14 @@ def cape(TP,RP,PP,T,R,P,ascent_flag=0,ptop=50,miss_handle=1):
201
201
# *** Calculate Parcel quantities ABOVE lifted condensation level ***
202
202
#
203
203
else :
204
-
205
- # Initial default values before loop
206
- TGNEW = T [j ]
207
- TJC = utilities .T_ktoC (T [j ])
208
- ES = utilities .es_cc (TJC )
209
- RG = utilities .rv (ES ,P [j ])
210
-
211
- #
212
- # *** Iteratively calculate lifted parcel temperature and mixing ***
213
- # *** ratio for reversible ascent ***
214
- #
215
-
216
- # set loop counter and initial condition
217
- NC = 0
218
- TG = 0
204
+ TG , RG , IFLAG = solve_temperature_from_entropy (S = S , P = P [j ], RP = RP , T_initial = T [j ])
205
+ if IFLAG == 2 : # Did not converge
206
+ CAPED = 0
207
+ TOB = T [0 ]
208
+ LNB = P [0 ]
209
+ # Return the uncoverged values
210
+ return (CAPED ,TOB ,LNB ,IFLAG )
219
211
220
- # loop until loop converges or bails out
221
- while ((np .abs (TGNEW - TG )) > 0.001 ):
222
-
223
- # Parcel temperature and mixing ratio during this iteration
224
- TG = TGNEW
225
- TC = utilities .T_ktoC (TG )
226
- ENEW = utilities .es_cc (TC )
227
- RG = utilities .rv (ENEW ,P [j ])
228
-
229
- # increase iteration count in the loop
230
- NC += 1
231
-
232
- #
233
- # *** Calculate estimates of the rates of change of the entropy ***
234
- # *** with temperature at constant pressure ***
235
- #
236
-
237
- ALV = utilities .Lv (TC )
238
- # calculate the rate of change of entropy with temperature, s_ell
239
- SL = (constants .CPD + RP * constants .CL + ALV * ALV * RG / (constants .RV * TG * TG ))/ TG
240
- EM = utilities .ev (RG ,P [j ])
241
- # calculate the saturated entropy, s_k, noting r_T=RP and
242
- # the last term vanishes with saturation, i.e. RH=1
243
- SG = (constants .CPD + RP * constants .CL )* np .log (TG )- constants .RD * np .log (P [j ]- EM )+ ALV * RG / TG
244
- # convergence speed (AP, step in entropy fraction) varies as a function of
245
- # number of iterations
246
- if (NC < 3 ):
247
- # converge slowly with a smaller step
248
- AP = 0.3
249
- else :
250
- # speed the process with a larger step when nearing convergence
251
- AP = 1.0
252
- # find the new temperature in the iteration
253
- TGNEW = TG + AP * (S - SG )/ SL
254
-
255
- #
256
- # *** If the routine does not converge, set IFLAG=2 and bail out ***
257
- #
258
- if (NC > 500 ) or (ENEW > (P [j ]- 1 )):
259
- CAPED = 0
260
- TOB = T [0 ]
261
- LNB = P [0 ]
262
- IFLAG = 2
263
- # Return the uncoverged values
264
- return (CAPED ,TOB ,LNB ,IFLAG )
265
-
266
- # store the number of iterations
267
- NCMAX = NC
268
-
269
212
#
270
213
# *** Calculate buoyancy ***
271
214
#
@@ -345,7 +288,100 @@ def cape(TP,RP,PP,T,R,P,ascent_flag=0,ptop=50,miss_handle=1):
345
288
# Return the calculated outputs to the above program level
346
289
return (CAPED ,TOB ,LNB ,IFLAG )
347
290
291
+
292
+ @njit ()
293
+ def solve_temperature_from_entropy (S , P , RP , T_initial ):
294
+ """Compute the temperature corresponding to a given value for saturated entropy.
295
+
296
+ For given pressure P and dry mixing ratio RP, saturated entropy is a function
297
+ of temperature SG(T). This function uses Newton-Raphson iteration to invert
298
+ saturated entropy to find the temperature T that satisfies SG(T) = S for
299
+ a target value of saturated entropy S.
300
+
301
+ Args:
302
+ S (float): Target saturated entropy (J/kg/K).
303
+ P (float): Ambient pressure (hPa).
304
+ RP (float): Parcel mixing ratio for the dry component (g/g).
305
+ T_initial (float): Initial guess for temperature (K).
306
+
307
+ Returns:
308
+ tuple: (TG, RG, IFLAG) where:
309
+ TG (float): Temperature (K) satisfying SG(T) = S.
310
+ RG (float): Computed saturated mixing ratio (g/g).
311
+ IFLAG (int): Status flag where:
312
+ 1 = Success
313
+ 2 = Did not converge
314
+
315
+ Examples:
316
+ >>> S = 4000
317
+ >>> P = 1000
318
+ >>> RP = 0.01
319
+ >>> TG, RG, IFLAG = solve_temperature_from_entropy(S, P, RP, T_initial=300)
320
+ >>> print(f"TG: {TG}, RG: {RG}, IFLAG: {IFLAG}")
321
+ TG: 292.676..., RG: 0.0144..., IFLAG: 1
322
+ """
323
+ # Initial default values before loop
324
+ TGNEW = T_initial
325
+ TJC = utilities .T_ktoC (T_initial )
326
+ ES = utilities .es_cc (TJC )
327
+ RG = utilities .rv (ES ,P )
348
328
329
+ #
330
+ # *** Iteratively calculate lifted parcel temperature and mixing ***
331
+ # *** ratio for reversible ascent ***
332
+ #
333
+
334
+ # set loop counter and initial condition
335
+ NC = 0
336
+ TG = 0
337
+
338
+ # loop until loop converges or bails out
339
+ while ((np .abs (TGNEW - TG )) > 0.001 ):
340
+
341
+ # Parcel temperature and mixing ratio during this iteration
342
+ TG = TGNEW
343
+ TC = utilities .T_ktoC (TG )
344
+ ENEW = utilities .es_cc (TC )
345
+ RG = utilities .rv (ENEW ,P )
346
+
347
+ # increase iteration count in the loop
348
+ NC += 1
349
+
350
+ #
351
+ # *** Calculate estimates of the rates of change of the entropy ***
352
+ # *** with temperature at constant pressure ***
353
+ #
354
+
355
+ ALV = utilities .Lv (TC )
356
+ # calculate the rate of change of entropy with temperature, s_ell
357
+ SL = (constants .CPD + RP * constants .CL + ALV * ALV * RG / (constants .RV * TG * TG ))/ TG
358
+ EM = utilities .ev (RG ,P )
359
+ # calculate the saturated entropy, s_k, noting r_T=RP and
360
+ # the last term vanishes with saturation, i.e. RH=1
361
+ SG = (constants .CPD + RP * constants .CL )* np .log (TG )- constants .RD * np .log (P - EM )+ ALV * RG / TG
362
+ # convergence speed (AP, step in entropy fraction) varies as a function of
363
+ # number of iterations
364
+ if (NC < 3 ):
365
+ # converge slowly with a smaller step
366
+ AP = 0.3
367
+ else :
368
+ # speed the process with a larger step when nearing convergence
369
+ AP = 1.0
370
+ # find the new temperature in the iteration
371
+ TGNEW = TG + AP * (S - SG )/ SL
372
+
373
+ #
374
+ # *** If the routine does not converge, set IFLAG=2 and bail out ***
375
+ #
376
+ if (NC > 500 ) or (ENEW > (P - 1 )):
377
+ IFLAG = 2 # Did not converge
378
+ return TG , RG , IFLAG
379
+
380
+ # store the number of iterations
381
+ NCMAX = NC
382
+
383
+ IFLAG = 1 # Success
384
+ return TG , RG , IFLAG
349
385
350
386
351
387
# define the function to calculate PI
0 commit comments