• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16import taskpool from '@ohos.taskpool';
17import { BusinessError } from '@ohos.base';
18import worker, { MessageEvents } from '@ohos.worker';
19import util from '@ohos.util';
20import { offsetMomentum, energy, advance } from './NBody_ETS_6';
21import Logger from '../utils/Logger';
22
23const TAG: string = 'CalculateUtil';
24let calculateResult: string = "Total time costed = %s ms."
25
26class WorkerMessage {
27  timeSteps: number;
28
29  constructor(timeSteps: number) {
30    this.timeSteps = timeSteps;
31  }
32}
33
34/**
35 * 运行天体轨道计算程序
36 * @param totalTimeSteps 时间推移量
37 * @returns 计算时间
38 */
39@Concurrent
40export function computeTask(totalTimeSteps: number): number {
41  const tagInTask: string = 'computeTask';
42  const timeStep: number = 0.01; // 单位:hour
43  const fractionDigits: number = 9; // 机械能数值小数位
44  let start: number = new Date().getTime();
45
46  // 建立孤立系统的动量守恒
47  offsetMomentum();
48  Logger.info(tagInTask, energy().toFixed(fractionDigits));
49
50  // 更新天体在按指定的时间变化后的位置信息
51  for (let i: number = 0; i < totalTimeSteps; i++) {
52    advance(timeStep);
53  }
54
55  // 判断系统计算前后机械能守恒
56  Logger.info(tagInTask, energy().toFixed(fractionDigits));
57  let end: number = new Date().getTime();
58  return end - start;
59}
60
61/**
62 * 使用TaskPool开启子线程,执行轨道计算任务
63 * @param totalTimeSteps 时间推移量
64 */
65export function computeNBodyByTaskPool(totalTimeSteps: number): void {
66  Logger.info(TAG, "computeNBodyByTaskPool: start executing");
67  let task: taskpool.Task = new taskpool.Task(computeTask, totalTimeSteps);
68  try {
69    Logger.info(TAG, 'computeNBodyByTaskPool: start calculating...');
70
71    // 向taskpool线程池派发子线程任务
72    taskpool.execute(task, taskpool.Priority.HIGH).then((res: number) => {
73      Logger.info(TAG, 'computeNBodyByTaskPool: executed successfully, total time costed = ' + res + ' ms.');
74      AppStorage.set<String>('timeCost', util.format(calculateResult, res.toString()))
75    })
76  } catch (err) {
77    Logger.error(TAG, "computeNBodyByTaskPool: execute failed, " + (err as BusinessError).toString());
78  }
79  Logger.info(TAG, "computeNBodyByTaskPool: finish executing");
80}
81
82/**
83 * 使用Worker开启子线程,执行轨道计算任务
84 * @param totalTimeSteps 时间推移量
85 */
86export function computeNBodyByWorker(totalTimeSteps: number): void {
87  Logger.info(TAG, "computeNBodyByWorker: start executing");
88  let workerInstance = new worker.ThreadWorker("entry/ets/workers/CalculateWorker.ts");
89
90  // 设置如何处理,来自worker线程的消息
91  workerInstance.onmessage = (e: MessageEvents): void => {
92    let data: Record<string, Object> = e.data;
93    Logger.info(TAG, 'computeNBodyByWorker: executed successfully, total time costed = ' + data.result + ' ms.');
94    AppStorage.set<String>('timeCost', util.format(calculateResult, data.result));
95  }
96
97  // 设置由主线程向worker线程发送什么消息
98  workerInstance.postMessage(new WorkerMessage(totalTimeSteps));
99}