//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RigReservoirBuilderMock::appendCells(size_t nodeStartIndex, size_t cellCount, RigGridBase* hostGrid, std::vector<RigCell>& cells) { size_t activeCellIndex = 0; size_t i; for (i = 0; i < cellCount; i++) { RigCell riCell; riCell.setHostGrid(hostGrid); riCell.setCellIndex(i); riCell.cornerIndices()[0] = nodeStartIndex + i * 8 + 0; riCell.cornerIndices()[1] = nodeStartIndex + i * 8 + 1; riCell.cornerIndices()[2] = nodeStartIndex + i * 8 + 2; riCell.cornerIndices()[3] = nodeStartIndex + i * 8 + 3; riCell.cornerIndices()[4] = nodeStartIndex + i * 8 + 4; riCell.cornerIndices()[5] = nodeStartIndex + i * 8 + 5; riCell.cornerIndices()[6] = nodeStartIndex + i * 8 + 6; riCell.cornerIndices()[7] = nodeStartIndex + i * 8 + 7; riCell.setParentCellIndex(0); //TODO: Rewrite active cell info in mock models /* if (!(i % 5)) { riCell.setActiveIndexInMatrixModel(cvf::UNDEFINED_SIZE_T); } else { riCell.setActiveIndexInMatrixModel(activeCellIndex++); } */ cells.push_back(riCell); } }
//-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- cvf::StructGridInterface::FaceType RigNNCData::calculateCellFaceOverlap(const RigCell &c1, const RigCell &c2, const RigMainGrid &mainGrid, std::vector<size_t>* connectionPolygon, std::vector<cvf::Vec3d>* connectionIntersections) { // Try to find the shared face bool isPossibleNeighborInDirection[6]={ true, true, true, true, true, true }; if ( c1.hostGrid() == c2.hostGrid() ) { char hasNeighbourInAnyDirection = 0; 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)); return cvf::StructGridInterface::NO_FACE; } } #if 0 // 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() ) { } } } #endif for ( unsigned 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>*)nullptr, cvf::wrapArrayConst(&mainGrid.nodes()), face1.data(), face2.data(), 1e-6); if ( foundOverlap ) { if (connectionPolygon)(*connectionPolygon) = polygon; if (connectionIntersections) (*connectionIntersections) = intersections; return (cvf::StructGridInterface::FaceType)(fIdx); } } return cvf::StructGridInterface::NO_FACE; }
bool transferGridCellData(RigMainGrid* mainGrid, RigGridBase* localGrid, const ecl_grid_type* localEclGrid, size_t matrixActiveStartIndex, size_t fractureActiveStartIndex) { int cellCount = ecl_grid_get_global_size(localEclGrid); size_t cellStartIndex = mainGrid->cells().size(); size_t nodeStartIndex = mainGrid->nodes().size(); RigCell defaultCell; defaultCell.setHostGrid(localGrid); mainGrid->cells().resize(cellStartIndex + cellCount, defaultCell); mainGrid->nodes().resize(nodeStartIndex + cellCount*8, cvf::Vec3d(0,0,0)); int progTicks = 100; double cellsPrProgressTick = cellCount/(float)progTicks; caf::ProgressInfo progInfo(progTicks, ""); size_t computedCellCount = 0; // Loop over cells and fill them with data #pragma omp parallel for for (int gIdx = 0; gIdx < cellCount; ++gIdx) { RigCell& cell = mainGrid->cells()[cellStartIndex + gIdx]; bool invalid = ecl_grid_cell_invalid1(localEclGrid, gIdx); cell.setInvalid(invalid); cell.setCellIndex(gIdx); // Active cell index int matrixActiveIndex = ecl_grid_get_active_index1(localEclGrid, gIdx); if (matrixActiveIndex != -1) { cell.setActiveIndexInMatrixModel(matrixActiveStartIndex + matrixActiveIndex); } else { cell.setActiveIndexInMatrixModel(cvf::UNDEFINED_SIZE_T); } int fractureActiveIndex = ecl_grid_get_active_fracture_index1(localEclGrid, gIdx); if (fractureActiveIndex != -1) { cell.setActiveIndexInFractureModel(fractureActiveStartIndex + fractureActiveIndex); } else { cell.setActiveIndexInFractureModel(cvf::UNDEFINED_SIZE_T); } // Parent cell index int parentCellIndex = ecl_grid_get_parent_cell1(localEclGrid, gIdx); if (parentCellIndex == -1) { cell.setParentCellIndex(cvf::UNDEFINED_SIZE_T); } else { cell.setParentCellIndex(parentCellIndex); } // Coarse cell info ecl_coarse_cell_type * coarseCellData = ecl_grid_get_cell_coarse_group1( localEclGrid , gIdx); cell.setInCoarseCell(coarseCellData != NULL); // Corner coordinates int cIdx; for (cIdx = 0; cIdx < 8; ++cIdx) { double * point = mainGrid->nodes()[nodeStartIndex + gIdx * 8 + cellMappingECLRi[cIdx]].ptr(); ecl_grid_get_corner_xyz1(localEclGrid, gIdx, cIdx, &(point[0]), &(point[1]), &(point[2])); point[2] = -point[2]; cell.cornerIndices()[cIdx] = nodeStartIndex + gIdx*8 + cIdx; } // Sub grid in cell const ecl_grid_type* subGrid = ecl_grid_get_cell_lgr1(localEclGrid, gIdx); if (subGrid != NULL) { int subGridFileIndex = ecl_grid_get_grid_nr(subGrid); CVF_ASSERT(subGridFileIndex > 0); cell.setSubGrid(static_cast<RigLocalGrid*>(mainGrid->gridByIndex(subGridFileIndex))); } // Mark inactive long pyramid looking cells as invalid if (!invalid && (cell.isInCoarseCell() || (!cell.isActiveInMatrixModel() && !cell.isActiveInFractureModel()) ) ) { cell.setInvalid(cell.isLongPyramidCell()); } #pragma omp atomic computedCellCount++; progInfo.setProgress((int)(computedCellCount/cellsPrProgressTick)); } return true; }