2018-02-21 11:08:35 +01:00
|
|
|
/////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
//
|
|
|
|
|
// Copyright (C) 2018 Statoil ASA
|
2018-02-22 18:15:56 +01:00
|
|
|
//
|
2018-02-21 11:08:35 +01:00
|
|
|
// ResInsight is free software: you can redistribute it and/or modify
|
|
|
|
|
// it under the terms of the GNU General Public License as published by
|
|
|
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
|
|
|
// (at your option) any later version.
|
2018-02-22 18:15:56 +01:00
|
|
|
//
|
2018-02-21 11:08:35 +01:00
|
|
|
// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
|
|
|
|
|
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
|
|
|
// FITNESS FOR A PARTICULAR PURPOSE.
|
2018-02-22 18:15:56 +01:00
|
|
|
//
|
|
|
|
|
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
|
2018-02-21 11:08:35 +01:00
|
|
|
// for more details.
|
|
|
|
|
//
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
#include "RiuMohrsCirclePlot.h"
|
|
|
|
|
|
2018-02-22 17:52:10 +01:00
|
|
|
#include "RiuSelectionManager.h"
|
|
|
|
|
|
2018-02-22 18:10:24 +01:00
|
|
|
#include "RiaColorTables.h"
|
|
|
|
|
|
2018-02-22 17:52:10 +01:00
|
|
|
#include "RigFemPartCollection.h"
|
|
|
|
|
#include "RigFemPartResultsCollection.h"
|
|
|
|
|
#include "RigGeoMechCaseData.h"
|
|
|
|
|
|
|
|
|
|
#include "RimGeoMechCase.h"
|
|
|
|
|
#include "RimGeoMechCellColors.h"
|
|
|
|
|
#include "RimGeoMechResultDefinition.h"
|
|
|
|
|
#include "RimGeoMechView.h"
|
2018-02-21 11:08:35 +01:00
|
|
|
|
|
|
|
|
#include "cvfAssert.h"
|
|
|
|
|
|
2018-02-22 18:10:24 +01:00
|
|
|
#include <QPainterPath>
|
|
|
|
|
#include <QWidget>
|
|
|
|
|
|
|
|
|
|
#include "qwt_plot_layout.h"
|
|
|
|
|
#include "qwt_plot_marker.h"
|
|
|
|
|
#include "qwt_plot_rescaler.h"
|
|
|
|
|
#include "qwt_plot_shapeitem.h"
|
|
|
|
|
|
2018-02-21 11:08:35 +01:00
|
|
|
//==================================================================================================
|
|
|
|
|
///
|
|
|
|
|
/// \class RiuMohrsCirclePlot
|
|
|
|
|
///
|
2018-02-22 18:15:56 +01:00
|
|
|
///
|
2018-02-21 11:08:35 +01:00
|
|
|
///
|
|
|
|
|
//==================================================================================================
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2018-02-22 18:15:56 +01:00
|
|
|
///
|
2018-02-21 11:08:35 +01:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
RiuMohrsCirclePlot::RiuMohrsCirclePlot(QWidget* parent)
|
2018-02-22 18:15:56 +01:00
|
|
|
: QwtPlot(parent)
|
2018-02-21 11:08:35 +01:00
|
|
|
{
|
|
|
|
|
setDefaults();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2018-02-22 18:15:56 +01:00
|
|
|
///
|
2018-02-21 11:08:35 +01:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
RiuMohrsCirclePlot::~RiuMohrsCirclePlot()
|
|
|
|
|
{
|
|
|
|
|
deleteCircles();
|
2018-02-22 18:15:56 +01:00
|
|
|
|
2018-02-22 18:10:24 +01:00
|
|
|
delete m_rescaler;
|
2018-02-21 11:08:35 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2018-02-22 18:15:56 +01:00
|
|
|
///
|
2018-02-21 11:08:35 +01:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
void RiuMohrsCirclePlot::setPrincipals(double p1, double p2, double p3)
|
|
|
|
|
{
|
|
|
|
|
CVF_ASSERT(p1 > p2);
|
|
|
|
|
CVF_ASSERT(p2 > p3);
|
|
|
|
|
|
|
|
|
|
m_principal1 = p1;
|
|
|
|
|
m_principal2 = p2;
|
|
|
|
|
m_principal3 = p3;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2018-02-22 18:15:56 +01:00
|
|
|
///
|
2018-02-21 11:08:35 +01:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
void RiuMohrsCirclePlot::setPrincipalsAndRedrawCircles(double p1, double p2, double p3)
|
|
|
|
|
{
|
|
|
|
|
setPrincipals(p1, p2, p3);
|
|
|
|
|
|
|
|
|
|
redrawCircles();
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-22 17:52:10 +01:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
2018-02-22 18:15:56 +01:00
|
|
|
///
|
2018-02-22 17:52:10 +01:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
void RiuMohrsCirclePlot::updateOnSelectionChanged(const RiuSelectionItem* selectionItem)
|
|
|
|
|
{
|
|
|
|
|
const RiuGeoMechSelectionItem* geoMechSelectionItem = dynamic_cast<const RiuGeoMechSelectionItem*>(selectionItem);
|
2018-02-22 18:15:56 +01:00
|
|
|
|
2018-02-23 10:05:03 +01:00
|
|
|
if (!geoMechSelectionItem)
|
|
|
|
|
{
|
|
|
|
|
this->clearPlot();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
RimGeoMechView* geoMechView = geoMechSelectionItem->m_view;
|
|
|
|
|
CVF_ASSERT(geoMechView);
|
2018-02-22 17:52:10 +01:00
|
|
|
|
2018-02-23 10:05:03 +01:00
|
|
|
if (this->isVisible())
|
2018-02-22 17:52:10 +01:00
|
|
|
{
|
|
|
|
|
const size_t gridIndex = geoMechSelectionItem->m_gridIndex;
|
|
|
|
|
const size_t cellIndex = geoMechSelectionItem->m_cellIndex;
|
2018-02-23 10:05:03 +01:00
|
|
|
|
|
|
|
|
queryDataAndUpdatePlot(geoMechView, gridIndex, cellIndex);
|
2018-02-22 17:52:10 +01:00
|
|
|
}
|
2018-02-23 10:05:03 +01:00
|
|
|
else
|
2018-02-22 17:52:10 +01:00
|
|
|
{
|
|
|
|
|
this->clearPlot();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2018-02-22 18:15:56 +01:00
|
|
|
///
|
2018-02-22 17:52:10 +01:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
void RiuMohrsCirclePlot::clearPlot()
|
|
|
|
|
{
|
|
|
|
|
deleteCircles();
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-21 11:08:35 +01:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
2018-02-22 18:15:56 +01:00
|
|
|
///
|
2018-02-21 11:08:35 +01:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
QSize RiuMohrsCirclePlot::sizeHint() const
|
|
|
|
|
{
|
|
|
|
|
return QSize(100, 100);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2018-02-22 18:15:56 +01:00
|
|
|
///
|
2018-02-21 11:08:35 +01:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
QSize RiuMohrsCirclePlot::minimumSizeHint() const
|
|
|
|
|
{
|
|
|
|
|
return QSize(0, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2018-02-22 18:15:56 +01:00
|
|
|
///
|
2018-02-21 11:08:35 +01:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
void RiuMohrsCirclePlot::redrawCircles()
|
|
|
|
|
{
|
|
|
|
|
deleteCircles();
|
|
|
|
|
createMohrCircles();
|
|
|
|
|
|
2018-02-22 18:10:24 +01:00
|
|
|
caf::ColorTable colors = RiaColorTables::mohrsCirclePaletteColors();
|
|
|
|
|
|
|
|
|
|
for (size_t i = 0; i < m_mohrCircles.size(); i++)
|
2018-02-21 11:08:35 +01:00
|
|
|
{
|
2018-02-22 18:15:56 +01:00
|
|
|
MohrCircle* circle = &m_mohrCircles[i];
|
2018-02-22 18:10:24 +01:00
|
|
|
QwtPlotShapeItem* plotItem = new QwtPlotShapeItem("Circle");
|
|
|
|
|
|
|
|
|
|
QPainterPath* circleDrawing = new QPainterPath();
|
2018-02-22 18:15:56 +01:00
|
|
|
QPointF center(circle->centerX, 0);
|
2018-02-22 18:10:24 +01:00
|
|
|
circleDrawing->addEllipse(center, circle->radius, circle->radius);
|
2018-02-23 10:05:03 +01:00
|
|
|
|
2018-02-22 18:10:24 +01:00
|
|
|
plotItem->setPen(QPen(colors.cycledQColor(i)));
|
|
|
|
|
plotItem->setShape(*circleDrawing);
|
|
|
|
|
plotItem->setRenderHint(QwtPlotItem::RenderAntialiased, true);
|
|
|
|
|
m_circlePlotItems.push_back(plotItem);
|
|
|
|
|
plotItem->attach(this);
|
2018-02-21 11:08:35 +01:00
|
|
|
}
|
|
|
|
|
|
2018-02-22 18:15:56 +01:00
|
|
|
double yHeight = 0.6 * (m_principal1 - m_principal3);
|
2018-02-22 18:10:24 +01:00
|
|
|
this->setAxisScale(QwtPlot::yLeft, -yHeight, yHeight);
|
|
|
|
|
|
2018-02-23 10:05:03 +01:00
|
|
|
// Scale the x-axis to show the y-axis if the largest circle's leftmost intersection of the
|
|
|
|
|
// x-axis (principal 3) is to the right of the y-axis
|
|
|
|
|
|
|
|
|
|
//The following examples shows the largest of the three Mohr circles
|
|
|
|
|
|
|
|
|
|
// Ex 1: xMin will be set to 1.1 * m_principal3 to be able to see the whole circle
|
|
|
|
|
// |y
|
|
|
|
|
// _|____
|
|
|
|
|
// / | \
|
|
|
|
|
// / | \
|
|
|
|
|
//--|---|-------|------- x
|
|
|
|
|
// \ | /
|
|
|
|
|
// \_|_____/
|
|
|
|
|
// |
|
|
|
|
|
// |
|
|
|
|
|
|
|
|
|
|
// Ex 2: xMin will be set to -1 to be able to see the y-axis
|
|
|
|
|
// |y
|
|
|
|
|
// | _______
|
|
|
|
|
// | / \
|
|
|
|
|
// | / \
|
|
|
|
|
// -|-------------|-----------|---------- x
|
|
|
|
|
// | \ /
|
|
|
|
|
// | \_______/
|
|
|
|
|
// |
|
|
|
|
|
// |
|
|
|
|
|
|
|
|
|
|
double xMin;
|
|
|
|
|
if (m_principal3 < 0)
|
|
|
|
|
{
|
|
|
|
|
xMin = 1.1 * m_principal3;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
xMin = -1;
|
|
|
|
|
}
|
|
|
|
|
// When using the rescaler, xMax is ignored
|
|
|
|
|
double xMax = 0;
|
|
|
|
|
|
2018-02-22 18:10:24 +01:00
|
|
|
this->setAxisScale(QwtPlot::xBottom, xMin, xMax);
|
|
|
|
|
|
2018-02-21 11:08:35 +01:00
|
|
|
this->replot();
|
2018-02-22 18:10:24 +01:00
|
|
|
m_rescaler->rescale();
|
|
|
|
|
this->plotLayout()->setAlignCanvasToScales(true);
|
2018-02-21 11:08:35 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2018-02-22 18:15:56 +01:00
|
|
|
///
|
2018-02-21 11:08:35 +01:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
void RiuMohrsCirclePlot::deleteCircles()
|
|
|
|
|
{
|
2018-02-22 18:10:24 +01:00
|
|
|
for (size_t i = 0; i < m_circlePlotItems.size(); i++)
|
2018-02-21 11:08:35 +01:00
|
|
|
{
|
2018-02-22 18:10:24 +01:00
|
|
|
m_circlePlotItems[i]->detach();
|
|
|
|
|
delete m_circlePlotItems[i];
|
2018-02-21 11:08:35 +01:00
|
|
|
}
|
|
|
|
|
|
2018-02-22 18:10:24 +01:00
|
|
|
m_circlePlotItems.clear();
|
2018-02-21 11:08:35 +01:00
|
|
|
}
|
|
|
|
|
|
2018-02-22 17:52:10 +01:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
2018-02-22 18:15:56 +01:00
|
|
|
///
|
2018-02-22 17:52:10 +01:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
2018-02-23 10:05:03 +01:00
|
|
|
void RiuMohrsCirclePlot::queryDataAndUpdatePlot(RimGeoMechView* geoMechView, size_t gridIndex, size_t cellIndex)
|
2018-02-22 17:52:10 +01:00
|
|
|
{
|
2018-02-23 10:05:03 +01:00
|
|
|
CVF_ASSERT(geoMechView);
|
2018-02-22 18:15:56 +01:00
|
|
|
|
2018-02-22 17:52:10 +01:00
|
|
|
RigFemPartResultsCollection* resultCollection = geoMechView->geoMechCase()->geoMechData()->femPartResults();
|
|
|
|
|
|
|
|
|
|
int frameIdx = geoMechView->currentTimeStep();
|
2018-02-22 18:15:56 +01:00
|
|
|
|
2018-02-22 17:52:10 +01:00
|
|
|
RigFemResultAddress currentAddress = geoMechView->cellResult->resultAddress();
|
|
|
|
|
|
2018-02-22 18:15:56 +01:00
|
|
|
// TODO: All tensors are calculated everytime this function is called. FIX
|
2018-02-22 17:52:10 +01:00
|
|
|
std::vector<caf::Ten3f> vertexTensors = resultCollection->tensors(currentAddress, 0, frameIdx);
|
2018-02-22 18:15:56 +01:00
|
|
|
RigFemPart* femPart = geoMechView->geoMechCase()->geoMechData()->femParts()->part(gridIndex);
|
2018-02-22 17:52:10 +01:00
|
|
|
|
|
|
|
|
caf::Ten3f tensorSumOfElmNodes = vertexTensors[femPart->elementNodeResultIdx((int)cellIndex, 0)];
|
|
|
|
|
for (int i = 1; i < 8; i++)
|
|
|
|
|
{
|
|
|
|
|
tensorSumOfElmNodes = tensorSumOfElmNodes + vertexTensors[femPart->elementNodeResultIdx((int)cellIndex, i)];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
caf::Ten3f elmTensor = tensorSumOfElmNodes * (1.0 / 8.0);
|
|
|
|
|
|
|
|
|
|
cvf::Vec3f principalDirs[3];
|
|
|
|
|
cvf::Vec3f elmPrincipals = elmTensor.calculatePrincipals(principalDirs);
|
|
|
|
|
|
|
|
|
|
setPrincipalsAndRedrawCircles(elmPrincipals[0], elmPrincipals[1], elmPrincipals[2]);
|
|
|
|
|
}
|
|
|
|
|
|
2018-02-21 11:08:35 +01:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
2018-02-22 18:15:56 +01:00
|
|
|
///
|
2018-02-21 11:08:35 +01:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
void RiuMohrsCirclePlot::setDefaults()
|
|
|
|
|
{
|
2018-02-22 18:10:24 +01:00
|
|
|
m_rescaler = new QwtPlotRescaler(this->canvas());
|
|
|
|
|
m_rescaler->setReferenceAxis(QwtPlot::yLeft);
|
|
|
|
|
m_rescaler->setAspectRatio(QwtPlot::xBottom, 1.0);
|
|
|
|
|
m_rescaler->setRescalePolicy(QwtPlotRescaler::Fixed);
|
|
|
|
|
m_rescaler->setEnabled(true);
|
|
|
|
|
|
2018-02-21 11:08:35 +01:00
|
|
|
enableAxis(QwtPlot::xBottom, true);
|
|
|
|
|
enableAxis(QwtPlot::yLeft, true);
|
|
|
|
|
enableAxis(QwtPlot::xTop, false);
|
|
|
|
|
enableAxis(QwtPlot::yRight, false);
|
2018-02-22 18:15:56 +01:00
|
|
|
|
|
|
|
|
QwtPlotMarker* lineXPlotMarker = new QwtPlotMarker("LineX");
|
|
|
|
|
lineXPlotMarker->setLineStyle(QwtPlotMarker::HLine);
|
|
|
|
|
lineXPlotMarker->setYValue(0);
|
|
|
|
|
lineXPlotMarker->attach(this);
|
|
|
|
|
|
|
|
|
|
QwtPlotMarker* lineYPlotMarker = new QwtPlotMarker("LineY");
|
|
|
|
|
lineYPlotMarker->setLineStyle(QwtPlotMarker::VLine);
|
|
|
|
|
lineYPlotMarker->setXValue(0);
|
|
|
|
|
lineYPlotMarker->attach(this);
|
2018-02-21 11:08:35 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2018-02-22 18:15:56 +01:00
|
|
|
///
|
2018-02-21 11:08:35 +01:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
void RiuMohrsCirclePlot::createMohrCircles()
|
|
|
|
|
{
|
|
|
|
|
m_mohrCircles[0].component = 2;
|
2018-02-23 10:05:03 +01:00
|
|
|
m_mohrCircles[0].radius = (m_principal1 - m_principal3) / 2.0;
|
|
|
|
|
m_mohrCircles[0].centerX = (m_principal1 + m_principal3) / 2.0;
|
2018-02-21 11:08:35 +01:00
|
|
|
|
|
|
|
|
m_mohrCircles[1].component = 1;
|
2018-02-23 10:05:03 +01:00
|
|
|
m_mohrCircles[1].radius = (m_principal2 - m_principal3) / 2.0;
|
|
|
|
|
m_mohrCircles[1].centerX = (m_principal2 + m_principal3) / 2.0;
|
2018-02-21 11:08:35 +01:00
|
|
|
|
|
|
|
|
m_mohrCircles[2].component = 3;
|
2018-02-23 10:05:03 +01:00
|
|
|
m_mohrCircles[2].radius = (m_principal1 - m_principal2) / 2.0;
|
|
|
|
|
m_mohrCircles[2].centerX = (m_principal1 + m_principal2) / 2.0;
|
2018-02-21 11:08:35 +01:00
|
|
|
}
|