#913 Added SFI as a derived results depending on two user controllable case constants

This commit is contained in:
Jacob Støren
2016-10-27 15:01:21 +02:00
parent bc91f74d72
commit daea2b7cd2
6 changed files with 184 additions and 17 deletions

View File

@@ -72,4 +72,23 @@ RigFemScalarResultFrames* RigFemPartResults::findScalarResult(const RigFemResult
void RigFemPartResults::deleteScalarResult(const RigFemResultAddress& resVarAddr)
{
resultSets.erase(resVarAddr); // Refcounting is supposed to destroy the data.
if (resVarAddr.representsAllTimeLapses())
{
std::vector<RigFemResultAddress> addressesToDelete;
for (auto it : resultSets)
{
if (it.first.resultPosType == resVarAddr.resultPosType
&& it.first.fieldName == resVarAddr.fieldName
&& it.first.componentName == resVarAddr.componentName)
{
addressesToDelete. push_back(it.first);
}
}
for (RigFemResultAddress& addr: addressesToDelete)
{
resultSets.erase(addr);
}
}
}

View File

@@ -41,6 +41,7 @@
#include "cafProgressInfo.h"
#include "RigFemPartGrid.h"
#include "cvfGeometryTools.h"
#include "cvfMath.h"
//--------------------------------------------------------------------------------------------------
@@ -59,6 +60,10 @@ RigFemPartResultsCollection::RigFemPartResultsCollection(RifGeoMechReaderInterfa
m_femPartResults[pIdx] = new RigFemPartResults;
m_femPartResults[pIdx]->initResultSteps(stepNames);
}
m_cohesion = 10.0;
m_frictionAngleRad = cvf::Math::toRadians(30.0);
}
//--------------------------------------------------------------------------------------------------
@@ -86,6 +91,20 @@ RigFormationNames* RigFemPartResultsCollection::activeFormationNames()
return m_activeFormationNamesData.p();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigFemPartResultsCollection::setCalculationParameters(double cohesion, double frictionAngleRad)
{
m_cohesion = cohesion;
m_frictionAngleRad = frictionAngleRad;
// Todo, delete all dependent results
this->deleteResult(RigFemResultAddress(RIG_ELEMENT_NODAL, "SE", "SFI", RigFemResultAddress::ALL_TIME_LAPSES));
this->deleteResult(RigFemResultAddress(RIG_INTEGRATION_POINT, "SE", "SFI", RigFemResultAddress::ALL_TIME_LAPSES));
}
//--------------------------------------------------------------------------------------------------
/// Will always return a valid object, but it can be empty
//--------------------------------------------------------------------------------------------------
@@ -187,6 +206,7 @@ std::map<std::string, std::vector<std::string> > RigFemPartResultsCollection::sc
fieldCompNames = m_readerInterface->scalarElementNodeFieldAndComponentNames();
fieldCompNames["SE"].push_back("SEM");
fieldCompNames["SE"].push_back("SFI");
fieldCompNames["SE"].push_back("S11");
fieldCompNames["SE"].push_back("S22");
@@ -242,6 +262,7 @@ std::map<std::string, std::vector<std::string> > RigFemPartResultsCollection::sc
fieldCompNames = m_readerInterface->scalarIntegrationPointFieldAndComponentNames();
fieldCompNames["SE"].push_back("SEM");
fieldCompNames["SE"].push_back("SFI");
fieldCompNames["SE"].push_back("S11");
fieldCompNames["SE"].push_back("S22");
@@ -479,6 +500,55 @@ RigFemScalarResultFrames* RigFemPartResultsCollection::calculateMeanStressSEM(in
return dstDataFrames;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigFemScalarResultFrames* RigFemPartResultsCollection::calculateSFI(int partIndex, const RigFemResultAddress& resVarAddr)
{
CVF_ASSERT(resVarAddr.fieldName == "SE" && resVarAddr.componentName == "SFI");
RigFemScalarResultFrames * se1Frames = nullptr;
RigFemScalarResultFrames * se3Frames = nullptr;
se1Frames = this->findOrLoadScalarResult(partIndex, RigFemResultAddress(resVarAddr.resultPosType, "SE", "S1"));
se3Frames = this->findOrLoadScalarResult(partIndex, RigFemResultAddress(resVarAddr.resultPosType, "SE", "S3"));
RigFemScalarResultFrames * dstDataFrames = m_femPartResults[partIndex]->createScalarResult(resVarAddr);
float cohPrFricAngle = (float)(m_cohesion/tan(m_frictionAngleRad));
float sinFricAng = sin(m_frictionAngleRad);
int frameCount = se1Frames->frameCount();
for ( int fIdx = 0; fIdx < frameCount; ++fIdx )
{
const std::vector<float>& se1Data = se1Frames->frameData(fIdx);
const std::vector<float>& se3Data = se3Frames->frameData(fIdx);
std::vector<float>& dstFrameData = dstDataFrames->frameData(fIdx);
size_t valCount = se1Data.size();
dstFrameData.resize(valCount);
for ( size_t vIdx = 0; vIdx < valCount; ++vIdx )
{
float se1 = se1Data[vIdx];
float se3 = se3Data[vIdx];
float se1Se3Diff = se1-se3;
if ( fabs(se1Se3Diff) < 1e-7 )
{
dstFrameData[vIdx] = std::numeric_limits<float>::infinity();
}
else
{
dstFrameData[vIdx] = ((cohPrFricAngle + 0.5*(se1Data[vIdx] + se3Data[vIdx])) * sin(m_frictionAngleRad)) / (0.5*(se1Data[vIdx] - se3Data[vIdx]));
}
}
}
return dstDataFrames;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -724,6 +794,11 @@ RigFemScalarResultFrames* RigFemPartResultsCollection::calculateDerivedResult(in
return calculateSurfaceAlignedStress(partIndex, resVarAddr);
}
if (resVarAddr.fieldName == "SE" && resVarAddr.componentName == "SFI")
{
return calculateSFI(partIndex, resVarAddr);
}
if(resVarAddr.fieldName == "NE" && resVarAddr.componentName == "EV")
{
return calculateVolumetricStrain(partIndex, resVarAddr);
@@ -1265,6 +1340,25 @@ void RigFemPartResultsCollection::deleteResult(const RigFemResultAddress& resVar
}
m_resultStatistics.erase(resVarAddr);
if ( resVarAddr.representsAllTimeLapses() )
{
std::vector<RigFemResultAddress> addressesToDelete;
for ( auto it : m_resultStatistics )
{
if ( it.first.resultPosType == resVarAddr.resultPosType
&& it.first.fieldName == resVarAddr.fieldName
&& it.first.componentName == resVarAddr.componentName )
{
addressesToDelete.push_back(it.first);
}
}
for ( RigFemResultAddress& addr: addressesToDelete )
{
m_resultStatistics.erase(addr);
}
}
}
//--------------------------------------------------------------------------------------------------

View File

@@ -42,6 +42,7 @@ public:
void setActiveFormationNames(RigFormationNames* activeFormationNames);
RigFormationNames* activeFormationNames();
void setCalculationParameters(double cohesion, double frictionAngleRad);
std::map<std::string, std::vector<std::string> > scalarFieldAndComponentNames(RigFemResultPosEnum resPos);
std::vector<std::string> stepNames();
@@ -81,6 +82,7 @@ private:
RigFemScalarResultFrames* calculateEnIpPorBarResult(int partIndex, const RigFemResultAddress &convertedResultAddr);
RigFemScalarResultFrames* calculateTimeLapseResult(int partIndex, const RigFemResultAddress& resVarAddr);
RigFemScalarResultFrames* calculateMeanStressSEM(int partIndex, const RigFemResultAddress& resVarAddr);
RigFemScalarResultFrames* calculateSFI(int partIndex, const RigFemResultAddress& resVarAddr);
RigFemScalarResultFrames* calculateMeanStressSTM(int partIndex, const RigFemResultAddress& resVarAddr);
RigFemScalarResultFrames* calculateDeviatoricStress(int partIndex, const RigFemResultAddress& resVarAddr);
RigFemScalarResultFrames* calculateVolumetricStrain(int partIndex, const RigFemResultAddress& resVarAddr);
@@ -91,6 +93,9 @@ private:
cvf::cref<RigFemPartCollection> m_femParts;
cvf::ref<RigFormationNames> m_activeFormationNamesData;
double m_cohesion;
double m_frictionAngleRad;
RigStatisticsDataCache* statistics(const RigFemResultAddress& resVarAddr);
std::vector< RigFemResultAddress> getResAddrToComponentsToRead(const RigFemResultAddress& resVarAddr);
std::map<RigFemResultAddress, cvf::ref<RigStatisticsDataCache> > m_resultStatistics;

View File

@@ -29,31 +29,36 @@
class RigFemResultAddress
{
public:
RigFemResultAddress(RigFemResultPosEnum resPosType,
const std::string& aFieldName,
const std::string& aComponentName)
: resultPosType(resPosType),
fieldName(aFieldName),
componentName(aComponentName),
timeLapseBaseFrameIdx(-1)
{}
RigFemResultAddress(RigFemResultPosEnum resPosType,
const std::string& aFieldName,
const std::string& aComponentName)
: resultPosType(resPosType),
fieldName(aFieldName),
componentName(aComponentName),
timeLapseBaseFrameIdx(-1)
{
}
RigFemResultAddress(RigFemResultPosEnum resPosType,
const std::string& aFieldName,
const std::string& aComponentName,
int aTimeLapseBaseFrame)
: resultPosType(resPosType),
fieldName(aFieldName),
componentName(aComponentName),
timeLapseBaseFrameIdx(aTimeLapseBaseFrame)
{}
RigFemResultAddress(RigFemResultPosEnum resPosType,
const std::string& aFieldName,
const std::string& aComponentName,
int aTimeLapseBaseFrame)
: resultPosType(resPosType),
fieldName(aFieldName),
componentName(aComponentName),
timeLapseBaseFrameIdx(aTimeLapseBaseFrame)
{
}
RigFemResultPosEnum resultPosType;
std::string fieldName;
std::string componentName;
int timeLapseBaseFrameIdx;
static const int ALL_TIME_LAPSES = -2;
bool isTimeLapse() const { return timeLapseBaseFrameIdx >= 0;}
bool representsAllTimeLapses() const { return timeLapseBaseFrameIdx == ALL_TIME_LAPSES;}
bool isValid() const
{

View File

@@ -50,6 +50,10 @@ RimGeoMechCase::RimGeoMechCase(void)
m_caseFileName.uiCapability()->setUiReadOnly(true);
CAF_PDM_InitFieldNoDefault(&geoMechViews, "GeoMechViews", "", "", "", "");
geoMechViews.uiCapability()->setUiHidden(true);
CAF_PDM_InitField(&m_cohesion, "CaseCohesion", 10.0, "Cohesion", "", "Used to calculate the SE:SFI result", "");
CAF_PDM_InitField(&m_frictionAngleDeg, "FrctionAngleDeg", 30.0, "Friction Angle [Deg]", "", "Used to calculate the SE:SFI result", "");
}
//--------------------------------------------------------------------------------------------------
@@ -254,6 +258,25 @@ void RimGeoMechCase::fieldChangedByUi(const caf::PdmFieldHandle* changedField, c
{
updateFormationNamesData();
}
if (changedField == &m_cohesion || changedField == &m_frictionAngleDeg)
{
RigGeoMechCaseData* rigCaseData = geoMechData();
if ( rigCaseData && rigCaseData->femPartResults() )
{
rigCaseData->femPartResults()->setCalculationParameters(m_cohesion(), cvf::Math::toRadians(m_frictionAngleDeg()));
}
std::vector<RimView*> views = this->views();
for ( RimView* view : views )
{
if ( view ) // Todo: only those using the variable actively
{
view->scheduleCreateDisplayModelAndRedraw();
}
}
}
}
//--------------------------------------------------------------------------------------------------
@@ -313,3 +336,19 @@ QString RimGeoMechCase::subStringOfDigits(const QString& inputString, int number
return "";
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimGeoMechCase::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering)
{
uiOrdering.add(&caseUserDescription);
uiOrdering.add(&caseId);
uiOrdering.add(&m_caseFileName);
auto group = uiOrdering.addNewGroup("Case Options");
group->add(&activeFormationNames);
group->add(&m_cohesion);
group->add(&m_frictionAngleDeg);
}

View File

@@ -73,6 +73,7 @@ public:
private:
virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override;
virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override;
virtual void updateFormationNamesData() override;
@@ -82,4 +83,8 @@ private:
private:
cvf::ref<RigGeoMechCaseData> m_geoMechCaseData;
caf::PdmField<QString> m_caseFileName;
caf::PdmField<double> m_cohesion;
caf::PdmField<double> m_frictionAngleDeg;
protected:
};