@@ -152,22 +152,6 @@ class Coefficients:
152152 c : Iterable [float ]
153153 s : Iterable [float ]
154154
155- @property
156- def num_coef_pairs (self ) -> int :
157- """
158- The length of .c and .s, which should be the same.
159- Raises
160- ------
161- ValueError:
162- If .c and .s do not match in length, then we have a problem.
163- """
164- if len (self .c )!= len (self .s ):
165- raise ValueError (
166- "Mismatched lengths between "
167- f"c ({ len (self .c )} ) and s ({ len (self .s )} )"
168- )
169- return len (self .c )
170-
171155 def validate_length (self , exp_len : int , parent_name : str ):
172156 """Validate that all fields has the correct length."""
173157 for const_name , const_value in asdict (self ).items ():
@@ -545,7 +529,7 @@ def _calculate_mean_energy_and_incident_bin(
545529
546530 def _groupwise_cs_values_in_layer (
547531 self , n : int , num_layer : int , x : float | npt .NDArray
548- ) -> tuple [ float , float ] | tuple [ npt .NDArray , npt . NDArray ] :
532+ ) -> npt .NDArray :
549533 """
550534 Calculate the num_layer-th layer n-th basis function at the specified
551535 x position(s).
@@ -557,7 +541,7 @@ def _groupwise_cs_values_in_layer(
557541 else :
558542 l = np .sqrt (- self .l2 [num_layer , n ])
559543 c , s = np .cos , np .sin
560- return c (abs_x / l ), s (abs_x / l )
544+ return np . array ([ c (abs_x / l ), s (abs_x / l )] )
561545
562546 def _groupwise_cs_differential_in_layer (
563547 self , n : int , num_layer : int , x : float | npt .NDArray
@@ -569,9 +553,9 @@ def _groupwise_cs_differential_in_layer(
569553 abs_x = abs (x )
570554 if self .l2 [num_layer , n ] > 0 :
571555 l = np .sqrt (self .l2 [num_layer , n ])
572- return np .sinh (abs_x / l ) / l , np .cosh (abs_x / l ) / l
556+ return np .array ([ np . sinh (abs_x / l ) / l , np .cosh (abs_x / l ) / l ])
573557 l = np .sqrt (- self .l2 [num_layer , n ])
574- return - np .sin (abs_x / l ) / l , np .cos (abs_x / l ) / l
558+ return np . array ([ - np .sin (abs_x / l ) / l , np .cos (abs_x / l ) / l ])
575559
576560 def _groupwise_cs_definite_integral_in_layer (
577561 self , n : int , num_layer : int , x_lower : float | npt .NDArray , x_upper
@@ -582,15 +566,15 @@ def _groupwise_cs_definite_integral_in_layer(
582566 """
583567 if self .l2 [num_layer , n ] > 0 :
584568 l = np .sqrt (self .l2 [num_layer , n ])
585- return (
569+ return np . array ([
586570 l * (np .sinh (x_upper / l ) - np .sinh (x_lower / l )),
587571 l * (np .cosh (x_upper / l ) - np .cosh (x_lower / l ))
588- )
572+ ] )
589573 l = np .sqrt (- self .l2 [num_layer , n ])
590- return (
574+ return np . array ([
591575 l * (np .sin (x_upper / l ) - np .sin (x_lower / l )),
592576 l * (np .cos (x_lower / l ) - np .cos (x_upper / l )) # reverse sign
593- )
577+ ] )
594578
595579 def solve_lowest_group (self ) -> None :
596580 """
@@ -666,9 +650,62 @@ def solve_lowest_group(self) -> None:
666650 [bz_c_factor ], [bz_s_factor ]
667651 )
668652 else :
669- raise NotImplementedError ( "Only implemented 2 groups so far." )
653+ return NotImplemented
670654 return
671655
656+ def _get_propagation_matrix_and_offset_vec (n : int , num_layer : int ):
657+ """
658+ Infer this layer's main basis functions' coefficients (.c[n] and .s[n])
659+ using using the previous layer's basis functions.
660+ """
661+ x_j = self .interface_x [num_layer ]
662+ coefs_in = np .array (astuple (self .coefficients [num_layer - 1 , n ])).T
663+ coefs_jn = np .array (astuple (self .coefficients [num_layer , n ])).T
664+ d_in = self .diffusion_const [num_layer - 1 , n ]
665+ d_jn = self .diffusion_const [num_layer , n ]
666+ l_in = self .l2 [num_layer - 1 , n ]
667+ l_jn = self .l2 [num_layer , n ]
668+
669+ diff_residual_flux = (sum (
670+ cs_coef_pair @ self ._groupwise_cs_values_in_layer (
671+ g , num_layer - 1 , x_j
672+ )
673+ for g , cs_coef_pair in enumerate (coefs_in ) if g != n
674+ ) - sum (
675+ cs_coef_pair @ self ._groupwise_cs_values_in_layer (
676+ g , num_layer , x_j
677+ )
678+ for g , cs_coef_pair in enumerate (coefs_jn ) if g != n
679+ )
680+ )
681+ diff_residual_current = l_jn * (
682+ - d_in / d_jn * sum (
683+ cs_coef_pair @ self ._groupwise_cs_differential_in_layer (
684+ g , num_layer - 1 , x_j
685+ )
686+ for g , cs_coef_pair in enumerate (coefs_in ) if g != n
687+ )
688+ + sum (
689+ cs_coef_pair @ self ._groupwise_cs_differential_in_layer (
690+ g , num_layer , x_j
691+ )
692+ for g , cs_coef_pair in enumerate (coefs_jn ) if g != n
693+ )
694+ )
695+ shift_vector = np .array ([diff_residual_flux , diff_residual_current ])
696+
697+ transformation_matrix = np .array ([
698+ self ._groupwise_cs_values_in_layer (n , num_layer - 1 , x_j ),
699+ - l_jn / d_jn * d_in / l_in * (
700+ self ._groupwise_cs_differential_in_layer (n , num_layer - 1 , x_j )
701+ ),
702+ ])
703+ A = np .array ([
704+ self ._groupwise_cs_values_in_layer (n , num_layer , x_j ),
705+ - self ._groupwise_cs_differential_in_layer (n , num_layer , x_j ),
706+ ])
707+ return A @ transformation_matrix , A @ shift_vector
708+
672709 def solve_group_n (self , n : int ) -> None :
673710 """
674711 Solve the n-th group of neutron's diffusion equation, where n <=
@@ -761,8 +798,8 @@ def solve_group_n(self, n: int) -> None:
761798 )
762799 * scale_factor
763800 )
764- _coefs [num_layer , n ].c [n ] = sum (skipped_c_coefs )
765- _coefs [num_layer , n ].s [n ] = sum (skipped_s_coefs )
801+ _coefs [num_layer , n ].c [n ] = ... - sum (skipped_c_coefs )
802+ _coefs [num_layer , n ].s [n ] = ... - sum (skipped_s_coefs )
766803
767804 self .coefficients [num_layer , n ] = _coefs
768805
0 commit comments