//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RigNNCData::processConnections(const RigMainGrid& mainGrid) { //cvf::Trace::show("NNC: Total number: " + cvf::String((int)m_connections.size())); for (size_t cnIdx = 0; cnIdx < m_connections.size(); ++cnIdx) { const RigCell& c1 = mainGrid.globalCellArray()[m_connections[cnIdx].m_c1GlobIdx]; const RigCell& c2 = mainGrid.globalCellArray()[m_connections[cnIdx].m_c2GlobIdx]; bool foundAnyOverlap = false; std::vector<size_t> connectionPolygon; std::vector<cvf::Vec3d> connectionIntersections; cvf::StructGridInterface::FaceType connectionFace = cvf::StructGridInterface::NO_FACE; connectionFace = calculateCellFaceOverlap(c1, c2, mainGrid, &connectionPolygon, &connectionIntersections); if (connectionFace != cvf::StructGridInterface::NO_FACE) { foundAnyOverlap = true; // Found an overlap polygon. Store data about connection m_connections[cnIdx].m_c1Face = connectionFace; for (size_t pIdx = 0; pIdx < connectionPolygon.size(); ++pIdx) { if (connectionPolygon[pIdx] < mainGrid.nodes().size()) m_connections[cnIdx].m_polygon.push_back(mainGrid.nodes()[connectionPolygon[pIdx]]); else m_connections[cnIdx].m_polygon.push_back(connectionIntersections[connectionPolygon[pIdx] - mainGrid.nodes().size()]); } // Add to search map, possibly not needed //m_cellIdxToFaceToConnectionIdxMap[m_connections[cnIdx].m_c1GlobIdx][connectionFace].push_back(cnIdx); //m_cellIdxToFaceToConnectionIdxMap[m_connections[cnIdx].m_c2GlobIdx][cvf::StructGridInterface::oppositeFace(connectionFace].push_back(cnIdx); } else { //cvf::Trace::show("NNC: No overlap found for : C1: " + cvf::String((int)m_connections[cnIdx].m_c1GlobIdx) + "C2: " + cvf::String((int)m_connections[cnIdx].m_c2GlobIdx)); } } }
bool interpretCommand(RiaSocketServer* server, const QList<QByteArray>& args, QDataStream& socketStream) override { RimEclipseCase* rimCase = RiaSocketTools::findCaseFromArgs(server, args); QString porosityModelName; porosityModelName = args[2]; RiaDefines::PorosityModelType porosityModelEnum = RiaDefines::MATRIX_MODEL; if (porosityModelName.toUpper() == "FRACTURE") { porosityModelEnum = RiaDefines::FRACTURE_MODEL; } if (!rimCase || !rimCase->eclipseCaseData() ) { // No data available socketStream << (quint64)0 << (quint64)0 ; return true; } RigActiveCellInfo* actCellInfo = rimCase->eclipseCaseData()->activeCellInfo(porosityModelEnum); RigMainGrid* mainGrid = rimCase->eclipseCaseData()->mainGrid(); size_t activeCellCount = actCellInfo->reservoirActiveCellCount(); size_t doubleValueCount = activeCellCount * 3 * 8; socketStream << (quint64)activeCellCount; quint64 byteCount = doubleValueCount * sizeof(double); socketStream << byteCount; // This structure is supposed to be received by Octave using a NDArray. The ordering of this loop is // defined by the ordering of the receiving NDArray // // See riGetCellCorners // // dim_vector dv; // dv.resize(3); // dv(0) = coordCount; // dv(1) = 8; // dv(2) = 3; cvf::Vec3d cornerVerts[8]; size_t blockByteCount = activeCellCount * sizeof(double); std::vector<double> doubleValues(blockByteCount); for (int coordIdx = 0; coordIdx < 3; coordIdx++) { for (size_t cornerIdx = 0; cornerIdx < 8; cornerIdx++) { size_t cornerIndexMapping = cellCornerMappingEclipse[cornerIdx]; quint64 valueIndex = 0; for (size_t reservoirCellIndex = 0; reservoirCellIndex < mainGrid->globalCellArray().size(); reservoirCellIndex++) { if (!actCellInfo->isActive(reservoirCellIndex)) continue; mainGrid->cellCornerVertices(reservoirCellIndex, cornerVerts); doubleValues[valueIndex++] = getCellCornerWithPositiveDepth(cornerVerts, cornerIndexMapping, coordIdx); } CVF_ASSERT(valueIndex == activeCellCount); RiaSocketTools::writeBlockData(server, server->currentClient(), (const char *)doubleValues.data(), blockByteCount); } } return true; }
//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RigNNCData::processConnections(const RigMainGrid& mainGrid) { //cvf::Trace::show("NNC: Total number: " + cvf::String((int)m_connections.size())); for (size_t cnIdx = 0; cnIdx < m_connections.size(); ++cnIdx) { const RigCell& c1 = mainGrid.globalCellArray()[m_connections[cnIdx].m_c1GlobIdx]; const RigCell& c2 = mainGrid.globalCellArray()[m_connections[cnIdx].m_c2GlobIdx]; // Try to find the shared face char hasNeighbourInAnyDirection = 0; bool isPossibleNeighborInDirection[6]= {true, true, true, true, true, true}; if (c1.hostGrid() == c2.hostGrid()) { size_t i1, j1, k1; c1.hostGrid()->ijkFromCellIndex(c1.gridLocalCellIndex(), &i1, &j1, &k1); size_t i2, j2, k2; c2.hostGrid()->ijkFromCellIndex(c2.gridLocalCellIndex(), &i2, &j2, &k2); isPossibleNeighborInDirection[cvf::StructGridInterface::POS_I] = ((i1 + 1) == i2); isPossibleNeighborInDirection[cvf::StructGridInterface::NEG_I] = ((i2 + 1) == i1); isPossibleNeighborInDirection[cvf::StructGridInterface::POS_J] = ((j1 + 1) == j2); isPossibleNeighborInDirection[cvf::StructGridInterface::NEG_J] = ((j2 + 1) == j1); isPossibleNeighborInDirection[cvf::StructGridInterface::POS_K] = ((k1 + 1) == k2); isPossibleNeighborInDirection[cvf::StructGridInterface::NEG_K] = ((k2 + 1) == k1); hasNeighbourInAnyDirection = isPossibleNeighborInDirection[cvf::StructGridInterface::POS_I] + isPossibleNeighborInDirection[cvf::StructGridInterface::NEG_I] + isPossibleNeighborInDirection[cvf::StructGridInterface::POS_J] + isPossibleNeighborInDirection[cvf::StructGridInterface::NEG_J] + isPossibleNeighborInDirection[cvf::StructGridInterface::POS_K] + isPossibleNeighborInDirection[cvf::StructGridInterface::NEG_K]; // If cell 2 is not adjancent with respect to any of the six ijk directions, // assume that we have no overlapping area. if (!hasNeighbourInAnyDirection) { // Add to search map //m_cellIdxToFaceToConnectionIdxMap[m_connections[cnIdx].m_c1GlobIdx][cvf::StructGridInterface::NO_FACE].push_back(cnIdx); //m_cellIdxToFaceToConnectionIdxMap[m_connections[cnIdx].m_c2GlobIdx][cvf::StructGridInterface::NO_FACE].push_back(cnIdx); //cvf::Trace::show("NNC: No direct neighbors : C1: " + cvf::String((int)m_connections[cnIdx].m_c1GlobIdx) + " C2: " + cvf::String((int)m_connections[cnIdx].m_c2GlobIdx)); continue; // to next connection } } // Possibly do some testing to avoid unneccesary overlap calculations cvf::Vec3d normal; for (char fIdx = 0; fIdx < 6; ++fIdx) { if (isPossibleNeighborInDirection[fIdx]) { cvf::Vec3d fc1 = c1.faceCenter((cvf::StructGridInterface::FaceType)(fIdx)); cvf::Vec3d fc2 = c2.faceCenter(cvf::StructGridInterface::oppositeFace((cvf::StructGridInterface::FaceType)(fIdx))); cvf::Vec3d fc1ToFc2 = fc2 - fc1; normal = c1.faceNormalWithAreaLenght((cvf::StructGridInterface::FaceType)(fIdx)); normal.normalize(); // Check that face centers are approx in the face plane if (normal.dot(fc1ToFc2) < 0.01*fc1ToFc2.length()) { } } } bool foundAnyOverlap = false; for (char fIdx = 0; fIdx < 6; ++fIdx) { if (!isPossibleNeighborInDirection[fIdx]) { continue; } // Calculate connection polygon std::vector<size_t> polygon; std::vector<cvf::Vec3d> intersections; caf::SizeTArray4 face1; caf::SizeTArray4 face2; c1.faceIndices((cvf::StructGridInterface::FaceType)(fIdx), &face1); c2.faceIndices(cvf::StructGridInterface::oppositeFace((cvf::StructGridInterface::FaceType)(fIdx)), &face2); bool foundOverlap = cvf::GeometryTools::calculateOverlapPolygonOfTwoQuads( &polygon, &intersections, (cvf::EdgeIntersectStorage<size_t>*)NULL, cvf::wrapArrayConst(&mainGrid.nodes()), face1.data(), face2.data(), 1e-6); if (foundOverlap) { foundAnyOverlap = true; // Found an overlap polygon. Store data about connection m_connections[cnIdx].m_c1Face = (cvf::StructGridInterface::FaceType)fIdx; for (size_t pIdx = 0; pIdx < polygon.size(); ++pIdx) { if (polygon[pIdx] < mainGrid.nodes().size()) m_connections[cnIdx].m_polygon.push_back(mainGrid.nodes()[polygon[pIdx]]); else m_connections[cnIdx].m_polygon.push_back(intersections[polygon[pIdx] - mainGrid.nodes().size()]); } // Add to search map, possibly not needed //m_cellIdxToFaceToConnectionIdxMap[m_connections[cnIdx].m_c1GlobIdx][fIdx].push_back(cnIdx); //m_cellIdxToFaceToConnectionIdxMap[m_connections[cnIdx].m_c2GlobIdx][cvf::StructGridInterface::oppositeFace((cvf::StructGridInterface::FaceType)(fIdx))].push_back(cnIdx); break; // The connection face is found. Stop looping over the cell faces. Jump to next connection } } if (!foundAnyOverlap) { //cvf::Trace::show("NNC: No overlap found for : C1: " + cvf::String((int)m_connections[cnIdx].m_c1GlobIdx) + "C2: " + cvf::String((int)m_connections[cnIdx].m_c2GlobIdx)); } } }