LMMC
Lamina Mathematic core
载入中...
搜索中...
未找到
ode_common.c
浏览该文件的文档.
1
5#include "internal.h"
6#include "lmmc/ode.h"
7
9 switch (reason) {
11 return "none";
12 }
14 return "invalid dimension";
15 }
17 return "invalid step";
18 }
20 return "max steps reached";
21 }
23 return "numerical issue";
24 }
26 return "rhs evaluation failed";
27 }
29 return "tolerance inconsistent";
30 }
31 default: {
32 return "unknown";
33 }
34 }
35}
36
37static size_t ode_default_max_steps(size_t problem_dim) {
38 if (problem_dim > ((size_t)-1) / 10000) {
39 return 100000;
40 }
41 size_t max_steps = problem_dim * 10000;
42 if (max_steps < 1000) {
43 max_steps = 1000;
44 }
45 return max_steps;
46}
47
49 lmmc_real_t t_start,
50 lmmc_real_t t_end,
51 size_t problem_dim,
52 lmmc_ode_config_t* out_cfg
53) {
54 lmmc_real_t span = 0.0;
55 lmmc_real_t initial_step = 0.0;
56 lmmc_real_t min_step = 0.0;
57 lmmc_real_t max_step = 0.0;
58 size_t max_steps = 0;
59 lmmc_real_t hundred = 100.0;
60 lmmc_real_t ten = 10.0;
61 lmmc_real_t span_factor = 1e-10;
62 lmmc_real_t step_factor = 1e-6;
63 lmmc_real_t tenth = 0.1;
64
65 if (out_cfg == NULL || problem_dim == 0 || !lmmc_is_finite(&t_start) ||
66 !lmmc_is_finite(&t_end) || !(t_end > t_start)) {
68 }
69
70 LMMC_REAL_SUB(&span, &t_end, &t_start);
71 LMMC_REAL_DIV(&initial_step, &span, &hundred);
72 if (!lmmc_is_finite(&initial_step) || initial_step <= 0.0) {
73 LMMC_REAL_SET_D(&initial_step, 1e-3);
74 }
75
76 LMMC_REAL_MUL(&min_step, &span, &span_factor);
77 if (!lmmc_is_finite(&min_step) || min_step <= 0.0) {
78 LMMC_REAL_MUL(&min_step, &initial_step, &step_factor);
79 }
80 if (min_step > initial_step) {
81 LMMC_REAL_MUL(&min_step, &initial_step, &tenth);
82 }
83
84 LMMC_REAL_DIV(&max_step, &span, &ten);
85 if (!lmmc_is_finite(&max_step) || max_step <= 0.0) {
86 LMMC_REAL_SET(&max_step, &initial_step);
87 }
88 if (max_step < initial_step) {
89 LMMC_REAL_SET(&max_step, &initial_step);
90 }
91
92 max_steps = ode_default_max_steps(problem_dim);
93
94 out_cfg->initial_step = initial_step;
95 out_cfg->min_step = min_step;
96 out_cfg->max_step = max_step;
99 out_cfg->max_steps = max_steps;
100 out_cfg->adaptive_step_beta = 0.9;
101 out_cfg->diagnostics = (lmmc_diagnostic_sink_t){0};
102 out_cfg->jacobian = NULL;
103 out_cfg->time_derivative = NULL;
104 return LMMC_STATUS_OK;
105}
#define LMMC_REAL_DIV(res, a, b)
计算 *res = *a / *b 。
#define LMMC_REAL_SUB(res, a, b)
计算 *res = *a - *b 。
double lmmc_real_t
Public and internal LMMC real type.
#define LMMC_REAL_SET(dst, src)
将一个 lmmc_real_t 赋值到另一个:*dst = *src 。
#define LMMC_REAL_MUL(res, a, b)
计算 *res = *a * *b 。
#define LMMC_REAL_SET_D(dst, dbl)
将一个 double 字面量赋值到 lmmc_real_t 。
LMMC 内部使用的公共工具(仅源文件可见).
#define LMMC_DEFAULT_REL_TOL
库默认的相对容差.
#define LMMC_DEFAULT_ABS_TOL
库默认的绝对容差.
常微分方程初值问题求解器:Euler、RK4、RK45(自适应)。
lmmc_status_t lmmc_ode_default_config(lmmc_real_t t_start, lmmc_real_t t_end, size_t problem_dim, lmmc_ode_config_t *out_cfg)
根据积分区间与维度生成合理的默认求解配置。
lmmc_diagnostic_sink_t diagnostics
定义 ode.h:99
lmmc_real_t initial_step
定义 ode.h:92
const char * lmmc_ode_failure_string(lmmc_ode_failure_t reason)
获取失败原因对应的可读字符串。
lmmc_ode_failure_t
ODE 求解失败原因。
定义 ode.h:35
@ LMMC_ODE_FAILURE_NUMERICAL_ISSUE
定义 ode.h:40
@ LMMC_ODE_FAILURE_INVALID_STEP
定义 ode.h:38
@ LMMC_ODE_FAILURE_TOLERANCE_INCONSISTENT
定义 ode.h:42
@ LMMC_ODE_FAILURE_NONE
定义 ode.h:36
@ LMMC_ODE_FAILURE_RHS_EVAL_FAILED
定义 ode.h:41
@ LMMC_ODE_FAILURE_INVALID_DIMENSION
定义 ode.h:37
@ LMMC_ODE_FAILURE_MAX_STEPS
定义 ode.h:39
lmmc_real_t abs_tol
定义 ode.h:95
lmmc_ode_dfdt_t time_derivative
定义 ode.h:101
lmmc_real_t rel_tol
定义 ode.h:96
lmmc_real_t max_step
定义 ode.h:94
lmmc_ode_jac_t jacobian
定义 ode.h:100
lmmc_real_t adaptive_step_beta
定义 ode.h:98
lmmc_real_t min_step
定义 ode.h:93
ODE 求解配置。
定义 ode.h:91
lmmc_status_t
LMMC 库统一返回的状态码.
@ LMMC_STATUS_OK
@ LMMC_STATUS_INVALID_ARGUMENT