@@ -10,14 +10,15 @@ use log::info;
10
10
/// This nonlinear solver makes use of a model trust-region method that makes use of a dogleg solver
11
11
/// for the sub-problem of the nonlinear problem. It reduces down to taking a full newton raphson step
12
12
/// when a given step is near the solution.
13
- pub struct TrustRegionDoglegSolver < ' a , const NP_NDIM : usize , F , NP >
13
+ pub struct TrustRegionDoglegSolver < ' a , F , NP >
14
14
where
15
15
F : crate :: FloatType ,
16
- NP : NonlinearProblem < F > ,
16
+ NP : NonlinearProblem < F > + Sized ,
17
+ [ f64 ; NP :: NDIM ] : Sized ,
17
18
{
18
19
/// The field we're solving for. Although, we typically are solving for a scaled version of this in order to have
19
20
/// a numerically stable system of equations.
20
- pub x : [ F ; NP_NDIM ] ,
21
+ pub x : [ F ; NP :: NDIM ] ,
21
22
/// This controls the step size that our solver takes while iterating for a solution
22
23
delta_control : & ' a TrustRegionDeltaControl < F > ,
23
24
/// The total number of function evaluations our solver took
@@ -44,13 +45,14 @@ where
44
45
logging_level : i32 ,
45
46
}
46
47
47
- impl < ' a , const NP_NDIM : usize , F , NP > TrustRegionDoglegSolver < ' a , NP_NDIM , F , NP >
48
+ impl < ' a , F , NP > TrustRegionDoglegSolver < ' a , F , NP >
48
49
where
49
50
F : crate :: FloatType ,
50
51
NP : NonlinearProblem < F > ,
52
+ [ f64 ; NP :: NDIM ] : Sized ,
51
53
{
52
54
/// The size of the jacobian
53
- const NDIM2 : usize = NP_NDIM * NP_NDIM ;
55
+ const NDIM2 : usize = NP :: NDIM * NP :: NDIM ;
54
56
55
57
/// Creates a new solver with default values for a number of fields when provided the delta control
56
58
/// and the nonlinear problem structure
@@ -64,14 +66,14 @@ where
64
66
pub fn new (
65
67
delta_control : & ' a TrustRegionDeltaControl < F > ,
66
68
crj : & ' a mut NP ,
67
- ) -> TrustRegionDoglegSolver < ' a , { NP_NDIM } , F , NP > {
68
- TrustRegionDoglegSolver :: < ' a , { NP_NDIM } , F , NP > {
69
- x : [ F :: zero ( ) ; NP_NDIM ] ,
69
+ ) -> TrustRegionDoglegSolver < ' a , F , NP > {
70
+ TrustRegionDoglegSolver :: < ' a , F , NP > {
71
+ x : [ F :: zero ( ) ; NP :: NDIM ] ,
70
72
delta_control,
71
73
function_evals : 0 ,
72
74
jacobian_evals : 0 ,
73
75
num_iterations : 0 ,
74
- max_iterations : NP_NDIM * 1000 ,
76
+ max_iterations : NP :: NDIM * 1000 ,
75
77
solution_tolerance : F :: from ( 1e-12 ) . unwrap ( ) ,
76
78
l2_error : -F :: one ( ) ,
77
79
delta : F :: from ( 1e8 ) . unwrap ( ) ,
@@ -86,37 +88,45 @@ where
86
88
fn compute_newton_step (
87
89
& self ,
88
90
residual : & [ F ] ,
89
- jacobian : & mut [ [ F ; NP_NDIM ] ] ,
91
+ jacobian : & mut [ [ F ; NP :: NDIM ] ] ,
90
92
newton_step : & mut [ F ] ,
91
93
) -> Result < ( ) , crate :: helix_error:: SolverError >
92
94
where
93
- [ F ; NP_NDIM + 1 ] : Sized ,
95
+ [ F ; NP :: NDIM + 1 ] : Sized ,
94
96
{
95
- lup_solver :: < { NP_NDIM } , F > ( residual, jacobian, newton_step) ?;
96
- for item in newton_step. iter_mut ( ) . take ( NP_NDIM ) {
97
+ lup_solver :: < { NP :: NDIM } , F > ( residual, jacobian, newton_step) ?;
98
+ for item in newton_step. iter_mut ( ) . take ( NP :: NDIM ) {
97
99
* item *= -F :: one ( ) ;
98
100
}
99
101
Ok ( ( ) )
100
102
}
101
103
102
104
/// Rejects the current iterations solution and returns the solution to its previous value
103
105
fn reject ( & mut self , delta_x : & [ F ] ) {
104
- assert ! ( delta_x. len( ) >= NP_NDIM ) ;
106
+ assert ! ( delta_x. len( ) >= NP :: NDIM ) ;
105
107
106
- for ( i_x, item) in delta_x. iter ( ) . enumerate ( ) . take ( NP_NDIM ) {
108
+ for ( i_x, item) in delta_x. iter ( ) . enumerate ( ) . take ( NP :: NDIM ) {
107
109
self . x [ i_x] -= * item;
108
110
}
109
111
}
110
112
}
111
113
112
- impl < ' a , const NP_NDIM : usize , F , NP > NonlinearSolver < F >
113
- for TrustRegionDoglegSolver < ' a , NP_NDIM , F , NP >
114
+ impl < ' a , F , NP > NonlinearSystemSize for TrustRegionDoglegSolver < ' a , F , NP >
115
+ where
116
+ F : crate :: FloatType ,
117
+ NP : NonlinearProblem < F > ,
118
+ [ F ; NP :: NDIM ] : Sized ,
119
+ {
120
+ const NDIM : usize = NP :: NDIM ;
121
+ }
122
+
123
+ impl < ' a , F , NP > NonlinearSolver < F >
124
+ for TrustRegionDoglegSolver < ' a , F , NP >
114
125
where
115
126
F : crate :: FloatType ,
116
127
NP : NonlinearProblem < F > ,
117
- [ F ; NP_NDIM + 1 ] : Sized ,
128
+ [ F ; NP :: NDIM + 1 ] : Sized ,
118
129
{
119
- const NDIM : usize = NP_NDIM ;
120
130
fn setup_options ( & mut self , max_iter : usize , tolerance : F , output_level : Option < i32 > ) {
121
131
self . converged = false ;
122
132
self . function_evals = 0 ;
@@ -148,14 +158,14 @@ where
148
158
info ! ( "Initial delta = {:?}" , self . delta) ;
149
159
}
150
160
151
- let mut residual = [ F :: zero ( ) ; NP_NDIM ] ;
152
- let mut jacobian = [ [ F :: zero ( ) ; NP_NDIM ] ; NP_NDIM ] ;
161
+ let mut residual = [ F :: zero ( ) ; NP :: NDIM ] ;
162
+ let mut jacobian = [ [ F :: zero ( ) ; NP :: NDIM ] ; NP :: NDIM ] ;
153
163
154
- if !self . compute_residual_jacobian :: < { NP_NDIM } > ( & mut residual, & mut jacobian) {
164
+ if !self . compute_residual_jacobian ( & mut residual, & mut jacobian) {
155
165
return Err ( crate :: helix_error:: SolverError :: InitialEvalFailure ) ;
156
166
}
157
167
158
- self . l2_error = norm :: < { NP_NDIM } , F > ( & residual) ;
168
+ self . l2_error = norm :: < { NP :: NDIM } , F > ( & residual) ;
159
169
160
170
let mut l2_error_0 = self . l2_error ;
161
171
@@ -165,28 +175,28 @@ where
165
175
166
176
let mut reject_previous = false ;
167
177
168
- let mut newton_raphson_step = [ F :: zero ( ) ; NP_NDIM ] ;
169
- let mut gradient = [ F :: zero ( ) ; NP_NDIM ] ;
170
- let mut delta_x = [ F :: zero ( ) ; NP_NDIM ] ;
178
+ let mut newton_raphson_step = [ F :: zero ( ) ; NP :: NDIM ] ;
179
+ let mut gradient = [ F :: zero ( ) ; NP :: NDIM ] ;
180
+ let mut delta_x = [ F :: zero ( ) ; NP :: NDIM ] ;
171
181
let mut jacob_grad_2 = F :: zero ( ) ;
172
182
173
183
while self . num_iterations < self . max_iterations {
174
184
self . num_iterations += 1 ;
175
185
176
186
if !reject_previous {
177
- mat_t_vec_mult :: < { NP_NDIM } , { NP_NDIM } , F > ( & jacobian, & residual, & mut gradient) ;
178
- let mut temp = [ F :: zero ( ) ; NP_NDIM ] ;
179
- mat_vec_mult :: < { NP_NDIM } , { NP_NDIM } , F > ( & jacobian, & gradient, & mut temp) ;
180
- jacob_grad_2 = dot_prod :: < { NP_NDIM } , F > ( & temp, & temp) ;
187
+ mat_t_vec_mult :: < { NP :: NDIM } , { NP :: NDIM } , F > ( & jacobian, & residual, & mut gradient) ;
188
+ let mut temp = [ F :: zero ( ) ; NP :: NDIM ] ;
189
+ mat_vec_mult :: < { NP :: NDIM } , { NP :: NDIM } , F > ( & jacobian, & gradient, & mut temp) ;
190
+ jacob_grad_2 = dot_prod :: < { NP :: NDIM } , F > ( & temp, & temp) ;
181
191
self . compute_newton_step ( & residual, & mut jacobian, & mut newton_raphson_step) ?;
182
192
}
183
193
184
194
let mut predicted_residual = -F :: one ( ) ;
185
195
let mut use_newton_raphson = false ;
186
196
187
- let newton_raphson_l2_norm = norm :: < { NP_NDIM } , F > ( & newton_raphson_step) ;
197
+ let newton_raphson_l2_norm = norm :: < { NP :: NDIM } , F > ( & newton_raphson_step) ;
188
198
189
- dogleg :: < { NP_NDIM } , F > (
199
+ dogleg :: < { NP :: NDIM } , F > (
190
200
self . delta ,
191
201
l2_error_0,
192
202
newton_raphson_l2_norm,
@@ -203,8 +213,8 @@ where
203
213
204
214
{
205
215
let resid_jacob_success =
206
- self . compute_residual_jacobian :: < { NP_NDIM } > ( & mut residual, & mut jacobian) ;
207
- let converged = self . delta_control . update :: < { NP_NDIM } > (
216
+ self . compute_residual_jacobian ( & mut residual, & mut jacobian) ;
217
+ let converged = self . delta_control . update :: < { NP :: NDIM } > (
208
218
& residual,
209
219
l2_error_0,
210
220
predicted_residual,
@@ -259,10 +269,10 @@ where
259
269
jacobian : & mut [ [ F ; NDIM ] ] ,
260
270
) -> bool {
261
271
assert ! (
262
- NP_NDIM == NDIM ,
272
+ NP :: NDIM == NDIM ,
263
273
"Self::NDIM/NP_NDIM and const NDIMs are not equal..."
264
274
) ;
265
275
self . crj
266
- . compute_resid_jacobian :: < { NDIM } > ( & self . x , fcn_eval, & mut Some ( jacobian) )
276
+ . compute_resid_jacobian ( & self . x , fcn_eval, & mut Some ( jacobian) )
267
277
}
268
278
}
0 commit comments