PageRenderTime 32ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/ResInsight-2018.01.1/ApplicationCode/UserInterface/RiuFemResultTextBuilder.cpp

https://bitbucket.org/terraai/resinsight
C++ | 389 lines | 266 code | 66 blank | 57 comment | 45 complexity | d7dac6f38a9a929462ec811ab8bd2401 MD5 | raw file
Possible License(s): GPL-3.0, LGPL-2.1
  1. /////////////////////////////////////////////////////////////////////////////////
  2. //
  3. // Copyright (C) Statoil ASA
  4. // Copyright (C) Ceetron Solutions AS
  5. //
  6. // ResInsight is free software: you can redistribute it and/or modify
  7. // it under the terms of the GNU General Public License as published by
  8. // the Free Software Foundation, either version 3 of the License, or
  9. // (at your option) any later version.
  10. //
  11. // ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY
  12. // WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13. // FITNESS FOR A PARTICULAR PURPOSE.
  14. //
  15. // See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
  16. // for more details.
  17. //
  18. /////////////////////////////////////////////////////////////////////////////////
  19. #include "RiuFemResultTextBuilder.h"
  20. #include "RigFemPart.h"
  21. #include "RigFemPartCollection.h"
  22. #include "RigFemPartGrid.h"
  23. #include "RigFemPartResultsCollection.h"
  24. #include "RigFormationNames.h"
  25. #include "RigGeoMechCaseData.h"
  26. #include "RimFormationNames.h"
  27. #include "RimGeoMechCase.h"
  28. #include "RimGeoMechResultDefinition.h"
  29. #include "RimGeoMechView.h"
  30. #include "RiuGeoMechXfTensorResultAccessor.h"
  31. //--------------------------------------------------------------------------------------------------
  32. ///
  33. //--------------------------------------------------------------------------------------------------
  34. RiuFemResultTextBuilder::RiuFemResultTextBuilder(RimGeoMechView* reservoirView,
  35. int gridIndex,
  36. int cellIndex,
  37. int timeStepIndex)
  38. : m_isIntersectionTriangleSet(false)
  39. {
  40. CVF_ASSERT(reservoirView);
  41. m_reservoirView = reservoirView;
  42. m_gridIndex = gridIndex;
  43. m_cellIndex = cellIndex;
  44. m_timeStepIndex = timeStepIndex;
  45. m_intersectionPoint = cvf::Vec3d::UNDEFINED;
  46. m_face = cvf::StructGridInterface::NO_FACE;
  47. }
  48. //--------------------------------------------------------------------------------------------------
  49. ///
  50. //--------------------------------------------------------------------------------------------------
  51. void RiuFemResultTextBuilder::setIntersectionPoint(cvf::Vec3d intersectionPoint)
  52. {
  53. m_intersectionPoint = intersectionPoint;
  54. }
  55. //--------------------------------------------------------------------------------------------------
  56. ///
  57. //--------------------------------------------------------------------------------------------------
  58. void RiuFemResultTextBuilder::setIntersectionTriangle(const std::array<cvf::Vec3f, 3>& triangle)
  59. {
  60. m_intersectionTriangle = triangle;
  61. m_isIntersectionTriangleSet = true;
  62. }
  63. //--------------------------------------------------------------------------------------------------
  64. ///
  65. //--------------------------------------------------------------------------------------------------
  66. void RiuFemResultTextBuilder::setFace(int face)
  67. {
  68. m_face = face;
  69. }
  70. //--------------------------------------------------------------------------------------------------
  71. ///
  72. //--------------------------------------------------------------------------------------------------
  73. QString RiuFemResultTextBuilder::mainResultText()
  74. {
  75. QString text;
  76. text = closestNodeResultText(m_reservoirView->cellResultResultDefinition());
  77. if (!text.isEmpty()) text += "\n";
  78. QString topoText = this->geometrySelectionText("\n");
  79. text += topoText;
  80. appendDetails(text, formationDetails());
  81. text += "\n";
  82. appendDetails(text, gridResultDetails());
  83. return text;
  84. }
  85. //--------------------------------------------------------------------------------------------------
  86. ///
  87. //--------------------------------------------------------------------------------------------------
  88. QString RiuFemResultTextBuilder::geometrySelectionText(QString itemSeparator)
  89. {
  90. QString text;
  91. if (m_reservoirView->geoMechCase())
  92. {
  93. RigGeoMechCaseData* geomData = m_reservoirView->geoMechCase()->geoMechData();
  94. if (geomData)
  95. {
  96. RigFemPart* femPart = geomData->femParts()->part(m_gridIndex);
  97. int elementId = femPart->elmId(m_cellIndex);
  98. text += QString("Element : Id[%1]").arg(elementId);
  99. size_t i = 0;
  100. size_t j = 0;
  101. size_t k = 0;
  102. if (geomData->femParts()->part(m_gridIndex)->structGrid()->ijkFromCellIndex(m_cellIndex, &i, &j, &k))
  103. {
  104. // Adjust to 1-based Eclipse indexing
  105. i++;
  106. j++;
  107. k++;
  108. cvf::Vec3d domainCoord = m_intersectionPoint; // + geomCase->femParts()->displayModelOffset();
  109. //cvf::StructGridInterface::FaceEnum faceEnum(m_face);
  110. //QString faceText = faceEnum.text();
  111. //text += QString("Face : %1").arg(faceText) + itemSeparator;
  112. //text += QString("Fem Part %1").arg(m_gridIndex) + itemSeparator;
  113. text += QString(", ijk[%1, %2, %3]").arg(i).arg(j).arg(k) + itemSeparator;
  114. QString formattedText;
  115. formattedText.sprintf("Intersection point : [E: %.2f, N: %.2f, Depth: %.2f]", domainCoord.x(), domainCoord.y(), -domainCoord.z());
  116. text += formattedText;
  117. }
  118. }
  119. }
  120. return text;
  121. }
  122. //--------------------------------------------------------------------------------------------------
  123. ///
  124. //--------------------------------------------------------------------------------------------------
  125. QString RiuFemResultTextBuilder::gridResultDetails()
  126. {
  127. QString text;
  128. if (m_reservoirView->geoMechCase() && m_reservoirView->geoMechCase()->geoMechData())
  129. {
  130. RigGeoMechCaseData* eclipseCaseData = m_reservoirView->geoMechCase()->geoMechData();
  131. this->appendTextFromResultColors(eclipseCaseData, m_gridIndex, m_cellIndex, m_timeStepIndex, m_reservoirView->cellResultResultDefinition(), &text);
  132. if (!text.isEmpty())
  133. {
  134. text.prepend("-- Element result details --\n");
  135. }
  136. }
  137. return text;
  138. }
  139. //--------------------------------------------------------------------------------------------------
  140. ///
  141. //--------------------------------------------------------------------------------------------------
  142. QString RiuFemResultTextBuilder::formationDetails()
  143. {
  144. QString text;
  145. RimCase* rimCase = m_reservoirView->ownerCase();
  146. if(rimCase)
  147. {
  148. if(rimCase->activeFormationNames() && rimCase->activeFormationNames()->formationNamesData())
  149. {
  150. RigFormationNames* formNames = rimCase->activeFormationNames()->formationNamesData();
  151. size_t k = cvf::UNDEFINED_SIZE_T;
  152. {
  153. RigGeoMechCaseData* geomData = m_reservoirView->geoMechCase()->geoMechData();
  154. if(geomData)
  155. {
  156. size_t i = 0;
  157. size_t j = 0;
  158. geomData->femParts()->part(m_gridIndex)->structGrid()->ijkFromCellIndex(m_cellIndex, &i, &j, &k);
  159. }
  160. }
  161. if(k != cvf::UNDEFINED_SIZE_T)
  162. {
  163. QString formName = formNames->formationNameFromKLayerIdx(k);
  164. if(!formName.isEmpty())
  165. {
  166. //text += "-- Formation details --\n";
  167. text += QString("Formation Name: %1\n").arg(formName);
  168. }
  169. }
  170. }
  171. }
  172. return text;
  173. }
  174. //--------------------------------------------------------------------------------------------------
  175. ///
  176. //--------------------------------------------------------------------------------------------------
  177. void RiuFemResultTextBuilder::appendTextFromResultColors(RigGeoMechCaseData* geomData, int gridIndex, int cellIndex, int timeStepIndex, RimGeoMechResultDefinition* resultDefinition, QString* resultInfoText)
  178. {
  179. if (!resultDefinition)
  180. {
  181. return;
  182. }
  183. if (resultDefinition->hasResult())
  184. {
  185. const std::vector<float>& scalarResults = geomData->femPartResults()->resultValues(resultDefinition->resultAddress(), gridIndex, timeStepIndex);
  186. if (scalarResults.size())
  187. {
  188. caf::AppEnum<RigFemResultPosEnum> resPosAppEnum = resultDefinition->resultPositionType();
  189. resultInfoText->append(resPosAppEnum.uiText() + ", ");
  190. resultInfoText->append(resultDefinition->resultFieldUiName()+ ", ") ;
  191. resultInfoText->append(resultDefinition->resultComponentUiName() + ":\n");
  192. if (resultDefinition->resultPositionType() != RIG_ELEMENT_NODAL_FACE)
  193. {
  194. RigFemPart* femPart = geomData->femParts()->part(gridIndex);
  195. RigElementType elmType = femPart->elementType(cellIndex);
  196. const int* elmentConn = femPart->connectivities(cellIndex);
  197. int elmNodeCount = RigFemTypes::elmentNodeCount(elmType);
  198. const int* lElmNodeToIpMap = RigFemTypes::localElmNodeToIntegrationPointMapping(elmType);
  199. for (int lNodeIdx = 0; lNodeIdx < elmNodeCount; ++lNodeIdx)
  200. {
  201. float scalarValue = std::numeric_limits<float>::infinity();
  202. int nodeIdx = elmentConn[lNodeIdx];
  203. if (resultDefinition->resultPositionType() == RIG_NODAL)
  204. {
  205. scalarValue = scalarResults[nodeIdx];
  206. }
  207. else
  208. {
  209. size_t resIdx = femPart->elementNodeResultIdx(cellIndex, lNodeIdx);
  210. scalarValue = scalarResults[resIdx];
  211. }
  212. if (resultDefinition->resultPositionType() == RIG_INTEGRATION_POINT)
  213. {
  214. resultInfoText->append(QString("\tIP:%1 \t: %2 \tAss. Node: \t%3").arg(lElmNodeToIpMap[lNodeIdx] + 1 ).arg(scalarValue).arg(femPart->nodes().nodeIds[nodeIdx]));
  215. }
  216. else
  217. {
  218. resultInfoText->append(QString("\tN:%1 \t: %2").arg(femPart->nodes().nodeIds[nodeIdx]).arg(scalarValue));
  219. }
  220. cvf::Vec3f nodeCoord = femPart->nodes().coordinates[nodeIdx];
  221. resultInfoText->append(QString("\t( %3, %4, %5)\n").arg(nodeCoord[0]).arg(nodeCoord[1]).arg(nodeCoord[2]));
  222. }
  223. }
  224. else
  225. {
  226. int elmNodeFaceStartResIdx = cellIndex *24;
  227. resultInfoText->append(QString("Pos I Face:\n"));
  228. for (int ptIdx = 0; ptIdx < 4; ++ptIdx)
  229. {
  230. resultInfoText->append(QString("\t%2\n").arg(scalarResults[elmNodeFaceStartResIdx+ptIdx]));
  231. }
  232. resultInfoText->append(QString("Neg I Face:\n"));
  233. for(int ptIdx = 4; ptIdx < 8; ++ptIdx)
  234. {
  235. resultInfoText->append(QString("\t%2\n").arg(scalarResults[elmNodeFaceStartResIdx+ptIdx]));
  236. }
  237. resultInfoText->append(QString("Pos J Face:\n"));
  238. for(int ptIdx = 8; ptIdx < 12; ++ptIdx)
  239. {
  240. resultInfoText->append(QString("\t%2\n").arg(scalarResults[elmNodeFaceStartResIdx+ptIdx]));
  241. }
  242. resultInfoText->append(QString("Neg J Face:\n"));
  243. for(int ptIdx = 12; ptIdx < 16; ++ptIdx)
  244. {
  245. resultInfoText->append(QString("\t%2\n").arg(scalarResults[elmNodeFaceStartResIdx+ptIdx]));
  246. }
  247. resultInfoText->append(QString("Pos K Face:\n"));
  248. for(int ptIdx = 16; ptIdx < 20; ++ptIdx)
  249. {
  250. resultInfoText->append(QString("\t%2\n").arg(scalarResults[elmNodeFaceStartResIdx+ptIdx]));
  251. }
  252. resultInfoText->append(QString("Neg K Face:\n"));
  253. for(int ptIdx = 20; ptIdx < 24; ++ptIdx)
  254. {
  255. resultInfoText->append(QString("\t%2\n").arg(scalarResults[elmNodeFaceStartResIdx+ptIdx]));
  256. }
  257. }
  258. }
  259. }
  260. }
  261. //--------------------------------------------------------------------------------------------------
  262. ///
  263. //--------------------------------------------------------------------------------------------------
  264. void RiuFemResultTextBuilder::appendDetails(QString& text, const QString& details)
  265. {
  266. if (!details.isEmpty())
  267. {
  268. text += "\n";
  269. text += details;
  270. }
  271. }
  272. //--------------------------------------------------------------------------------------------------
  273. ///
  274. //--------------------------------------------------------------------------------------------------
  275. QString RiuFemResultTextBuilder::closestNodeResultText(RimGeoMechResultDefinition* resultColors)
  276. {
  277. QString text;
  278. if (!resultColors)
  279. {
  280. return text;
  281. }
  282. if (resultColors->hasResult())
  283. {
  284. if (! (m_reservoirView->geoMechCase() && m_reservoirView->geoMechCase()->geoMechData())) return text;
  285. RigGeoMechCaseData* geomData = m_reservoirView->geoMechCase()->geoMechData();
  286. const std::vector<float>& scalarResults = geomData->femPartResults()->resultValues(resultColors->resultAddress(), m_gridIndex, m_timeStepIndex);
  287. if (scalarResults.size())
  288. {
  289. RigFemPart* femPart = geomData->femParts()->part(m_gridIndex);
  290. RigFemResultPosEnum activeResultPosition = resultColors->resultPositionType();
  291. RigFemClosestResultIndexCalculator closestIndexCalc(femPart,
  292. activeResultPosition,
  293. m_cellIndex,
  294. m_face,
  295. m_intersectionPoint);
  296. int resultIndex = closestIndexCalc.resultIndexToClosestResult();
  297. int closestNodeId = closestIndexCalc.closestNodeId();
  298. int closestElmNodResIdx = closestIndexCalc.closestElementNodeResIdx();
  299. float scalarValue = (resultIndex >= 0) ? scalarResults[resultIndex]: std::numeric_limits<float>::infinity();
  300. if (activeResultPosition != RIG_ELEMENT_NODAL_FACE)
  301. {
  302. text.append(QString("Closest result: N[%1], %2\n").arg(closestNodeId)
  303. .arg(scalarValue));
  304. }
  305. else if ( m_face != -1 )
  306. {
  307. text.append(QString("Closest result: N[%1], on face: %2, %3\n").arg(closestNodeId)
  308. .arg(caf::AppEnum<cvf::StructGridInterface::FaceType>::textFromIndex(m_face))
  309. .arg(scalarValue));
  310. }
  311. else if (m_isIntersectionTriangleSet && activeResultPosition == RIG_ELEMENT_NODAL_FACE)
  312. {
  313. RiuGeoMechXfTensorResultAccessor tensAccessor(geomData->femPartResults(), resultColors->resultAddress(), m_timeStepIndex);
  314. float tensValue = tensAccessor.calculateElmNodeValue(m_intersectionTriangle, closestElmNodResIdx);
  315. text.append(QString("Closest result: N[%1], in Element[%2] transformed onto intersection: %3 \n")
  316. .arg(closestNodeId)
  317. .arg(femPart->elmId(m_cellIndex))
  318. .arg(tensValue));
  319. }
  320. }
  321. }
  322. return text;
  323. }