37template<
typename State>
41 double current_time{0.0};
42 std::exception_ptr exception;
46 std::coroutine_handle<promise_type>::from_promise(*
this)
50 std::suspend_always initial_suspend() {
return {}; }
51 std::suspend_always final_suspend()
noexcept {
return {}; }
53 void unhandled_exception() {
54 exception = std::current_exception();
60 std::suspend_always yield_value(std::pair<const State&, double> value) {
61 current_state = value.first;
62 current_time = value.second;
67 using handle_type = std::coroutine_handle<promise_type>;
80 : coro(std::exchange(other.coro, {})) {}
84 if (coro) coro.destroy();
85 coro = std::exchange(other.coro, {});
96 if (!coro || coro.done())
return false;
103 return !coro || coro.done();
107 std::pair<State, double> get_current()
const {
109 return {coro.promise().current_state, coro.promise().current_time};
111 throw std::runtime_error(
"No current state available");
115 void check_exception() {
116 if (coro && coro.promise().exception) {
117 std::rethrow_exception(coro.promise().exception);
122 bool await_ready() const noexcept {
126 void await_suspend(std::coroutine_handle<> h) {
128 std::thread([
this, h]() {
131 std::this_thread::sleep_for(std::chrono::milliseconds{1});
137 std::pair<State, double> await_resume() {
140 return {coro.promise().current_state, coro.promise().current_time};
142 throw std::runtime_error(
"Coroutine not available");
150 std::chrono::milliseconds delay;
152 bool await_ready()
const noexcept {
return delay.count() <= 0; }
154 void await_suspend(std::coroutine_handle<> h)
const {
155 std::thread([h,
this]() {
156 std::this_thread::sleep_for(delay);
161 void await_resume()
const noexcept {}
171template<
typename State>
174 std::unique_ptr<diffeq::core::AbstractIntegrator<State>> integrator_;
179 : integrator_(std::move(integrator)) {}
190 typename diffeq::core::AbstractIntegrator<State>::time_type dt,
191 typename diffeq::core::AbstractIntegrator<State>::time_type end_time,
192 size_t yield_interval = 10) {
194 State state = std::move(initial_state);
195 double current_time = 0.0;
196 integrator_->set_time(current_time);
197 size_t step_count = 0;
199 while (current_time < end_time) {
201 auto step_dt = std::min(dt, end_time - current_time);
202 integrator_->step(state, step_dt);
203 current_time += step_dt;
204 integrator_->set_time(current_time);
208 if (step_count % yield_interval == 0) {
209 co_yield std::make_pair(std::cref(state), current_time);
214 co_yield std::make_pair(std::cref(state), current_time);
220 template<
typename ProgressCallback>
223 typename diffeq::core::AbstractIntegrator<State>::time_type dt,
224 typename diffeq::core::AbstractIntegrator<State>::time_type end_time,
225 ProgressCallback&& callback) {
227 State state = std::move(initial_state);
228 double current_time = 0.0;
229 integrator_->set_time(current_time);
231 while (current_time < end_time) {
233 auto step_dt = std::min(dt, end_time - current_time);
234 integrator_->step(state, step_dt);
235 current_time += step_dt;
236 integrator_->set_time(current_time);
239 double progress = current_time / end_time;
240 bool should_continue = callback(state, current_time, progress);
242 if (!should_continue) {
247 co_yield std::make_pair(std::cref(state), current_time);
262 std::function<bool()> resume_func;
264 std::chrono::steady_clock::time_point last_run;
265 std::chrono::milliseconds interval;
268 std::vector<Task> tasks_;
275 template<
typename State>
277 const std::string& name,
278 std::chrono::milliseconds interval = std::chrono::milliseconds{0}) {
279 std::lock_guard<std::mutex> lock(mutex_);
282 auto task_ptr = std::make_shared<IntegrationTask<State>>(std::move(task));
285 [task_ptr]() {
return task_ptr->resume(); },
287 std::chrono::steady_clock::now(),
296 void run(std::chrono::milliseconds duration) {
297 auto end_time = std::chrono::steady_clock::now() + duration;
299 while (std::chrono::steady_clock::now() < end_time) {
300 std::vector<Task> active_tasks;
303 std::lock_guard<std::mutex> lock(mutex_);
305 for (
auto& task : tasks_) {
306 auto now = std::chrono::steady_clock::now();
307 if (now - task.last_run >= task.interval) {
308 if (task.resume_func()) {
310 active_tasks.push_back(task);
312 std::cout <<
"任务 '" << task.name <<
"' 已完成" << std::endl;
315 active_tasks.push_back(task);
318 tasks_ = std::move(active_tasks);
322 std::this_thread::sleep_for(std::chrono::milliseconds{1});
330 std::lock_guard<std::mutex> lock(mutex_);
331 return tasks_.size();
345 double epsilon = 0.01) {
348 auto system = [epsilon](
double t,
const std::vector<double>& x,
349 std::vector<double>& dx) {
351 dx[0] = -x[0] + x[1];
353 dx[1] = -(1.0/epsilon) * (x[1] - x[0]*x[0]);
357 auto integrator = std::make_unique<diffeq::RK45Integrator<std::vector<double>>>(system);
361 std::vector<double> state = {1.0, 0.0};
363 std::cout <<
"\n=== 多尺度系统积分 (ε = " << epsilon <<
") ===" << std::endl;
366 auto task = coro_integrator.integrate_coro(state, 0.001, 5.0, 10);
368 size_t yield_count = 0;
369 while (!task.done()) {
373 auto [current_state, current_time] = task.get_current();
377 if (yield_count % 50 == 0) {
378 std::cout <<
"t = " << current_time
379 <<
", 慢变量 = " << current_state[0]
380 <<
", 快变量 = " << current_state[1] << std::endl;
388 std::cout <<
"多尺度积分完成,共 yield " << yield_count <<
" 次" << std::endl;
398template<
typename State>
401 std::function<
void(
double,
const State&,
double)> result_handler) {
404 auto system = [param](
double t,
const std::vector<double>& x,
405 std::vector<double>& dx) {
407 dx[1] = param * (1 - x[0]*x[0]) * x[1] - x[0];
410 auto integrator = std::make_unique<diffeq::RK4Integrator<std::vector<double>>>(system);
413 State state = {2.0, 0.0};
416 auto task = coro_integrator.integrate_with_progress(
418 [param](
const auto& s,
double t,
double progress) {
420 if (
static_cast<int>(progress * 100) % 25 == 0 &&
421 static_cast<int>(progress * 100) % 25 < 1) {
422 std::cout <<
"参数 " << param <<
" 的积分进度: "
423 <<
static_cast<int>(progress * 100) <<
"%" << std::endl;
430 while (!task.done()) {
434 auto [current_state, current_time] = task.get_current();
437 co_await std::suspend_always{};
442 auto [final_state, final_time] = task.get_current();
443 result_handler(param, final_state, final_time);
452 SetConsoleOutputCP(CP_UTF8);
455 std::cout <<
"=== C++20 协程与 diffeq 库集成示例 ===" << std::endl;
456 std::cout <<
"展示协程在细粒度 CPU 运行控制上的优势\n" << std::endl;
459 std::cout <<
"1. 基本协程积分示例" << std::endl;
462 auto lorenz = [](
double t,
const std::vector<double>& x,
463 std::vector<double>& dx) {
464 const double sigma = 10.0, rho = 28.0, beta = 8.0/3.0;
465 dx[0] = sigma * (x[1] - x[0]);
466 dx[1] = x[0] * (rho - x[2]) - x[1];
467 dx[2] = x[0] * x[1] - beta * x[2];
470 auto integrator = std::make_unique<diffeq::RK45Integrator<std::vector<double>>>(lorenz);
473 std::vector<double> initial_state = {1.0, 1.0, 1.0};
476 auto task = coro_integrator.integrate_coro(initial_state, 0.01, 2.0, 20);
478 std::cout <<
"开始 Lorenz 系统积分..." << std::endl;
479 size_t step_count = 0;
481 while (!task.done()) {
485 if (!task.done() && step_count % 5 == 0) {
487 auto [state, time] = task.get_current();
488 std::cout <<
" t = " << time
489 <<
", ||x|| = " << std::sqrt(state[0]*state[0] +
493 }
catch (
const std::exception& e) {
494 std::cout <<
" 获取 Lorenz 状态失败: " << e.what() << std::endl;
499 std::cout <<
"Lorenz 积分完成,共暂停/恢复 " << step_count <<
" 次\n" << std::endl;
503 std::cout <<
"2. 参数扫描示例" << std::endl;
505 std::vector<double> parameters = {0.5, 1.0, 2.0};
506 std::vector<std::pair<double, std::vector<double>>> results;
508 for (
double param : parameters) {
509 std::cout <<
"开始参数 μ = " << param <<
" 的积分..." << std::endl;
511 auto system = [param](
double t,
const std::vector<double>& x,
512 std::vector<double>& dx) {
514 dx[1] = param * (1 - x[0]*x[0]) * x[1] - x[0];
517 auto integrator = std::make_unique<diffeq::RK4Integrator<std::vector<double>>>(system);
520 std::vector<double> state = {2.0, 0.0};
521 auto task = coro_integrator.integrate_coro(state, 0.05, 10.0, 50);
524 size_t step_count = 0;
525 while (!task.done()) {
529 if (!task.done() && step_count % 20 == 0) {
531 auto [current_state, current_time] = task.get_current();
532 std::cout <<
" μ = " << param
533 <<
", t = " << current_time
534 <<
", x = [" << current_state[0] <<
", " << current_state[1] <<
"]"
536 }
catch (
const std::exception& e) {
537 std::cout <<
" 获取状态失败: " << e.what() << std::endl;
543 auto [final_state, final_time] = task.get_current();
544 results.emplace_back(param, final_state);
545 std::cout <<
"参数 μ = " << param <<
" 积分完成" << std::endl;
546 }
catch (
const std::exception& e) {
547 std::cout <<
"参数 μ = " << param <<
" 积分失败: " << e.what() << std::endl;
551 std::cout <<
"\n参数扫描结果:" << std::endl;
552 for (
const auto& [param, state] : results) {
553 std::cout <<
" μ = " << param
554 <<
", 最终状态 = [" << state[0] <<
", " << state[1] <<
"]"
560 std::cout <<
"\n3. 带进度监控的协程积分" << std::endl;
563 auto damped_oscillator = [](
double t,
const std::vector<double>& x,
564 std::vector<double>& dx) {
565 double omega = 2.0, gamma = 0.1;
567 dx[1] = -omega*omega*x[0] - 2*gamma*x[1];
570 auto integrator = std::make_unique<diffeq::RK45Integrator<std::vector<double>>>(damped_oscillator);
573 std::vector<double> state = {1.0, 0.0};
575 auto task = coro_integrator.integrate_with_progress(
577 [](
const auto& s,
double t,
double progress) {
579 int progress_percent =
static_cast<int>(progress * 100);
580 if (progress_percent % 25 == 0 && progress_percent > 0) {
581 std::cout <<
" 进度: " << progress_percent
583 <<
", 能量 = " << 0.5 * (s[0]*s[0] + s[1]*s[1])
590 std::cout <<
"开始阻尼振荡器积分..." << std::endl;
591 while (!task.done()) {
595 auto [final_state, final_time] = task.get_current();
596 std::cout <<
"阻尼振荡器积分完成,最终能量 = "
597 << 0.5 * (final_state[0]*final_state[0] + final_state[1]*final_state[1])
602 std::cout <<
"\n4. 协程的细粒度控制示例" << std::endl;
605 auto orbital_system = [](
double t,
const std::vector<double>& x,
606 std::vector<double>& dx) {
608 double r = std::sqrt(x[0]*x[0] + x[1]*x[1]);
613 dx[2] = -mu * x[0] / r3;
614 dx[3] = -mu * x[1] / r3;
617 auto integrator = std::make_unique<diffeq::RK45Integrator<std::vector<double>>>(orbital_system);
621 std::vector<double> state = {1.0, 0.0, 0.0, 0.8};
623 auto task = coro_integrator.integrate_coro(state, 0.01, 6.28, 25);
625 std::cout <<
"开始轨道积分(每25步暂停一次)..." << std::endl;
626 size_t resume_count = 0;
628 while (!task.done()) {
633 auto [current_state, current_time] = task.get_current();
634 double r = std::sqrt(current_state[0]*current_state[0] + current_state[1]*current_state[1]);
635 double v = std::sqrt(current_state[2]*current_state[2] + current_state[3]*current_state[3]);
636 double energy = 0.5 * v*v - 1.0/r;
638 std::cout <<
" 第 " << resume_count <<
" 次恢复: t = " << current_time
640 <<
", 能量 = " << energy << std::endl;
643 std::this_thread::sleep_for(std::chrono::milliseconds{10});
647 auto [final_state, final_time] = task.get_current();
648 std::cout <<
"轨道积分完成,共恢复 " << resume_count <<
" 次" << std::endl;
649 std::cout <<
"最终位置: [" << final_state[0] <<
", " << final_state[1] <<
"]" << std::endl;
652 std::cout <<
"\n=== 协程集成演示完成 ===" << std::endl;
653 std::cout <<
"关键优势:" << std::endl;
654 std::cout <<
"- 细粒度的执行控制" << std::endl;
655 std::cout <<
"- 协作式多任务处理" << std::endl;
656 std::cout <<
"- 零开销的状态保存和恢复" << std::endl;
657 std::cout <<
"- 与标准库的无缝集成" << std::endl;
IntegrationTask< State > integrate_coro(State initial_state, typename diffeq::core::AbstractIntegrator< State >::time_type dt, typename diffeq::core::AbstractIntegrator< State >::time_type end_time, size_t yield_interval=10)
协程化的积分,每步都可以暂停
IntegrationTask< State > integrate_with_progress(State initial_state, typename diffeq::core::AbstractIntegrator< State >::time_type dt, typename diffeq::core::AbstractIntegrator< State >::time_type end_time, ProgressCallback &&callback)
带进度回调的协程积分
void run(std::chrono::milliseconds duration)
运行调度器
void add_task(IntegrationTask< State > &&task, const std::string &name, std::chrono::milliseconds interval=std::chrono::milliseconds{0})
添加一个协程任务
size_t active_task_count()
获取活跃任务数
Modern C++ ODE Integration Library with Real-time Signal Processing.