|
|
|
@ -857,6 +857,71 @@ bool nmCalculationDllPebiSolverTask::updateSensitivityRun(
|
|
|
|
return true;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool nmCalculationDllPebiSolverTask::calculateSensitivityBatch(
|
|
|
|
|
|
|
|
const nmDataSensitive& sampling, std::vector<SensitivityRunResult>& results,
|
|
|
|
|
|
|
|
QString* errorMessage) const
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
results.clear();
|
|
|
|
|
|
|
|
if(errorMessage) errorMessage->clear();
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
// 冻结整次批量的配置,次数、运行顺序和返回参数都使用同一份采样数据。
|
|
|
|
|
|
|
|
const nmDataSensitive frozenSampling(sampling);
|
|
|
|
|
|
|
|
bool overflow = false;
|
|
|
|
|
|
|
|
const quint64 count = frozenSampling.calculateModelCount(&overflow);
|
|
|
|
|
|
|
|
const nmDataSensitive::CalculationType type = frozenSampling.getCalculationType();
|
|
|
|
|
|
|
|
if(overflow || count == 0 || !frozenSampling.usesBaseUnits() ||
|
|
|
|
|
|
|
|
(type != nmDataSensitive::CALC_DETERMINISTIC &&
|
|
|
|
|
|
|
|
type != nmDataSensitive::CALC_DETERMINISTIC_MULTIVARIATE)) {
|
|
|
|
|
|
|
|
if(errorMessage) *errorMessage = tr("Invalid sensitivity sampling configuration.");
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 只在整次批量开始时复制模型与网格;首组参数由创建接口填入。
|
|
|
|
|
|
|
|
QString creationError;
|
|
|
|
|
|
|
|
QScopedPointer<nmCalculationDllPebiSolverTask> task(
|
|
|
|
|
|
|
|
createSensitivityRun(frozenSampling, 0, &creationError));
|
|
|
|
|
|
|
|
if(!task) {
|
|
|
|
|
|
|
|
if(errorMessage) *errorMessage = creationError;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for(quint64 runIndex = 0; runIndex < count; ++runIndex) {
|
|
|
|
|
|
|
|
SensitivityRunResult result;
|
|
|
|
|
|
|
|
result.m_nRunIndex = runIndex;
|
|
|
|
|
|
|
|
// 单参数法保持其余参数的模型值,多参数法按预览组合顺序逐组取值。
|
|
|
|
|
|
|
|
bool inputReady = frozenSampling.getRunValues(runIndex, result.m_vecParameters);
|
|
|
|
|
|
|
|
if(!inputReady) {
|
|
|
|
|
|
|
|
result.m_sFailureReason = tr("Invalid sensitivity sampling configuration.");
|
|
|
|
|
|
|
|
} else if(runIndex > 0) {
|
|
|
|
|
|
|
|
// 本组更新失败仍保留运行编号,下一组继续从冻结基准更新。
|
|
|
|
|
|
|
|
inputReady = task->updateSensitivityRun(frozenSampling, runIndex,
|
|
|
|
|
|
|
|
&result.m_sFailureReason);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if(inputReady) {
|
|
|
|
|
|
|
|
task->run();
|
|
|
|
|
|
|
|
result.m_bSucceeded = task->wasSuccessful();
|
|
|
|
|
|
|
|
if(result.m_bSucceeded) {
|
|
|
|
|
|
|
|
result.m_vecPressure = task->getAutoFitResultPressure();
|
|
|
|
|
|
|
|
result.m_vecLogLog = task->getAutoFitResultLogLog();
|
|
|
|
|
|
|
|
result.m_vecSemiLog = task->getAutoFitResultSemiLog();
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
result.m_sFailureReason = task->getFailureReason();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
// Qt 曲线容器按值保留;下一组清空任务结果不会清掉这里的曲线。
|
|
|
|
|
|
|
|
// 不预先展开全部组合或预分配总次数,也不合并重复的基准组合。
|
|
|
|
|
|
|
|
results.push_back(result);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
} catch(const std::bad_alloc&) {
|
|
|
|
|
|
|
|
if(errorMessage) *errorMessage = tr("Insufficient memory to process solver results.");
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
} catch(const std::length_error&) {
|
|
|
|
|
|
|
|
if(errorMessage) *errorMessage = tr("Insufficient memory to process solver results.");
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void nmCalculationDllPebiSolverTask::run()
|
|
|
|
void nmCalculationDllPebiSolverTask::run()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
m_nSolveTimeMs = -1;
|
|
|
|
m_nSolveTimeMs = -1;
|
|
|
|
|