@@ -195,18 +195,11 @@ def R_1n_vectorized(n, r, i, h, d, a):
195195 # ---------------------------------------------------------------------------------
196196
197197 cond_n_is_zero = (n == 0 )
198- cond_r_at_boundary = (r == scale (a )[i ])
198+ cond_r_at_scale = (r == scale (a )[i ])
199199
200200 # --- Define the outcomes for each condition ---
201- # FIX: n=0 logic must match scalar version
202- if i == 0 :
203- outcome_for_n_zero = np .full_like (r , 0.5 )
204- else :
205- # Annulus: 1.0 + 0.5 * log(r / outer)
206- # Use np.divide to handle r=0 gracefully just in case
207- with np .errstate (divide = 'ignore' , invalid = 'ignore' ):
208- val = 1.0 + 0.5 * np .log (np .divide (r , scale (a )[i ]))
209- outcome_for_n_zero = val
201+ # Outcome 1: n=0 eigenfunction (constant)
202+ outcome_for_n_zero = np .full_like (r , 0.5 )
210203
211204 # Outcome 2: If n>=1 and r is at the boundary, the value is 1.0.
212205 outcome_for_r_boundary = 1.0
@@ -221,7 +214,7 @@ def R_1n_vectorized(n, r, i, h, d, a):
221214 exp (safe_lambda * (r - scale (a )[i ]))
222215
223216 # --- Apply the logic using nested np.where ---
224- result_if_n_not_zero = np .where (cond_r_at_boundary , outcome_for_r_boundary , bessel_term )
217+ result_if_n_not_zero = np .where (cond_r_at_scale , outcome_for_r_boundary , bessel_term )
225218
226219 return np .where (cond_n_is_zero , outcome_for_n_zero , result_if_n_not_zero )
227220
@@ -237,11 +230,8 @@ def diff_R_1n_vectorized(n, r, i, h, d, a):
237230
238231 condition = (n == 0 )
239232
240- if i == 0 :
241- value_if_true = np .zeros_like (r )
242- else :
243- # Derivative is 1/(2r)
244- value_if_true = np .divide (1.0 , 2 * r , out = np .full_like (r , np .inf ), where = (r != 0 ))
233+ # n=0 eigenfunction is constant -> derivative is zero
234+ value_if_true = np .zeros_like (r )
245235
246236 # --- Calculation for when n > 0 ---
247237 lambda_val = lambda_ni (n , i , h , d )
@@ -276,31 +266,31 @@ def R_2n_vectorized(n, r, i, a, h, d):
276266 # -------------------------------------------
277267
278268 # LEGACY: Use Outer Radius
279- outer_r = scale (a )[i ]
269+ scale_r = scale (a )[i ]
280270
281271 cond_n_is_zero = (n == 0 )
282- cond_r_at_boundary = (r == outer_r )
272+ cond_r_at_scale = (r == scale_r )
283273
284274 # Case 1: n = 0
285275 with np .errstate (divide = 'ignore' , invalid = 'ignore' ):
286- outcome_for_n_zero = 0.5 * np .log (np .divide (r , outer_r ))
276+ outcome_for_n_zero = 0.5 * np .log (np .divide (r , scale_r ))
287277
288278 # Case 2: n > 0 and r is at the boundary
289- outcome_for_r_boundary = 1.0
279+ outcome_for_r_scale = 1.0
290280
291281 # Case 3: n > 0 and r is not at the boundary
292282 lambda_val = lambda_ni (n , i , h , d )
293283
294284 # Mask input where n=0 to prevent 'inf' errors
295285 lambda_safe = np .where (cond_n_is_zero , 1.0 , lambda_val )
296286
297- # LEGACY: Denom uses OUTER radius
298- denom = besselke (0 , lambda_safe * outer_r )
287+ # LEGACY: Denom uses scaled radius
288+ denom = besselke (0 , lambda_safe * scale_r )
299289 denom = np .where (np .abs (denom ) < 1e-12 , np .nan , denom )
300290
301- bessel_term = (besselke (0 , lambda_safe * r ) / denom ) * exp (lambda_safe * (outer_r - r ))
291+ bessel_term = (besselke (0 , lambda_safe * r ) / denom ) * exp (lambda_safe * (scale_r - r ))
302292
303- result_if_n_not_zero = np .where (cond_r_at_boundary , outcome_for_r_boundary , bessel_term )
293+ result_if_n_not_zero = np .where (cond_r_at_scale , outcome_for_r_scale , bessel_term )
304294
305295 return np .where (cond_n_is_zero , outcome_for_n_zero , result_if_n_not_zero )
306296
@@ -316,19 +306,19 @@ def diff_R_2n_vectorized(n, r, i, h, d, a):
316306
317307 # Case n > 0
318308 lambda_val = lambda_ni (n , i , h , d )
319- outer_r = scale (a )[i ] # LEGACY ANCHOR
309+ scale_r = scale (a )[i ] # LEGACY ANCHOR
320310
321311 lambda_safe = np .where (n == 0 , 1.0 , lambda_val )
322312
323- # LEGACY: Denom uses OUTER radius
324- denom = besselke (0 , lambda_safe * outer_r )
313+ # LEGACY: Denom uses scale radius
314+ denom = besselke (0 , lambda_safe * scale_r )
325315 safe_denom = np .where (np .abs (denom ) < 1e-10 , 1e-10 , denom )
326316
327317 with np .errstate (divide = 'ignore' , invalid = 'ignore' ):
328318 numerator = - lambda_safe * besselke (1 , lambda_safe * r )
329319 ratio = numerator / safe_denom
330320 # LEGACY: Exponential decay from OUTER radius
331- exp_term = exp (lambda_safe * (outer_r - r ))
321+ exp_term = exp (lambda_safe * (scale_r - r ))
332322 value_if_false = ratio * exp_term
333323
334324 return np .where (n == 0 , value_if_true , value_if_false )
@@ -386,9 +376,9 @@ def Lambda_k_vectorized(k, r, m0, a, m_k_arr):
386376 # -------------------------------------------
387377
388378 cond_k_is_zero = (k == 0 )
389- cond_r_at_boundary = (r == scale (a )[- 1 ])
379+ cond_r_at_scale = (r == scale (a )[- 1 ])
390380
391- outcome_boundary = 1.0
381+ outcome_scale = 1.0
392382
393383 # --- Case 2: k = 0 ---
394384 if m0 == inf :
@@ -426,13 +416,13 @@ def Lambda_k_vectorized(k, r, m0, a, m_k_arr):
426416 where = np .isfinite (denom_k_nonzero ) & (denom_k_nonzero != 0 ))
427417 outcome_k_nonzero = bessel_ratio * exp (safe_m_k * (scale (a )[- 1 ] - r ))
428418
429- result_if_not_boundary = np .where (cond_k_is_zero ,
419+ result_if_not_scale = np .where (cond_k_is_zero ,
430420 outcome_k_zero ,
431421 outcome_k_nonzero )
432422
433- return np .where (cond_r_at_boundary ,
434- outcome_boundary ,
435- result_if_not_boundary )
423+ return np .where (cond_r_at_scale ,
424+ outcome_scale ,
425+ result_if_not_scale )
436426
437427# Differentiate wrt r
438428def diff_Lambda_k_vectorized (k , r , m0 , a , m_k_arr ):
@@ -567,27 +557,11 @@ def diff_Z_k_e_vectorized(k, z, m0, h, m_k_arr, N_k_arr):
567557#integrating R_1n * r
568558# Integration
569559def int_R_1n (i , n , a , h , d ):
570- if n == 0 :
560+ if n == 0 : # Integral of 0.5 * r
571561 if i == 0 :
572- # Central cylinder: Integral of 0.5 * r
573562 return a [i ]** 2 / 4
574563 else :
575- # Annulus: Integral of r * (1.0 + 0.5 * ln(r/outer_r))
576- outer_r = scale (a )[i ]
577- inner_r = a [i - 1 ]
578-
579- cyl_term = (outer_r ** 2 - inner_r ** 2 ) / 2.0
580-
581- def log_indefinite_int (r ):
582- # Integral of 0.5 * r * ln(r/outer)
583- # = 0.5 * [ (r^2/2)*ln(r/outer) - r^2/4 ]
584- log_val = np .log (r / outer_r ) if r > 0 else 0
585- return 0.5 * ((r ** 2 / 2.0 ) * log_val - (r ** 2 / 4.0 ))
586-
587- val_outer = log_indefinite_int (outer_r ) # log(1)=0, so just -r^2/4 term
588- val_inner = log_indefinite_int (inner_r )
589-
590- return cyl_term + (val_outer - val_inner )
564+ return (a [i ]** 2 - a [i - 1 ]** 2 )/ 4
591565 else :
592566 # Standard Bessel I integral (Unchanged)
593567 lambda0 = lambda_ni (n , i , h , d )
@@ -608,8 +582,9 @@ def int_R_2n(i, n, a, h, d):
608582 raise ValueError ("i cannot be 0" )
609583
610584 # LEGACY: Use Outer Radius
611- outer_r = scale ( a ) [i ]
585+ outer_r = a [i ]
612586 inner_r = a [i - 1 ] # Previous radius is inner
587+ scale_r = scale (a )[i ]
613588
614589 if n == 0 :
615590 # Integral of r * (0.5 * ln(r/outer_r))
@@ -618,7 +593,7 @@ def int_R_2n(i, n, a, h, d):
618593 def indefinite (r ):
619594 if r <= 0 : return 0
620595 # ln(r/outer_r) is 0 when r=outer_r
621- term_log = np .log (r / outer_r )
596+ term_log = np .log (r / scale_r )
622597 return 0.5 * ((r ** 2 / 2 ) * term_log - (r ** 2 / 4 ))
623598
624599 val_outer = indefinite (outer_r )
@@ -629,13 +604,14 @@ def indefinite(r):
629604 lambda0 = lambda_ni (n , i , h , d )
630605
631606 term_outer = (outer_r * besselke (1 , lambda0 * outer_r ))
632- # exp(la - la) = 1, so no exp factor needed for outer term.
607+ # exp(la - la) = 1, for scale = outer_r, so no exp factor needed for outer term in that case.
608+ term_outer *= np .exp (lambda0 * (scale_r - outer_r ))
633609
634610 term_inner = (inner_r * besselke (1 , lambda0 * inner_r ))
635611 # exp(la - li). We need to multiply by this.
636- term_inner *= np .exp (lambda0 * (outer_r - inner_r ))
612+ term_inner *= np .exp (lambda0 * (scale_r - inner_r ))
637613
638- denom = lambda0 * besselke (0 , lambda0 * outer_r )
614+ denom = lambda0 * besselke (0 , lambda0 * scale_r )
639615
640616 return (term_inner - term_outer ) / denom
641617#integrating phi_p_i * d_phi_p_i/dz * r *d_r at z=d[i]
@@ -657,8 +633,8 @@ def z_n_d(n):
657633#############################################
658634def excitation_phase (x , NMK , m0 , a ): # x-vector of unknown coefficients
659635 coeff = x [- NMK [- 1 ]] # first coefficient of e-region expansion
660- local_scale = scale (a )
661- return - (pi / 2 ) + np .angle (coeff ) - np .angle (besselh (0 , m0 * local_scale [ - 1 ] ))
636+ exterior_scale = scale (a )[ - 1 ]
637+ return - (pi / 2 ) + np .angle (coeff ) - np .angle (besselh (0 , m0 * exterior_scale ))
662638
663639def excitation_force (damping , m0 , h ):
664640 # --- FIX: Handle infinite m0 ---
0 commit comments