@@ -34,9 +34,58 @@ module num_lib
34
34
! NOTE: because of copyright restrictions,
35
35
! mesa doesn' t use any routines from Numerical Recipes.
36
36
37
-
38
37
implicit none
39
38
39
+ private
40
+ public :: find0
41
+ public :: find0_quadratic
42
+ public :: binary_search
43
+ public :: binary_search_sg
44
+ public :: safe_root
45
+ public :: safe_root_with_guess
46
+ public :: safe_root_with_brackets
47
+ public :: safe_root_without_brackets
48
+ public :: null_mas
49
+ public :: null_fcn
50
+ public :: null_jac
51
+ public :: null_sjac
52
+ public :: null_fcn_blk_dble
53
+ public :: null_jac_blk_dble
54
+ public :: brent_safe_zero
55
+ public :: brent_local_min
56
+ public :: brent_global_min
57
+ public :: default_bdomain
58
+ public :: default_force_another_iter
59
+ public :: default_inspectb
60
+ public :: default_set_primaries
61
+ public :: default_set_secondaries
62
+ public :: default_size_equ
63
+ public :: default_sizeb
64
+ public :: default_xdomain
65
+ public :: integrate
66
+ public :: bobyqa
67
+ public :: dop853
68
+ public :: dop853_work_sizes
69
+ public :: isolve
70
+ public :: isolve_work_sizes
71
+ public :: dopri5
72
+ public :: dopri5_work_sizes
73
+ public :: newton
74
+ public :: newton_work_sizes
75
+ public :: newuoa
76
+ public :: find_max_quadratic
77
+ public :: look_for_brackets
78
+ public :: nm_simplex
79
+ public :: qsort
80
+ public :: qsort_string_index
81
+ public :: iln10
82
+ public :: dfridr
83
+ public :: solver_option
84
+ public :: linear_interp
85
+ public :: two_piece_linear_coeffs
86
+ public :: simplex_info_str
87
+ public :: simplex_op_code
88
+
40
89
41
90
contains ! the procedure interface for the library
42
91
! client programs should only call these routines.
@@ -47,7 +96,7 @@ module num_lib
47
96
! safe root finding
48
97
! uses alternating bisection and inverse parabolic interpolation
49
98
! also have option to use derivative as accelerator (newton method)
50
- include "num_safe_root.dek"
99
+ include "num_safe_root.dek"
51
100
52
101
53
102
! solvers for ODEs and DAEs.
@@ -59,7 +108,7 @@ module num_lib
59
108
60
109
61
110
! but there are lots of fancier options too.
62
-
111
+
63
112
64
113
! selections from the Hairer family of ODE/DAE integrators.
65
114
! from Ernst Hairer' s website: http:// www.unige.ch/ ~hairer/
@@ -75,16 +124,16 @@ module num_lib
75
124
include " num_dop853.dek" ! " DOramand Prince order 8(5, 3)"
76
125
77
126
! both integrators have automatic step size control and monitoring for stiffness.
78
-
127
+
79
128
! For a description see:
80
129
! Hairer, Norsett and Wanner (1993 ):
81
130
! Solving Ordinary Differential Equations. Nonstiff Problems. 2nd edition.
82
131
! Springer Series in Comput. Math., vol. 8 .
83
132
! http:// www.unige.ch/ ~hairer/ books.html
84
-
85
-
133
+
134
+
86
135
! implicit solvers (for stiff problems)
87
-
136
+
88
137
! there are a bunch of implicit solvers to pick from (listed below),
89
138
! but they all have pretty much the same arguments,
90
139
! so I' ve provided a general routine, called "isolve", that let' s you
@@ -96,10 +145,10 @@ module num_lib
96
145
! rather than calling one of the particular solvers.
97
146
! only call a specific solver if you need a feature it provides
98
147
! that isn' t supported by isolve.
99
-
148
+
100
149
! you can find an example program using isolve in num/test/src/sample_ode_solver.f
101
-
102
-
150
+
151
+
103
152
! the implicit solver routines
104
153
105
154
! for detailed descriptions of these routines see:
@@ -139,15 +188,15 @@ module num_lib
139
188
! that work well at high tolerances will fail with low
140
189
! tolerances and vice-versa. so you need to match
141
190
! the solver to the problem.
142
-
191
+
143
192
! your best bet is to try them all on some typical cases.
144
193
! happily this isn' t too hard to do since they all
145
194
! use the same function arguments and have (almost)
146
195
! identical calling sequences and options.
147
-
148
-
196
+
197
+
149
198
! flexible choice of linear algebra routines
150
-
199
+
151
200
! the solvers need to solve linear systems.
152
201
! this is typically done by first factoring the matrix A
153
202
! and then repeatedly using the factored form to solve
@@ -158,10 +207,10 @@ module num_lib
158
207
! routines to perform these tasks. the mesa/ mtx package
159
208
! includes several choices for implementations of the
160
209
! required routines.
161
-
162
-
210
+
211
+
163
212
! dense, banded, or sparse matrix
164
-
213
+
165
214
! All the packages allow the matrix to be in dense or banded form.
166
215
! the choice of sparse matrix package is not fixed by the solvers.
167
216
! the only constraint is the the sparse format must be either
@@ -171,10 +220,10 @@ module num_lib
171
220
! Since the sparse routines are passed as arguments to the solvers,
172
221
! it is possible to experiment with different linear algebra
173
222
! packages without a great deal of effort.
174
-
175
-
223
+
224
+
176
225
! analytical or numerical jacobian
177
-
226
+
178
227
! to solve M* y' = f(y), the solvers need to have the jacobian matrix, df/dy.
179
228
! the jacobian can either be calculated analytically by a user supplied routine,
180
229
! or the solver can form a numerical difference estimate by repeatedly
@@ -192,7 +241,7 @@ module num_lib
192
241
193
242
194
243
! explicit or implicit ODE systems
195
-
244
+
196
245
! systems of the form y' = f(y) are called " explicit ODE systems" .
197
246
198
247
! systems of the form M* y' = f(y), with M not equal to the identity matrix,
@@ -204,44 +253,44 @@ module num_lib
204
253
! even including the case of M singular.
205
254
206
255
! for M non-constant, see the discussion of "problems with special structure"
207
-
208
-
256
+
257
+
209
258
! problems with special structure
210
-
259
+
211
260
! 3 special cases can be handled easily
212
-
261
+
213
262
! case 1, second derivatives: y'' = f(t, y, y' )
214
263
! case 2 , nonconstant matrix: C(x, y)* y' = f(t, y)
215
264
! case 3, both of the above: C(x, y)*y'' = f(t, y, y' )
216
-
265
+
217
266
! these all work by adding auxiliary variables to the problem and
218
267
! converting back to the standard form with a constant matrix M.
219
268
220
269
! case 1 : y' ' = f(t, y, y' )
221
270
! after add auxiliary variables z, this becomes
222
271
! y' = z
223
272
! z' = f(t, y, z)
224
-
273
+
225
274
! case 2: C(x, y)*y' = f(t, y)
226
275
! after add auxiliary variables z, this becomes
227
276
! y' = z
228
277
! 0 = C(x, y)*z - f(t, y)
229
-
278
+
230
279
! case 3: C(x, y)*y'' = f(t, y, y' )
231
280
! after add auxiliary variables z and u, this becomes
232
281
! y' = z
233
282
! z' = u
234
283
! 0 = C(x, y)* u - f(t, y, z)
235
-
284
+
236
285
! The last two cases take advantage of the ability to have M singular.
237
-
286
+
238
287
! If the matrix for df/ dy is dense in these special cases, all the solvers
239
288
! can reduce the cost of the linear algebra operations by special treatment
240
289
! of the auxiliary variables.
241
-
242
-
290
+
291
+
243
292
! " projection" of solution to valid range of values.
244
-
293
+
245
294
! it is often the case that the n- dimensional solution
246
295
! is actually constrained to a subspace of full n dimensional
247
296
! space of numbers. The proposed solutions at each step
@@ -250,10 +299,10 @@ module num_lib
250
299
! option by calling a " solout" routine, supplied by the user,
251
300
! after every accepted step. The user' s solout routine can modify
252
301
! the solution y before returning to continue the integration.
253
-
254
-
302
+
303
+
255
304
! "dense output"
256
-
305
+
257
306
! the routines provide estimates of the solution over entire step.
258
307
! useful for tabulating the solution at prescribed points
259
308
! or for smooth graphical presentation of the solution.
@@ -301,7 +350,7 @@ subroutine null_fcn_blk_dble(n, caller_id, nvar, nz, x, h, y, f, lrpar, rpar, li
301
350
integer , intent (out ) :: ierr ! nonzero means retry with smaller timestep.
302
351
f= 0 ; ierr= 0
303
352
end subroutine null_fcn_blk_dble
304
-
353
+
305
354
306
355
subroutine null_jac (n , x , h , y , f , dfy , ldfy , lrpar , rpar , lipar , ipar , ierr )
307
356
integer , intent (in ) :: n, ldfy, lrpar, lipar
@@ -376,8 +425,8 @@ end function interp_y
376
425
integer , intent (out ) :: irtrn
377
426
irtrn = 0
378
427
end subroutine null_solout
379
-
380
-
428
+
429
+
381
430
subroutine null_dfx (n , x , y , fx , lrpar , rpar , lipar , ipar , ierr )
382
431
integer , intent (in ) :: n, lrpar, lipar
383
432
real (dp), intent (in ) :: x, y(:) ! (n)
@@ -388,15 +437,14 @@ subroutine null_dfx(n, x, y, fx, lrpar, rpar, lipar, ipar, ierr)
388
437
ierr = 0
389
438
fx = 0
390
439
end subroutine null_dfx
391
-
392
-
440
+
441
+
393
442
! Newton- Raphson iterative solver for nonlinear systems
394
443
! square or banded
395
444
! analytic or numerical difference jacobian
396
445
! where possible, reuses jacobian to improve efficiency
397
446
! uses line search method to improve " global" convergence
398
447
include " num_newton.dek"
399
-
400
448
401
449
402
450
! minimize scalar function of many variables without using derivatives.
@@ -430,13 +478,11 @@ end subroutine null_dfx
430
478
! "A Simplex Method for Function Minimization."
431
479
! Comput. J. 7, 308-313, 1965.
432
480
433
-
434
-
481
+
435
482
! global or local minimum of scalar function of 1 variable
436
483
include "num_brent.dek"
437
484
438
485
439
-
440
486
! QuickSort. ACM Algorithm 402, van Emden, 1970
441
487
! mesa' s implementation from Joseph M. Krahn
442
488
! http:// fortranwiki.org/ fortran/ show/ qsort_inline
@@ -447,23 +493,23 @@ subroutine qsort(index,n,vals)
447
493
real (dp) :: vals(:)
448
494
call sortp_dp(n,index,vals)
449
495
end subroutine qsort
450
-
496
+
451
497
subroutine qsort_strings (index ,n ,strings )
452
498
use mod_qsort, only: sortp_string
453
499
integer :: index (:), n
454
500
character (len=* ), intent (in ) :: strings(:)
455
501
call sortp_string(n,index,strings)
456
502
end subroutine qsort_strings
457
-
503
+
458
504
subroutine qsort_string_index (index ,n ,string_index ,strings )
459
505
use mod_qsort, only: sortp_string_index
460
506
integer :: index (:), n
461
507
integer , intent (in ) :: string_index(:) ! (n)
462
508
character (len=* ), intent (in ) :: strings(:) ! 1 ..maxval (string_index)
463
509
call sortp_string_index(n,index,string_index,strings)
464
510
end subroutine qsort_string_index
465
-
466
-
511
+
512
+
467
513
! random numbers
468
514
real(dp) function get_dp_uniform_01 (seed )
469
515
! returns a unit pseudorandom real (dp)
@@ -480,8 +526,8 @@ function get_i4_uniform(a, b, seed)
480
526
integer ( kind = 4 ) a, b, seed, get_i4_uniform
481
527
get_i4_uniform = i4_uniform(a, b, seed)
482
528
end function get_i4_uniform
483
-
484
-
529
+
530
+
485
531
subroutine get_perm_uniform ( n , base , seed , p )
486
532
! selects a random permutation of n integers
487
533
use mod_random, only: perm_uniform
@@ -491,20 +537,20 @@ subroutine get_perm_uniform ( n, base, seed, p )
491
537
integer ( kind = 4 ) seed
492
538
call perm_uniform ( n, base, seed, p )
493
539
end subroutine get_perm_uniform
494
-
495
-
540
+
541
+
496
542
subroutine get_seed_for_random (seed )
497
543
! returns a seed for the random number generator
498
544
use mod_random, only: get_seed
499
545
integer ( kind = 4 ) seed
500
546
call get_seed(seed)
501
547
end subroutine get_seed_for_random
502
548
503
-
549
+
504
550
! binary search
505
551
include " num_binary_search.dek"
506
552
507
-
553
+
508
554
real(dp) function linear_interp (x1 , y1 , x2 , y2 , x )
509
555
real (dp), intent (in ) :: x1, y1, x2, y2, x
510
556
if (x2 == x1) then
@@ -582,8 +628,8 @@ subroutine find_max_quadratic(x1, y1, x2, y2, x3, y3, xmax, ymax, ierr)
582
628
if (y2 < max (y1,y2)) ierr = - 1
583
629
if (.not. ((x1 < x2 .and. x2 < x3) .or. (x1 > x2 .and. x2 > x3))) ierr = - 1
584
630
end subroutine find_max_quadratic
585
-
586
-
631
+
632
+
587
633
subroutine two_piece_linear_coeffs (x , x0 , x1 , x2 , a0 , a1 , a2 , ierr )
588
634
! interpolation value at x is a0* f(x0) + a1* f(x1) + a2* f(x2)
589
635
real (dp), intent (in ) :: x, x0, x1, x2
0 commit comments