|
|
|
@ -1,5 +1,7 @@
|
|
|
|
#include "nmPebiResultSnapshotBuilder.h"
|
|
|
|
#include "nmPebiResultSnapshotBuilder.h"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#include "nmPebiCellMapping.h"
|
|
|
|
|
|
|
|
|
|
|
|
#include <QSet>
|
|
|
|
#include <QSet>
|
|
|
|
#include <QUuid>
|
|
|
|
#include <QUuid>
|
|
|
|
#include <QtGlobal>
|
|
|
|
#include <QtGlobal>
|
|
|
|
@ -30,6 +32,22 @@ bool isFiniteValue(double dValue)
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 这四个名称由结果快照独占。基础网格若已携带同名数组,无法判断其
|
|
|
|
|
|
|
|
// 来源和语义,必须在接管所有权前拒绝,而不是在 finalize() 中静默删除。
|
|
|
|
|
|
|
|
bool hasReservedResultPropertyArray(vtkUnstructuredGrid* pGrid)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if(pGrid == NULL || pGrid->GetCellData() == NULL)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vtkCellData* pCellData = pGrid->GetCellData();
|
|
|
|
|
|
|
|
return pCellData->GetAbstractArray("p") != NULL ||
|
|
|
|
|
|
|
|
pCellData->GetAbstractArray("permeability") != NULL ||
|
|
|
|
|
|
|
|
pCellData->GetAbstractArray("porosity") != NULL ||
|
|
|
|
|
|
|
|
pCellData->GetAbstractArray("thickness") != NULL;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool isValidInstanceId(const QString& sInstanceId)
|
|
|
|
bool isValidInstanceId(const QString& sInstanceId)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
return !sInstanceId.isEmpty() && !QUuid(sInstanceId).isNull();
|
|
|
|
return !sInstanceId.isEmpty() && !QUuid(sInstanceId).isNull();
|
|
|
|
@ -377,15 +395,111 @@ bool areSolverSettingsValid(const nmPebiResultSolverSettings& oSettings)
|
|
|
|
oSettings.m_dMaxDeltaT >= oSettings.m_dMinDeltaT);
|
|
|
|
oSettings.m_dMaxDeltaT >= oSettings.m_dMinDeltaT);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool buildStaticPropertyArray(
|
|
|
|
|
|
|
|
const QVector<double>& vecOriginalValues,
|
|
|
|
|
|
|
|
const QVector<vtkIdType>& vecVtkToOriginal,
|
|
|
|
|
|
|
|
const char* pArrayName,
|
|
|
|
|
|
|
|
vtkSmartPointer<vtkDoubleArray>& pArray,
|
|
|
|
|
|
|
|
double aRange[2])
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if(pArrayName == NULL || vecOriginalValues.isEmpty() ||
|
|
|
|
|
|
|
|
vecVtkToOriginal.isEmpty() || aRange == NULL)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
vtkSmartPointer<vtkDoubleArray> pCandidate =
|
|
|
|
|
|
|
|
vtkSmartPointer<vtkDoubleArray>::New();
|
|
|
|
|
|
|
|
if(pCandidate == NULL)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
pCandidate->SetName(pArrayName);
|
|
|
|
|
|
|
|
pCandidate->SetNumberOfComponents(1);
|
|
|
|
|
|
|
|
pCandidate->SetNumberOfTuples(vecVtkToOriginal.size());
|
|
|
|
|
|
|
|
double dMinimum = DBL_MAX;
|
|
|
|
|
|
|
|
double dMaximum = -DBL_MAX;
|
|
|
|
|
|
|
|
for(int nVtkCellId = 0;
|
|
|
|
|
|
|
|
nVtkCellId < vecVtkToOriginal.size(); ++nVtkCellId)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
const vtkIdType nOriginalCellId = vecVtkToOriginal[nVtkCellId];
|
|
|
|
|
|
|
|
if(nOriginalCellId < 0 ||
|
|
|
|
|
|
|
|
nOriginalCellId >= vecOriginalValues.size())
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
const double dValue =
|
|
|
|
|
|
|
|
vecOriginalValues[static_cast<int>(nOriginalCellId)];
|
|
|
|
|
|
|
|
if(!isFiniteValue(dValue))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
pCandidate->SetValue(nVtkCellId, dValue);
|
|
|
|
|
|
|
|
dMinimum = qMin(dMinimum, dValue);
|
|
|
|
|
|
|
|
dMaximum = qMax(dMaximum, dValue);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if(pCandidate->GetNumberOfComponents() != 1 ||
|
|
|
|
|
|
|
|
pCandidate->GetNumberOfTuples() != vecVtkToOriginal.size() ||
|
|
|
|
|
|
|
|
dMinimum == DBL_MAX || dMaximum == -DBL_MAX)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
pArray = pCandidate;
|
|
|
|
|
|
|
|
aRange[0] = dMinimum;
|
|
|
|
|
|
|
|
aRange[1] = dMaximum;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool validateStaticPropertyArray(
|
|
|
|
|
|
|
|
const QVector<double>& vecOriginalValues,
|
|
|
|
|
|
|
|
const QVector<vtkIdType>& vecVtkToOriginal,
|
|
|
|
|
|
|
|
vtkDoubleArray* pArray,
|
|
|
|
|
|
|
|
const char* pArrayName,
|
|
|
|
|
|
|
|
const double aRange[2])
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if(pArray == NULL || pArrayName == NULL || aRange == NULL ||
|
|
|
|
|
|
|
|
pArray->GetName() == NULL ||
|
|
|
|
|
|
|
|
QString::fromLatin1(pArray->GetName()) !=
|
|
|
|
|
|
|
|
QString::fromLatin1(pArrayName) ||
|
|
|
|
|
|
|
|
pArray->GetNumberOfComponents() != 1 ||
|
|
|
|
|
|
|
|
pArray->GetNumberOfTuples() != vecVtkToOriginal.size())
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
double dMinimum = DBL_MAX;
|
|
|
|
|
|
|
|
double dMaximum = -DBL_MAX;
|
|
|
|
|
|
|
|
for(int nVtkCellId = 0;
|
|
|
|
|
|
|
|
nVtkCellId < vecVtkToOriginal.size(); ++nVtkCellId)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
const vtkIdType nOriginalCellId = vecVtkToOriginal[nVtkCellId];
|
|
|
|
|
|
|
|
if(nOriginalCellId < 0 ||
|
|
|
|
|
|
|
|
nOriginalCellId >= vecOriginalValues.size())
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
const double dExpected =
|
|
|
|
|
|
|
|
vecOriginalValues[static_cast<int>(nOriginalCellId)];
|
|
|
|
|
|
|
|
const double dActual = pArray->GetValue(nVtkCellId);
|
|
|
|
|
|
|
|
if(!isFiniteValue(dActual) || dActual != dExpected)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
dMinimum = qMin(dMinimum, dActual);
|
|
|
|
|
|
|
|
dMaximum = qMax(dMaximum, dActual);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return dMinimum == aRange[0] && dMaximum == aRange[1];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
nmPebiResultSnapshotBuilder::nmPebiResultSnapshotBuilder()
|
|
|
|
nmPebiResultSnapshotBuilder::nmPebiResultSnapshotBuilder()
|
|
|
|
: m_bFinalized(false),
|
|
|
|
: m_bFinalized(false),
|
|
|
|
m_bFailed(false),
|
|
|
|
m_bFailed(false),
|
|
|
|
m_bHasScalarRange(false),
|
|
|
|
m_bHasScalarRange(false),
|
|
|
|
|
|
|
|
m_bHasStaticProperties(false),
|
|
|
|
m_bHasReservoirParameters(false),
|
|
|
|
m_bHasReservoirParameters(false),
|
|
|
|
m_bHasPvtParameters(false),
|
|
|
|
m_bHasPvtParameters(false),
|
|
|
|
m_bHasSolverSettings(false)
|
|
|
|
m_bHasSolverSettings(false),
|
|
|
|
|
|
|
|
m_nOriginalCellCount(0)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
try
|
|
|
|
try
|
|
|
|
{
|
|
|
|
{
|
|
|
|
@ -460,16 +574,93 @@ bool nmPebiResultSnapshotBuilder::takeResultGrid(
|
|
|
|
vtkSmartPointer<vtkUnstructuredGrid>& pResultGrid)
|
|
|
|
vtkSmartPointer<vtkUnstructuredGrid>& pResultGrid)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if(!canWrite() || pResultGrid == NULL ||
|
|
|
|
if(!canWrite() || pResultGrid == NULL ||
|
|
|
|
pResultGrid->GetNumberOfCells() <= 0)
|
|
|
|
pResultGrid->GetNumberOfCells() <= 0 ||
|
|
|
|
|
|
|
|
m_pCandidate->m_pResultGrid != NULL)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
return fail("Invalid PEBI result grid.");
|
|
|
|
return fail("Invalid PEBI result grid.");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(hasReservedResultPropertyArray(pResultGrid))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return fail("PEBI result grid contains reserved property arrays.");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
QVector<vtkIdType> vecVtkToOriginal;
|
|
|
|
|
|
|
|
QVector<vtkIdType> vecOriginalToVtk;
|
|
|
|
|
|
|
|
QString sMappingError;
|
|
|
|
|
|
|
|
if(nmPebiCellMapping::read(pResultGrid,
|
|
|
|
|
|
|
|
&vecVtkToOriginal, &vecOriginalToVtk, &sMappingError) !=
|
|
|
|
|
|
|
|
nmPebiCellMapping::MappingStatus_Valid ||
|
|
|
|
|
|
|
|
vecVtkToOriginal.size() != pResultGrid->GetNumberOfCells() ||
|
|
|
|
|
|
|
|
vecOriginalToVtk.isEmpty())
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return fail(sMappingError.isEmpty()
|
|
|
|
|
|
|
|
? QString::fromLatin1("Invalid PEBI result cell mapping.")
|
|
|
|
|
|
|
|
: sMappingError);
|
|
|
|
|
|
|
|
}
|
|
|
|
// 通过交换所有权避免大网格 DeepCopy;成功后调用方不能再修改源网格。
|
|
|
|
// 通过交换所有权避免大网格 DeepCopy;成功后调用方不能再修改源网格。
|
|
|
|
|
|
|
|
m_vecVtkToOriginal.swap(vecVtkToOriginal);
|
|
|
|
|
|
|
|
m_nOriginalCellCount = vecOriginalToVtk.size();
|
|
|
|
m_pCandidate->m_pResultGrid = pResultGrid;
|
|
|
|
m_pCandidate->m_pResultGrid = pResultGrid;
|
|
|
|
pResultGrid = NULL;
|
|
|
|
pResultGrid = NULL;
|
|
|
|
return true;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bool nmPebiResultSnapshotBuilder::takeStaticProperties(
|
|
|
|
|
|
|
|
nmPebiStaticPropertyValues& oValues)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if(!canWrite() || m_pCandidate->m_pResultGrid == NULL ||
|
|
|
|
|
|
|
|
m_bHasStaticProperties || m_nOriginalCellCount <= 0 ||
|
|
|
|
|
|
|
|
!oValues.isValidForCellCount(
|
|
|
|
|
|
|
|
static_cast<int>(m_nOriginalCellCount)))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return fail("Invalid PEBI static property values.");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vtkSmartPointer<vtkDoubleArray> pPermeability;
|
|
|
|
|
|
|
|
vtkSmartPointer<vtkDoubleArray> pPorosity;
|
|
|
|
|
|
|
|
vtkSmartPointer<vtkDoubleArray> pThickness;
|
|
|
|
|
|
|
|
double aPermeabilityRange[2] = { 0.0, 0.0 };
|
|
|
|
|
|
|
|
double aPorosityRange[2] = { 0.0, 0.0 };
|
|
|
|
|
|
|
|
double aThicknessRange[2] = { 0.0, 0.0 };
|
|
|
|
|
|
|
|
if(!buildStaticPropertyArray(
|
|
|
|
|
|
|
|
oValues.m_vecPermeabilityMilliDarcy,
|
|
|
|
|
|
|
|
m_vecVtkToOriginal, "permeability",
|
|
|
|
|
|
|
|
pPermeability, aPermeabilityRange) ||
|
|
|
|
|
|
|
|
!buildStaticPropertyArray(
|
|
|
|
|
|
|
|
oValues.m_vecPorosity,
|
|
|
|
|
|
|
|
m_vecVtkToOriginal, "porosity",
|
|
|
|
|
|
|
|
pPorosity, aPorosityRange) ||
|
|
|
|
|
|
|
|
!buildStaticPropertyArray(
|
|
|
|
|
|
|
|
oValues.m_vecThicknessMeters,
|
|
|
|
|
|
|
|
m_vecVtkToOriginal, "thickness",
|
|
|
|
|
|
|
|
pThickness, aThicknessRange))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return fail("Cannot build PEBI static property render caches.");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 到这里之后不再执行可能失败的操作,连续交换保证调用方只在成功时清空。
|
|
|
|
|
|
|
|
m_pCandidate->m_pPermeability = pPermeability;
|
|
|
|
|
|
|
|
m_pCandidate->m_pPorosity = pPorosity;
|
|
|
|
|
|
|
|
m_pCandidate->m_pThickness = pThickness;
|
|
|
|
|
|
|
|
for(int nRangeIndex = 0; nRangeIndex < 2; ++nRangeIndex)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
m_pCandidate->m_aStaticRanges[0][nRangeIndex] =
|
|
|
|
|
|
|
|
aPermeabilityRange[nRangeIndex];
|
|
|
|
|
|
|
|
m_pCandidate->m_aStaticRanges[1][nRangeIndex] =
|
|
|
|
|
|
|
|
aPorosityRange[nRangeIndex];
|
|
|
|
|
|
|
|
m_pCandidate->m_aStaticRanges[2][nRangeIndex] =
|
|
|
|
|
|
|
|
aThicknessRange[nRangeIndex];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
qSwap(m_pCandidate->m_oStaticProperties.
|
|
|
|
|
|
|
|
m_vecPermeabilityMilliDarcy,
|
|
|
|
|
|
|
|
oValues.m_vecPermeabilityMilliDarcy);
|
|
|
|
|
|
|
|
qSwap(m_pCandidate->m_oStaticProperties.m_vecPorosity,
|
|
|
|
|
|
|
|
oValues.m_vecPorosity);
|
|
|
|
|
|
|
|
qSwap(m_pCandidate->m_oStaticProperties.m_vecThicknessMeters,
|
|
|
|
|
|
|
|
oValues.m_vecThicknessMeters);
|
|
|
|
|
|
|
|
m_bHasStaticProperties = true;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
bool nmPebiResultSnapshotBuilder::addPressureFrame(
|
|
|
|
bool nmPebiResultSnapshotBuilder::addPressureFrame(
|
|
|
|
double dTime,
|
|
|
|
double dTime,
|
|
|
|
vtkSmartPointer<vtkDoubleArray>& pPressure)
|
|
|
|
vtkSmartPointer<vtkDoubleArray>& pPressure)
|
|
|
|
@ -711,6 +902,41 @@ bool nmPebiResultSnapshotBuilder::validate(QString* pError)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
return fail("PEBI result grid is missing.", pError);
|
|
|
|
return fail("PEBI result grid is missing.", pError);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
QVector<vtkIdType> vecVerifiedVtkToOriginal;
|
|
|
|
|
|
|
|
QVector<vtkIdType> vecVerifiedOriginalToVtk;
|
|
|
|
|
|
|
|
QString sMappingError;
|
|
|
|
|
|
|
|
if(nmPebiCellMapping::read(m_pCandidate->m_pResultGrid,
|
|
|
|
|
|
|
|
&vecVerifiedVtkToOriginal, &vecVerifiedOriginalToVtk,
|
|
|
|
|
|
|
|
&sMappingError) != nmPebiCellMapping::MappingStatus_Valid ||
|
|
|
|
|
|
|
|
vecVerifiedVtkToOriginal != m_vecVtkToOriginal ||
|
|
|
|
|
|
|
|
vecVerifiedOriginalToVtk.size() != m_nOriginalCellCount)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return fail(sMappingError.isEmpty()
|
|
|
|
|
|
|
|
? QString::fromLatin1(
|
|
|
|
|
|
|
|
"PEBI result cell mapping changed during construction.")
|
|
|
|
|
|
|
|
: sMappingError,
|
|
|
|
|
|
|
|
pError);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!m_bHasStaticProperties ||
|
|
|
|
|
|
|
|
!m_pCandidate->m_oStaticProperties.isValidForCellCount(
|
|
|
|
|
|
|
|
static_cast<int>(m_nOriginalCellCount)) ||
|
|
|
|
|
|
|
|
!validateStaticPropertyArray(
|
|
|
|
|
|
|
|
m_pCandidate->m_oStaticProperties.
|
|
|
|
|
|
|
|
m_vecPermeabilityMilliDarcy,
|
|
|
|
|
|
|
|
m_vecVtkToOriginal, m_pCandidate->m_pPermeability,
|
|
|
|
|
|
|
|
"permeability", m_pCandidate->m_aStaticRanges[0]) ||
|
|
|
|
|
|
|
|
!validateStaticPropertyArray(
|
|
|
|
|
|
|
|
m_pCandidate->m_oStaticProperties.m_vecPorosity,
|
|
|
|
|
|
|
|
m_vecVtkToOriginal, m_pCandidate->m_pPorosity,
|
|
|
|
|
|
|
|
"porosity", m_pCandidate->m_aStaticRanges[1]) ||
|
|
|
|
|
|
|
|
!validateStaticPropertyArray(
|
|
|
|
|
|
|
|
m_pCandidate->m_oStaticProperties.m_vecThicknessMeters,
|
|
|
|
|
|
|
|
m_vecVtkToOriginal, m_pCandidate->m_pThickness,
|
|
|
|
|
|
|
|
"thickness", m_pCandidate->m_aStaticRanges[2]))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
return fail("PEBI static properties are incomplete or inconsistent.",
|
|
|
|
|
|
|
|
pError);
|
|
|
|
|
|
|
|
}
|
|
|
|
if(m_pCandidate->m_vecPressureFrames.isEmpty())
|
|
|
|
if(m_pCandidate->m_vecPressureFrames.isEmpty())
|
|
|
|
{
|
|
|
|
{
|
|
|
|
return fail("PEBI pressure frames are missing.", pError);
|
|
|
|
return fail("PEBI pressure frames are missing.", pError);
|
|
|
|
@ -746,6 +972,9 @@ bool nmPebiResultSnapshotBuilder::validate(QString* pError)
|
|
|
|
if(!isFiniteValue(oFrame.m_dTime) ||
|
|
|
|
if(!isFiniteValue(oFrame.m_dTime) ||
|
|
|
|
(nIndex > 0 && oFrame.m_dTime <= dPreviousTime) ||
|
|
|
|
(nIndex > 0 && oFrame.m_dTime <= dPreviousTime) ||
|
|
|
|
oFrame.m_pPressure == NULL ||
|
|
|
|
oFrame.m_pPressure == NULL ||
|
|
|
|
|
|
|
|
oFrame.m_pPressure->GetName() == NULL ||
|
|
|
|
|
|
|
|
QString::fromLatin1(oFrame.m_pPressure->GetName()) !=
|
|
|
|
|
|
|
|
QString::fromLatin1("p") ||
|
|
|
|
oFrame.m_pPressure->GetNumberOfComponents() != 1 ||
|
|
|
|
oFrame.m_pPressure->GetNumberOfComponents() != 1 ||
|
|
|
|
oFrame.m_pPressure->GetNumberOfTuples() != nCellCount)
|
|
|
|
oFrame.m_pPressure->GetNumberOfTuples() != nCellCount)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
@ -885,13 +1114,12 @@ bool nmPebiResultSnapshotBuilder::validate(QString* pError)
|
|
|
|
setDisplayWellIds.insert(sWellInstanceId);
|
|
|
|
setDisplayWellIds.insert(sWellInstanceId);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 发布前基础网格必须与压力帧解耦,渲染网格只能按帧受控绑定。
|
|
|
|
// finalize() 只验证候选,不再修改基础网格。正式结果数组必须由快照
|
|
|
|
m_pCandidate->m_pResultGrid->GetCellData()->SetScalars(NULL);
|
|
|
|
// 独立持有,其他模块写入的非保留数组和活动属性则保持原样。
|
|
|
|
m_pCandidate->m_pResultGrid->GetCellData()->RemoveArray("p");
|
|
|
|
if(hasReservedResultPropertyArray(m_pCandidate->m_pResultGrid))
|
|
|
|
if(m_pCandidate->m_pResultGrid->GetCellData()->GetScalars() != NULL ||
|
|
|
|
|
|
|
|
m_pCandidate->m_pResultGrid->GetCellData()->GetArray("p") != NULL)
|
|
|
|
|
|
|
|
{
|
|
|
|
{
|
|
|
|
return fail("PEBI result grid still owns pressure scalars.", pError);
|
|
|
|
return fail("PEBI result grid still owns result property scalars.",
|
|
|
|
|
|
|
|
pError);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|