MswRollUp: Updated Ert to experimental MSW branch. Updated ResInsight code to handle API changes

067fa99faa
This is an intermediate commit and does not compile
p4#: 22212
This commit is contained in:
Jacob Støren 2013-08-26 13:56:42 +02:00
parent 64c234d988
commit b63f51921d
250 changed files with 9280 additions and 4701 deletions

View File

@ -111,6 +111,8 @@ bool transferGridCellData(RigMainGrid* mainGrid, RigActiveCellInfo* activeCellIn
{
RigCell& cell = mainGrid->cells()[cellStartIndex + localCellIdx];
bool invalid = ecl_grid_cell_invalid1(localEclGrid, localCellIdx);
cell.setInvalid(invalid);
cell.setCellIndex(localCellIdx);
// Active cell index
@ -161,7 +163,10 @@ bool transferGridCellData(RigMainGrid* mainGrid, RigActiveCellInfo* activeCellIn
// Mark inactive long pyramid looking cells as invalid
// Forslag
//if (!invalid && (cell.isInCoarseCell() || (!cell.isActiveInMatrixModel() && !cell.isActiveInFractureModel()) ) )
cell.setInvalid(cell.isLongPyramidCell());
if (!invalid)
{
cell.setInvalid(cell.isLongPyramidCell());
}
#pragma omp atomic
computedCellCount++;
@ -355,7 +360,6 @@ bool RifReaderEclipseOutput::open(const QString& fileName, RigCaseData* eclipseC
m_filesWithSameBaseName = fileSet;
// Read geometry
// Todo: Needs to check existence of file before calling ert, else it will abort
ecl_grid_type * mainEclGrid = ecl_grid_alloc( fileName.toAscii().data() );
progInfo.incrementProgress();
@ -366,24 +370,22 @@ bool RifReaderEclipseOutput::open(const QString& fileName, RigCaseData* eclipseC
if (!transferGeometry(mainEclGrid, eclipseCase)) return false;
progInfo.incrementProgress();
progInfo.setProgressDescription("Releasing reader memory");
ecl_grid_free( mainEclGrid );
progInfo.incrementProgress();
m_eclipseCase = eclipseCase;
progInfo.setProgressDescription("Reading Result index");
progInfo.setNextProgressIncrement(60);
m_eclipseCase = eclipseCase;
// Build results meta data
buildMetaData();
progInfo.incrementProgress();
progInfo.setNextProgressIncrement(8);
progInfo.setProgressDescription("Reading Well information");
readWellCells(mainEclGrid);
readWellCells();
progInfo.setProgressDescription("Releasing reader memory");
ecl_grid_free( mainEclGrid );
progInfo.incrementProgress();
return true;
}
@ -597,9 +599,6 @@ void RifReaderEclipseOutput::buildMetaData()
staticDate.push_back(m_timeSteps.front());
}
// Add ACTNUM
matrixResultNames += "ACTNUM";
for (int i = 0; i < matrixResultNames.size(); ++i)
{
size_t resIndex = matrixModelResults->addEmptyScalarResult(RimDefines::STATIC_NATIVE, matrixResultNames[i], false);
@ -619,9 +618,6 @@ void RifReaderEclipseOutput::buildMetaData()
staticDate.push_back(m_timeSteps.front());
}
// Add ACTNUM
fractureResultNames += "ACTNUM";
for (int i = 0; i < fractureResultNames.size(); ++i)
{
size_t resIndex = fractureModelResults->addEmptyScalarResult(RimDefines::STATIC_NATIVE, fractureResultNames[i], false);
@ -666,14 +662,6 @@ bool RifReaderEclipseOutput::staticResult(const QString& result, PorosityModelRe
{
CVF_ASSERT(values);
if (result.compare("ACTNUM", Qt::CaseInsensitive) == 0)
{
RigActiveCellInfo* activeCellInfo = m_eclipseCase->activeCellInfo(matrixOrFracture);
values->resize(activeCellInfo->globalActiveCellCount(), 1.0);
return true;
}
openInitFile();
if(m_ecl_init_file)
@ -719,16 +707,48 @@ bool RifReaderEclipseOutput::dynamicResult(const QString& result, PorosityModelR
return true;
}
// Helper structure to handle the metadata for connections in segments
struct SegmentData
{
SegmentData(const well_conn_collection_type* connections) :
m_branchId(-1),
m_segmentId(-1),
m_gridIndex(cvf::UNDEFINED_SIZE_T),
m_connections(connections)
{}
int m_branchId;
int m_segmentId;
size_t m_gridIndex;
const well_conn_collection_type* m_connections;
};
void getSegmentDataByBranchId(const std::list<SegmentData>& segments, std::vector<SegmentData>& branchSegments, int branchId)
{
std::list<SegmentData>::const_iterator it;
for (it = segments.begin(); it != segments.end(); it++)
{
if (it->m_branchId == branchId)
{
branchSegments.push_back(*it);
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RifReaderEclipseOutput::readWellCells()
void RifReaderEclipseOutput::readWellCells(const ecl_grid_type* mainEclGrid)
{
CVF_ASSERT(m_eclipseCase);
if (m_dynamicResultsAccess.isNull()) return;
well_info_type* ert_well_info = well_info_alloc(NULL);
well_info_type* ert_well_info = well_info_alloc(mainEclGrid);
if (!ert_well_info) return;
m_dynamicResultsAccess->readWellData(ert_well_info);
@ -795,25 +815,29 @@ void RifReaderEclipseOutput::readWellCells()
// Loop over all the grids in the model. If we have connections in one, we will discard
// the maingrid connections as they are "duplicates"
// the main grid connections as the well connections are duplicated in the main grid and LGR grids
bool hasWellConnectionsInLGR = false;
#if 0
// To be discussed with Statoil
for (size_t gridNr = 1; gridNr < grids.size(); ++gridNr)
{
int branchCount = well_state_iget_lgr_num_branches(ert_well_state, static_cast<int>(gridNr));
if (branchCount > 0)
RigGridBase* lgrGrid = m_eclipseCase->grid(gridNr);
if (well_state_has_grid_connections(ert_well_state, lgrGrid->gridName().data()))
{
hasWellConnectionsInLGR = true;
break;
}
}
#endif
size_t gridNr = hasWellConnectionsInLGR ? 1 : 0;
for (; gridNr < grids.size(); ++gridNr)
{
// Wellhead. If several grids have a wellhead definition for this well, we use tha last one. (Possibly the innermost LGR)
// Wellhead. If several grids have a wellhead definition for this well, we use the last one. (Possibly the innermost LGR)
const well_conn_type* ert_wellhead = well_state_iget_wellhead(ert_well_state, static_cast<int>(gridNr));
if (ert_wellhead)
{
@ -831,53 +855,275 @@ void RifReaderEclipseOutput::readWellCells()
wellResFrame.m_wellHead.m_gridCellIndex = grids[gridNr]->cellIndexFromIJK(cellI, cellJ, cellK);
wellResFrame.m_wellHead.m_gridIndex = gridNr;
}
int branchCount = well_state_iget_lgr_num_branches(ert_well_state, static_cast<int>(gridNr));
if (branchCount > 0)
else
{
if (static_cast<int>(wellResFrame.m_wellResultBranches.size()) < branchCount) wellResFrame.m_wellResultBranches.resize(branchCount);
CVF_ASSERT(0);
}
for (int branchIdx = 0; branchIdx < branchCount; ++branchIdx )
std::string gridName;
if (gridNr == 0)
{
gridName = ECL_GRID_GLOBAL_GRID;
}
else
{
RigGridBase* rigGrid = m_eclipseCase->grid(gridNr);
gridName = rigGrid->gridName();
}
std::list<SegmentData> segmentList;
std::vector<const well_segment_type*> outletBranchSegmentList; // Keep a list of branch outlet segments to avoid traversal twice
std::vector<int> ertBranchIDs;
int branchCount = 0;
if (well_state_is_MSW(ert_well_state))
{
wellResults->setMultiSegmentWell(true);
well_branch_collection_type* branches = well_state_get_branches(ert_well_state);
branchCount = well_branch_collection_get_size(branches);
for (int branchIdx = 0; branchIdx < well_branch_collection_get_size(branches); branchIdx++)
{
// Connections
int connectionCount = well_state_iget_num_lgr_connections(ert_well_state, static_cast<int>(gridNr), branchIdx);
if (connectionCount > 0)
const well_segment_type* segment = well_branch_collection_iget_start_segment(branches, branchIdx);
int branchId = well_segment_get_branch_id(segment);
ertBranchIDs.push_back(branchId);
while (segment && branchId == well_segment_get_branch_id(segment))
{
SegmentData segmentData(NULL);
segmentData.m_branchId = branchId;
segmentData.m_segmentId = well_segment_get_id(segment);
segmentData.m_gridIndex = gridNr;
RigWellResultBranch& wellSegment = wellResFrame.m_wellResultBranches[branchIdx]; // Is this completely right? Is the branch index actually the same between lgrs ?
wellSegment.m_branchNumber = branchIdx;
size_t existingConnCount = wellSegment.m_wellCells.size();
wellSegment.m_wellCells.resize(existingConnCount + connectionCount);
int connIdx;
for (connIdx = 0; connIdx < connectionCount; connIdx++)
if (well_segment_has_grid_connections(segment, gridName.data()))
{
const well_conn_type* ert_connection = well_state_iget_lgr_connections( ert_well_state, static_cast<int>(gridNr), branchIdx)[connIdx];
const well_conn_collection_type* connections = well_segment_get_connections(segment, gridName.data());
segmentData.m_connections = connections;
}
// Insert in front, as the segments are accessed starting from grid cell closes to well head
segmentList.push_front(segmentData);
if (well_segment_get_outlet_id(segment) == -1)
{
break;
}
segment = well_segment_get_outlet(segment);
}
outletBranchSegmentList.push_back(segment);
}
}
else
{
branchCount = 1;
ertBranchIDs.push_back(0);
const well_conn_collection_type* connections = well_state_get_grid_connections(ert_well_state, gridName.data());
SegmentData segmentData(connections);
segmentData.m_gridIndex = gridNr;
segmentList.push_front(segmentData);
}
size_t currentGridBranchStartIndex = wellResFrame.m_wellResultBranches.size();
wellResFrame.m_wellResultBranches.resize(currentGridBranchStartIndex + branchCount);
// Import all well result cells for all connections
for (int branchIdx = 0; branchIdx < branchCount; branchIdx++)
{
RigWellResultBranch& wellResultBranch = wellResFrame.m_wellResultBranches[currentGridBranchStartIndex + branchIdx];
wellResultBranch.m_branchIndex = branchIdx;
int ertBranchId = ertBranchIDs[branchIdx];
wellResultBranch.m_ertBranchId = ertBranchId;
std::vector<SegmentData> branchSegments;
getSegmentDataByBranchId(segmentList, branchSegments, ertBranchId);
for (size_t segmentIdx = 0; segmentIdx < branchSegments.size(); segmentIdx++)
{
SegmentData& connData = branchSegments[segmentIdx];
if (!connData.m_connections)
{
size_t existingCellCount = wellResultBranch.m_wellCells.size();
wellResultBranch.m_wellCells.resize(existingCellCount + 1);
RigWellResultCell& data = wellResultBranch.m_wellCells[existingCellCount];
data.m_ertBranchId = connData.m_branchId;
data.m_ertSegmentId = connData.m_segmentId;
}
else
{
int connectionCount = well_conn_collection_get_size(connData.m_connections);
size_t existingCellCount = wellResultBranch.m_wellCells.size();
wellResultBranch.m_wellCells.resize(existingCellCount + connectionCount);
for (int connIdx = 0; connIdx < connectionCount; connIdx++)
{
well_conn_type* ert_connection = well_conn_collection_iget(connData.m_connections, connIdx);
CVF_ASSERT(ert_connection);
RigWellResultCell& data = wellSegment.m_wellCells[existingConnCount + connIdx];
data.m_gridIndex = gridNr;
RigWellResultCell& data = wellResultBranch.m_wellCells[existingCellCount + connIdx];
int cellI = well_conn_get_i( ert_connection );
int cellJ = well_conn_get_j( ert_connection );
int cellK = well_conn_get_k( ert_connection );
bool isCellOpen = well_conn_open( ert_connection );
// If a well is defined in fracture region, the K-value is from (cellCountK - 1) -> cellCountK*2 - 1
// Adjust K so index is always in valid grid region
if (cellK >= static_cast<int>(grids[gridNr]->cellCountK()))
{
int cellI = well_conn_get_i( ert_connection );
int cellJ = well_conn_get_j( ert_connection );
int cellK = well_conn_get_k( ert_connection );
bool open = well_conn_open( ert_connection );
int branch = well_conn_get_branch( ert_connection );
int segment = well_conn_get_segment( ert_connection );
cellK -= static_cast<int>(grids[gridNr]->cellCountK());
}
// If a well is defined in fracture region, the K-value is from (cellCountK - 1) -> cellCountK*2 - 1
// Adjust K so index is always in valid grid region
if (cellK >= static_cast<int>(grids[gridNr]->cellCountK()))
data.m_gridIndex = gridNr;
data.m_gridCellIndex = grids[gridNr]->cellIndexFromIJK(cellI, cellJ, cellK);
data.m_isOpen = isCellOpen;
data.m_ertBranchId = connData.m_branchId;
data.m_ertSegmentId = connData.m_segmentId;
}
}
}
}
if (well_state_is_MSW(ert_well_state))
{
// Assign outlet well cells to leaf branch well heads
for (int branchIdx = 0; branchIdx < branchCount; branchIdx++)
{
RigWellResultBranch& wellResultLeafBranch = wellResFrame.m_wellResultBranches[currentGridBranchStartIndex + branchIdx];
const well_segment_type* outletBranchSegment = outletBranchSegmentList[branchIdx];
CVF_ASSERT(outletBranchSegment);
int outletErtBranchId = well_segment_get_branch_id(outletBranchSegment);
size_t outletErtBranchIndex = cvf::UNDEFINED_SIZE_T;
for (size_t i = 0; i < ertBranchIDs.size(); i++)
{
if (ertBranchIDs[i] == outletErtBranchId)
{
outletErtBranchIndex = i;
}
}
RigWellResultBranch& outletResultBranch = wellResFrame.m_wellResultBranches[currentGridBranchStartIndex + outletErtBranchIndex];
int outletErtSegmentId = well_segment_get_branch_id(outletBranchSegment);
size_t lastCellIndexForSegmentIdInOutletBranch = cvf::UNDEFINED_SIZE_T;
for (size_t outletCellIdx = 0; outletCellIdx < outletResultBranch.m_wellCells.size(); outletCellIdx++)
{
if (outletResultBranch.m_wellCells[outletCellIdx].m_ertSegmentId == outletErtSegmentId)
{
lastCellIndexForSegmentIdInOutletBranch = outletCellIdx;
}
}
if (lastCellIndexForSegmentIdInOutletBranch == cvf::UNDEFINED_SIZE_T)
{
// Did not find the cell in the outlet branch based on branch id and segment id from outlet cell in leaf branch
CVF_ASSERT(0);
}
else
{
RigWellResultCell& outletCell = outletResultBranch.m_wellCells[lastCellIndexForSegmentIdInOutletBranch];
wellResultLeafBranch.m_outletBranchIndex = currentGridBranchStartIndex + outletErtBranchIndex;
wellResultLeafBranch.m_outletBranchHeadCellIndex = lastCellIndexForSegmentIdInOutletBranch;
}
}
// Update outlet well cells with no grid cell connections
for (int branchIdx = 0; branchIdx < branchCount; branchIdx++)
{
RigWellResultBranch& wellResultLeafBranch = wellResFrame.m_wellResultBranches[currentGridBranchStartIndex + branchIdx];
const RigWellResultCell* leafBranchHead = wellResFrame.findResultCellFromOutletSpecification(wellResultLeafBranch.m_outletBranchIndex, wellResultLeafBranch.m_outletBranchHeadCellIndex);
if (!leafBranchHead || leafBranchHead->hasGridConnections())
{
continue;
}
RigWellResultBranch& outletResultBranch = wellResFrame.m_wellResultBranches[wellResultLeafBranch.m_outletBranchIndex];
size_t firstCellIndexWithGridConnectionInLeafBranch = cvf::UNDEFINED_SIZE_T;
for (size_t j = 0; j < wellResultLeafBranch.m_wellCells.size(); j++)
{
if (wellResultLeafBranch.m_wellCells[j].hasGridConnections())
{
firstCellIndexWithGridConnectionInLeafBranch = j;
break;
}
}
if (firstCellIndexWithGridConnectionInLeafBranch != cvf::UNDEFINED_SIZE_T)
{
const RigCell& firstCellWithGridConnectionInLeafBranch = m_eclipseCase->cellFromWellResultCell(wellResultLeafBranch.m_wellCells[firstCellIndexWithGridConnectionInLeafBranch]);
cvf::Vec3d firstGridConnectionCenterInLeafBranch = firstCellWithGridConnectionInLeafBranch.center();
size_t cellIndexInOutletBranch = wellResultLeafBranch.m_outletBranchHeadCellIndex;
CVF_ASSERT(cellIndexInOutletBranch != cvf::UNDEFINED_SIZE_T);
RigWellResultCell& currCell = outletResultBranch.m_wellCells[cellIndexInOutletBranch];
while (cellIndexInOutletBranch != cvf::UNDEFINED_SIZE_T && !currCell.hasGridConnections())
{
size_t branchConnectionCount = currCell.m_branchConnectionCount;
if (branchConnectionCount == 0)
{
currCell.m_averageCenter = firstGridConnectionCenterInLeafBranch;
}
else
{
cvf::Vec3d currentWeightedCoord = currCell.m_averageCenter * branchConnectionCount / static_cast<double>(branchConnectionCount + 1);
cvf::Vec3d additionalWeightedCoord = firstGridConnectionCenterInLeafBranch / static_cast<double>(branchConnectionCount + 1);
currCell.m_averageCenter = currentWeightedCoord + additionalWeightedCoord;
}
currCell.m_branchConnectionCount++;
if (cellIndexInOutletBranch == 0)
{
cellIndexInOutletBranch = cvf::UNDEFINED_SIZE_T;
// Find the branch the outlet is connected to, and continue update of
// segments until a segment with a grid connection is found
const RigWellResultCell* leafBranchHead = wellResFrame.findResultCellFromOutletSpecification(outletResultBranch.m_outletBranchIndex, outletResultBranch.m_outletBranchHeadCellIndex);
if (leafBranchHead &&
!leafBranchHead->hasGridConnections() &&
leafBranchHead->m_ertBranchId != outletResultBranch.m_ertBranchId)
{
cellK -= static_cast<int>(grids[gridNr]->cellCountK());
outletResultBranch = wellResFrame.m_wellResultBranches[outletResultBranch.m_outletBranchIndex];
cellIndexInOutletBranch = outletResultBranch.m_outletBranchHeadCellIndex;
}
}
else
{
cellIndexInOutletBranch--;
}
data.m_gridCellIndex = grids[gridNr]->cellIndexFromIJK(cellI , cellJ , cellK);
data.m_isOpen = open;
data.m_branchId = branch;
data.m_segmentId = segment;
if(cellIndexInOutletBranch >= 0 && cellIndexInOutletBranch < outletResultBranch.m_wellCells.size())
{
currCell = outletResultBranch.m_wellCells[cellIndexInOutletBranch];
}
}
}
@ -886,6 +1132,7 @@ void RifReaderEclipseOutput::readWellCells()
}
}
wellResults->computeMappingFromResultTimeIndicesToWellTimeIndices(m_timeSteps);
wells.push_back(wellResults.p());

View File

@ -56,7 +56,7 @@ public:
private:
bool readActiveCellInfo();
void buildMetaData();
void readWellCells();
void readWellCells(const ecl_grid_type* mainEclGrid);
void openInitFile();
bool openDynamicAccess();

View File

@ -176,13 +176,13 @@ void RivWellPipesPartMgr::calculateWellPipeCenterline( std::vector< std::vector
RigCaseData* rigReservoir = m_rimReservoirView->eclipseCase()->reservoirData();
RigSingleWellResultsData* wellResults = m_rimWell->wellResults();
const RigWellResultFrame& staticWellFrame = m_rimWell->wellResults()->m_staticWellCells;
// Make sure we have computed the static representation of the well
if (staticWellFrame.m_wellResultBranches.size() == 0)
if (wellResults->m_staticWellCells.m_wellResultBranches.size() == 0)
{
wellResults->computeStaticWellCellPath();
}
const RigWellResultFrame& staticWellFrame = wellResults->m_staticWellCells;
if (staticWellFrame.m_wellResultBranches.size() == 0) return;
// Initialize the return arrays
@ -211,31 +211,93 @@ void RivWellPipesPartMgr::calculateWellPipeCenterline( std::vector< std::vector
if (hasResultCells)
{
// Create a new branch from wellhead
pipeBranchesCLCoords.push_back(std::vector<cvf::Vec3d>());
pipeBranchesCellIds.push_back(std::vector <RigWellResultCell>());
// We start by entering the first cell (the wellhead)
const RigWellResultCell* prevResCell = whResCell;
pipeBranchesCLCoords.back().push_back(whStartPos);
pipeBranchesCellIds.back().push_back(*prevResCell );
// Add extra coordinate between cell face and cell center
// to make sure the well pipe terminated in a segment parallel to z-axis
cvf::Vec3d whIntermediate = whStartPos;
whIntermediate.z() = (whStartPos.z() + whCell.center().z()) / 2.0;
pipeBranchesCLCoords.back().push_back(whIntermediate);
pipeBranchesCellIds.back().push_back(*prevResCell );
const RigWellResultCell* prevResCell = NULL;
// Use well head if branch head is not specified
if (!wellResults->isMultiSegmentWell())
{
// Create a new branch from wellhead
pipeBranchesCLCoords.push_back(std::vector<cvf::Vec3d>());
pipeBranchesCellIds.push_back(std::vector <RigWellResultCell>());
prevResCell = whResCell;
pipeBranchesCLCoords.back().push_back(whStartPos);
pipeBranchesCellIds.back().push_back(*prevResCell);
pipeBranchesCLCoords.back().push_back(whIntermediate);
pipeBranchesCellIds.back().push_back(*prevResCell);
}
for (size_t brIdx = 0; brIdx < resBranches.size(); brIdx++)
{
if (resBranches[brIdx].m_wellCells.size() == 0)
continue; // Skip empty branches. Do not know why they exist, but they make problems.
prevResCell = NULL;
// Find the start the MSW well-branch centerline. Normal wells are started "once" at wellhead in the code above
if (wellResults->isMultiSegmentWell())
{
pipeBranchesCLCoords.push_back(std::vector<cvf::Vec3d>());
pipeBranchesCellIds.push_back(std::vector <RigWellResultCell>());
if (brIdx == 0)
{
// The first branch contains segment number 1, and this is the only segment connected to well head
// See Eclipse documentation for the keyword WELSEGS
prevResCell = whResCell;
pipeBranchesCLCoords.back().push_back(whStartPos);
pipeBranchesCellIds.back().push_back(*prevResCell);
pipeBranchesCLCoords.back().push_back(whIntermediate);
pipeBranchesCellIds.back().push_back(*prevResCell);
}
else
{
const RigWellResultCell* leafBranchHead = staticWellFrame.findResultCellFromOutletSpecification(resBranches[brIdx].m_outletBranchIndex, resBranches[brIdx].m_outletBranchHeadCellIndex);
if (leafBranchHead && leafBranchHead->hasGridConnections())
{
// Create a new branch and use branch head as previous result cell
prevResCell = leafBranchHead;
const RigCell& cell = rigReservoir->cellFromWellResultCell(*leafBranchHead);
cvf::Vec3d branchHeadStartPos = cell.faceCenter(cvf::StructGridInterface::NEG_K);
pipeBranchesCLCoords.back().push_back(branchHeadStartPos);
pipeBranchesCellIds.back().push_back(*prevResCell);
}
else if (leafBranchHead)
{
cvf::Vec3d interpolatedCoord = leafBranchHead->m_averageCenter;
CVF_ASSERT(interpolatedCoord != cvf::Vec3d::UNDEFINED);
if (interpolatedCoord != cvf::Vec3d::UNDEFINED)
{
pipeBranchesCLCoords.back().push_back(interpolatedCoord);
pipeBranchesCellIds.back().push_back(RigWellResultCell());
}
}
else
{
// No branch head found: Possibly main branch
CVF_ASSERT(false);
}
}
}
// Loop over all the resultCells in the branch
const std::vector<RigWellResultCell>& resBranchCells = resBranches[brIdx].m_wellCells;
@ -245,56 +307,101 @@ void RivWellPipesPartMgr::calculateWellPipeCenterline( std::vector< std::vector
std::vector<RigWellResultCell>& branchCellIds = pipeBranchesCellIds.back();
const RigWellResultCell& resCell = resBranchCells[cIdx];
if (!resCell.hasConnections())
{
continue;
}
if (resCell.hasBranchConnections())
{
// Use the interpolated value of branch head
cvf::Vec3d interpolatedCoord = resCell.m_averageCenter;
CVF_ASSERT(interpolatedCoord != cvf::Vec3d::UNDEFINED);
if (interpolatedCoord != cvf::Vec3d::UNDEFINED)
{
pipeBranchesCLCoords.back().push_back(interpolatedCoord);
pipeBranchesCellIds.back().push_back(RigWellResultCell());
}
// Set previous result cell to NULL
prevResCell = NULL;
continue;
}
const RigCell& cell = rigReservoir->cellFromWellResultCell(resCell);
// Check if this and the previous cells has shared faces
cvf::StructGridInterface::FaceType sharedFace;
if (rigReservoir->findSharedSourceFace(sharedFace, resCell, *prevResCell))
if (prevResCell && rigReservoir->findSharedSourceFace(sharedFace, resCell, *prevResCell))
{
branchCLCoords.push_back(cell.faceCenter(sharedFace));
branchCellIds.push_back(resCell);
}
else
{
// This and the previous cell does not share a face. We need to go out of the previous cell, before entering this.
const RigCell& prevCell = rigReservoir->cellFromWellResultCell(*prevResCell);
cvf::Vec3d centerPrevCell = prevCell.center();
cvf::Vec3d previousCoord;
if (prevResCell)
{
// This and the previous cell does not share a face. We need to go out of the previous cell, before entering this.
const RigCell& prevCell = rigReservoir->cellFromWellResultCell(*prevResCell);
previousCoord = prevCell.center();
}
else
{
previousCoord = pipeBranchesCLCoords.back().back();
}
cvf::Vec3d centerThisCell = cell.center();
// First make sure this cell is not starting a new "display" branch
if ( !isAutoDetectBranches || (prevResCell == whResCell)
|| (centerThisCell-centerPrevCell).lengthSquared() <= (centerThisCell - whStartPos).lengthSquared())
if ( wellResults->isMultiSegmentWell()
|| !isAutoDetectBranches
|| (prevResCell == whResCell)
|| (centerThisCell-previousCoord).lengthSquared() <= (centerThisCell - whStartPos).lengthSquared()
)
{
// Not starting a "display" branch
// Create ray and intersect with cells
cvf::Ray rayToThisCell;
rayToThisCell.setOrigin(centerPrevCell);
rayToThisCell.setDirection((centerThisCell - centerPrevCell).getNormalized());
rayToThisCell.setOrigin(previousCoord);
rayToThisCell.setDirection((centerThisCell - previousCoord).getNormalized());
cvf::Vec3d outOfPrevCell(centerPrevCell);
cvf::Vec3d intoThisCell(centerThisCell);
cell.firstIntersectionPoint(rayToThisCell, &intoThisCell);
bool intersectionOk = prevCell.firstIntersectionPoint(rayToThisCell, &outOfPrevCell);
//CVF_ASSERT(intersectionOk);
intersectionOk = cell.firstIntersectionPoint(rayToThisCell, &intoThisCell);
//CVF_ASSERT(intersectionOk);
if ((intoThisCell - outOfPrevCell).lengthSquared() > 1e-3)
if (prevResCell)
{
branchCLCoords.push_back(outOfPrevCell);
branchCellIds.push_back(RigWellResultCell());
cvf::Vec3d outOfPrevCell(previousCoord);
const RigCell& prevCell = rigReservoir->cellFromWellResultCell(*prevResCell);
bool intersectionOk = prevCell.firstIntersectionPoint(rayToThisCell, &outOfPrevCell);
//CVF_ASSERT(intersectionOk);
//CVF_ASSERT(intersectionOk);
if ((intoThisCell - outOfPrevCell).lengthSquared() > 1e-3)
{
branchCLCoords.push_back(outOfPrevCell);
branchCellIds.push_back(*prevResCell);
}
}
branchCLCoords.push_back(intoThisCell);
branchCellIds.push_back(resCell);
}
else
{
CVF_ASSERT(!wellResults->isMultiSegmentWell());
// This cell is further from the previous cell than from the well head,
// thus we interpret it as a new branch.
// First finish the current branch
branchCLCoords.push_back(branchCLCoords.back() + 1.5*(centerPrevCell - branchCLCoords.back()) );
branchCLCoords.push_back(branchCLCoords.back() + 1.5*(previousCoord - branchCLCoords.back()) );
// Create new display branch
pipeBranchesCLCoords.push_back(std::vector<cvf::Vec3d>());
@ -316,14 +423,32 @@ void RivWellPipesPartMgr::calculateWellPipeCenterline( std::vector< std::vector
}
prevResCell = &resCell;
}
if ( wellResults->isMultiSegmentWell())
{
// All MSW branches are completed using the point 0.5 past the center of last cell
size_t clCoordCount = pipeBranchesCLCoords.back().size();
CVF_ASSERT(clCoordCount >= 2);
cvf::Vec3d centerPrevCell = pipeBranchesCLCoords.back()[clCoordCount - 2];
cvf::Vec3d centerThisCell = pipeBranchesCLCoords.back()[clCoordCount - 1];
pipeBranchesCLCoords.back().push_back(centerThisCell + 1.5*(centerPrevCell - centerThisCell) );
}
}
// For the last cell, add the point 0.5 past the center of that cell
const RigCell& prevCell = rigReservoir->cellFromWellResultCell(*prevResCell);
cvf::Vec3d centerPrevCell = prevCell.center();
pipeBranchesCLCoords.back().push_back(pipeBranchesCLCoords.back().back() + 1.5*(centerPrevCell - pipeBranchesCLCoords.back().back()) );
if (!wellResults->isMultiSegmentWell())
{
// None MSW wells
// For the last cell, add the point 0.5 past the center of that cell
size_t clCoordCount = pipeBranchesCLCoords.back().size();
CVF_ASSERT(clCoordCount >= 2);
cvf::Vec3d centerPrevCell = pipeBranchesCLCoords.back()[clCoordCount - 2];
cvf::Vec3d centerThisCell = pipeBranchesCLCoords.back()[clCoordCount - 1];
pipeBranchesCLCoords.back().push_back(centerThisCell + 1.5*(centerPrevCell - centerThisCell) );
}
}
@ -389,7 +514,12 @@ void RivWellPipesPartMgr::updatePipeResultColor(size_t frameIndex)
for (size_t wcIdx = 0; wcIdx < cellIds.size(); ++wcIdx)
{
// we need a faster lookup, I guess
const RigWellResultCell* wResCell = wResFrame.findResultCell(cellIds[wcIdx].m_gridIndex, cellIds[wcIdx].m_gridCellIndex);
const RigWellResultCell* wResCell = NULL;
if (cellIds[wcIdx].hasGridConnections())
{
wResCell = wResFrame.findResultCell(cellIds[wcIdx].m_gridIndex, cellIds[wcIdx].m_gridCellIndex);
}
if (wResCell == NULL)
{

View File

@ -435,9 +435,6 @@ void RimReservoirView::fieldChangedByUi(const caf::PdmFieldHandle* changedField,
}
else if ( changedField == &showInactiveCells )
{
m_reservoirGridPartManager->scheduleGeometryRegen(RivReservoirViewPartMgr::INACTIVE);
m_reservoirGridPartManager->scheduleGeometryRegen(RivReservoirViewPartMgr::RANGE_FILTERED_INACTIVE);
createDisplayModelAndRedraw();
}
else if ( changedField == &showMainGrid )
@ -678,22 +675,6 @@ void RimReservoirView::updateCurrentTimeStep()
float opacity = static_cast< float> (1 - cvf::Math::clamp(this->wellCollection()->wellCellTransparencyLevel(), 0.0, 1.0));
m_reservoirGridPartManager->updateCellColor(RivReservoirViewPartMgr::PROPERTY_FILTERED_WELL_CELLS, m_currentTimeStep, cvf::Color4f(cvf::Color3f(cvf::Color3::WHITE), opacity));
if (this->showInactiveCells())
{
std::vector<size_t> gridIndices;
this->indicesToVisibleGrids(&gridIndices);
if (this->rangeFilterCollection()->hasActiveFilters() || this->wellCollection()->hasVisibleWellCells())
{
m_reservoirGridPartManager->appendStaticGeometryPartsToModel(frameParts.p(), RivReservoirViewPartMgr::RANGE_FILTERED_INACTIVE, gridIndices);
}
else
{
m_reservoirGridPartManager->appendStaticGeometryPartsToModel(frameParts.p(), RivReservoirViewPartMgr::INACTIVE, gridIndices);
}
}
if (m_viewer)
{
cvf::Scene* frameScene = m_viewer->frame(m_currentTimeStep);
@ -1044,6 +1025,29 @@ void RimReservoirView::appendCellResultInfo(size_t gridIndex, size_t cellIndex,
}
}
}
cvf::Collection<RigSingleWellResultsData> wellResults = m_reservoir->reservoirData()->wellResults();
for (size_t i = 0; i < wellResults.size(); i++)
{
RigSingleWellResultsData* singleWellResultData = wellResults.at(i);
if (m_currentTimeStep < singleWellResultData->firstResultTimeStep())
{
continue;
}
const RigWellResultFrame& wellResultFrame = singleWellResultData->wellResultFrame(m_currentTimeStep);
const RigWellResultCell* wellResultCell = wellResultFrame.findResultCell(gridIndex, cellIndex);
if (wellResultCell)
{
resultInfoText->append(QString("(0-based) Branch Id : %1 Segment Id %2\n").arg(wellResultCell->m_ertBranchId).arg(wellResultCell->m_ertSegmentId));
if (wellResultCell->hasBranchConnections())
{
resultInfoText->append(QString("Branch Connection Count : %1\n").arg(wellResultCell->m_branchConnectionCount));
resultInfoText->append(QString("Center coord : %1 %2 %3\n").arg(wellResultCell->m_averageCenter.x()).arg(wellResultCell->m_averageCenter.y()).arg(wellResultCell->m_averageCenter.z()));
}
}
}
}
}
@ -1400,6 +1404,11 @@ void RimReservoirView::calculateVisibleWellCellsIncFence(cvf::UByteArray* visibl
{
if (wsResCells[cIdx].m_gridIndex == grid->gridIndex())
{
if (!wsResCells[cIdx].hasGridConnections())
{
continue;
}
size_t gridCellIndex = wsResCells[cIdx].m_gridCellIndex;
(*visibleCells)[gridCellIndex] = true;

View File

@ -148,18 +148,12 @@ bool RimWell::calculateWellPipeVisibility(size_t frameIndex)
if (m_reservoirView == NULL) return false;
if (this->wellResults() == NULL) return false;
if (frameIndex >= this->wellResults()->m_resultTimeStepIndexToWellTimeStepIndex.size())
{
if ( this->wellResults()->firstResultTimeStep() == cvf::UNDEFINED_SIZE_T
|| frameIndex < this->wellResults()->firstResultTimeStep()
|| frameIndex >= this->wellResults()->m_wellCellsTimeSteps.size())
return false;
}
size_t wellTimeStepIndex = this->wellResults()->m_resultTimeStepIndexToWellTimeStepIndex[frameIndex];
if (wellTimeStepIndex == cvf::UNDEFINED_SIZE_T)
{
return false;
}
if (!m_reservoirView->wellCollection()->isActive())
if (!m_reservoirView->wellCollection()->active())
return false;
if (m_reservoirView->wellCollection()->wellPipeVisibility() == RimWellCollection::PIPES_FORCE_ALL_ON)
@ -202,13 +196,16 @@ bool RimWell::calculateWellPipeVisibility(size_t frameIndex)
const std::vector<RigWellResultCell>& wsResCells = wellResSegments[wsIdx].m_wellCells;
for (size_t cIdx = 0; cIdx < wsResCells.size(); ++ cIdx)
{
gridIndex = wsResCells[cIdx].m_gridIndex;
gridCellIndex = wsResCells[cIdx].m_gridCellIndex;
cvf::cref<cvf::UByteArray> cellVisibility = rvMan->cellVisibility(visGridParts[gpIdx], gridIndex, frameIndex);
if ((*cellVisibility)[gridCellIndex])
if (wsResCells[cIdx].hasGridConnections())
{
return true;
gridIndex = wsResCells[cIdx].m_gridIndex;
gridCellIndex = wsResCells[cIdx].m_gridCellIndex;
cvf::cref<cvf::UByteArray> cellVisibility = rvMan->cellVisibility(visGridParts[gpIdx], gridIndex, frameIndex);
if ((*cellVisibility)[gridCellIndex])
{
return true;
}
}
}
}

View File

@ -118,7 +118,7 @@ void RigSingleWellResultsData::computeStaticWellCellPath()
for (size_t bIdx = 0; bIdx < m_wellCellsTimeSteps[0].m_wellResultBranches.size(); ++bIdx)
{
size_t branchNumber = m_wellCellsTimeSteps[0].m_wellResultBranches[bIdx].m_branchNumber;
size_t branchNumber = m_wellCellsTimeSteps[0].m_wellResultBranches[bIdx].m_branchIndex;
std::vector<RigWellResultCell>& frameCells = m_wellCellsTimeSteps[0].m_wellResultBranches[bIdx].m_wellCells;
std::list< RigWellResultCell >& branch = staticWellBranches[branchNumber];
@ -137,7 +137,7 @@ void RigSingleWellResultsData::computeStaticWellCellPath()
for (size_t bIdx = 0; bIdx < m_wellCellsTimeSteps[tIdx].m_wellResultBranches.size(); ++bIdx)
{
size_t branchNumber = m_wellCellsTimeSteps[tIdx].m_wellResultBranches[bIdx].m_branchNumber;
size_t branchNumber = m_wellCellsTimeSteps[tIdx].m_wellResultBranches[bIdx].m_branchIndex;
std::vector<RigWellResultCell>& resBranch = m_wellCellsTimeSteps[tIdx].m_wellResultBranches[bIdx].m_wellCells;
std::list< RigWellResultCell >& stBranch = staticWellBranches[branchNumber];
@ -252,12 +252,20 @@ void RigSingleWellResultsData::computeStaticWellCellPath()
for (bIt = staticWellBranches.begin(); bIt != staticWellBranches.end(); ++bIt)
{
RigWellResultBranch rigBranch;
rigBranch.m_branchNumber = bIt->first;
if (bIt->first >= m_wellCellsTimeSteps[0].m_wellResultBranches.size())
{
continue;
}
// Copy from first time step
RigWellResultBranch rigBranch = m_wellCellsTimeSteps[0].m_wellResultBranches[bIt->first];
rigBranch.m_branchIndex = bIt->first;
// Clear well cells, and insert the collection of well cells for the static situation
rigBranch.m_wellCells.clear();
std::list< RigWellResultCell >& branch = bIt->second;
std::list< RigWellResultCell >::iterator cIt;
for (cIt = branch.begin(); cIt != branch.end(); ++cIt)
{
RigWellResultCell rwc = *cIt;
@ -269,3 +277,19 @@ void RigSingleWellResultsData::computeStaticWellCellPath()
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RigSingleWellResultsData::setMultiSegmentWell(bool isMultiSegmentWell)
{
m_isMultiSegmentWell = isMultiSegmentWell;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RigSingleWellResultsData::isMultiSegmentWell() const
{
return m_isMultiSegmentWell;
}

View File

@ -25,33 +25,72 @@
#include "RimDefines.h"
#include <QDateTime>
#include <vector>
#include "cvfVector3.h"
struct RigWellResultCell
{
RigWellResultCell() :
m_gridIndex(cvf::UNDEFINED_SIZE_T),
m_gridCellIndex(cvf::UNDEFINED_SIZE_T),
m_branchId(-1),
m_segmentId(-1),
m_isOpen(false)
m_isOpen(false),
m_ertBranchId(-1),
m_ertSegmentId(-1),
m_averageCenter(cvf::Vec3d::UNDEFINED),
m_branchConnectionCount(0)
{ }
bool hasBranchConnections() const
{
return m_branchConnectionCount != 0;
}
bool hasGridConnections() const
{
return m_gridCellIndex != cvf::UNDEFINED_SIZE_T;
}
bool hasConnections() const
{
return hasGridConnections() || hasBranchConnections();
}
size_t m_gridIndex;
size_t m_gridCellIndex; //< Index to cell which is included in the well
int m_branchId;
int m_segmentId;
bool m_isOpen; //< Marks the well as open or closed as of Eclipse simulation
int m_ertBranchId;
int m_ertSegmentId;
cvf::Vec3d m_averageCenter;
size_t m_branchConnectionCount;
};
struct RigWellResultBranch
{
RigWellResultBranch() :
m_branchNumber(cvf::UNDEFINED_SIZE_T)
m_branchIndex(cvf::UNDEFINED_SIZE_T),
m_ertBranchId(-1),
m_outletBranchIndex(cvf::UNDEFINED_SIZE_T),
m_outletBranchHeadCellIndex(cvf::UNDEFINED_SIZE_T)
{}
size_t m_branchNumber;
size_t m_branchIndex;
int m_ertBranchId;
std::vector<RigWellResultCell> m_wellCells;
// Grid cell from last connection in outlet segment. For MSW wells, this is either well head or a well result cell in another branch
// For standard wells, this is always well head.
RigWellResultCell m_branchHead;
// Grid cell from last connection in outlet segment. For MSW wells, this is either well head or a well result cell in another branch
// For standard wells, this is always well head.
size_t m_outletBranchIndex;
size_t m_outletBranchHeadCellIndex;
};
class RigWellResultFrame
@ -67,6 +106,8 @@ public:
const RigWellResultCell* findResultCell(size_t gridIndex, size_t gridCellIndex) const
{
CVF_ASSERT(gridIndex != cvf::UNDEFINED_SIZE_T && gridCellIndex != cvf::UNDEFINED_SIZE_T);
if (m_wellHead.m_gridCellIndex == gridCellIndex && m_wellHead.m_gridIndex == gridIndex )
{
return &m_wellHead;
@ -87,6 +128,21 @@ public:
return NULL;
}
const RigWellResultCell* findResultCellFromOutletSpecification(size_t branchIndex, size_t wellResultCellIndex) const
{
if (branchIndex != cvf::UNDEFINED_SIZE_T && branchIndex < m_wellResultBranches.size())
{
const RigWellResultBranch& resBranch = m_wellResultBranches[branchIndex];
if (wellResultCellIndex != cvf::UNDEFINED_SIZE_T && wellResultCellIndex < resBranch.m_wellCells.size())
{
return (&resBranch.m_wellCells[wellResultCellIndex]);
}
}
return NULL;
}
WellProductionType m_productionType;
bool m_isOpen;
RigWellResultCell m_wellHead;
@ -102,6 +158,11 @@ public:
class RigSingleWellResultsData : public cvf::Object
{
public:
RigSingleWellResultsData() { m_isMultiSegmentWell = false; }
void setMultiSegmentWell(bool isMultiSegmentWell);
bool isMultiSegmentWell() const;
bool hasWellResult(size_t resultTimeStepIndex) const;
size_t firstResultTimeStep() const;
@ -113,6 +174,7 @@ public:
public:
QString m_wellName;
bool m_isMultiSegmentWell;
std::vector<size_t> m_resultTimeStepIndexToWellTimeStepIndex; // Well result timesteps may differ from result timesteps
std::vector< RigWellResultFrame > m_wellCellsTimeSteps;

View File

@ -11,7 +11,11 @@ target_file = sys.argv[2]
(target_path , tail) = os.path.split( target_file )
if not os.path.exists( target_path ):
os.makedirs( target_path )
try:
os.makedirs( target_path )
except:
# When running with make -j 4 there might be a race to create this directory.
pass
shutil.copyfile( src_file , target_file )
try:

View File

@ -17,6 +17,10 @@ for (root , dir_list , file_list) in os.walk( root_path ):
(tmp , ext) = os.path.splitext( full_path )
if ext == ".py":
py_file = full_path
pyc_file = full_path + "c"
if os.path.exists( pyc_file ):
os.unlink( pyc_file )
try:
print "Compiling: %s" % py_file
py_compile.compile( py_file , doraise = True )

View File

@ -3,6 +3,7 @@ if (BUILD_APPLICATIONS)
add_executable( make_grid make_grid.c )
add_executable( grdecl_grid grdecl_grid.c )
add_executable( summary2csv summary2csv.c )
add_executable( summary2csv2 summary2csv2.c )
if (ERT_LINUX)
add_executable( esummary.x esummary.c )
add_executable( convert.x convert.c )
@ -15,7 +16,7 @@ if (BUILD_APPLICATIONS)
add_executable( summary.x view_summary.c )
add_executable( select_test.x select_test.c )
add_executable( load_test.x load_test.c )
set(program_list summary2csv esummary.x kw_extract.x grdecl_grid make_grid sum_write load_test.x grdecl_test.x grid_dump_ascii.x select_test.x grid_dump.x convert.x kw_list.x grid_info.x summary.x)
set(program_list summary2csv2 summary2csv esummary.x kw_extract.x grdecl_grid make_grid sum_write load_test.x grdecl_test.x grid_dump_ascii.x select_test.x grid_dump.x convert.x kw_list.x grid_info.x summary.x)
else()
# The stupid .x extension creates problems on windows
add_executable( convert convert.c )
@ -28,7 +29,7 @@ if (BUILD_APPLICATIONS)
add_executable( summary view_summary.c )
add_executable( select_test select_test.c )
add_executable( load_test load_test.c )
set(program_list summary2csv kw_extract grdecl_grid make_grid sum_write load_test grdecl_test grid_dump_ascii select_test grid_dump convert kw_list grid_info summary)
set(program_list summary2csv2 summary2csv kw_extract grdecl_grid make_grid sum_write load_test grdecl_test grid_dump_ascii select_test grid_dump convert kw_list grid_info summary)
endif()

View File

@ -1,163 +0,0 @@
# CMAKE generated file: DO NOT EDIT!
# Generated by "MinGW Makefiles" Generator, CMake Version 2.8
# Default target executed when no arguments are given to make.
default_target: all
.PHONY : default_target
#=============================================================================
# Special targets provided by cmake.
# Disable implicit rules so canoncical targets will work.
.SUFFIXES:
# Remove some rules from gmake that .SUFFIXES does not remove.
SUFFIXES =
.SUFFIXES: .hpux_make_needs_suffix_list
# Suppress display of executed commands.
$(VERBOSE).SILENT:
# A target that is always out of date.
cmake_force:
.PHONY : cmake_force
#=============================================================================
# Set environment variables for the build.
SHELL = cmd.exe
# The CMake executable.
CMAKE_COMMAND = "C:\Program Files\CMake 2.8\bin\cmake.exe"
# The command to remove a file.
RM = "C:\Program Files\CMake 2.8\bin\cmake.exe" -E remove -f
# The program to use to edit the cache.
CMAKE_EDIT_COMMAND = "C:\Program Files\CMake 2.8\bin\cmake-gui.exe"
# The top-level source directory on which CMake was run.
CMAKE_SOURCE_DIR = C:\code\ERT
# The top-level build directory on which CMake was run.
CMAKE_BINARY_DIR = C:\code\ERT
#=============================================================================
# Targets provided globally by CMake.
# Special rule for the target edit_cache
edit_cache:
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake cache editor..."
"C:\Program Files\CMake 2.8\bin\cmake-gui.exe" -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)
.PHONY : edit_cache
# Special rule for the target edit_cache
edit_cache/fast: edit_cache
.PHONY : edit_cache/fast
# Special rule for the target rebuild_cache
rebuild_cache:
@$(CMAKE_COMMAND) -E cmake_echo_color --switch=$(COLOR) --cyan "Running CMake to regenerate build system..."
"C:\Program Files\CMake 2.8\bin\cmake.exe" -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR)
.PHONY : rebuild_cache
# Special rule for the target rebuild_cache
rebuild_cache/fast: rebuild_cache
.PHONY : rebuild_cache/fast
# The main all target
all: cmake_check_build_system
cd /d C:\code\ERT && $(CMAKE_COMMAND) -E cmake_progress_start C:\code\ERT\CMakeFiles C:\code\ERT\libecl\applications\CMakeFiles\progress.marks
cd /d C:\code\ERT && $(MAKE) -f CMakeFiles\Makefile2 libecl/applications/all
$(CMAKE_COMMAND) -E cmake_progress_start C:\code\ERT\CMakeFiles 0
.PHONY : all
# The main clean target
clean:
cd /d C:\code\ERT && $(MAKE) -f CMakeFiles\Makefile2 libecl/applications/clean
.PHONY : clean
# The main clean target
clean/fast: clean
.PHONY : clean/fast
# Prepare targets for installation.
preinstall: all
cd /d C:\code\ERT && $(MAKE) -f CMakeFiles\Makefile2 libecl/applications/preinstall
.PHONY : preinstall
# Prepare targets for installation.
preinstall/fast:
cd /d C:\code\ERT && $(MAKE) -f CMakeFiles\Makefile2 libecl/applications/preinstall
.PHONY : preinstall/fast
# clear depends
depend:
cd /d C:\code\ERT && $(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles\Makefile.cmake 1
.PHONY : depend
# Convenience name for target.
libecl/applications/CMakeFiles/grid_info.x.dir/rule:
cd /d C:\code\ERT && $(MAKE) -f CMakeFiles\Makefile2 libecl/applications/CMakeFiles/grid_info.x.dir/rule
.PHONY : libecl/applications/CMakeFiles/grid_info.x.dir/rule
# Convenience name for target.
grid_info.x: libecl/applications/CMakeFiles/grid_info.x.dir/rule
.PHONY : grid_info.x
# fast build rule for target.
grid_info.x/fast:
cd /d C:\code\ERT && $(MAKE) -f libecl\applications\CMakeFiles\grid_info.x.dir\build.make libecl/applications/CMakeFiles/grid_info.x.dir/build
.PHONY : grid_info.x/fast
grid_info.obj: grid_info.c.obj
.PHONY : grid_info.obj
# target to build an object file
grid_info.c.obj:
cd /d C:\code\ERT && $(MAKE) -f libecl\applications\CMakeFiles\grid_info.x.dir\build.make libecl/applications/CMakeFiles/grid_info.x.dir/grid_info.c.obj
.PHONY : grid_info.c.obj
grid_info.i: grid_info.c.i
.PHONY : grid_info.i
# target to preprocess a source file
grid_info.c.i:
cd /d C:\code\ERT && $(MAKE) -f libecl\applications\CMakeFiles\grid_info.x.dir\build.make libecl/applications/CMakeFiles/grid_info.x.dir/grid_info.c.i
.PHONY : grid_info.c.i
grid_info.s: grid_info.c.s
.PHONY : grid_info.s
# target to generate assembly for a file
grid_info.c.s:
cd /d C:\code\ERT && $(MAKE) -f libecl\applications\CMakeFiles\grid_info.x.dir\build.make libecl/applications/CMakeFiles/grid_info.x.dir/grid_info.c.s
.PHONY : grid_info.c.s
# Help Target
help:
@$(CMAKE_COMMAND) -E echo "The following are some of the valid targets for this Makefile:"
@$(CMAKE_COMMAND) -E echo "... all (the default if no target is provided)"
@$(CMAKE_COMMAND) -E echo "... clean"
@$(CMAKE_COMMAND) -E echo "... depend"
@$(CMAKE_COMMAND) -E echo "... edit_cache"
@$(CMAKE_COMMAND) -E echo "... grid_info.x"
@$(CMAKE_COMMAND) -E echo "... rebuild_cache"
@$(CMAKE_COMMAND) -E echo "... grid_info.obj"
@$(CMAKE_COMMAND) -E echo "... grid_info.i"
@$(CMAKE_COMMAND) -E echo "... grid_info.s"
.PHONY : help
#=============================================================================
# Special targets to cleanup operation of make.
# Special rule to run CMake to check the build system integrity.
# No rule that depends on this can have commands that come from listfiles
# because they might be regenerated.
cmake_check_build_system:
cd /d C:\code\ERT && $(CMAKE_COMMAND) -H$(CMAKE_SOURCE_DIR) -B$(CMAKE_BINARY_DIR) --check-build-system CMakeFiles\Makefile.cmake 0
.PHONY : cmake_check_build_system

View File

@ -27,39 +27,32 @@
static void build_key_list( const ecl_sum_type * ecl_sum , stringlist_type * key_list ) {
int iw;
static bool extend_key_list( const ecl_sum_type * ecl_sum , const stringlist_type * var_list , const char * well , stringlist_type * key_list ) {
bool oil_producer = false;
int last_step = ecl_sum_get_data_length( ecl_sum ) - 1;
stringlist_type * well_list = ecl_sum_alloc_well_list( ecl_sum , NULL );
for (iw = 0; iw < stringlist_get_size( well_list ); iw++) {
const char * well = stringlist_iget( well_list , iw );
char * wopt_key = ecl_sum_alloc_well_key( ecl_sum , "WOPR", well);
if (ecl_sum_has_key( ecl_sum , wopt_key) && (ecl_sum_get_well_var( ecl_sum , last_step , well , "WOPT") > 0 )) {
/*
We add all the keys unconditionally here; and then let the
ecl_sum_fprintf() function print a message on stderr if it is
missing.
*/
stringlist_append_owned_ref( key_list , ecl_sum_alloc_well_key( ecl_sum , "WOPR", well) );
stringlist_append_owned_ref( key_list , ecl_sum_alloc_well_key( ecl_sum , "WOPT", well) );
stringlist_append_owned_ref( key_list , ecl_sum_alloc_well_key( ecl_sum , "WGPR", well) );
stringlist_append_owned_ref( key_list , ecl_sum_alloc_well_key( ecl_sum , "WGPT", well) );
stringlist_append_owned_ref( key_list , ecl_sum_alloc_well_key( ecl_sum , "WWPR", well) );
stringlist_append_owned_ref( key_list , ecl_sum_alloc_well_key( ecl_sum , "WWPT", well) );
} else
printf("Ignoring well: %s \n",well);
free( wopt_key );
char * wopt_key = ecl_sum_alloc_well_key( ecl_sum , "WOPT", well);
if (ecl_sum_has_key( ecl_sum , wopt_key) && (ecl_sum_get_well_var( ecl_sum , last_step , well , "WOPT") > 0 )) {
/*
We add all the keys unconditionally here; and then let the
ecl_sum_fprintf() function print a message on stderr if it is
missing.
*/
int ivar;
for (ivar = 0; ivar < stringlist_get_size( var_list ); ivar++) {
const char * var = stringlist_iget( var_list , ivar );
stringlist_append_owned_ref( key_list , ecl_sum_alloc_well_key( ecl_sum , var, well) );
}
oil_producer = true;
}
stringlist_free( well_list );
free( wopt_key );
return oil_producer;
}
int main(int argc , char ** argv) {
{
ecl_sum_fmt_type fmt;
bool well_rows = false;
bool include_restart = true;
int arg_offset = 1;
@ -71,23 +64,49 @@ int main(int argc , char ** argv) {
{
char * data_file = argv[arg_offset];
ecl_sum_type * ecl_sum;
stringlist_type * var_list = stringlist_alloc_new();
stringlist_append_ref( var_list , "WOPR" );
stringlist_append_ref( var_list , "WOPT" );
stringlist_append_ref( var_list , "WGPR" );
stringlist_append_ref( var_list , "WGPT" );
stringlist_append_ref( var_list , "WWPR" );
stringlist_append_ref( var_list , "WWPT" );
ecl_sum_fmt_init_csv( &fmt );
ecl_sum = ecl_sum_fread_alloc_case__( data_file , ":" , include_restart);
if (ecl_sum != NULL) {
char * csv_file = util_alloc_filename( NULL , ecl_sum_get_base(ecl_sum) , "txt"); // Will save to current path; can use ecl_sum_get_path() to save to target path instead.
FILE * stream = util_fopen( csv_file , "w");
stringlist_type * well_list = ecl_sum_alloc_well_list( ecl_sum , NULL );
stringlist_type * key_list = stringlist_alloc_new( );
build_key_list( ecl_sum , key_list );
{
char * csv_file = util_alloc_filename( NULL , ecl_sum_get_base(ecl_sum) , "txt"); // Weill save to current path; can use ecl_sum_get_path() to save to target path instead.
FILE * stream = util_fopen( csv_file , "w");
ecl_sum_fprintf(ecl_sum , stream , key_list , false , &fmt);
fclose( stream );
free( csv_file );
int iw;
for (iw = 0; iw < stringlist_get_size( well_list ); iw++) {
const char * well = stringlist_iget( well_list , iw );
if (!extend_key_list( ecl_sum , var_list , well , key_list))
fprintf(stderr , "Ignoring well: %s \n",well);
if (well_rows) {
if (stringlist_get_size(key_list)) {
ecl_sum_fprintf(ecl_sum , stream , key_list , false , &fmt);
stringlist_clear( key_list );
}
}
}
if (!well_rows)
ecl_sum_fprintf(ecl_sum , stream , key_list , false , &fmt);
stringlist_free( well_list );
stringlist_free( key_list );
ecl_sum_free(ecl_sum);
fclose( stream );
free( csv_file );
} else
fprintf(stderr,"summary2csv: No summary data found for case:%s\n", data_file );
stringlist_free( var_list );
}
}
}

View File

@ -0,0 +1,146 @@
/*
Copyright (C) 2013 Statoil ASA, Norway.
The file 'summary2csv2.c' is part of ERT - Ensemble based Reservoir Tool.
ERT 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.
ERT 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.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include <stdbool.h>
#include <ert/util/util.h>
#include <ert/util/stringlist.h>
#include <ert/ecl/ecl_sum.h>
static void fprintf_line( const ecl_sum_type * ecl_sum , const ecl_sum_fmt_type * fmt , const char * well , int time_index , const stringlist_type * var_list , FILE * stream) {
/* WELL */
fprintf(stream , fmt->header_fmt , well);
fprintf(stream , fmt->sep );
/* DAYS */
fprintf(stream , fmt->days_fmt , ecl_sum_iget_sim_days(ecl_sum , time_index));
fprintf(stream , fmt->sep );
/* DATE */
{
struct tm ts;
const int DATE_STRING_LENGTH = 128;
char * date_string = util_malloc( DATE_STRING_LENGTH * sizeof * date_string);
time_t sim_time = ecl_sum_iget_sim_time(ecl_sum , time_index );
util_localtime( &sim_time , &ts);
strftime( date_string , DATE_STRING_LENGTH - 1 , fmt->date_fmt , &ts);
fprintf(stream , date_string );
free( date_string );
}
{
int ivar;
for (ivar = 0; ivar < stringlist_get_size( var_list ); ivar++) {
const char * var = stringlist_iget( var_list , ivar );
double value = 0;
if (ecl_sum_has_well_var( ecl_sum , well , var ))
value = ecl_sum_get_well_var( ecl_sum , time_index , well , var );
else
fprintf(stderr,"Missing variable:%s for well:%s - substituting 0.0 \n",var , well);
fprintf(stream , fmt->sep );
fprintf(stream , fmt->value_fmt , value );
}
fprintf( stream , fmt->newline );
}
}
int main(int argc , char ** argv) {
{
ecl_sum_fmt_type fmt;
bool include_restart = true;
int arg_offset = 1;
if (argc != 2) {
printf("You must supply the name of a case as:\n\n summary2csv.exe ECLIPSE_CASE\n\nThe case can optionally contain a leading path component.\n");
exit(1);
}
{
char * data_file = argv[arg_offset];
ecl_sum_type * ecl_sum;
stringlist_type * var_list = stringlist_alloc_new();
stringlist_append_ref( var_list , "WOPR" );
stringlist_append_ref( var_list , "WOPT" );
stringlist_append_ref( var_list , "WGPR" );
stringlist_append_ref( var_list , "WGPT" );
stringlist_append_ref( var_list , "WWPR" );
stringlist_append_ref( var_list , "WWPT" );
ecl_sum_fmt_init_csv( &fmt );
ecl_sum = ecl_sum_fread_alloc_case__( data_file , ":" , include_restart);
if (ecl_sum != NULL) {
char * csv_file = util_alloc_filename( NULL , ecl_sum_get_base(ecl_sum) , "txt"); // Will save to current path; can use ecl_sum_get_path() to save to target path instead.
FILE * stream = util_fopen( csv_file , "w");
stringlist_type * well_list = ecl_sum_alloc_well_list( ecl_sum , NULL );
stringlist_type * key_list = stringlist_alloc_new( );
fprintf(stream , fmt.header_fmt , "WELLNAME");
fprintf(stream , fmt.sep );
fprintf(stream , fmt.header_fmt , "DAYS");
fprintf(stream , fmt.sep );
fprintf(stream , fmt.header_fmt , "DATES");
{
int ivar;
for (ivar = 0; ivar < stringlist_get_size( var_list ); ivar++) {
const char * var = stringlist_iget( var_list , ivar );
fprintf(stream , fmt.sep );
fprintf(stream , fmt.header_fmt , var );
}
fprintf(stream , "\n");
}
{
int iw;
for (iw = 0; iw < stringlist_get_size( well_list ); iw++) {
const char * well = stringlist_iget( well_list , iw );
if (ecl_sum_is_oil_producer( ecl_sum , well )) {
int time_index;
for (time_index = 0; time_index < ecl_sum_get_data_length( ecl_sum ); time_index++)
fprintf_line( ecl_sum , &fmt , well , time_index , var_list , stream);
}
}
}
stringlist_free( well_list );
stringlist_free( key_list );
ecl_sum_free(ecl_sum);
fclose( stream );
free( csv_file );
} else
fprintf(stderr,"summary2csv2: No summary data found for case:%s\n", data_file );
stringlist_free( var_list );
}
}
}

View File

@ -31,6 +31,8 @@ extern "C" {
#include <ert/ecl/ecl_kw.h>
#include <ert/ecl/grid_dims.h>
#define ECL_GRID_GLOBAL_GRID "Global" // used as key in hash tables over grids.
typedef double (block_function_ftype) ( const double_vector_type *);
typedef struct ecl_grid_struct ecl_grid_type;
@ -140,6 +142,7 @@ extern "C" {
ecl_grid_type * ecl_grid_iget_lgr(const ecl_grid_type * main_grid , int lgr_nr);
ecl_grid_type * ecl_grid_get_lgr(const ecl_grid_type * main_grid, const char * __lgr_name);
bool ecl_grid_has_lgr(const ecl_grid_type * main_grid, const char * __lgr_name);
const char * ecl_grid_iget_lgr_name( const ecl_grid_type * ecl_grid , int lgr_nr);
stringlist_type * ecl_grid_alloc_lgr_name_list(const ecl_grid_type * ecl_grid);
int ecl_grid_get_parent_cell1( const ecl_grid_type * grid , int global_index);
int ecl_grid_get_parent_cell3( const ecl_grid_type * grid , int i , int j , int k);
@ -172,6 +175,8 @@ extern "C" {
bool ecl_grid_dual_grid( const ecl_grid_type * ecl_grid );
UTIL_IS_INSTANCE_HEADER( ecl_grid );
#ifdef __cplusplus
}
#endif

View File

@ -104,6 +104,7 @@ extern "C" {
#define ZWEL_KW "ZWEL"
#define ICON_KW "ICON"
#define ISEG_KW "ISEG"
#define RSEG_KW "RSEG"
#define ECLIPSE100_OIL_DEN_KW "OIL_DEN"
#define ECLIPSE100_GAS_DEN_KW "GAS_DEN"
@ -135,9 +136,9 @@ extern "C" {
#define INTEHEAD_NSEGMX_INDEX 176
#define INTEHEAD_NLBRMX_INDEX 177
#define INTEHEAD_NISEGZ_INDEX 178
#define INTEHEAD_NRSEGZ_INDEX 179
#define INTEHEAD_NILBRZ_INDEX 180
#define DOUBHEAD_DAYS_INDEX 0
/*****************************************************************/
@ -230,7 +231,11 @@ extern "C" {
#define CONGRAT_KW "CONGRAT" /* Gas ... */
#define CONORAT_KW "CONORAT" /* Oil ... */
#define CONPRES_KW "CONPRES" /* Pressure ... */
#define CONLENST_KW "CONLENST" /* Length along MSW well */
#define CONVTUB_KW "CONVTUB" /* Volumetric flow at tubing head conditions. */
#define CONOTUB_KW "CONOTUB" /* Volumetric oil flow at tubing head conditions. */
#define CONGTUB_KW "CONGTUB" /* Volumetric gas flow at tubing head conditions. */
#define CONWTUB_KW "CONWTUB" /* Volumetric water flow at tubing head conditions. */
#define WELLETC_TYPE_INDEX 5 /* At this keyword the WELLETC keyword contains a string

View File

@ -0,0 +1,83 @@
/*
Copyright (C) 2011 Statoil ASA, Norway.
The file 'ecl_rft_cell.h' is part of ERT - Ensemble based Reservoir Tool.
ERT 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.
ERT 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.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#ifndef __ECL_RFT_CELL_H__
#define __ECL_RFT_CELL_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <ert/util/type_macros.h>
#define ECL_RFT_CELL_INVALID_VALUE -1
typedef struct ecl_rft_cell_struct ecl_rft_cell_type;
UTIL_IS_INSTANCE_HEADER( ecl_rft_cell );
ecl_rft_cell_type * ecl_rft_cell_alloc_PLT( int i ,
int j ,
int k ,
double depth ,
double pressure ,
double orat ,
double grat ,
double wrat ,
double connection_start,
double flowrate,
double oil_flowrate,
double gas_flowrate,
double water_flowrate);
ecl_rft_cell_type * ecl_rft_cell_alloc_RFT( int i , int j , int k , double depth , double pressure , double swat , double sgas);
void ecl_rft_cell_free( ecl_rft_cell_type * cell );
void ecl_rft_cell_free__( void * arg);
bool ecl_rft_cell_ijk_equal( const ecl_rft_cell_type * cell , int i , int j , int k);
void ecl_rft_cell_get_ijk( const ecl_rft_cell_type * cell , int * i , int * j , int * k);
int ecl_rft_cell_get_i( const ecl_rft_cell_type * cell );
int ecl_rft_cell_get_j( const ecl_rft_cell_type * cell );
int ecl_rft_cell_get_k( const ecl_rft_cell_type * cell );
double ecl_rft_cell_get_depth( const ecl_rft_cell_type * cell );
double ecl_rft_cell_get_pressure( const ecl_rft_cell_type * cell );
double ecl_rft_cell_get_swat( const ecl_rft_cell_type * cell );
double ecl_rft_cell_get_sgas( const ecl_rft_cell_type * cell );
double ecl_rft_cell_get_soil( const ecl_rft_cell_type * cell );
double ecl_rft_cell_get_wrat( const ecl_rft_cell_type * cell );
double ecl_rft_cell_get_grat( const ecl_rft_cell_type * cell );
double ecl_rft_cell_get_orat( const ecl_rft_cell_type * cell );
double ecl_rft_cell_get_connection_start( const ecl_rft_cell_type * cell );
double ecl_rft_cell_get_flowrate( const ecl_rft_cell_type * cell );
double ecl_rft_cell_get_oil_flowrate( const ecl_rft_cell_type * cell );
double ecl_rft_cell_get_gas_flowrate( const ecl_rft_cell_type * cell );
double ecl_rft_cell_get_water_flowrate( const ecl_rft_cell_type * cell );
int ecl_rft_cell_cmp__( const void * arg1 , const void * arg2);
int ecl_rft_cell_cmp( const ecl_rft_cell_type * cell1 , const ecl_rft_cell_type * cell2);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -39,15 +39,13 @@ void ecl_rft_file_free(ecl_rft_file_type * );
void ecl_rft_file_block(const ecl_rft_file_type * , double , const char * , int , const double * , int * , int * , int *);
void ecl_rft_file_fprintf_rft_obs(const ecl_rft_file_type * , double , const char * , const char *, const char * , double);
ecl_rft_node_type * ecl_rft_file_get_node(const ecl_rft_file_type * , const char * );
void ecl_rft_file_summarize(const ecl_rft_file_type * , bool );
void ecl_rft_file_xml_summary( const ecl_rft_file_type * rft_file );
const ecl_rft_node_type * ecl_rft_file_get_well_time_rft( const ecl_rft_file_type * rft_file , const char * well , time_t recording_time);
int ecl_rft_file_get_size__( const ecl_rft_file_type * rft_file, const char * well_pattern , time_t recording_time);
int ecl_rft_file_get_size( const ecl_rft_file_type * rft_file);
const ecl_rft_node_type * ecl_rft_file_iget_node( const ecl_rft_file_type * rft_file , int index);
const ecl_rft_node_type * ecl_rft_file_iget_well_rft( const ecl_rft_file_type * rft_file , const char * well, int index);
ecl_rft_node_type * ecl_rft_file_get_well_time_rft( const ecl_rft_file_type * rft_file , const char * well , time_t recording_time);
ecl_rft_node_type * ecl_rft_file_iget_node( const ecl_rft_file_type * rft_file , int index);
ecl_rft_node_type * ecl_rft_file_iget_well_rft( const ecl_rft_file_type * rft_file , const char * well, int index);
bool ecl_rft_file_has_well( const ecl_rft_file_type * rft_file , const char * well);
int ecl_rft_file_get_well_occurences( const ecl_rft_file_type * rft_file , const char * well);
stringlist_type * ecl_rft_file_alloc_well_list(const ecl_rft_file_type * rft_file );

View File

@ -24,6 +24,7 @@ extern "C" {
#include <stdbool.h>
#include <ert/ecl/ecl_file.h>
#include <ert/ecl/ecl_rft_cell.h>
typedef enum { RFT = 1 ,
PLT = 2 ,
@ -31,28 +32,34 @@ typedef enum { RFT = 1 ,
typedef struct ecl_rft_node_struct ecl_rft_node_type;
int ecl_rft_node_lookup_ijk( const ecl_rft_node_type * rft_node , int i, int j , int k);
void ecl_rft_node_inplace_sort_cells( ecl_rft_node_type * rft_node );
const ecl_rft_cell_type * ecl_rft_node_iget_cell_sorted( ecl_rft_node_type * rft_node , int index);
const ecl_rft_cell_type * ecl_rft_node_iget_cell( const ecl_rft_node_type * rft_node , int index);
const ecl_rft_cell_type * ecl_rft_node_lookup_ijk( const ecl_rft_node_type * rft_node , int i, int j , int k);
void ecl_rft_node_fprintf_rft_obs(const ecl_rft_node_type * , double , const char * , const char * , double );
ecl_rft_node_type * ecl_rft_node_alloc(const ecl_file_type * file_map );
const char * ecl_rft_node_get_well_name(const ecl_rft_node_type * );
void ecl_rft_node_free(ecl_rft_node_type * );
void ecl_rft_node_free__(void * );
void ecl_rft_node_block2(const ecl_rft_node_type * , int , const double * , const double * , int * , int * , int *);
void ecl_rft_node_block(const ecl_rft_node_type * , double , int , const double * , int * , int * , int *);
time_t ecl_rft_node_get_date(const ecl_rft_node_type * );
int ecl_rft_node_get_size(const ecl_rft_node_type * );
void ecl_rft_node_summarize(const ecl_rft_node_type * , bool );
const char * ecl_rft_node_get_well_name( const ecl_rft_node_type * rft_node );
void ecl_rft_node_iget_ijk( const ecl_rft_node_type * rft_node , int index , int *i , int *j , int *k);
void ecl_rft_node_export_DEPTH(const ecl_rft_node_type * , const char * );
bool ecl_rft_node_is_RFT( const ecl_rft_node_type * rft_node );
bool ecl_rft_node_is_PLT( const ecl_rft_node_type * rft_node );
bool ecl_rft_node_is_SEGMENT( const ecl_rft_node_type * rft_node );
bool ecl_rft_node_is_MSW( const ecl_rft_node_type * rft_node );
double ecl_rft_node_iget_pressure( const ecl_rft_node_type * rft_node , int index);
double ecl_rft_node_iget_depth( const ecl_rft_node_type * rft_node , int index);
double ecl_rft_node_iget_wrat( const ecl_rft_node_type * rft_node , int index);
double ecl_rft_node_iget_grat( const ecl_rft_node_type * rft_node , int index);
double ecl_rft_node_iget_orat( const ecl_rft_node_type * rft_node , int index);
double ecl_rft_node_iget_swat( const ecl_rft_node_type * rft_node , int index);
double ecl_rft_node_iget_sgas( const ecl_rft_node_type * rft_node , int index);
double ecl_rft_node_iget_soil( const ecl_rft_node_type * rft_node , int index);
#ifdef __cplusplus
}

View File

@ -63,6 +63,7 @@ extern "C" {
int nswlmx; // The maximum number of segmented wells
int nlbrmx; // The maximum number of lateral branches pr well
int nilbrz; // The number of entries pr segment in ILBR array
int nrsegz; // The number of entries pr segment in RSEG array
// Properteies from the LOGIHEAD keyword:
bool dualp;

View File

@ -200,6 +200,7 @@ typedef struct ecl_sum_struct ecl_sum_type;
ecl_sum_tstep_type * ecl_sum_add_tstep( ecl_sum_type * ecl_sum , int report_step , double sim_days);
void ecl_sum_update_wgname( ecl_sum_type * ecl_sum , smspec_node_type * node , const char * wgname );
bool ecl_sum_is_oil_producer( const ecl_sum_type * ecl_sum , const char * well);
char * ecl_sum_alloc_well_key( const ecl_sum_type * ecl_sum , const char * keyword , const char * wgname);
UTIL_IS_INSTANCE_HEADER( ecl_sum );

View File

@ -2,9 +2,9 @@ include_directories( ext )
file(GLOB ext_source "ext/*.c" )
file(GLOB ext_header "ext/*.h" )
set( source_files ecl_rsthead.c ecl_sum_tstep.c ecl_rst_file.c ecl_init_file.c ecl_grid_cache.c smspec_node.c ecl_kw_grdecl.c ecl_file_kw.c ecl_grav.c ecl_grav_calc.c ecl_smspec.c ecl_sum_data.c ecl_util.c ecl_kw.c ecl_sum.c fortio.c ecl_rft_file.c ecl_rft_node.c ecl_grid.c ecl_coarse_cell.c ecl_box.c ecl_io_config.c ecl_file.c ecl_region.c point.c tetrahedron.c ecl_subsidence.c ecl_grid_dims.c grid_dims.c ecl_grav_common.c ${ext_source})
set( source_files ecl_rsthead.c ecl_sum_tstep.c ecl_rst_file.c ecl_init_file.c ecl_grid_cache.c smspec_node.c ecl_kw_grdecl.c ecl_file_kw.c ecl_grav.c ecl_grav_calc.c ecl_smspec.c ecl_sum_data.c ecl_util.c ecl_kw.c ecl_sum.c fortio.c ecl_rft_file.c ecl_rft_node.c ecl_rft_cell.c ecl_grid.c ecl_coarse_cell.c ecl_box.c ecl_io_config.c ecl_file.c ecl_region.c point.c tetrahedron.c ecl_subsidence.c ecl_grid_dims.c grid_dims.c ecl_grav_common.c ${ext_source})
set( header_files ecl_rsthead.h ecl_sum_tstep.h ecl_rst_file.h ecl_init_file.h smspec_node.h ecl_grid_cache.h ecl_kw_grdecl.h ecl_file_kw.h ecl_grav.h ecl_grav_calc.h ecl_endian_flip.h ecl_smspec.h ecl_sum_data.h ecl_util.h ecl_kw.h ecl_sum.h fortio.h ecl_rft_file.h ecl_rft_node.h ecl_box.h ecl_coarse_cell.h ecl_grid.h ecl_io_config.h ecl_file.h ecl_region.h ecl_kw_magic.h ecl_subsidence.h ecl_grid_dims.h grid_dims.h ${ext_header} ecl_grav_common.h)
set( header_files ecl_rsthead.h ecl_sum_tstep.h ecl_rst_file.h ecl_init_file.h smspec_node.h ecl_grid_cache.h ecl_kw_grdecl.h ecl_file_kw.h ecl_grav.h ecl_grav_calc.h ecl_endian_flip.h ecl_smspec.h ecl_sum_data.h ecl_util.h ecl_kw.h ecl_sum.h fortio.h ecl_rft_file.h ecl_rft_node.h ecl_rft_cell.h ecl_box.h ecl_coarse_cell.h ecl_grid.h ecl_io_config.h ecl_file.h ecl_region.h ecl_kw_magic.h ecl_subsidence.h ecl_grid_dims.h grid_dims.h ${ext_header} ecl_grav_common.h)

View File

@ -513,12 +513,12 @@ struct ecl_grid_struct {
int parent_box[6]; /* integers i1,i2, j1,j2, k1,k2 of the parent grid region containing this lgr. the indices are inclusive - zero offset */
/* not used yet .. */
int dualp_flag;
bool use_mapaxes;
double unit_x[2];
double unit_y[2];
double origo[2];
float mapaxes[6];
int dualp_flag;
bool use_mapaxes;
double unit_x[2];
double unit_y[2];
double origo[2];
float mapaxes[6];
/*------------------------------: the fields below this line are used for blocking algorithms - and not allocated by default.*/
int block_dim; /* == 2 for maps and 3 for fields. 0 when not in use. */
int block_size;
@ -1089,6 +1089,7 @@ static void ecl_cell_init_regular( ecl_cell_type * cell , const double * offset
/* starting on the ecl_grid proper implementation */
UTIL_SAFE_CAST_FUNCTION(ecl_grid , ECL_GRID_ID);
UTIL_IS_INSTANCE_FUNCTION( ecl_grid , ECL_GRID_ID);
/**
this function allocates the internal index_map and inv_index_map fields.
@ -2601,7 +2602,10 @@ ecl_grid_type * ecl_grid_load_case( const char * case_input ) {
ecl_grid_type * ecl_grid = NULL;
char * grid_file = ecl_grid_alloc_case_filename( case_input );
if (grid_file != NULL) {
ecl_grid = ecl_grid_alloc( grid_file );
if (util_file_exists( grid_file ))
ecl_grid = ecl_grid_alloc( grid_file );
free( grid_file );
}
return ecl_grid;
@ -3541,6 +3545,15 @@ stringlist_type * ecl_grid_alloc_lgr_name_list(const ecl_grid_type * ecl_grid) {
}
}
const char * ecl_grid_iget_lgr_name( const ecl_grid_type * ecl_grid , int lgr_nr) {
__assert_main_grid( ecl_grid );
if (lgr_nr < (vector_get_size( ecl_grid->LGR_list ) - 1)) {
const ecl_grid_type * lgr = vector_iget( ecl_grid->LGR_list , lgr_nr + 1);
return lgr->name;
} else
return NULL;
}
/*****************************************************************/

View File

@ -689,8 +689,9 @@ void ecl_region_deselect_i1i2( ecl_region_type * region , int i1 , int i2) {
static void ecl_region_select_j1j2__( ecl_region_type * region , int j1 , int j2 , bool select) {
if (j1 > j2)
util_abort("%s: i1 > i2 - this is illogical ... \n",__func__);
j1 = util_int_max(0 , j1);
j2 = util_int_min(region->grid_nx - 1 , j2);
j2 = util_int_min(region->grid_ny - 1 , j2);
{
int i,j,k;
for (k = 0; k < region->grid_nz; k++)
@ -729,7 +730,7 @@ static void ecl_region_select_k1k2__( ecl_region_type * region , int k1 , int k2
if (k1 > k2)
util_abort("%s: i1 > i2 - this is illogical ... \n",__func__);
k1 = util_int_max(0 , k1);
k2 = util_int_min(region->grid_nx - 1 , k2);
k2 = util_int_min(region->grid_nz - 1 , k2);
{
int i,j,k;
for (k = k1; k <= k2; k++)

View File

@ -0,0 +1,357 @@
/*
Copyright (C) 2011 Statoil ASA, Norway.
The file 'ecl_rft_cell.c' is part of ERT - Ensemble based Reservoir Tool.
ERT 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.
ERT 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.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#include <math.h>
#include <time.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdio.h>
#include <ert/util/util.h>
#include <ert/util/type_macros.h>
#include <ert/ecl/ecl_kw.h>
#include <ert/ecl/ecl_kw_magic.h>
#include <ert/ecl/ecl_file.h>
#include <ert/ecl/ecl_rft_cell.h>
#define ECL_RFT_CELL_TYPE_ID 99164012
#define RFT_DATA_TYPE_ID 66787166
#define PLT_DATA_TYPE_ID 87166667
struct ecl_rft_cell_struct {
UTIL_TYPE_ID_DECLARATION;
int i,j,k;
double pressure;
double depth;
void * data;
};
typedef struct plt_data_struct plt_data_type;
typedef struct rft_data_struct rft_data_type;
struct rft_data_struct {
UTIL_TYPE_ID_DECLARATION;
double swat;
double sgas;
};
struct plt_data_struct {
UTIL_TYPE_ID_DECLARATION;
double orat;
double wrat;
double grat;
double connection_start;
double flowrate;
double oil_flowrate;
double gas_flowrate;
double water_flowrate;
};
/*****************************************************************/
static rft_data_type * rft_data_alloc( double swat , double sgas) {
rft_data_type * data = util_malloc( sizeof * data );
UTIL_TYPE_ID_INIT( data , RFT_DATA_TYPE_ID );
data->swat = swat;
data->sgas = sgas;
return data;
}
static void rft_data_free( rft_data_type * data ) {
free( data );
}
static UTIL_TRY_CAST_FUNCTION_CONST( rft_data , RFT_DATA_TYPE_ID)
static UTIL_IS_INSTANCE_FUNCTION( rft_data , RFT_DATA_TYPE_ID)
/*****************************************************************/
static plt_data_type * plt_data_alloc( double orat , double grat , double wrat,double connection_start, double flowrate , double oil_flowrate , double gas_flowrate , double water_flowrate) {
plt_data_type * data = util_malloc( sizeof * data );
UTIL_TYPE_ID_INIT( data , PLT_DATA_TYPE_ID );
data->orat = orat;
data->grat = grat;
data->wrat = wrat;
data->connection_start = connection_start;
data->flowrate = flowrate;
data->oil_flowrate = oil_flowrate;
data->gas_flowrate = gas_flowrate;
data->water_flowrate = water_flowrate;
return data;
}
static void plt_data_free( plt_data_type * data ) {
free( data );
}
static UTIL_TRY_CAST_FUNCTION_CONST( plt_data , PLT_DATA_TYPE_ID)
static UTIL_IS_INSTANCE_FUNCTION( plt_data , PLT_DATA_TYPE_ID)
/*****************************************************************/
static UTIL_SAFE_CAST_FUNCTION( ecl_rft_cell , ECL_RFT_CELL_TYPE_ID)
static UTIL_SAFE_CAST_FUNCTION_CONST( ecl_rft_cell , ECL_RFT_CELL_TYPE_ID)
UTIL_IS_INSTANCE_FUNCTION( ecl_rft_cell , ECL_RFT_CELL_TYPE_ID)
static ecl_rft_cell_type * ecl_rft_cell_alloc_common(int i , int j , int k , double depth , double pressure) {
ecl_rft_cell_type * cell = util_malloc( sizeof * cell );
UTIL_TYPE_ID_INIT( cell , ECL_RFT_CELL_TYPE_ID );
cell->i = i;
cell->j = j;
cell->k = k;
cell->depth = depth;
cell->pressure = pressure;
return cell;
}
ecl_rft_cell_type * ecl_rft_cell_alloc_RFT( int i , int j , int k , double depth , double pressure , double swat , double sgas) {
ecl_rft_cell_type * cell = ecl_rft_cell_alloc_common( i , j , k , depth , pressure );
cell->data = rft_data_alloc( swat , sgas );
return cell;
}
ecl_rft_cell_type * ecl_rft_cell_alloc_PLT( int i ,
int j ,
int k ,
double depth ,
double pressure ,
double orat ,
double grat ,
double wrat,
double connection_start,
double flowrate ,
double oil_flowrate ,
double gas_flowrate ,
double water_flowrate) {
ecl_rft_cell_type * cell = ecl_rft_cell_alloc_common( i , j , k , depth , pressure );
cell->data = plt_data_alloc( orat , grat , wrat , connection_start , flowrate , oil_flowrate , gas_flowrate , water_flowrate);
return cell;
}
void ecl_rft_cell_free( ecl_rft_cell_type * cell ) {
if (rft_data_is_instance( cell->data ))
rft_data_free( cell->data );
else if (plt_data_is_instance( cell->data ))
plt_data_free( cell->data );
free( cell );
}
void ecl_rft_cell_free__( void * arg) {
ecl_rft_cell_type * cell = ecl_rft_cell_safe_cast( arg );
ecl_rft_cell_free( cell );
}
/*****************************************************************/
int ecl_rft_cell_get_i( const ecl_rft_cell_type * cell ) {
return cell->i;
}
int ecl_rft_cell_get_j( const ecl_rft_cell_type * cell ) {
return cell->j;
}
int ecl_rft_cell_get_k( const ecl_rft_cell_type * cell ) {
return cell->k;
}
void ecl_rft_cell_get_ijk( const ecl_rft_cell_type * cell , int * i , int * j , int * k) {
*i = cell->i;
*j = cell->j;
*k = cell->k;
}
double ecl_rft_cell_get_depth( const ecl_rft_cell_type * cell ) {
return cell->depth;
}
double ecl_rft_cell_get_pressure( const ecl_rft_cell_type * cell ) {
return cell->pressure;
}
/*****************************************************************/
double ecl_rft_cell_get_swat( const ecl_rft_cell_type * cell ) {
const rft_data_type * data = rft_data_try_cast_const( cell->data );
if (data)
return data->swat;
else
return ECL_RFT_CELL_INVALID_VALUE;
}
double ecl_rft_cell_get_sgas( const ecl_rft_cell_type * cell ) {
const rft_data_type * data = rft_data_try_cast_const( cell->data );
if (data)
return data->sgas;
else
return ECL_RFT_CELL_INVALID_VALUE;
}
double ecl_rft_cell_get_soil( const ecl_rft_cell_type * cell ) {
const rft_data_type * data = rft_data_try_cast_const( cell->data );
if (data)
return 1 - (data->swat + data->sgas);
else
return ECL_RFT_CELL_INVALID_VALUE;
}
/*****************************************************************/
double ecl_rft_cell_get_orat( const ecl_rft_cell_type * cell ) {
const plt_data_type * data = plt_data_try_cast_const( cell->data );
if (data)
return data->orat;
else
return ECL_RFT_CELL_INVALID_VALUE;
}
double ecl_rft_cell_get_grat( const ecl_rft_cell_type * cell ) {
const plt_data_type * data = plt_data_try_cast_const( cell->data );
if (data)
return data->grat;
else
return ECL_RFT_CELL_INVALID_VALUE;
}
double ecl_rft_cell_get_wrat( const ecl_rft_cell_type * cell ) {
const plt_data_type * data = plt_data_try_cast_const( cell->data );
if (data)
return data->wrat;
else
return ECL_RFT_CELL_INVALID_VALUE;
}
double ecl_rft_cell_get_connection_start( const ecl_rft_cell_type * cell ) {
const plt_data_type * data = plt_data_try_cast_const( cell->data );
if (data)
return data->connection_start;
else
return ECL_RFT_CELL_INVALID_VALUE;
}
double ecl_rft_cell_get_flowrate( const ecl_rft_cell_type * cell ) {
const plt_data_type * data = plt_data_try_cast_const( cell->data );
if (data)
return data->flowrate;
else
return ECL_RFT_CELL_INVALID_VALUE;
}
double ecl_rft_cell_get_oil_flowrate( const ecl_rft_cell_type * cell ) {
const plt_data_type * data = plt_data_try_cast_const( cell->data );
if (data)
return data->oil_flowrate;
else
return ECL_RFT_CELL_INVALID_VALUE;
}
double ecl_rft_cell_get_gas_flowrate( const ecl_rft_cell_type * cell ) {
const plt_data_type * data = plt_data_try_cast_const( cell->data );
if (data)
return data->gas_flowrate;
else
return ECL_RFT_CELL_INVALID_VALUE;
}
double ecl_rft_cell_get_water_flowrate( const ecl_rft_cell_type * cell ) {
const plt_data_type * data = plt_data_try_cast_const( cell->data );
if (data)
return data->water_flowrate;
else
return ECL_RFT_CELL_INVALID_VALUE;
}
/*****************************************************************/
bool ecl_rft_cell_ijk_equal( const ecl_rft_cell_type * cell , int i , int j , int k) {
return ( (i == cell->i) &&
(j == cell->j) &&
(k == cell->k) );
}
/*
Currently only comparison based on connection length along PLT is supported.
*/
int ecl_rft_cell_cmp( const ecl_rft_cell_type * cell1 , const ecl_rft_cell_type * cell2) {
double val1 = ecl_rft_cell_get_connection_start( cell1 );
double val2 = ecl_rft_cell_get_connection_start( cell2 );
if (val1 < val2)
return -1;
else if (val1 == val2)
return 0;
else
return 0;
}
int ecl_rft_cell_cmp__( const void * arg1 , const void * arg2) {
const ecl_rft_cell_type * cell1 = ecl_rft_cell_safe_cast_const( arg1 );
const ecl_rft_cell_type * cell2 = ecl_rft_cell_safe_cast_const( arg2 );
return ecl_rft_cell_cmp( cell1 , cell2 );
}

View File

@ -226,8 +226,8 @@ int ecl_rft_file_get_size__( const ecl_rft_file_type * rft_file, const char * we
for ( i=0; i < vector_get_size( rft_file->data ); i++) {
const ecl_rft_node_type * rft = vector_iget_const( rft_file->data , i);
if (well_pattern != NULL) {
if (!util_fnmatch( well_pattern , ecl_rft_node_get_well_name( rft )))
if (well_pattern) {
if (util_fnmatch( well_pattern , ecl_rft_node_get_well_name( rft )) != 0)
continue;
}
@ -269,8 +269,8 @@ const char * ecl_rft_file_get_filename( const ecl_rft_file_type * rft_file ) {
handle that.
*/
const ecl_rft_node_type * ecl_rft_file_iget_node( const ecl_rft_file_type * rft_file , int index) {
return vector_iget_const( rft_file->data , index );
ecl_rft_node_type * ecl_rft_file_iget_node( const ecl_rft_file_type * rft_file , int index) {
return vector_iget( rft_file->data , index );
}
@ -301,7 +301,7 @@ const ecl_rft_node_type * ecl_rft_file_iget_node( const ecl_rft_file_type * rft_
const ecl_rft_node_type * ecl_rft_file_iget_well_rft( const ecl_rft_file_type * rft_file , const char * well, int index) {
ecl_rft_node_type * ecl_rft_file_iget_well_rft( const ecl_rft_file_type * rft_file , const char * well, int index) {
const int_vector_type * index_vector = hash_get(rft_file->well_index , well);
return ecl_rft_file_iget_node( rft_file , int_vector_iget(index_vector , index));
}
@ -315,8 +315,8 @@ const ecl_rft_node_type * ecl_rft_file_iget_well_rft( const ecl_rft_file_type *
*/
const ecl_rft_node_type * ecl_rft_file_get_well_time_rft( const ecl_rft_file_type * rft_file , const char * well , time_t recording_time) {
const ecl_rft_node_type * node = NULL;
ecl_rft_node_type * ecl_rft_file_get_well_time_rft( const ecl_rft_file_type * rft_file , const char * well , time_t recording_time) {
ecl_rft_node_type * node = NULL;
if (hash_has_key( rft_file->well_index , well)) {
const int_vector_type * index_vector = hash_get(rft_file->well_index , well);
int index = 0;
@ -367,56 +367,6 @@ stringlist_type * ecl_rft_file_alloc_well_list(const ecl_rft_file_type * rft_fil
}
/*****************************************************************/
void ecl_rft_file_summarize(const ecl_rft_file_type * rft_vector , bool show_completions) {
int iw;
for (iw = 0; iw < vector_get_size( rft_vector->data ); iw++) {
ecl_rft_node_summarize(vector_iget( rft_vector->data , iw) , show_completions);
printf("\n");
}
}
void ecl_rft_file_xml_summary( const ecl_rft_file_type * rft_file ) {
stringlist_type * wells = ecl_rft_file_alloc_well_list( rft_file );
printf("<ECLIPSE RFT FILE>\n");
{
int iw;
for (iw = 0; iw < stringlist_get_size( wells ); iw++) {
const char * well = stringlist_iget(wells , iw);
printf(" <WELL>\n");
{
int it;
for (it = 0; it < ecl_rft_file_get_well_occurences( rft_file , well ); it++) {
const ecl_rft_node_type * node = ecl_rft_file_iget_well_rft( rft_file , well , it);
time_t date = ecl_rft_node_get_date( node );
{
int mday, year,month;
util_set_date_values( date , &mday , &month , &year);
printf(" <RFT>\n");
printf(" <DATE>%02d/%02d/%4d</DATE> \n",mday,month,year);
{
int num_cells = ecl_rft_node_get_size( node );
int icell;
for (icell = 0; icell < num_cells; icell++) {
int i,j,k;
ecl_rft_node_iget_ijk( node , icell , &i , &j , &k);
printf(" <cell>\n");
printf(" <PRESSURE> %g </PRESSURE> \n", ecl_rft_node_iget_pressure( node, icell));
printf(" <DPETH> %g </DEPTH> \n" , ecl_rft_node_iget_depth( node , icell));
printf(" <ijk> %3d,%3d,%3d </ijk> \n",i,j,k);
printf(" </cell>\n");
}
}
printf(" </RFT>\n");
}
}
}
printf(" </WELL>\n");
}
}
printf("</ECLIPSE RFT FILE>\n");
stringlist_free( wells );
}

View File

@ -25,12 +25,14 @@
#include <ert/util/util.h>
#include <ert/util/hash.h>
#include <ert/util/vector.h>
#include <ert/util/int_vector.h>
#include <ert/ecl/ecl_kw.h>
#include <ert/ecl/ecl_kw_magic.h>
#include <ert/ecl/ecl_file.h>
#include <ert/ecl/ecl_rft_node.h>
#include <ert/ecl/ecl_rft_cell.h>
/**
The RFT's from several wells, and possibly also several timesteps
@ -48,80 +50,20 @@
*/
/**
Here comes some small structs containing various pieces of
information. Observe the following which is common to all these
structs:
* In the implementation only 'full instance' are employed, and
not pointers. This implies that the code does not provide
xxx_alloc() and xx_free() functions.
* They should NOT be exported out of this file.
*/
/**
This type is used to hold the coordinates of a perforated
cell. This type is used irrespective of whether this is a simple
RFT or a PLT.
*/
typedef struct {
int i;
int j;
int k;
double depth;
double pressure; /* both CONPRES from PLT and PRESSURE from RFT are internalized as pressure in the cell_type. */
} cell_type;
/*-----------------------------------------------------------------*/
/**
Type which contains the information for one cell in an RFT.
*/
typedef struct {
double swat;
double sgas;
} rft_data_type;
/*-----------------------------------------------------------------*/
/**
Type which contains the information for one cell in an PLT.
*/
typedef struct {
double orat;
double grat;
double wrat;
/* There is quite a lot of more information in the PLT - not yet internalized. */
} plt_data_type;
/* This is not implemented at all ..... */
typedef struct {
double data;
} segment_data_type;
#define ECL_RFT_NODE_ID 887195
struct ecl_rft_node_struct {
UTIL_TYPE_ID_DECLARATION;
char * well_name; /* Name of the well. */
int size; /* The number of entries in this RFT vector (i.e. the number of cells) .*/
ecl_rft_enum data_type; /* What type of data: RFT|PLT|SEGMENT */
time_t recording_date; /* When was the RFT recorded - date.*/
double days; /* When was the RFT recorded - days after simulaton start. */
cell_type *cells; /* Coordinates and depth of the well cells. */
bool MSW;
/* Only one of segment_data, rft_data or plt_data can be != NULL */
segment_data_type * segment_data;
rft_data_type * rft_data;
plt_data_type * plt_data;
bool __vertical_well; /* Internal variable - when this is true we can try to block - otherwise it is NO FUXXXX WAY. */
bool sort_perm_in_sync ;
int_vector_type * sort_perm;
vector_type *cells;
};
@ -131,7 +73,7 @@ struct ecl_rft_node_struct {
that is not (yet) supported.
*/
static ecl_rft_node_type * ecl_rft_node_alloc_empty(int size , const char * data_type_string) {
static ecl_rft_node_type * ecl_rft_node_alloc_empty(const char * data_type_string) {
ecl_rft_enum data_type = SEGMENT;
/* According to the ECLIPSE documentaton. */
@ -153,23 +95,12 @@ static ecl_rft_node_type * ecl_rft_node_alloc_empty(int size , const char * data
{
ecl_rft_node_type * rft_node = util_malloc(sizeof * rft_node );
rft_node->plt_data = NULL;
rft_node->rft_data = NULL;
rft_node->segment_data = NULL;
UTIL_TYPE_ID_INIT( rft_node , ECL_RFT_NODE_ID );
rft_node->cells = util_calloc( size , sizeof * rft_node->cells );
if (data_type == RFT)
rft_node->rft_data = util_calloc( size , sizeof * rft_node->rft_data );
else if (data_type == PLT)
rft_node->plt_data = util_calloc( size , sizeof * rft_node->plt_data);
else if (data_type == SEGMENT)
rft_node->segment_data = util_calloc( size , sizeof * rft_node->segment_data );
rft_node->__vertical_well = false;
rft_node->size = size;
rft_node->cells = vector_alloc_new();
rft_node->data_type = data_type;
rft_node->sort_perm = NULL;
rft_node->sort_perm_in_sync = false;
return rft_node;
}
@ -180,21 +111,106 @@ UTIL_SAFE_CAST_FUNCTION( ecl_rft_node , ECL_RFT_NODE_ID );
UTIL_IS_INSTANCE_FUNCTION( ecl_rft_node , ECL_RFT_NODE_ID );
static void ecl_rft_node_append_cell( ecl_rft_node_type * rft_node , ecl_rft_cell_type * cell) {
vector_append_owned_ref( rft_node->cells , cell , ecl_rft_cell_free__ );
rft_node->sort_perm_in_sync = false;
}
static void ecl_rft_node_init_RFT_cells( ecl_rft_node_type * rft_node , const ecl_file_type * rft) {
const ecl_kw_type * conipos = ecl_file_iget_named_kw( rft , CONIPOS_KW , 0);
const ecl_kw_type * conjpos = ecl_file_iget_named_kw( rft , CONJPOS_KW , 0);
const ecl_kw_type * conkpos = ecl_file_iget_named_kw( rft , CONKPOS_KW , 0);
const ecl_kw_type * depth_kw = ecl_file_iget_named_kw( rft , DEPTH_KW , 0);
const ecl_kw_type * swat_kw = ecl_file_iget_named_kw( rft , SWAT_KW , 0);
const ecl_kw_type * sgas_kw = ecl_file_iget_named_kw( rft , SGAS_KW , 0);
const ecl_kw_type * pressure_kw = ecl_file_iget_named_kw( rft , PRESSURE_KW , 0);
const float * SW = ecl_kw_get_float_ptr( swat_kw );
const float * SG = ecl_kw_get_float_ptr( sgas_kw );
const float * P = ecl_kw_get_float_ptr( pressure_kw );
const float * depth = ecl_kw_get_float_ptr( depth_kw );
const int * i = ecl_kw_get_int_ptr( conipos );
const int * j = ecl_kw_get_int_ptr( conjpos );
const int * k = ecl_kw_get_int_ptr( conkpos );
{
int c;
for (c = 0; c < ecl_kw_get_size( conipos ); c++) {
/* The connection coordinates are shifted -= 1; i.e. all internal usage is offset 0. */
ecl_rft_cell_type * cell = ecl_rft_cell_alloc_RFT( i[c] - 1 , j[c] - 1 , k[c] - 1 ,
depth[c] , P[c] , SW[c] , SG[c]);
ecl_rft_node_append_cell( rft_node , cell );
}
}
}
static void ecl_rft_node_init_PLT_cells( ecl_rft_node_type * rft_node , const ecl_file_type * rft) {
/* For PLT there is quite a lot of extra information which is not yet internalized. */
const ecl_kw_type * conipos = ecl_file_iget_named_kw( rft , CONIPOS_KW , 0);
const ecl_kw_type * conjpos = ecl_file_iget_named_kw( rft , CONJPOS_KW , 0);
const ecl_kw_type * conkpos = ecl_file_iget_named_kw( rft , CONKPOS_KW , 0);
const int * i = ecl_kw_get_int_ptr( conipos );
const int * j = ecl_kw_get_int_ptr( conjpos );
const int * k = ecl_kw_get_int_ptr( conkpos );
const float * WR = ecl_kw_get_float_ptr( ecl_file_iget_named_kw( rft , CONWRAT_KW , 0));
const float * GR = ecl_kw_get_float_ptr( ecl_file_iget_named_kw( rft , CONGRAT_KW , 0));
const float * OR = ecl_kw_get_float_ptr( ecl_file_iget_named_kw( rft , CONORAT_KW , 0));
const float * P = ecl_kw_get_float_ptr( ecl_file_iget_named_kw( rft , CONPRES_KW , 0));
const float * depth = ecl_kw_get_float_ptr( ecl_file_iget_named_kw( rft , CONDEPTH_KW , 0));
const float * flowrate = ecl_kw_get_float_ptr( ecl_file_iget_named_kw( rft , CONVTUB_KW , 0));
const float * oil_flowrate = ecl_kw_get_float_ptr( ecl_file_iget_named_kw( rft , CONOTUB_KW , 0));
const float * gas_flowrate = ecl_kw_get_float_ptr( ecl_file_iget_named_kw( rft , CONGTUB_KW , 0));
const float * water_flowrate = ecl_kw_get_float_ptr( ecl_file_iget_named_kw( rft , CONWTUB_KW , 0));
const float * connection_start = NULL;
/* This keyword is ONLY present if we are dealing with a MSW well. */
if (ecl_file_has_kw( rft , CONLENST_KW))
connection_start = ecl_kw_get_float_ptr( ecl_file_iget_named_kw( rft , CONLENST_KW , 0));
{
int c;
for ( c = 0; c < ecl_kw_get_size( conipos ); c++) {
ecl_rft_cell_type * cell;
double cs = 0;
if (connection_start)
cs = connection_start[c];
/* The connection coordinates are shifted -= 1; i.e. all internal usage is offset 0. */
cell = ecl_rft_cell_alloc_PLT( i[c] -1 , j[c] -1 , k[c] -1 ,
depth[c] , P[c] , OR[c] , GR[c] , WR[c] , cs , flowrate[c] , oil_flowrate[c] , gas_flowrate[c] , water_flowrate[c]);
ecl_rft_node_append_cell( rft_node , cell );
}
}
}
static void ecl_rft_node_init_cells( ecl_rft_node_type * rft_node , const ecl_file_type * rft ) {
if (rft_node->data_type == RFT)
ecl_rft_node_init_RFT_cells( rft_node , rft );
else if (rft_node->data_type == PLT)
ecl_rft_node_init_PLT_cells( rft_node , rft );
}
ecl_rft_node_type * ecl_rft_node_alloc(const ecl_file_type * rft) {
ecl_kw_type * conipos = ecl_file_iget_named_kw(rft , CONIPOS_KW , 0);
ecl_kw_type * welletc = ecl_file_iget_named_kw(rft , WELLETC_KW , 0);
ecl_rft_node_type * rft_node = ecl_rft_node_alloc_empty(ecl_kw_get_size(conipos) ,
ecl_kw_iget_ptr(welletc , WELLETC_TYPE_INDEX));
ecl_rft_node_type * rft_node = ecl_rft_node_alloc_empty(ecl_kw_iget_ptr(welletc , WELLETC_TYPE_INDEX));
if (rft_node != NULL) {
ecl_kw_type * date_kw = ecl_file_iget_named_kw( rft , DATE_KW , 0);
ecl_kw_type * conjpos = ecl_file_iget_named_kw( rft , CONJPOS_KW , 0);
ecl_kw_type * conkpos = ecl_file_iget_named_kw( rft , CONKPOS_KW , 0);
ecl_kw_type * depth_kw;
if (rft_node->data_type == RFT)
depth_kw = ecl_file_iget_named_kw( rft , DEPTH_KW , 0);
else
depth_kw = ecl_file_iget_named_kw( rft , CONDEPTH_KW , 0);
rft_node->well_name = util_alloc_strip_copy( ecl_kw_iget_ptr(welletc , WELLETC_NAME_INDEX));
/* Time information. */
@ -203,73 +219,12 @@ ecl_rft_node_type * ecl_rft_node_alloc(const ecl_file_type * rft) {
rft_node->recording_date = util_make_date( time[DATE_DAY_INDEX] , time[DATE_MONTH_INDEX] , time[DATE_YEAR_INDEX] );
}
rft_node->days = ecl_kw_iget_float( ecl_file_iget_named_kw( rft , TIME_KW , 0 ) , 0);
if (ecl_file_has_kw( rft , CONLENST_KW))
rft_node->MSW = true;
else
rft_node->MSW = false;
/* Cell information */
{
const int * i = ecl_kw_get_int_ptr( conipos );
const int * j = ecl_kw_get_int_ptr( conjpos );
const int * k = ecl_kw_get_int_ptr( conkpos );
const float * depth = ecl_kw_get_float_ptr( depth_kw );
/* The ECLIPSE file has offset-1 coordinates, and that is
currently what we store; What a fxxxing mess. */
int c;
for (c = 0; c < rft_node->size; c++) {
rft_node->cells[c].i = i[c];
rft_node->cells[c].j = j[c];
rft_node->cells[c].k = k[c];
rft_node->cells[c].depth = depth[c];
}
}
/* Now we are done with the information which is common to both RFT and PLT. */
if (rft_node->data_type == RFT) {
const float * SW = ecl_kw_get_float_ptr( ecl_file_iget_named_kw( rft , SWAT_KW , 0));
const float * SG = ecl_kw_get_float_ptr( ecl_file_iget_named_kw( rft , SGAS_KW , 0));
const float * P = ecl_kw_get_float_ptr( ecl_file_iget_named_kw( rft , PRESSURE_KW , 0));
int c;
for (c = 0; c < rft_node->size; c++) {
rft_node->rft_data[c].swat = SW[c];
rft_node->rft_data[c].sgas = SG[c];
rft_node->cells[c].pressure = P[c];
}
} else if (rft_node->data_type == PLT) {
/* For PLT there is quite a lot of extra information which is not yet internalized. */
const float * WR = ecl_kw_get_float_ptr( ecl_file_iget_named_kw( rft , CONWRAT_KW , 0));
const float * GR = ecl_kw_get_float_ptr( ecl_file_iget_named_kw( rft , CONGRAT_KW , 0));
const float * OR = ecl_kw_get_float_ptr( ecl_file_iget_named_kw( rft , CONORAT_KW , 0));
const float * P = ecl_kw_get_float_ptr( ecl_file_iget_named_kw( rft , CONPRES_KW , 0));
int c;
for ( c = 0; c < rft_node->size; c++) {
rft_node->plt_data[c].orat = OR[c];
rft_node->plt_data[c].grat = GR[c];
rft_node->plt_data[c].wrat = WR[c];
rft_node->cells[c].pressure = P[c];
}
} else {
/* Segmnet code - not implemented. */
}
/*
Checking if the well is monotone in the z-direction; if it is we can
reasonably safely try some blocking.
*/
{
int i;
double first_delta = rft_node->cells[1].depth - rft_node->cells[0].depth;
rft_node->__vertical_well = true;
for (i = 1; i < (rft_node->size - 1); i++) {
double delta = rft_node->cells[i+1].depth - rft_node->cells[i].depth;
if (fabs(delta) > 0) {
if (first_delta * delta < 0)
rft_node->__vertical_well = false;
}
}
}
ecl_rft_node_init_cells( rft_node , rft );
}
return rft_node;
}
@ -281,11 +236,12 @@ const char * ecl_rft_node_get_well_name(const ecl_rft_node_type * rft_node) {
void ecl_rft_node_free(ecl_rft_node_type * rft_node) {
free(rft_node->well_name);
free(rft_node->cells);
util_safe_free(rft_node->segment_data);
util_safe_free(rft_node->rft_data);
util_safe_free(rft_node->plt_data);
vector_free( rft_node->cells );
if (rft_node->sort_perm)
int_vector_free( rft_node->sort_perm );
free(rft_node);
}
@ -295,247 +251,10 @@ void ecl_rft_node_free__(void * void_node) {
void ecl_rft_node_summarize(const ecl_rft_node_type * rft_node , bool print_cells) {
int i;
printf("--------------------------------------------------------------\n");
printf("Well.............: %s \n",rft_node->well_name);
printf("Completed cells..: %d \n",rft_node->size);
printf("Vertical well....: %d \n",rft_node->__vertical_well);
{
int day , month , year;
util_set_date_values(rft_node->recording_date , &day , &month , &year);
printf("Recording date...: %02d/%02d/%4d / %g days after simulation start.\n" , day , month , year , rft_node->days);
}
printf("-----------------------------------------\n");
if (print_cells) {
printf(" i j k Depth Pressure\n");
printf("-----------------------------------------\n");
for (i=0; i < rft_node->size; i++)
printf("%2d: %3d %3d %3d | %10.2f %10.2f \n",i,
rft_node->cells[i].i ,
rft_node->cells[i].j ,
rft_node->cells[i].k ,
rft_node->cells[i].depth,
rft_node->cells[i].pressure);
printf("-----------------------------------------\n");
}
}
/*
For this function to work the ECLIPSE keyword COMPORD must be used.
*/
void ecl_rft_node_block(const ecl_rft_node_type * rft_node , double epsilon , int size , const double * tvd , int * i, int * j , int *k) {
int rft_index , tvd_index;
int last_rft_index = 0;
bool * blocked = util_calloc(rft_node->size , sizeof * blocked);
if (!rft_node->__vertical_well) {
fprintf(stderr,"**************************************************************************\n");
fprintf(stderr,"** WARNING: Trying to block horizontal well: %s from only tvd, this **\n", ecl_rft_node_get_well_name(rft_node));
fprintf(stderr,"** is extremely error prone - blocking should be carefully checked. **\n");
fprintf(stderr,"**************************************************************************\n");
}
ecl_rft_node_summarize(rft_node , true);
for (tvd_index = 0; tvd_index < size; tvd_index++) {
double min_diff = 100000;
int min_diff_index = 0;
if (rft_node->__vertical_well) {
for (rft_index = last_rft_index; rft_index < rft_node->size; rft_index++) {
double diff = fabs(tvd[tvd_index] - rft_node->cells[rft_index].depth);
if (diff < min_diff) {
min_diff = diff;
min_diff_index = rft_index;
}
}
} else {
for (rft_index = last_rft_index; rft_index < (rft_node->size - 1); rft_index++) {
int next_rft_index = rft_index + 1;
if ((rft_node->cells[next_rft_index].depth - tvd[tvd_index]) * (tvd[tvd_index] - rft_node->cells[rft_index].depth) > 0) {
/*
We have bracketing ... !!
*/
min_diff_index = rft_index;
min_diff = 0;
printf("Bracketing: %g | %g | %g \n",rft_node->cells[next_rft_index].depth ,
tvd[tvd_index] , rft_node->cells[rft_index].depth);
break;
}
}
}
if (min_diff < epsilon) {
i[tvd_index] = rft_node->cells[min_diff_index].i;
j[tvd_index] = rft_node->cells[min_diff_index].j;
k[tvd_index] = rft_node->cells[min_diff_index].k;
blocked[min_diff_index] = true;
last_rft_index = min_diff_index;
} else {
i[tvd_index] = -1;
j[tvd_index] = -1;
k[tvd_index] = -1;
fprintf(stderr,"%s: Warning: True Vertical Depth:%g (Point:%d/%d) could not be mapped to well_path for well:%s \n",__func__ , tvd[tvd_index] , tvd_index+1 , size , rft_node->well_name);
}
}
free(blocked);
}
/*
Faen - dette er jeg egentlig *ikke* interessert i ....
*/
static double * ecl_rft_node_alloc_well_md(const ecl_rft_node_type * rft_node , int fixed_index , double md_offset) {
double * md = util_calloc(rft_node->size , sizeof * md );
return md;
}
void ecl_rft_node_block_static(const ecl_rft_node_type * rft_node , int rft_index_offset , int md_size , int md_index_offset , const double * md , int * i , int * j , int * k) {
const double md_offset = md[md_index_offset];
double *well_md = ecl_rft_node_alloc_well_md(rft_node , rft_index_offset , md_offset);
int index;
for (index = 0; index < md_size; index++) {
i[index] = -1;
j[index] = -1;
k[index] = -1;
}
i[md_index_offset] = rft_node->cells[rft_index_offset].i;
j[md_index_offset] = rft_node->cells[rft_index_offset].j;
k[md_index_offset] = rft_node->cells[rft_index_offset].k;
free(well_md);
}
void ecl_rft_node_block2(const ecl_rft_node_type * rft_node , int tvd_size , const double * md , const double * tvd , int * i, int * j , int *k) {
const double epsilon = 1.0;
int rft_index ;
ecl_rft_node_summarize(rft_node , true);
{
double min_diff = 100000;
int min_diff_index = 0;
int tvd_index = 0;
double local_tvd_peak = 99999999;
{
int index;
for (index = 1; index < (tvd_size - 1); index++)
if (tvd[index] < tvd[index+1] && tvd[index] < tvd[index-1])
local_tvd_peak = util_double_min(tvd[index] , local_tvd_peak);
}
while (min_diff > epsilon) {
for (rft_index = 0; rft_index < rft_node->size; rft_index++) {
double diff = fabs(tvd[tvd_index] - rft_node->cells[rft_index].depth);
if (diff < min_diff) {
min_diff = diff;
min_diff_index = rft_index;
}
}
if (min_diff > epsilon) {
tvd_index++;
if (tvd_index == tvd_size) {
fprintf(stderr,"%s: could not map tvd:%g to well-path depth - aborting \n",__func__ , tvd[tvd_index]);
abort();
}
if (tvd[tvd_index] > local_tvd_peak) {
fprintf(stderr,"%s: could not determine offset before well path becomes multivalued - aborting\n",__func__);
abort();
}
}
}
ecl_rft_node_block_static(rft_node , min_diff_index , tvd_size , tvd_index , md , i , j , k);
}
}
void ecl_rft_node_fprintf_rft_obs(const ecl_rft_node_type * rft_node , double epsilon , const char * tvd_file , const char * target_file , double p_std) {
FILE * input_stream = util_fopen(tvd_file , "r" );
int size = util_count_file_lines(input_stream);
double *p = util_calloc(size , sizeof * p );
double *tvd = util_calloc(size , sizeof * tvd );
double *md = util_calloc(size , sizeof * md );
int *i = util_calloc(size , sizeof * i);
int *j = util_calloc(size , sizeof * j);
int *k = util_calloc(size , sizeof * k);
{
double *arg1 , *arg2;
int line;
arg1 = p;
arg2 = tvd;
for (line = 0; line < size; line++)
if (fscanf(input_stream , "%lg %lg", &arg1[line] , &arg2[line]) != 2) {
fprintf(stderr,"%s: something wrong when reading: %s - aborting \n",__func__ , tvd_file);
abort();
}
}
fclose(input_stream);
ecl_rft_node_block(rft_node , epsilon , size , tvd , i , j , k);
{
int active_lines = 0;
int line;
for (line = 0; line < size; line++)
if (i[line] != -1)
active_lines++;
if (active_lines > 0) {
FILE * output_stream = util_fopen(target_file , "w" );
fprintf(output_stream,"%d\n" , active_lines);
for (line = 0; line < size; line++)
if (i[line] != -1)
fprintf(output_stream , "%3d %3d %3d %g %g\n",i[line] , j[line] , k[line] , p[line] , p_std);
fclose(output_stream);
} else
fprintf(stderr,"%s: Warning found no active cells when blocking well:%s to data_file:%s \n",__func__ , rft_node->well_name , tvd_file);
}
free(md);
free(p);
free(tvd);
free(i);
free(j);
free(k);
}
void ecl_rft_node_export_DEPTH(const ecl_rft_node_type * rft_node , const char * path) {
FILE * stream;
char * full;
char * filename = util_alloc_string_copy(ecl_rft_node_get_well_name(rft_node));
int i;
filename = util_strcat_realloc(filename , ".DEPTH");
full = util_alloc_filename(path , filename , NULL);
stream = fopen(full , "w");
for (i=0; i < rft_node->size; i++)
fprintf(stream , "%d %g \n",i , rft_node->cells[i].depth);
fclose(stream);
/*
free(full);
free(filename);
*/
}
int ecl_rft_node_get_size(const ecl_rft_node_type * rft_node) { return rft_node->size; }
int ecl_rft_node_get_size(const ecl_rft_node_type * rft_node) { return vector_get_size( rft_node->cells ); }
time_t ecl_rft_node_get_date(const ecl_rft_node_type * rft_node) { return rft_node->recording_date; }
ecl_rft_enum ecl_rft_node_get_type(const ecl_rft_node_type * rft_node) { return rft_node->data_type; }
@ -543,65 +262,87 @@ ecl_rft_enum ecl_rft_node_get_type(const ecl_rft_node_type * rft_node) { return
/*****************************************************************/
/* various functions to access properties at the cell level */
static cell_type * ecl_rft_node_iget_cell( const ecl_rft_node_type * rft_node , int index) {
if (index < rft_node->size)
return &rft_node->cells[index];
const ecl_rft_cell_type * ecl_rft_node_iget_cell( const ecl_rft_node_type * rft_node , int index) {
return vector_iget_const( rft_node->cells , index );
}
static void ecl_rft_node_create_sort_perm( ecl_rft_node_type * rft_node ) {
if (rft_node->sort_perm)
int_vector_free( rft_node->sort_perm );
rft_node->sort_perm = vector_alloc_sort_perm( rft_node->cells , ecl_rft_cell_cmp__ );
rft_node->sort_perm_in_sync = true;
}
void ecl_rft_node_inplace_sort_cells( ecl_rft_node_type * rft_node ) {
vector_sort( rft_node->cells , ecl_rft_cell_cmp__ );
rft_node->sort_perm_in_sync = false; // The permutation is no longer sorted; however the vector itself is sorted ....
}
const ecl_rft_cell_type * ecl_rft_node_iget_cell_sorted( ecl_rft_node_type * rft_node , int index) {
if (ecl_rft_node_is_RFT( rft_node ))
return ecl_rft_node_iget_cell( rft_node , index );
else {
util_abort("%s: asked for cell:%d max:%d \n",__func__ , index , rft_node->size - 1);
return NULL;
if (!rft_node->sort_perm_in_sync)
ecl_rft_node_create_sort_perm( rft_node );
return vector_iget_const( rft_node->cells , int_vector_iget( rft_node->sort_perm , index ));
}
}
double ecl_rft_node_iget_depth( const ecl_rft_node_type * rft_node , int index) {
const cell_type * cell = ecl_rft_node_iget_cell( rft_node , index );
return cell->depth;
const ecl_rft_cell_type * cell = ecl_rft_node_iget_cell( rft_node , index );
return ecl_rft_cell_get_depth( cell );
}
double ecl_rft_node_iget_pressure( const ecl_rft_node_type * rft_node , int index) {
const cell_type * cell = ecl_rft_node_iget_cell( rft_node , index );
return cell->pressure;
const ecl_rft_cell_type * cell = ecl_rft_node_iget_cell( rft_node , index );
return ecl_rft_cell_get_pressure( cell );
}
void ecl_rft_node_iget_ijk( const ecl_rft_node_type * rft_node , int index , int *i , int *j , int *k) {
const cell_type * cell = ecl_rft_node_iget_cell( rft_node , index );
*i = cell->i;
*j = cell->j;
*k = cell->k;
const ecl_rft_cell_type * cell = ecl_rft_node_iget_cell( rft_node , index );
ecl_rft_cell_get_ijk( cell , i,j,k);
}
int ecl_rft_node_lookup_ijk( const ecl_rft_node_type * rft_node , int i, int j , int k) {
const ecl_rft_cell_type * ecl_rft_node_lookup_ijk( const ecl_rft_node_type * rft_node , int i, int j , int k) {
int index = 0;
int size = ecl_rft_node_get_size( rft_node );
while (true) {
const cell_type * cell = ecl_rft_node_iget_cell( rft_node , index );
if ((cell->i == (i+1)) && (cell->j == (j+1)) && (cell->k == (k+1))) /* OK - found it. */
return index;
const ecl_rft_cell_type * cell = ecl_rft_node_iget_cell( rft_node , index );
if (ecl_rft_cell_ijk_equal( cell , i , j , k ))
return cell;
index++;
if (index == rft_node->size) /* Could not find it. */
return -1;
if (index == size) /* Could not find it. */
return NULL;
}
}
static void assert_type_and_index( const ecl_rft_node_type * rft_node , ecl_rft_enum target_type , int index) {
if (rft_node->data_type != target_type)
util_abort("%s: wrong type \n",__func__);
if ((index < 0) || (index >= rft_node->size))
if ((index < 0) || (index >= vector_get_size( rft_node->cells )))
util_abort("%s: invalid index:%d \n",__func__ , index);
}
double ecl_rft_node_iget_sgas( const ecl_rft_node_type * rft_node , int index) {
assert_type_and_index( rft_node , RFT , index );
{
const rft_data_type rft_data = rft_node->rft_data[ index ];
return rft_data.sgas;
const ecl_rft_cell_type * cell = vector_iget_const( rft_node->cells , index );
return ecl_rft_cell_get_sgas( cell );
}
}
@ -609,17 +350,28 @@ double ecl_rft_node_iget_sgas( const ecl_rft_node_type * rft_node , int index) {
double ecl_rft_node_iget_swat( const ecl_rft_node_type * rft_node , int index) {
assert_type_and_index( rft_node , RFT , index );
{
const rft_data_type rft_data = rft_node->rft_data[ index ];
return rft_data.swat;
const ecl_rft_cell_type * cell = vector_iget_const( rft_node->cells , index );
return ecl_rft_cell_get_swat( cell );
}
}
double ecl_rft_node_iget_soil( const ecl_rft_node_type * rft_node , int index) {
assert_type_and_index( rft_node , RFT , index );
{
const ecl_rft_cell_type * cell = vector_iget_const( rft_node->cells , index );
return ecl_rft_cell_get_soil( cell );
}
}
/*****************************************************************/
double ecl_rft_node_iget_orat( const ecl_rft_node_type * rft_node , int index) {
assert_type_and_index( rft_node , PLT , index );
{
const plt_data_type plt_data = rft_node->plt_data[ index ];
return plt_data.orat;
const ecl_rft_cell_type * cell = vector_iget_const( rft_node->cells , index );
return ecl_rft_cell_get_orat( cell );
}
}
@ -627,8 +379,8 @@ double ecl_rft_node_iget_orat( const ecl_rft_node_type * rft_node , int index) {
double ecl_rft_node_iget_wrat( const ecl_rft_node_type * rft_node , int index) {
assert_type_and_index( rft_node , PLT , index );
{
const plt_data_type plt_data = rft_node->plt_data[ index ];
return plt_data.wrat;
const ecl_rft_cell_type * cell = vector_iget_const( rft_node->cells , index);
return ecl_rft_cell_get_wrat( cell );
}
}
@ -636,8 +388,36 @@ double ecl_rft_node_iget_wrat( const ecl_rft_node_type * rft_node , int index) {
double ecl_rft_node_iget_grat( const ecl_rft_node_type * rft_node , int index) {
assert_type_and_index( rft_node , PLT , index );
{
const plt_data_type plt_data = rft_node->plt_data[ index ];
return plt_data.grat;
const ecl_rft_cell_type * cell = vector_iget_const( rft_node->cells , index);
return ecl_rft_cell_get_grat( cell );
}
}
bool ecl_rft_node_is_MSW( const ecl_rft_node_type * rft_node ) {
return rft_node->MSW;
}
bool ecl_rft_node_is_PLT( const ecl_rft_node_type * rft_node ) {
if (rft_node->data_type == PLT)
return true;
else
return false;
}
bool ecl_rft_node_is_SEGMENT( const ecl_rft_node_type * rft_node ) {
if (rft_node->data_type == SEGMENT)
return true;
else
return false;
}
bool ecl_rft_node_is_RFT( const ecl_rft_node_type * rft_node ) {
if (rft_node->data_type == RFT)
return true;
else
return false;
}

View File

@ -71,6 +71,7 @@ ecl_rsthead_type * ecl_rsthead_ialloc( const ecl_file_type * rst_file , int occu
rsthead->nisegz = data[INTEHEAD_NISEGZ_INDEX];
rsthead->nsegmx = data[INTEHEAD_NSEGMX_INDEX];
rsthead->nswlmx = data[INTEHEAD_NSWLMX_INDEX];
rsthead->nrsegz = data[INTEHEAD_NRSEGZ_INDEX];
// The only derived quantity
rsthead->sim_time = rsthead_date( rsthead->day , rsthead->month , rsthead->year );

View File

@ -333,6 +333,7 @@ void ecl_sum_free( ecl_sum_type * ecl_sum ) {
util_safe_free( ecl_sum->path );
util_safe_free( ecl_sum->ext );
util_safe_free( ecl_sum->abs_path );
free( ecl_sum->base );
free( ecl_sum->ecl_case );
@ -882,8 +883,6 @@ void ecl_sum_fmt_init_summary_x( ecl_sum_fmt_type * fmt ) {
#define DATE_STRING_LENGTH 128
static void __ecl_sum_fprintf_line( const ecl_sum_type * ecl_sum , FILE * stream , int internal_index , const bool_vector_type * has_var , const int_vector_type * var_index , char * date_string , const ecl_sum_fmt_type * fmt) {
int ivar , day,month,year;
util_set_date_values(ecl_sum_iget_sim_time(ecl_sum , internal_index ) , &day , &month, &year);
fprintf(stream , fmt->days_fmt , ecl_sum_iget_sim_days(ecl_sum , internal_index));
fprintf(stream , fmt->sep );
@ -895,10 +894,13 @@ static void __ecl_sum_fprintf_line( const ecl_sum_type * ecl_sum , FILE * stream
fprintf(stream , date_string );
}
for (ivar = 0; ivar < int_vector_size( var_index ); ivar++) {
if (bool_vector_iget( has_var , ivar )) {
fprintf(stream , fmt->sep);
fprintf(stream , fmt->value_fmt , ecl_sum_iget(ecl_sum , internal_index, int_vector_iget( var_index , ivar )));
{
int ivar;
for (ivar = 0; ivar < int_vector_size( var_index ); ivar++) {
if (bool_vector_iget( has_var , ivar )) {
fprintf(stream , fmt->sep);
fprintf(stream , fmt->value_fmt , ecl_sum_iget(ecl_sum , internal_index, int_vector_iget( var_index , ivar )));
}
}
}
@ -980,6 +982,7 @@ void ecl_sum_fprintf(const ecl_sum_type * ecl_sum , FILE * stream , const string
bool_vector_free( has_var );
if (current_locale != NULL)
setlocale( LC_NUMERIC , current_locale);
free( date_string );
}
#undef DATE_STRING_LENGTH
@ -1163,6 +1166,21 @@ char * ecl_sum_alloc_well_key( const ecl_sum_type * ecl_sum , const char * keywo
bool ecl_sum_is_oil_producer( const ecl_sum_type * ecl_sum , const char * well) {
const char * WOPT_KEY = "WOPT";
bool oil_producer = false;
if (ecl_sum_has_well_var( ecl_sum , well , WOPT_KEY)) {
int last_step = ecl_sum_get_data_length( ecl_sum ) - 1;
double wopt = ecl_sum_get_well_var( ecl_sum , last_step , well , WOPT_KEY);
if (wopt > 0)
oil_producer = true;
}
return oil_producer;
}

View File

@ -8,6 +8,20 @@ target_link_libraries( ecl_restart_test ecl )
add_test( ecl_restart_test ${EXECUTABLE_OUTPUT_PATH}/ecl_restart_test ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/Gurbat/ECLIPSE.UNRST )
add_executable( ecl_grid_lgr_name ecl_grid_lgr_name.c )
target_link_libraries( ecl_grid_lgr_name ecl )
set_target_properties( ecl_grid_lgr_name PROPERTIES COMPILE_FLAGS "-Werror")
add_test( ecl_grid_lgr_name ${EXECUTABLE_OUTPUT_PATH}/ecl_grid_lgr_name ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/10kcase/TEST10K_FLT_LGR_NNC.EGRID)
add_executable( ecl_region ecl_region.c )
target_link_libraries( ecl_region ecl )
add_test( ecl_region ${EXECUTABLE_OUTPUT_PATH}/ecl_region ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/Gurbat/ECLIPSE.EGRID )
add_executable( ecl_grid_case ecl_grid_case.c )
target_link_libraries( ecl_grid_case ecl )
add_test( ecl_grid_case ${EXECUTABLE_OUTPUT_PATH}/ecl_grid_case ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/Gurbat/ECLIPSE.EGRID ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/Gurbat/ECLIPSE )
add_executable( ecl_lgr_test ecl_lgr_test.c )
target_link_libraries( ecl_lgr_test ecl )
@ -75,20 +89,35 @@ target_link_libraries( ecl_rsthead ecl )
add_test( ecl_rsthead ${EXECUTABLE_OUTPUT_PATH}/ecl_rsthead ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/Gurbat/ECLIPSE.UNRST
${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/DualPoro/DUALPORO.X0005 )
set_property( TEST ecl_fmt PROPERTY LABELS Statoil )
set_property( TEST ecl_coarse_test PROPERTY LABELS Statoil )
set_property( TEST ecl_restart_test PROPERTY LABELS Statoil )
set_property( TEST ecl_lgr_test1 PROPERTY LABELS Statoil )
set_property( TEST ecl_lgr_test2 PROPERTY LABELS Statoil )
set_property( TEST ecl_lgr_test3 PROPERTY LABELS Statoil )
set_property( TEST ecl_grid_simple PROPERTY LABELS Statoil )
set_property( TEST ecl_dualp PROPERTY LABELS Statoil )
set_property( TEST ecl_sum_test PROPERTY LABELS Statoil )
set_property( TEST ecl_fortio PROPERTY LABELS Statoil)
set_property( TEST ecl_grid_dims1 PROPERTY LABELS Statoil )
set_property( TEST ecl_grid_dims2 PROPERTY LABELS Statoil )
set_property( TEST ecl_grid_dims3 PROPERTY LABELS Statoil )
set_property( TEST ecl_grid_dims4 PROPERTY LABELS Statoil )
set_property( TEST ecl_grid_dims5 PROPERTY LABELS Statoil )
set_property( TEST ecl_file PROPERTY LABELS Statoil)
set_property( TEST ecl_rsthead PROPERTY LABELS Statoil)
add_executable( ecl_rft ecl_rft.c )
target_link_libraries( ecl_rft ecl )
add_test( ecl_rft_rft ${EXECUTABLE_OUTPUT_PATH}/ecl_rft ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/Gurbat/ECLIPSE.RFT RFT)
add_test( ecl_rft_plt ${EXECUTABLE_OUTPUT_PATH}/ecl_rft ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/RFT/TEST1_1A.RFT PLT)
add_executable( ecl_rft_cell ecl_rft_cell.c )
target_link_libraries( ecl_rft_cell ecl )
add_test( ecl_rft_cell ${EXECUTABLE_OUTPUT_PATH}/ecl_rft_cell )
set_property( TEST ecl_fmt PROPERTY LABELS StatoilData )
set_property( TEST ecl_coarse_test PROPERTY LABELS StatoilData )
set_property( TEST ecl_restart_test PROPERTY LABELS StatoilData )
set_property( TEST ecl_lgr_test1 PROPERTY LABELS StatoilData )
set_property( TEST ecl_lgr_test2 PROPERTY LABELS StatoilData )
set_property( TEST ecl_lgr_test3 PROPERTY LABELS StatoilData )
set_property( TEST ecl_grid_lgr_name PROPERTY LABELS StatoilData )
set_property( TEST ecl_grid_simple PROPERTY LABELS StatoilData )
set_property( TEST ecl_dualp PROPERTY LABELS StatoilData )
set_property( TEST ecl_sum_test PROPERTY LABELS StatoilData )
set_property( TEST ecl_fortio PROPERTY LABELS StatoilData)
set_property( TEST ecl_grid_dims1 PROPERTY LABELS StatoilData )
set_property( TEST ecl_grid_dims2 PROPERTY LABELS StatoilData )
set_property( TEST ecl_grid_dims3 PROPERTY LABELS StatoilData )
set_property( TEST ecl_grid_dims4 PROPERTY LABELS StatoilData )
set_property( TEST ecl_grid_dims5 PROPERTY LABELS StatoilData )
set_property( TEST ecl_file PROPERTY LABELS StatoilData)
set_property( TEST ecl_rsthead PROPERTY LABELS StatoilData)
set_property( TEST ecl_region PROPERTY LABELS StatoilData)
set_property( TEST ecl_grid_case PROPERTY LABELS StatoilData)
set_property( TEST ecl_rft_rft PROPERTY LABELS StatoilData)
set_property( TEST ecl_rft_plt PROPERTY LABELS StatoilData)

View File

@ -0,0 +1,46 @@
/*
Copyright (C) 2013 Statoil ASA, Norway.
The file 'ecl_grid_case.c' is part of ERT - Ensemble based Reservoir Tool.
ERT 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.
ERT 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.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#include <stdlib.h>
#include <stdbool.h>
#include <ert/util/test_util.h>
#include <ert/ecl/ecl_grid.h>
void test_grid( const char * input , bool expected) {
ecl_grid_type * grid = ecl_grid_load_case( input );
if (expected) {
test_assert_true( ecl_grid_is_instance( grid ));
ecl_grid_free( grid );
} else
test_assert_NULL( grid );
}
int main(int argc , char ** argv) {
const char * grid_file = argv[1];
const char * case_path = argv[2];
test_grid( grid_file , true );
test_grid( case_path , true );
test_grid( "/tmp/does/not/exists/file.EGRID" , false );
test_grid( "/tmp/does/not/exists/CASE" , false );
exit(0);
}

View File

@ -0,0 +1,38 @@
/*
Copyright (C) 2013 Statoil ASA, Norway.
The file 'ecl_grid_lgr_name.c' is part of ERT - Ensemble based Reservoir Tool.
ERT 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.
ERT 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.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#include <stdlib.h>
#include <stdbool.h>
#include <ert/util/util.h>
#include <ert/util/test_util.h>
#include <ert/ecl/ecl_grid.h>
int main(int argc , char ** argv) {
const char * grid_file = argv[1];
ecl_grid_type * ecl_grid = ecl_grid_alloc( grid_file );
test_assert_int_equal( 1 , ecl_grid_get_num_lgr( ecl_grid ));
test_assert_string_equal( "LGR1" , ecl_grid_iget_lgr_name( ecl_grid , 0 ));
test_assert_string_equal( NULL , ecl_grid_iget_lgr_name( ecl_grid , 1 ));
ecl_grid_free( ecl_grid );
exit(0);
}

View File

@ -0,0 +1,70 @@
/*
Copyright (C) 2012 Statoil ASA, Norway.
The file 'ecl_region.c' is part of ERT - Ensemble based Reservoir Tool.
ERT 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.
ERT 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.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#include <stdlib.h>
#include <stdbool.h>
#include <ert/util/test_util.h>
#include <ert/ecl/ecl_grid.h>
#include <ert/ecl/ecl_region.h>
void test_list( int volume , int nactive , ecl_region_type * region ) {
const int_vector_type * active_list;
const int_vector_type * global_list;
active_list = ecl_region_get_active_list( region );
global_list = ecl_region_get_global_list( region );
test_assert_int_equal( nactive , int_vector_size( active_list ));
test_assert_int_equal( volume , int_vector_size( global_list ));
ecl_region_deselect_all( region );
active_list = ecl_region_get_active_list( region );
global_list = ecl_region_get_global_list( region );
test_assert_int_equal( 0 , int_vector_size( active_list ));
test_assert_int_equal( 0 , int_vector_size( global_list ));
}
void test_slice( const ecl_grid_type * grid ) {
int nx = ecl_grid_get_nx( grid );
int ny = ecl_grid_get_ny( grid );
int nz = ecl_grid_get_nz( grid );
int nactive = ecl_grid_get_nactive( grid );
ecl_region_type * region = ecl_region_alloc( grid , false );
ecl_region_select_i1i2( region , 0 , nx - 1);
test_list( nx*ny*nz , nactive , region );
ecl_region_select_j1j2( region , 0 , ny - 1);
test_list( nx*ny*nz , nactive , region );
ecl_region_select_k1k2( region , 0 , nz - 1);
test_list( nx*ny*nz , nactive , region );
ecl_region_free( region );
}
int main(int argc , char ** argv) {
const char * grid_file = argv[1];
ecl_grid_type * grid = ecl_grid_alloc( grid_file );
test_slice( grid );
ecl_grid_free( grid );
exit(0);
}

View File

@ -0,0 +1,131 @@
/*
Copyright (C) 2013 Statoil ASA, Norway.
The file 'ecl_rft.c' is part of ERT - Ensemble based Reservoir Tool.
ERT 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.
ERT 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.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#include <stdlib.h>
#include <stdbool.h>
#include <ert/util/test_util.h>
#include <ert/util/time_t_vector.h>
#include <ert/util/util.h>
#include <ert/ecl/ecl_rft_file.h>
// Hardcoded GURBAT values
void test_rft( const char * rft_file ) {
ecl_rft_file_type * rft = ecl_rft_file_alloc( rft_file );
ecl_rft_node_type * rft_node = ecl_rft_file_iget_node( rft , 0 );
test_assert_true( ecl_rft_node_is_RFT( rft_node ));
test_assert_int_equal( 14 , ecl_rft_node_get_size( rft_node ));
test_assert_false( ecl_rft_node_is_MSW( rft_node ));
test_assert_double_equal( 259.146 , ecl_rft_node_iget_pressure( rft_node , 0 ));
test_assert_double_equal( 0.0580598 , ecl_rft_node_iget_soil( rft_node , 0 ));
test_assert_double_equal( 0.940477 , ecl_rft_node_iget_swat( rft_node , 0 ));
test_assert_double_equal( 0.00146271 , ecl_rft_node_iget_sgas( rft_node , 0 ));
{
int i,j,k;
ecl_rft_node_iget_ijk( rft_node , 0 , &i , &j , &k );
test_assert_int_equal( 32 , i );
test_assert_int_equal( 53 , j );
test_assert_int_equal( 0 , k );
ecl_rft_node_iget_ijk( rft_node , 13 , &i , &j , &k );
test_assert_int_equal( 32 , i );
test_assert_int_equal( 54 , j );
test_assert_int_equal( 12 , k );
for (i=0; i < ecl_rft_node_get_size( rft_node ); i++) {
const ecl_rft_cell_type * cell1 = ecl_rft_node_iget_cell( rft_node , i );
const ecl_rft_cell_type * cell2 = ecl_rft_node_iget_cell_sorted( rft_node , i );
test_assert_ptr_equal( cell1 , cell2 );
}
}
ecl_rft_node_inplace_sort_cells( rft_node );
ecl_rft_file_free( rft );
}
// Have no such case yet ...
void test_plt_msw( const char * plt_file ) {
}
// Hardcoded values from a test case with a PLT.
void test_plt( const char * plt_file ) {
ecl_rft_file_type * plt = ecl_rft_file_alloc( plt_file );
ecl_rft_node_type * plt_node = ecl_rft_file_iget_node( plt , 11 );
test_assert_true( ecl_rft_node_is_PLT( plt_node ));
test_assert_false( ecl_rft_node_is_MSW( plt_node ));
test_assert_int_equal( 22 , ecl_rft_node_get_size( plt_node ));
test_assert_double_equal( 244.284 , ecl_rft_node_iget_pressure( plt_node , 0 ));
test_assert_double_equal( 167.473 , ecl_rft_node_iget_orat( plt_node , 0 ));
test_assert_double_equal( 41682.2 , ecl_rft_node_iget_grat( plt_node , 0 ));
test_assert_double_equal( 0.958927 , ecl_rft_node_iget_wrat( plt_node , 0 ));
{
int i,j,k;
ecl_rft_node_iget_ijk( plt_node , 0 , &i , &j , &k );
test_assert_int_equal( 39 , i );
test_assert_int_equal( 33 , j );
test_assert_int_equal( 16 , k );
ecl_rft_node_iget_ijk( plt_node , 21 , &i , &j , &k );
test_assert_int_equal( 44 , i );
test_assert_int_equal( 34 , j );
test_assert_int_equal( 7 , k );
for (i=0; i < ecl_rft_node_get_size( plt_node ); i++) {
const ecl_rft_cell_type * cell1 = ecl_rft_node_iget_cell( plt_node , i );
const ecl_rft_cell_type * cell2 = ecl_rft_node_iget_cell_sorted( plt_node , i );
test_assert_ptr_equal( cell1 , cell2 );
}
ecl_rft_node_inplace_sort_cells( plt_node );
}
ecl_rft_file_free( plt );
}
int main( int argc , char ** argv) {
const char * rft_file = argv[1];
const char * mode_string = argv[2];
if (strcmp( mode_string , "RFT") == 0)
test_rft( rft_file );
else if (strcmp( mode_string , "PLT") == 0)
test_plt( rft_file );
else if (strcmp( mode_string , "MSW-PLT") == 0)
test_plt_msw( rft_file );
else
test_error_exit("Second argument:%s not recognized. Valid values are: RFT and PLT" , mode_string);
exit(0);
}

View File

@ -0,0 +1,147 @@
/*
Copyright (C) 2013 Statoil ASA, Norway.
The file 'ecl_rft_cell.c' is part of ERT - Ensemble based Reservoir Tool.
ERT 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.
ERT 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.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#include <stdlib.h>
#include <stdbool.h>
#include <ert/util/test_util.h>
#include <ert/util/time_t_vector.h>
#include <ert/util/util.h>
#include <ert/ecl/ecl_rft_node.h>
#include <ert/ecl/ecl_rft_cell.h>
void test_rft_cell() {
const int i = 10;
const int j = 11;
const int k = 12;
const double depth = 100;
const double pressure = 200;
const double swat = 0.25;
const double sgas = 0.35;
ecl_rft_cell_type * cell = ecl_rft_cell_alloc_RFT(i,j,k,depth,pressure,swat,sgas);
test_assert_int_equal( i , ecl_rft_cell_get_i( cell ));
test_assert_int_equal( j , ecl_rft_cell_get_j( cell ));
test_assert_int_equal( k , ecl_rft_cell_get_k( cell ));
{
int ii,jj,kk;
ecl_rft_cell_get_ijk( cell , &ii , &jj , &kk);
test_assert_int_equal( i , ii);
test_assert_int_equal( j , jj);
test_assert_int_equal( k , kk);
}
test_assert_double_equal( depth , ecl_rft_cell_get_depth( cell ));
test_assert_double_equal( pressure , ecl_rft_cell_get_pressure( cell ));
test_assert_double_equal( swat , ecl_rft_cell_get_swat( cell ));
test_assert_double_equal( sgas , ecl_rft_cell_get_sgas( cell ));
test_assert_double_equal( 1 - (swat + sgas) , ecl_rft_cell_get_soil( cell ));
test_assert_double_equal( ECL_RFT_CELL_INVALID_VALUE , ecl_rft_cell_get_orat( cell ));
test_assert_double_equal( ECL_RFT_CELL_INVALID_VALUE , ecl_rft_cell_get_grat( cell ));
test_assert_double_equal( ECL_RFT_CELL_INVALID_VALUE , ecl_rft_cell_get_wrat( cell ));
test_assert_double_equal( ECL_RFT_CELL_INVALID_VALUE , ecl_rft_cell_get_flowrate( cell ));
test_assert_double_equal( ECL_RFT_CELL_INVALID_VALUE , ecl_rft_cell_get_connection_start( cell ));
test_assert_double_equal( ECL_RFT_CELL_INVALID_VALUE , ecl_rft_cell_get_oil_flowrate( cell ));
test_assert_double_equal( ECL_RFT_CELL_INVALID_VALUE , ecl_rft_cell_get_gas_flowrate( cell ));
test_assert_double_equal( ECL_RFT_CELL_INVALID_VALUE , ecl_rft_cell_get_water_flowrate( cell ));
ecl_rft_cell_free( cell );
{
ecl_rft_cell_type * cell = ecl_rft_cell_alloc_RFT(i,j,k,depth,pressure,swat,sgas);
test_assert_true( ecl_rft_cell_ijk_equal( cell , i , j , k ));
test_assert_false( ecl_rft_cell_ijk_equal( cell , i , j , k + 1 ));
ecl_rft_cell_free__( cell );
}
}
void test_plt_cell() {
const int i = 10;
const int j = 11;
const int k = 12;
const double depth = 100;
const double pressure = 200;
const double orat = 0.25;
const double grat = 0.35;
const double wrat = 0.45;
const double flowrate = 100.0;
const double connection_start = 891;
const double oil_flowrate = 0.891;
const double gas_flowrate = 7771;
const double water_flowrate = 77614;
ecl_rft_cell_type * cell = ecl_rft_cell_alloc_PLT(i,j,k,depth,pressure,orat,grat,wrat,connection_start,flowrate,oil_flowrate , gas_flowrate , water_flowrate);
test_assert_int_equal( i , ecl_rft_cell_get_i( cell ));
test_assert_int_equal( j , ecl_rft_cell_get_j( cell ));
test_assert_int_equal( k , ecl_rft_cell_get_k( cell ));
{
int ii,jj,kk;
ecl_rft_cell_get_ijk( cell , &ii , &jj , &kk);
test_assert_int_equal( i , ii);
test_assert_int_equal( j , jj);
test_assert_int_equal( k , kk);
}
test_assert_double_equal( depth , ecl_rft_cell_get_depth( cell ));
test_assert_double_equal( pressure , ecl_rft_cell_get_pressure( cell ));
test_assert_double_equal( orat , ecl_rft_cell_get_orat( cell ));
test_assert_double_equal( grat , ecl_rft_cell_get_grat( cell ));
test_assert_double_equal( wrat , ecl_rft_cell_get_wrat( cell ));
test_assert_double_equal( connection_start, ecl_rft_cell_get_connection_start( cell ));
test_assert_double_equal(flowrate , ecl_rft_cell_get_flowrate( cell ));
test_assert_double_equal(oil_flowrate , ecl_rft_cell_get_oil_flowrate( cell ));
test_assert_double_equal(gas_flowrate , ecl_rft_cell_get_gas_flowrate( cell ));
test_assert_double_equal(water_flowrate , ecl_rft_cell_get_water_flowrate( cell ));
test_assert_double_equal( ECL_RFT_CELL_INVALID_VALUE , ecl_rft_cell_get_swat( cell ));
test_assert_double_equal( ECL_RFT_CELL_INVALID_VALUE , ecl_rft_cell_get_sgas( cell ));
test_assert_double_equal( ECL_RFT_CELL_INVALID_VALUE , ecl_rft_cell_get_soil( cell ));
ecl_rft_cell_free( cell );
}
int main( int argc , char ** argv) {
test_rft_cell();
test_plt_cell();
exit(0);
}

View File

@ -51,6 +51,12 @@ void test_days( const ecl_sum_type * ecl_sum ) {
}
void test_is_oil_producer( const ecl_sum_type * ecl_sum) {
test_assert_true( ecl_sum_is_oil_producer( ecl_sum , "OP_1"));
test_assert_false( ecl_sum_is_oil_producer( ecl_sum , "WI_1"));
test_assert_false( ecl_sum_is_oil_producer( ecl_sum , "DoesNotExist"));
}
@ -61,6 +67,7 @@ int main( int argc , char ** argv) {
test_time_range( ecl_sum );
test_days( ecl_sum );
test_is_oil_producer(ecl_sum);
exit(0);
}

View File

@ -1,5 +1,5 @@
add_subdirectory( src )
if (BUILD_APPLICATONS)
if (BUILD_APPLICATIONS)
add_subdirectory( applications )
endif()

View File

@ -1,6 +1,7 @@
add_executable( well_info_test well_info_test.c )
add_executable( segment_info segment_info.c )
set(program_list well_info_test )
set(program_list well_info_test segment_info )
foreach(prog ${program_list})
target_link_libraries( ${prog} ecl_well ecl)

View File

@ -0,0 +1,107 @@
/*
Copyright (C) 2013 Statoil ASA, Norway.
The file 'segment_info.c' is part of ERT - Ensemble based Reservoir Tool.
ERT 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.
ERT 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.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#include <stdlib.h>
#include <stdbool.h>
#include <unistd.h>
#include <math.h>
#include <ert/util/stringlist.h>
#include <ert/util/util.h>
#include <ert/util/test_util.h>
#include <ert/ecl/ecl_util.h>
#include <ert/ecl/ecl_file.h>
#include <ert/ecl/ecl_rsthead.h>
#include <ert/ecl/ecl_kw_magic.h>
#include <ert/ecl/ecl_grid.h>
#include <ert/ecl_well/well_conn_collection.h>
#include <ert/ecl_well/well_segment.h>
#include <ert/ecl_well/well_const.h>
#include <ert/ecl_well/well_segment_collection.h>
int main(int argc , char ** argv) {
const char * Xfile = argv[1];
ecl_file_type * rst_file = ecl_file_open( Xfile , 0 );
ecl_rsthead_type * rst_head = ecl_rsthead_alloc( rst_file );
const ecl_kw_type * iwel_kw = ecl_file_iget_named_kw( rst_file , IWEL_KW , 0 );
const ecl_kw_type * iseg_kw = ecl_file_iget_named_kw( rst_file , ISEG_KW , 0 );
const ecl_kw_type * rseg_kw = ecl_file_iget_named_kw( rst_file , RSEG_KW , 0 );
const ecl_kw_type * icon_kw = ecl_file_iget_named_kw( rst_file , ICON_KW , 0 );
const ecl_kw_type * zwel_kw = ecl_file_iget_named_kw( rst_file , ZWEL_KW , 0 );
test_install_SIGNALS();
{
int well_nr;
for (well_nr = 0; well_nr < rst_head->nwells; well_nr++) {
const int zwel_offset = rst_head->nzwelz * well_nr;
char * well_name = util_alloc_strip_copy(ecl_kw_iget_ptr( zwel_kw , zwel_offset ));
printf("=================================================================\n");
printf("Well: %s ",well_name);
{
well_conn_collection_type * connections = well_conn_collection_alloc();
well_segment_collection_type * segments = well_segment_collection_alloc();
if (well_segment_collection_load_from_kw( segments , well_nr , iwel_kw , iseg_kw , rseg_kw , rst_head )) {
well_branch_collection_type * branches = well_branch_collection_alloc();
well_conn_collection_load_from_kw( connections , iwel_kw , icon_kw , well_nr , rst_head);
well_segment_collection_link( segments );
well_segment_collection_add_branches( segments , branches );
well_segment_collection_add_connections( segments , ECL_GRID_GLOBAL_GRID , connections );
printf("\n");
printf("Segments:\n");
{
int is;
for (is=0; is < well_segment_collection_get_size( segments ); is++) {
well_segment_type * segment = well_segment_collection_iget( segments , is );
printf("-----------------------------------------------------------------\n");
printf("ID : %d \n",well_segment_get_id( segment ));
printf("Outlet : %d \n",well_segment_get_outlet_id( segment ));
printf("Branch : %d \n",well_segment_get_branch_id( segment ));
printf("Connections : [");
{
well_conn_collection_type * connections = well_segment_get_global_connections( segment );
if (connections) {
int ic;
for (ic = 0; ic < well_conn_collection_get_size( connections ); ic++) {
const well_conn_type * conn = well_conn_collection_iget( connections , ic );
printf("(%d , %d , %d) ",well_conn_get_i( conn ), well_conn_get_j( conn ), well_conn_get_k( conn ));
}
}
}
printf("]\n");
}
}
well_branch_collection_free( branches );
} else
printf("not MSW well\n\n");
well_conn_collection_free( connections );
well_segment_collection_free( segments );
}
}
}
ecl_file_close( rst_file );
ecl_rsthead_free( rst_head );
}

View File

@ -1,42 +0,0 @@
/*
Copyright (C) 2012 Statoil ASA, Norway.
The file 'well_branch.h' is part of ERT - Ensemble based Reservoir Tool.
ERT 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.
ERT 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.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#ifndef __WELL_BRANCH_H__
#define __WELL_BRANCH_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <ert/ecl_well/well_conn.h>
typedef struct well_branch_struct well_branch_type;
well_branch_type * well_branch_alloc(int branch_nr);
void well_branch_free( well_branch_type * branch );
void well_branch_add_conn( well_branch_type * branch , well_conn_type * connection );
int well_branch_get_length( const well_branch_type * branch );
const well_conn_type ** well_branch_get_connections( const well_branch_type * branch );
int well_branch_get_nr( const well_branch_type * branch );
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,50 @@
/*
Copyright (C) 2013 Statoil ASA, Norway.
The file 'well_branch_collection.h' is part of ERT - Ensemble based Reservoir Tool.
ERT 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.
ERT 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.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#ifndef __WELL_BRANCH_COLLECTION_H__
#define __WELL_BRANCH_COLLECTION_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <stdbool.h>
#include <ert/util/type_macros.h>
#include <ert/ecl_well/well_segment.h>
typedef struct well_branch_collection_struct well_branch_collection_type;
well_branch_collection_type * well_branch_collection_alloc();
void well_branch_collection_free( well_branch_collection_type * branches );
void well_branch_collection_free__( void * arg );
bool well_branch_collection_has_branch( const well_branch_collection_type * branches , int branch_id);
int well_branch_collection_get_size( const well_branch_collection_type * branches );
const well_segment_type * well_branch_collection_iget_start_segment( const well_branch_collection_type * branches , int index );
const well_segment_type * well_branch_collection_get_start_segment( const well_branch_collection_type * branches , int branch_id);
bool well_branch_collection_add_start_segment( well_branch_collection_type * branches , const well_segment_type * start_segment);
UTIL_IS_INSTANCE_HEADER( well_branch_collection );
#ifdef __cplusplus
}
#endif
#endif

View File

@ -27,6 +27,8 @@ extern "C" {
#include <stdbool.h>
#include <ert/util/type_macros.h>
#include <ert/ecl/ecl_rsthead.h>
typedef enum {
@ -43,10 +45,17 @@ extern "C" {
void well_conn_free( well_conn_type * conn);
void well_conn_free__( void * arg );
well_conn_type * well_conn_alloc( const ecl_kw_type * icon_kw , const ecl_kw_type * iseg_kw , const ecl_rsthead_type * header , int well_nr , int seg_well_nr , int conn_nr);
well_conn_type * well_conn_alloc( int i , int j , int k , well_conn_dir_enum dir, bool open);
well_conn_type * well_conn_alloc_MSW( int i , int j , int k , well_conn_dir_enum dir, bool open, int segment);
well_conn_type * well_conn_alloc_fracture( int i , int j , int k , well_conn_dir_enum dir, bool open);
well_conn_type * well_conn_alloc_fracture_MSW( int i , int j , int k , well_conn_dir_enum dir, bool open, int segment);
bool well_conn_MSW(const well_conn_type * conn);
well_conn_type * well_conn_alloc_from_kw( const ecl_kw_type * icon_kw , const ecl_rsthead_type * header , int well_nr , int conn_nr);
well_conn_type * well_conn_alloc_wellhead( const ecl_kw_type * iwel_kw , const ecl_rsthead_type * header , int well_nr);
int well_conn_get_branch(const well_conn_type * conn);
int well_conn_get_i(const well_conn_type * conn);
int well_conn_get_j(const well_conn_type * conn);
int well_conn_get_k(const well_conn_type * conn);
@ -55,6 +64,11 @@ extern "C" {
int well_conn_get_segment( const well_conn_type * conn );
bool well_conn_fracture_connection( const well_conn_type * conn);
bool well_conn_matrix_connection( const well_conn_type * conn);
bool well_conn_equal( const well_conn_type *conn1 , const well_conn_type * conn2);
UTIL_IS_INSTANCE_HEADER( well_conn );
UTIL_SAFE_CAST_HEADER( well_conn );
#ifdef __cplusplus
}

View File

@ -0,0 +1,51 @@
/*
Copyright (C) 2013 Statoil ASA, Norway.
The file 'well_conn_collection.h' is part of ERT - Ensemble based Reservoir Tool.
ERT 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.
ERT 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.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#ifndef __WELL_CONN_COLLECTION_H__
#define __WELL_CONN_COLLECTION_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <ert/util/type_macros.h>
#include <ert/ecl/ecl_kw.h>
#include <ert/ecl_well/well_conn.h>
typedef struct well_conn_collection_struct well_conn_collection_type;
well_conn_collection_type * well_conn_collection_alloc();
void well_conn_collection_free( well_conn_collection_type * wellcc );
void well_conn_collection_free__( void * arg );
int well_conn_collection_get_size( const well_conn_collection_type * wellcc );
const well_conn_type * well_conn_collection_iget_const( const well_conn_collection_type * wellcc , int index);
well_conn_type * well_conn_collection_iget(const well_conn_collection_type * wellcc , int index);
void well_conn_collection_add( well_conn_collection_type * wellcc , well_conn_type * conn);
void well_conn_collection_add_ref( well_conn_collection_type * wellcc , well_conn_type * conn);
int well_conn_collection_load_from_kw( well_conn_collection_type * wellcc , const ecl_kw_type * iwel_kw , const ecl_kw_type * icon_kw , int iwell , const ecl_rsthead_type * rst_head);
UTIL_IS_INSTANCE_HEADER( well_conn_collection );
#ifdef __cplusplus
}
#endif
#endif

View File

@ -39,6 +39,8 @@ extern "C" {
#define IWEL_LGR_ITEM 42
#define IWEL_SEGMENTED_WELL_NR_ITEM 70
#define IWEL_SEGMENTED_WELL_NR_NORMAL_VALUE -1
#define ISEG_OUTLET_ITEM 1
#define ISEG_BRANCH_ITEM 3
@ -59,6 +61,11 @@ extern "C" {
#define ICON_DEFAULT_DIR_TARGET ICON_DIRZ
#define RSEG_LENGTH_INDEX 0
#define RSEG_DIAMETER_INDEX 2
#define RSEG_TOTAL_LENGTH_INDEX 6
#define RSEG_DEPTH_INDEX 7
/*
The ECLIPSE documentation says that a certain item in the IWEL array
should indicate the type of the well, the available types are the

View File

@ -1,48 +0,0 @@
/*
Copyright (C) 2012 Statoil ASA, Norway.
The file 'well_path.h' is part of ERT - Ensemble based Reservoir Tool.
ERT 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.
ERT 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.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#ifndef __WELL_PATH_H__
#define __WELL_PATH_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <stdbool.h>
#include <ert/ecl_well/well_conn.h>
#include <ert/ecl_well/well_branch.h>
typedef struct well_path_struct well_path_type;
well_path_type * well_path_alloc(const char * grid_name );
void well_path_free( well_path_type * path );
void well_path_add_conn( well_path_type * well_path , well_conn_type * conn);
well_branch_type * well_path_iget_branch( const well_path_type * well_path , int branch_nr);
void well_path_free__(void * arg);
int well_path_get_max_branches( const well_path_type * well_path );
int well_path_get_num_active_branches( const well_path_type * well_path );
const char * well_path_get_grid_name( const well_path_type * well_path );
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,79 @@
/*
Copyright (C) 2013 Statoil ASA, Norway.
The file 'well_segment.h' is part of ERT - Ensemble based Reservoir Tool.
ERT 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.
ERT 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.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#ifndef __WELL_SEGMENT_H__
#define __WELL_SEGMENT_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <stdbool.h>
#include <ert/ecl/ecl_kw.h>
#include <ert/ecl/ecl_rsthead.h>
#include <ert/ecl_well/well_conn_collection.h>
#include <ert/ecl_well/well_conn.h>
/* The values are shifted one down compared to ISEG description in table 6.1 in ECLIPSE file formats reference. */
#define ECLIPSE_WELL_SEGMENT_OUTLET_END_VALUE -1
#define ECLIPSE_WELL_SEGMENT_BRANCH_MAIN_STEM_VALUE 0
#define ECLIPSE_WELL_SEGMENT_BRANCH_INACTIVE_VALUE -1
typedef struct well_segment_struct well_segment_type;
well_segment_type * well_segment_alloc_from_kw( const ecl_kw_type * iseg_kw , const ecl_kw_type * rseg_kw , const ecl_rsthead_type * header , int well_nr, int segment_id);
well_segment_type * well_segment_alloc(int segment_id , int outlet_segment_id , int branch_id , const double * rseg_data);
void well_segment_free(well_segment_type * segment );
void well_segment_free__(void * arg);
bool well_segment_active( const well_segment_type * segment );
bool well_segment_main_stem( const well_segment_type * segment );
bool well_segment_nearest_wellhead( const well_segment_type * segment );
int well_segment_get_link_count( const well_segment_type * segment );
int well_segment_get_branch_id( const well_segment_type * segment );
int well_segment_get_outlet_id( const well_segment_type * segment );
int well_segment_get_id( const well_segment_type * segment );
well_segment_type * well_segment_get_outlet( const well_segment_type * segment );
bool well_segment_link( well_segment_type * segment , well_segment_type * outlet_segment );
void well_segment_link_strict( well_segment_type * segment , well_segment_type * outlet_segment );
bool well_segment_has_grid_connections( const well_segment_type * segment , const char * grid_name);
bool well_segment_has_global_grid_connections( const well_segment_type * segment);
bool well_segment_add_connection( well_segment_type * segment , const char * grid_name , well_conn_type * conn);
const well_conn_collection_type * well_segment_get_connections(const well_segment_type * segment , const char * grid_name );
const well_conn_collection_type * well_segment_get_global_connections(const well_segment_type * segment );
bool well_segment_well_is_MSW(int well_nr , const ecl_kw_type * iwel_kw , const ecl_rsthead_type * rst_head);
double well_segment_get_depth( const well_segment_type * segment );
double well_segment_get_length( const well_segment_type * segment );
double well_segment_get_total_length( const well_segment_type * segment );
double well_segment_get_diameter( const well_segment_type * segment );
UTIL_IS_INSTANCE_HEADER( well_segment );
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,60 @@
/*
Copyright (C) 2013 Statoil ASA, Norway.
The file 'well_segment_collection.h' is part of ERT - Ensemble based Reservoir Tool.
ERT 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.
ERT 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.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#ifndef __WELL_SEGMENT_COLLECTION_H__
#define __WELL_SEGMENT_COLLECTION_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <stdbool.h>
#include <ert/ecl/ecl_kw.h>
#include <ert/ecl_well/well_segment.h>
#include <ert/ecl_well/well_conn_collection.h>
#include <ert/ecl_well/well_branch_collection.h>
typedef struct well_segment_collection_struct well_segment_collection_type;
well_segment_collection_type * well_segment_collection_alloc();
void well_segment_collection_free(well_segment_collection_type * segment_collection );
int well_segment_collection_get_size( const well_segment_collection_type * segment_collection );
void well_segment_collection_add( well_segment_collection_type * segment_collection , well_segment_type * segment);
bool well_segment_collection_has_segment( const well_segment_collection_type * segment_collection , int segment_id);
well_segment_type * well_segment_collection_get( const well_segment_collection_type * segment_collection , int segment_id);
well_segment_type * well_segment_collection_iget( const well_segment_collection_type * segment_collection , int index);
int well_segment_collection_load_from_kw( well_segment_collection_type * segment_collection , int well_nr ,
const ecl_kw_type * iwel_kw ,
const ecl_kw_type * iseg_kw ,
const ecl_kw_type * rseg_kw ,
const ecl_rsthead_type * rst_head);
void well_segment_collection_link(const well_segment_collection_type * segment_collection);
void well_segment_collection_add_connections(well_segment_collection_type * segment_collection ,
const char * grid_name ,
const well_conn_collection_type * connections);
void well_segment_collection_add_branches( const well_segment_collection_type * segment_collection ,
well_branch_collection_type * branches );
#ifdef __cplusplus
}
#endif
#endif

View File

@ -27,16 +27,37 @@ extern "C" {
#include <time.h>
#include <ert/ecl/ecl_file.h>
#include <ert/ecl/ecl_grid.h>
#include <ert/ecl_well/well_conn.h>
#include <ert/ecl_well/well_const.h>
#include <ert/ecl_well/well_conn_collection.h>
#include <ert/ecl_well/well_segment_collection.h>
#include <ert/ecl_well/well_branch_collection.h>
#define GLOBAL_GRID_NAME "GLOBAL" // The name assigned to the global grid for name based lookup.
typedef struct well_state_struct well_state_type;
well_state_type * well_state_alloc( ecl_file_type * ecl_file , int report_step , int well_nr);
well_state_type * well_state_alloc(const char * well_name , int global_well_nr , bool open, well_type_enum type , int report_nr, time_t valid_from);
well_state_type * well_state_alloc_from_file( ecl_file_type * ecl_file , const ecl_grid_type * grid , int report_step , int well_nr);
void well_state_add_connections( well_state_type * well_state ,
const ecl_grid_type * grid ,
ecl_file_type * rst_file ,
int well_nr);
bool well_state_add_MSW( well_state_type * well_state ,
const ecl_file_type * rst_file ,
int well_nr);
bool well_state_is_MSW( const well_state_type * well_state);
well_segment_collection_type * well_state_get_segments( const well_state_type * well_state );
well_branch_collection_type * well_state_get_branches( const well_state_type * well_state );
void well_state_free( well_state_type * well );
const char * well_state_get_name( const well_state_type * well );
int well_state_get_report_nr( const well_state_type * well_state );
@ -44,24 +65,18 @@ extern "C" {
well_conn_type * well_state_iget_connection( const well_state_type * well_state , int index);
well_type_enum well_state_get_type( const well_state_type * well_state);
bool well_state_is_open( const well_state_type * well_state );
int well_state_get_well_nr( const well_state_type * well_state );
const well_conn_type * well_state_iget_wellhead( const well_state_type * well_state , int grid_nr);
const well_conn_type * well_state_get_wellhead( const well_state_type * well_state , const char * grid_name);
const well_conn_type ** well_state_iget_lgr_connections(const well_state_type * well_state , int grid_nr , int branch_nr );
const well_conn_type ** well_state_get_lgr_connections(const well_state_type * well_state , const char * lgr_name , int branch_nr);
const well_conn_type ** well_state_get_connections(const well_state_type * well_state , int branch_nr );
int well_state_iget_num_lgr_connections(const well_state_type * well_state , int grid_nr , int branch_nr );
int well_state_get_num_lgr_connections(const well_state_type * well_state , const char * lgr_name , int branch_nr);
int well_state_get_num_connections(const well_state_type * well_state , int branch_nr );
int well_state_iget_lgr_num_branches( const well_state_type * well_state , int grid_nr);
int well_state_get_lgr_num_branches( const well_state_type * well_state , const char * lgr_name);
int well_state_get_num_branches(const well_state_type * well_state );
void well_state_summarize( const well_state_type * well_state , FILE * stream );
well_type_enum well_state_translate_ecl_type_int(int int_type);
const well_conn_collection_type * well_state_get_grid_connections( const well_state_type * well_state , const char * grid_name);
const well_conn_collection_type * well_state_get_global_connections( const well_state_type * well_state );
bool well_state_has_grid_connections( const well_state_type * well_state , const char * grid_name);
bool well_state_has_global_connections( const well_state_type * well_state );
UTIL_IS_INSTANCE_HEADER( well_state );

View File

@ -1,5 +1,10 @@
set( source_files well_state.c well_conn.c well_info.c well_ts.c well_branch.c well_path.c )
set( header_files well_state.h well_const.h well_conn.h well_info.h well_ts.h well_branch.h well_path.h )
set( source_files well_state.c well_conn.c well_info.c well_ts.c well_conn_collection.c well_segment.c well_segment_collection.c well_branch_collection.c)
set( header_files well_state.h well_const.h well_conn.h well_info.h well_ts.h well_conn_collection.h well_segment.h well_segment_collection.h well_branch_collection.h)
if (NOT ERT_WINDOWS)
set_property( SOURCE well_branch_collection.c well_segment.c well_segment_collection.c well_conn_collection.c well_conn.c PROPERTY COMPILE_FLAGS "-Werror")
endif()
include_directories( ${CMAKE_CURRENT_SOURCE_DIR} )
include_directories( ${libgeometry_src_path} )

View File

@ -1,103 +0,0 @@
/*
Copyright (C) 2012 Statoil ASA, Norway.
The file 'well_branch.c' is part of ERT - Ensemble based Reservoir Tool.
ERT 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.
ERT 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.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#include <stdlib.h>
#include <ert/util/util.h>
#include <ert/ecl_well/well_branch.h>
#include <ert/ecl_well/well_const.h>
#include <ert/ecl_well/well_conn.h>
/*
See also documentation on the top of well_path.c for how a path and
a branch are related.
*/
struct well_branch_struct {
int branch_nr;
well_conn_type ** connections;
int size;
int alloc_size;
};
static void well_branch_resize( well_branch_type * branch , int new_size) {
if (new_size < branch->alloc_size)
util_abort("%s: sorry - can only grow \n",__func__);
branch->connections = util_realloc( branch->connections , new_size * sizeof * branch->connections );
{
int i;
for (i=branch->alloc_size; i < new_size; i++)
branch->connections[i] = NULL;
}
branch->alloc_size = new_size;
}
well_branch_type * well_branch_alloc(int branch_nr) {
well_branch_type * branch = util_malloc( sizeof * branch );
branch->branch_nr = branch_nr;
branch->connections = NULL;
branch->alloc_size = 0;
branch->size = 0;
well_branch_resize( branch , 10 );
return branch;
}
void well_branch_free( well_branch_type * branch ) {
int i;
for ( i=0; i < branch->alloc_size; i++) {
well_conn_type * conn = branch->connections[i];
if (conn != NULL)
well_conn_free( conn );
}
free( branch->connections );
free( branch );
}
int well_branch_get_length( const well_branch_type * branch) {
return branch->size;
}
const well_conn_type ** well_branch_get_connections( const well_branch_type * branch ) {
if (branch->size == 0)
return NULL;
else
return (const well_conn_type **) branch->connections;
}
void well_branch_add_conn( well_branch_type * branch, well_conn_type * connection ) {
if (branch->size == branch->alloc_size)
well_branch_resize(branch , 2*( 1 + branch->alloc_size ));
branch->connections[ branch->size ] = connection;
branch->size++;
}
int well_branch_get_nr( const well_branch_type * branch ) {
return branch->branch_nr;
}

View File

@ -0,0 +1,117 @@
/*
Copyright (C) 2013 Statoil ASA, Norway.
The file 'well_branch_collection.c' is part of ERT - Ensemble based Reservoir Tool.
ERT 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.
ERT 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.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#include <stdbool.h>
#include <ert/util/util.h>
#include <ert/util/type_macros.h>
#include <ert/util/vector.h>
#include <ert/util/int_vector.h>
#include <ert/ecl_well/well_const.h>
#include <ert/ecl_well/well_conn.h>
#include <ert/ecl_well/well_branch_collection.h>
#define WELL_BRANCH_COLLECTION_TYPE_ID 67177087
struct well_branch_collection_struct {
UTIL_TYPE_ID_DECLARATION;
vector_type * __start_segments;
int_vector_type * index_map;
};
UTIL_IS_INSTANCE_FUNCTION( well_branch_collection , WELL_BRANCH_COLLECTION_TYPE_ID )
static UTIL_SAFE_CAST_FUNCTION( well_branch_collection , WELL_BRANCH_COLLECTION_TYPE_ID )
well_branch_collection_type * well_branch_collection_alloc() {
well_branch_collection_type * branch_collection = util_malloc( sizeof * branch_collection );
UTIL_TYPE_ID_INIT( branch_collection , WELL_BRANCH_COLLECTION_TYPE_ID );
branch_collection->__start_segments = vector_alloc_new();
branch_collection->index_map = int_vector_alloc(0 , -1 );
return branch_collection;
}
void well_branch_collection_free( well_branch_collection_type * branches ) {
vector_free( branches->__start_segments );
int_vector_free( branches->index_map );
free( branches );
}
void well_branch_collection_free__( void * arg ) {
well_branch_collection_type * branches = well_branch_collection_safe_cast( arg );
well_branch_collection_free( branches );
}
int well_branch_collection_get_size( const well_branch_collection_type * branches ) {
return vector_get_size( branches->__start_segments );
}
bool well_branch_collection_has_branch( const well_branch_collection_type * branches , int branch_id) {
if (int_vector_safe_iget( branches->index_map , branch_id) >= 0)
return true;
else
return false;
}
const well_segment_type * well_branch_collection_iget_start_segment( const well_branch_collection_type * branches , int index ) {
if (index < vector_get_size( branches->__start_segments))
return vector_iget_const( branches->__start_segments , index);
else
return NULL;
}
const well_segment_type * well_branch_collection_get_start_segment( const well_branch_collection_type * branches , int branch_id) {
int internal_index = int_vector_safe_iget( branches->index_map , branch_id);
if (internal_index >= 0)
return well_branch_collection_iget_start_segment( branches , internal_index );
else
return NULL;
}
bool well_branch_collection_add_start_segment( well_branch_collection_type * branches , const well_segment_type * start_segment) {
if ((well_segment_get_link_count( start_segment ) == 0) && (well_segment_get_outlet(start_segment))) {
int branch_id = well_segment_get_branch_id( start_segment );
int current_index = int_vector_safe_iget( branches->index_map , branch_id);
if (current_index >= 0)
vector_iset_ref( branches->__start_segments , current_index , start_segment);
else {
int new_index = vector_get_size( branches->__start_segments );
vector_append_ref( branches->__start_segments , start_segment);
int_vector_iset( branches->index_map , branch_id , new_index);
}
return true;
} else
return false;
}

View File

@ -17,8 +17,10 @@
*/
#include <stdbool.h>
#include <string.h>
#include <ert/util/util.h>
#include <ert/util/type_macros.h>
#include <ert/ecl/ecl_kw.h>
#include <ert/ecl/ecl_rsthead.h>
@ -26,110 +28,151 @@
#include <ert/ecl_well/well_const.h>
#include <ert/ecl_well/well_conn.h>
#define WELL_CONN_NORMAL_WELL_SEGMENT_ID -999
#define ECLIPSE_NORMAL_WELL_SEGMENT_ID -1
/*
Observe that when the (ijk) values are initialized they are
shifted to zero offset values, to be aligned with the rest of the
ert libraries.
*/
#define WELL_CONN_TYPE_ID 702052013
struct well_conn_struct {
int i;
int j;
int k;
well_conn_dir_enum dir;
bool open;
int segment; // -1: Ordinary well
bool matrix_connection; // k >= nz => fracture (and k -= nz )
/*-----------------------------------------------------------------*/
/* If the segment field == -1 - i.e. an ordinary well, the
outlet_segment is rubbish and should not be consulted.
*/
int branch;
int outlet_segment; // -1: This segment flows to the wellhead.
UTIL_TYPE_ID_DECLARATION;
int i;
int j;
int k;
well_conn_dir_enum dir;
bool open;
int segment; // -1: Ordinary well
bool matrix_connection; // k >= nz => fracture (and k -= nz )
};
static void well_conn_set_k( well_conn_type * conn , const ecl_rsthead_type * header , int icon_k) {
conn->k = icon_k;
conn->matrix_connection = true;
if (header->dualp) {
int geometric_nz = header->nz / 2;
if (icon_k >= geometric_nz) {
conn->k -= geometric_nz;
conn->matrix_connection = false;
}
}
bool well_conn_equal( const well_conn_type *conn1 , const well_conn_type * conn2) {
if (memcmp(conn1 , conn2 , sizeof * conn1) == 0)
return true;
else
return false;
}
bool well_conn_MSW( const well_conn_type * conn ) {
if (conn->segment == WELL_CONN_NORMAL_WELL_SEGMENT_ID)
return false;
else
return true;
}
static bool well_conn_assert_direction( well_conn_dir_enum dir, bool matrix_connection) {
if ((dir == well_conn_fracX || dir == well_conn_fracY) && matrix_connection)
return false;
else
return true;
}
well_conn_type * well_conn_alloc_wellhead( const ecl_kw_type * iwel_kw , const ecl_rsthead_type * header , int well_nr) {
const int iwel_offset = header->niwelz * well_nr;
int conn_i = ecl_kw_iget_int( iwel_kw , iwel_offset + IWEL_HEADI_ITEM );
UTIL_IS_INSTANCE_FUNCTION( well_conn , WELL_CONN_TYPE_ID)
UTIL_SAFE_CAST_FUNCTION( well_conn , WELL_CONN_TYPE_ID)
if (conn_i > 0) {
static well_conn_type * well_conn_alloc__( int i , int j , int k , well_conn_dir_enum dir , bool open, int segment_id, bool matrix_connection) {
if (well_conn_assert_direction( dir , matrix_connection)) {
well_conn_type * conn = util_malloc( sizeof * conn );
UTIL_TYPE_ID_INIT( conn , WELL_CONN_TYPE_ID );
conn->i = i;
conn->j = j;
conn->k = k;
conn->open = open;
conn->dir = dir;
conn->i = ecl_kw_iget_int( iwel_kw , iwel_offset + IWEL_HEADI_ITEM ) - 1;
conn->j = ecl_kw_iget_int( iwel_kw , iwel_offset + IWEL_HEADJ_ITEM ) - 1;
{
int icon_k = ecl_kw_iget_int( iwel_kw , iwel_offset + IWEL_HEADK_ITEM ) - 1;
well_conn_set_k( conn , header , icon_k);
}
conn->matrix_connection = matrix_connection;
if (segment_id == ECLIPSE_NORMAL_WELL_SEGMENT_ID)
conn->segment = WELL_CONN_NORMAL_WELL_SEGMENT_ID;
else
conn->segment = segment_id;
conn->open = true; // This is not really specified anywhere.
conn->branch = 0;
conn->segment = 0;
conn->outlet_segment = 0;
return conn;
} else
// The well is completed in this LGR - however the wellhead is in another LGR.
} else {
printf("assert-direction failed. dir:%d matrix_connection:%d \n",dir , matrix_connection);
return NULL;
}
static well_conn_type * well_conn_alloc__( const ecl_kw_type * icon_kw , const ecl_rsthead_type * header , int icon_offset) {
well_conn_type * conn = util_malloc( sizeof * conn );
conn->i = ecl_kw_iget_int( icon_kw , icon_offset + ICON_I_ITEM ) - 1;
conn->j = ecl_kw_iget_int( icon_kw , icon_offset + ICON_J_ITEM ) - 1;
{
int icon_k = ecl_kw_iget_int( icon_kw , icon_offset + ICON_K_ITEM ) - 1;
well_conn_set_k( conn , header , icon_k);
}
conn->segment = ecl_kw_iget_int( icon_kw , icon_offset + ICON_SEGMENT_ITEM ) - 1;
conn->outlet_segment = -999;
conn->branch = -999;
return conn;
}
well_conn_type * well_conn_alloc( int i , int j , int k , well_conn_dir_enum dir , bool open) {
return well_conn_alloc__(i , j , k , dir , open , WELL_CONN_NORMAL_WELL_SEGMENT_ID , true );
}
well_conn_type * well_conn_alloc_MSW( int i , int j , int k , well_conn_dir_enum dir , bool open, int segment) {
return well_conn_alloc__(i , j , k , dir , open , segment , true );
}
well_conn_type * well_conn_alloc_fracture( int i , int j , int k , well_conn_dir_enum dir , bool open) {
return well_conn_alloc__(i , j , k , dir , open , WELL_CONN_NORMAL_WELL_SEGMENT_ID , false);
}
well_conn_type * well_conn_alloc_fracture_MSW( int i , int j , int k , well_conn_dir_enum dir , bool open, int segment) {
return well_conn_alloc__(i , j , k , dir , open , segment , false);
}
/*
Observe that the (ijk) and branch values are shifted to zero offset to be
aligned with the rest of the ert libraries.
*/
well_conn_type * well_conn_alloc( const ecl_kw_type * icon_kw ,
const ecl_kw_type * iseg_kw ,
const ecl_rsthead_type * header ,
int well_nr ,
int seg_well_nr ,
int conn_nr ) {
well_conn_type * well_conn_alloc_from_kw( const ecl_kw_type * icon_kw ,
const ecl_rsthead_type * header ,
int well_nr ,
int conn_nr ) {
const int icon_offset = header->niconz * ( header->ncwmax * well_nr + conn_nr );
int IC = ecl_kw_iget_int( icon_kw , icon_offset + ICON_IC_ITEM );
if (IC > 0) {
well_conn_type * conn = well_conn_alloc__( icon_kw , header , icon_offset );
well_conn_type * conn;
int i = ecl_kw_iget_int( icon_kw , icon_offset + ICON_I_ITEM ) - 1;
int j = ecl_kw_iget_int( icon_kw , icon_offset + ICON_J_ITEM ) - 1;
int k = ecl_kw_iget_int( icon_kw , icon_offset + ICON_K_ITEM ) - 1;
int segment = ecl_kw_iget_int( icon_kw , icon_offset + ICON_SEGMENT_ITEM ) - 1;
bool matrix_connection = true;
bool open;
well_conn_dir_enum dir = well_conn_fracX;
/* Set the status */
{
int int_status = ecl_kw_iget_int( icon_kw , icon_offset + ICON_STATUS_ITEM );
if (int_status > 0)
conn->open = true;
open = true;
else
conn->open = false;
open = false;
}
/* Set the K value and fracture flag. */
{
if (header->dualp) {
int geometric_nz = header->nz / 2;
if (k >= geometric_nz) {
k -= geometric_nz;
matrix_connection = false;
}
}
}
/* Set the direction flag */
{
int int_direction = ecl_kw_iget_int( icon_kw , icon_offset + ICON_DIRECTION_ITEM );
if (int_direction == ICON_DEFAULT_DIR_VALUE)
@ -137,25 +180,27 @@ well_conn_type * well_conn_alloc( const ecl_kw_type * icon_kw ,
switch (int_direction) {
case(ICON_DIRX):
conn->dir = well_conn_dirX;
dir = well_conn_dirX;
break;
case(ICON_DIRY):
conn->dir = well_conn_dirY;
dir = well_conn_dirY;
break;
case(ICON_DIRZ):
conn->dir = well_conn_dirZ;
dir = well_conn_dirZ;
break;
case(ICON_FRACX):
conn->dir = well_conn_fracX;
dir = well_conn_fracX;
break;
case(ICON_FRACY):
conn->dir = well_conn_fracY;
dir = well_conn_fracY;
break;
default:
util_abort("%s: icon direction value:%d not recognized\n",__func__ , int_direction);
}
}
conn = well_conn_alloc__(i,j,k,dir,open,segment,matrix_connection);
/**
For multisegmented wells ONLY the global part of the restart
file has segment information, i.e. the ?SEG
@ -163,8 +208,9 @@ well_conn_type * well_conn_alloc( const ecl_kw_type * icon_kw ,
MSW + LGR well.
*/
/*
if (iseg_kw != NULL) {
if (conn->segment >= 0) {
if (conn->segment != WELL_CONN_NORMAL_WELL_SEGMENT_ID) {
const int iseg_offset = header->nisegz * ( header->nsegmx * seg_well_nr + conn->segment );
conn->outlet_segment = ecl_kw_iget_int( iseg_kw , iseg_offset + ISEG_OUTLET_ITEM );
conn->branch = ecl_kw_iget_int( iseg_kw , iseg_offset + ISEG_BRANCH_ITEM );
@ -176,6 +222,7 @@ well_conn_type * well_conn_alloc( const ecl_kw_type * icon_kw ,
conn->branch = 0;
conn->outlet_segment = 0;
}
*/
return conn;
} else
@ -189,11 +236,42 @@ void well_conn_free( well_conn_type * conn) {
void well_conn_free__( void * arg ) {
well_conn_type * conn = (well_conn_type *) arg;
well_conn_type * conn = well_conn_safe_cast( arg );
well_conn_free( conn );
}
well_conn_type * well_conn_alloc_wellhead( const ecl_kw_type * iwel_kw , const ecl_rsthead_type * header , int well_nr) {
const int iwel_offset = header->niwelz * well_nr;
int conn_i = ecl_kw_iget_int( iwel_kw , iwel_offset + IWEL_HEADI_ITEM ) - 1;
if (conn_i >= 0) {
//well_conn_type * conn = util_malloc( sizeof * conn );
int conn_j = ecl_kw_iget_int( iwel_kw , iwel_offset + IWEL_HEADJ_ITEM ) - 1;
int conn_k = ecl_kw_iget_int( iwel_kw , iwel_offset + IWEL_HEADK_ITEM ) - 1;
bool matrix_connection = true;
bool open = true;
if (header->dualp) {
int geometric_nz = header->nz / 2;
if (conn_k >= geometric_nz) {
conn_k -= geometric_nz;
matrix_connection = false;
}
}
if (matrix_connection)
return well_conn_alloc( conn_i , conn_j , conn_k , open , well_conn_dirZ );
else
return well_conn_alloc_fracture( conn_i , conn_j , conn_k , open , well_conn_dirZ );
} else
// The well is completed in this LGR - however the wellhead is in another LGR.
return NULL;
}
/*****************************************************************/
@ -210,9 +288,6 @@ int well_conn_get_k(const well_conn_type * conn) {
}
int well_conn_get_branch(const well_conn_type * conn) {
return conn->branch;
}
well_conn_dir_enum well_conn_get_dir(const well_conn_type * conn) {
return conn->dir;
@ -222,6 +297,7 @@ bool well_conn_open( const well_conn_type * conn ) {
return conn->open;
}
int well_conn_get_segment( const well_conn_type * conn ) {
return conn->segment;
}

View File

@ -0,0 +1,115 @@
/*
Copyright (C) 2013 Statoil ASA, Norway.
The file 'well_conn_collection.c' is part of ERT - Ensemble based Reservoir Tool.
ERT 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.
ERT 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.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#include <stdbool.h>
#include <ert/util/util.h>
#include <ert/util/type_macros.h>
#include <ert/util/vector.h>
#include <ert/ecl/ecl_kw.h>
#include <ert/ecl/ecl_rsthead.h>
#include <ert/ecl_well/well_const.h>
#include <ert/ecl_well/well_conn.h>
#include <ert/ecl_well/well_conn_collection.h>
#define WELL_CONN_COLLECTION_TYPE_ID 67150087
struct well_conn_collection_struct {
UTIL_TYPE_ID_DECLARATION;
vector_type * connection_list;
};
UTIL_IS_INSTANCE_FUNCTION( well_conn_collection , WELL_CONN_COLLECTION_TYPE_ID )
static UTIL_SAFE_CAST_FUNCTION( well_conn_collection , WELL_CONN_COLLECTION_TYPE_ID )
well_conn_collection_type * well_conn_collection_alloc() {
well_conn_collection_type * wellcc = util_malloc( sizeof * wellcc );
UTIL_TYPE_ID_INIT( wellcc , WELL_CONN_COLLECTION_TYPE_ID );
wellcc->connection_list = vector_alloc_new();
return wellcc;
}
/*
The collection takes ownership of the connection object and frees it
when the collection is discarded.
*/
void well_conn_collection_add( well_conn_collection_type * wellcc , well_conn_type * conn) {
vector_append_owned_ref( wellcc->connection_list , conn , well_conn_free__);
}
/*
The collection only stores a refernce to the object, which will be destroyed by 'someone else'.
*/
void well_conn_collection_add_ref( well_conn_collection_type * wellcc , well_conn_type * conn) {
vector_append_ref( wellcc->connection_list , conn );
}
void well_conn_collection_free( well_conn_collection_type * wellcc ) {
vector_free( wellcc->connection_list );
free( wellcc );
}
void well_conn_collection_free__( void * arg ) {
well_conn_collection_type * wellcc = well_conn_collection_safe_cast( arg );
well_conn_collection_free( wellcc );
}
int well_conn_collection_get_size( const well_conn_collection_type * wellcc ) {
return vector_get_size( wellcc->connection_list );
}
const well_conn_type * well_conn_collection_iget_const(const well_conn_collection_type * wellcc , int index) {
int size = well_conn_collection_get_size( wellcc );
if (index < size)
return vector_iget_const( wellcc->connection_list , index );
else
return NULL;
}
well_conn_type * well_conn_collection_iget(const well_conn_collection_type * wellcc , int index) {
int size = well_conn_collection_get_size( wellcc );
if (index < size)
return vector_iget( wellcc->connection_list , index );
else
return NULL;
}
int well_conn_collection_load_from_kw( well_conn_collection_type * wellcc , const ecl_kw_type * iwel_kw , const ecl_kw_type * icon_kw , int iwell , const ecl_rsthead_type * rst_head) {
const int iwel_offset = rst_head->niwelz * iwell;
int num_connections = ecl_kw_iget_int( iwel_kw , iwel_offset + IWEL_CONNECTIONS_ITEM );
int iconn;
for (iconn = 0; iconn < num_connections; iconn++) {
well_conn_type * conn = well_conn_alloc_from_kw( icon_kw , rst_head , iwell , iconn );
if (conn)
well_conn_collection_add( wellcc , conn );
}
return num_connections;
}

View File

@ -52,22 +52,9 @@
contains a time series for one well.
well_state_type: The well_state_type datatype contains the
state/properties of one well at one particular instant of time.
well_path_type: The well_path_type datatype hold information about
the path of the well, i.e. which cells it goes through. The
well_path_type instance is for one grid only; and if the well
goes through LGRs the well_state instance contains one
well_path instance for the global grid and additional well_path
instances for each LGR.
well_branch_type: The wells can be split into several
branches. The well_branch_type datatype contain a collection of
well connections which form a 1-dimensional segment.
well_conn_type: This is the connection of a well to one cell. This
datatype is exported, i.e. calling scope can inspect
(read-only!) the members of a well_conn_type instance.
state/properties of one well at one particular instant of
time. The well_state.c file contains further documentation of
the concepts connections, branches and segments.
WELL1
@ -279,18 +266,18 @@ static void well_info_add_state( well_info_type * well_info , well_state_type *
by calling this function repeatedly.
This function will go through all the wells by number and call the
well_state_alloc() function to create a well state object for each
well. The well_state_alloc() function will iterate through all the
well_state_alloc_from_file() function to create a well state object for each
well. The well_state_alloc_from_file() function will iterate through all the
grids and assign well properties corresponding to each of the
grids, the global grid special-cased to determine is consulted to
determine the number of wells.
*/
void well_info_add_wells( well_info_type * well_info , ecl_file_type * rst_file , int report_nr) {
ecl_rsthead_type * global_header = ecl_rsthead_alloc( rst_file );
int well_nr;
ecl_rsthead_type * global_header = ecl_rsthead_alloc( rst_file );
for (well_nr = 0; well_nr < global_header->nwells; well_nr++) {
well_state_type * well_state = well_state_alloc( rst_file , report_nr , well_nr );
well_state_type * well_state = well_state_alloc_from_file( rst_file , well_info->grid , report_nr , well_nr );
if (well_state != NULL)
well_info_add_state( well_info , well_state );
}

View File

@ -1,185 +0,0 @@
/*
Copyright (C) 2012 Statoil ASA, Norway.
The file 'well_path.c' is part of ERT - Ensemble based Reservoir Tool.
ERT 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.
ERT 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.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#include <stdlib.h>
#include <ert/util/util.h>
#include <ert/ecl_well/well_path.h>
#include <ert/ecl_well/well_branch.h>
#include <ert/ecl_well/well_const.h>
#include <ert/ecl_well/well_conn.h>
/*
This file implements the well_path structure which is container for
the grid connections for one grid realisation; i.e. if the well is
perforated in LGRs in addition to the global grid the parent
well_state structure will have several well_path instances - one for
the global grid and one for each LGR.
The well_path structure consist of one or several well_branch_type
instances; the well_branch is a collection of cells which are
connected on a 1D line.
--------------D
/
/
A---------------B----------C
All of this figure is one well; how this structure is connected to
one particular grid is described by the well_path structure in this
file. The current well consist of two branches: A-B-C and B-D; these
are two well_branch instance in the well_path structure.
*/
#define WELL_PATH_TYPE_ID 91916433
struct well_path_struct {
UTIL_TYPE_ID_DECLARATION;
char * grid_name; // Will be NULL for 'null_path' construction in the well_state object.
well_branch_type ** branches;
int max_branches; // This might be misleading due to NULL pointers 'inside' the branches array.
int alloc_size;
};
static void well_path_resize( well_path_type * well_path , int new_size) {
well_path->branches = util_realloc( well_path->branches , new_size * sizeof * well_path->branches );
{
int i;
for (i=well_path->alloc_size; i < new_size; i++)
well_path->branches[i] = NULL;
}
well_path->alloc_size = new_size;
}
static UTIL_SAFE_CAST_FUNCTION( well_path , WELL_PATH_TYPE_ID )
well_path_type * well_path_alloc(const char * grid_name) {
well_path_type * well_path = util_malloc( sizeof * well_path );
UTIL_TYPE_ID_INIT( well_path , WELL_PATH_TYPE_ID );
well_path->grid_name = util_alloc_string_copy( grid_name );
well_path->branches = NULL;
well_path->max_branches = 0;
well_path->alloc_size = 0;
well_path_resize( well_path , 4 );
return well_path;
}
well_branch_type * well_path_add_branch( well_path_type * well_path , int branch_nr) {
well_branch_type * new_branch = well_branch_alloc( branch_nr );
if (branch_nr >= well_path->alloc_size)
well_path_resize( well_path , 2 * branch_nr );
well_path->branches[ branch_nr ] = new_branch;
if (branch_nr >= well_path->max_branches)
well_path->max_branches = branch_nr + 1;
return new_branch;
}
bool well_path_has_branch( const well_path_type * well_path , int branch_nr ) {
if (branch_nr >= 0 && branch_nr < well_path->max_branches) {
well_branch_type * branch = well_path->branches[ branch_nr ];
if (branch != NULL)
return true;
else
return false;
} else
return false;
}
/**
This will return the maximum branch number; there can be holes in
the branches array:
branches = [ branch0, NULL , branch1 , NULL , branch3]
In this case the the well_path_get_max_branches() will return five;
however there are only three active branches in this case. The
alternative function well_path_get_num_active_branches() will count
the number of active (i.e. != NULL) branches.
*/
int well_path_get_max_branches( const well_path_type * well_path ) {
return well_path->max_branches;
}
int well_path_get_num_active_branches( const well_path_type * well_path) {
int branch_nr;
int num_active = 0;
for (branch_nr = 0; branch_nr < well_path->max_branches; branch_nr++)
if (well_path->branches[ branch_nr ] != NULL)
num_active++;
return num_active;
}
/**
Will return NULL if the branch does not exist.
*/
well_branch_type * well_path_iget_branch( const well_path_type * well_path , int branch_nr) {
if (well_path_has_branch( well_path , branch_nr ))
return well_path->branches[ branch_nr ];
else
return NULL;
}
void well_path_add_conn( well_path_type * well_path , well_conn_type * conn) {
int branch_nr = well_conn_get_branch( conn );
if (!well_path_has_branch( well_path , branch_nr))
well_path_add_branch( well_path , branch_nr );
{
well_branch_type * branch = well_path_iget_branch( well_path , branch_nr );
well_branch_add_conn( branch , conn );
}
}
void well_path_free( well_path_type * well_path ) {
int i;
for (i=0; i < well_path->alloc_size; i++) {
if (well_path->branches[i] != NULL)
well_branch_free( well_path->branches[i] );
}
util_safe_free( well_path->grid_name );
free( well_path->branches );
free( well_path );
}
void well_path_free__(void * arg) {
well_path_type * well_path = well_path_safe_cast( arg );
well_path_free( well_path );
}
const char * well_path_get_grid_name( const well_path_type * well_path ) {
return well_path->grid_name;
}

View File

@ -0,0 +1,249 @@
/*
Copyright (C) 2013 Statoil ASA, Norway.
The file 'well_segment.c' is part of ERT - Ensemble based Reservoir Tool.
ERT 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.
ERT 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.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#include <stdbool.h>
#include <ert/util/util.h>
#include <ert/util/hash.h>
#include <ert/ecl/ecl_kw.h>
#include <ert/ecl/ecl_rsthead.h>
#include <ert/ecl/ecl_grid.h>
#include <ert/ecl_well/well_const.h>
#include <ert/ecl_well/well_conn.h>
#include <ert/ecl_well/well_segment.h>
#include <ert/ecl_well/well_conn_collection.h>
#define WELL_SEGMENT_TYPE_ID 2209166
struct well_segment_struct {
UTIL_TYPE_ID_DECLARATION;
int link_count;
int segment_id;
int branch_id;
int outlet_segment_id; // This is in the global index space given by the ISEG keyword.
well_segment_type * outlet_segment;
hash_type * connections; // hash_type<grid_name , well_conn_collection>;
double depth; // The depth of the segment node; furthest away from the wellhead.
double length;
double total_length; // Total length from wellhead.
double diameter; // The tube diametere available for flow.
};
UTIL_IS_INSTANCE_FUNCTION( well_segment , WELL_SEGMENT_TYPE_ID )
static UTIL_SAFE_CAST_FUNCTION( well_segment , WELL_SEGMENT_TYPE_ID )
well_segment_type * well_segment_alloc(int segment_id , int outlet_segment_id , int branch_id , const double * rseg_data) {
well_segment_type * segment = util_malloc( sizeof * segment );
UTIL_TYPE_ID_INIT( segment , WELL_SEGMENT_TYPE_ID );
segment->link_count = 0;
segment->segment_id = segment_id;
segment->outlet_segment_id = outlet_segment_id;
segment->branch_id = branch_id;
segment->outlet_segment = NULL;
segment->connections = hash_alloc();
segment->depth = rseg_data[ RSEG_DEPTH_INDEX ];
segment->length = rseg_data[ RSEG_LENGTH_INDEX ];
segment->total_length = rseg_data[ RSEG_TOTAL_LENGTH_INDEX ];
segment->diameter = rseg_data[ RSEG_DIAMETER_INDEX ];
return segment;
}
well_segment_type * well_segment_alloc_from_kw( const ecl_kw_type * iseg_kw , const ecl_kw_type * rseg_kw , const ecl_rsthead_type * header , int well_nr, int segment_id) {
if (rseg_kw == NULL) {
util_abort("%s: fatal internal error - tried to create well_segment instance without RSEG keyword.\n",__func__);
return NULL;
} else {
const int iseg_offset = header->nisegz * ( header->nsegmx * well_nr + segment_id);
const int rseg_offset = header->nrsegz * ( header->nsegmx * well_nr + segment_id);
int outlet_segment_id = ecl_kw_iget_int( iseg_kw , iseg_offset + ISEG_OUTLET_ITEM ) - 1;
int branch_id = ecl_kw_iget_int( iseg_kw , iseg_offset + ISEG_BRANCH_ITEM ) - 1;
const double * rseg_data = ecl_kw_iget_ptr( rseg_kw , rseg_offset );
well_segment_type * segment = well_segment_alloc( segment_id , outlet_segment_id , branch_id , rseg_data);
return segment;
}
}
/*
if (iseg_kw != NULL) {
if (conn->segment != WELL_CONN_NORMAL_WELL_SEGMENT_ID) {
} else {
conn->branch = 0;
conn->outlet_segment = 0;
}
} else {
conn->branch = 0;
conn->outlet_segment = 0;
}
*/
void well_segment_free(well_segment_type * segment ) {
hash_free( segment->connections );
free( segment );
}
void well_segment_free__(void * arg) {
well_segment_type * segment = well_segment_safe_cast( arg );
well_segment_free( segment );
}
bool well_segment_active( const well_segment_type * segment ) {
if (segment->branch_id == ECLIPSE_WELL_SEGMENT_BRANCH_INACTIVE_VALUE)
return false;
else
return true;
}
bool well_segment_main_stem( const well_segment_type * segment ) {
if (segment->branch_id == ECLIPSE_WELL_SEGMENT_BRANCH_MAIN_STEM_VALUE)
return true;
else
return false;
}
bool well_segment_nearest_wellhead( const well_segment_type * segment ) {
if (segment->outlet_segment_id == ECLIPSE_WELL_SEGMENT_OUTLET_END_VALUE)
return true;
else
return false;
}
int well_segment_get_link_count( const well_segment_type * segment ) {
return segment->link_count;
}
int well_segment_get_branch_id( const well_segment_type * segment ) {
return segment->branch_id;
}
int well_segment_get_outlet_id( const well_segment_type * segment ) {
return segment->outlet_segment_id;
}
int well_segment_get_id( const well_segment_type * segment ) {
return segment->segment_id;
}
well_segment_type * well_segment_get_outlet( const well_segment_type * segment ) {
return segment->outlet_segment;
}
bool well_segment_link( well_segment_type * segment , well_segment_type * outlet_segment ) {
if (segment->outlet_segment_id == outlet_segment->segment_id) {
segment->outlet_segment = outlet_segment;
outlet_segment->link_count++;
return true;
} else
/*
This is a quite fatal topological error - and aborting is probaly the wisest
thing to do. I.e. the function well_segment_link_strict() is recommended.
*/
return false;
}
void well_segment_link_strict( well_segment_type * segment , well_segment_type * outlet_segment ) {
if (!well_segment_link( segment , outlet_segment))
util_abort("%s: tried to create invalid link between segments %d and %d \n",segment->segment_id , outlet_segment->segment_id);
}
bool well_segment_has_grid_connections( const well_segment_type * segment , const char * grid_name) {
return hash_has_key( segment->connections , grid_name );
}
bool well_segment_has_global_grid_connections( const well_segment_type * segment) {
return well_segment_has_grid_connections( segment , ECL_GRID_GLOBAL_GRID );
}
bool well_segment_add_connection( well_segment_type * segment , const char * grid_name , well_conn_type * conn) {
int conn_segment_id = well_conn_get_segment( conn );
if (conn_segment_id == segment->segment_id) {
if (!well_segment_has_grid_connections( segment , grid_name ))
hash_insert_hash_owned_ref( segment->connections , grid_name , well_conn_collection_alloc() , well_conn_collection_free__ );
{
well_conn_collection_type * connections = hash_get( segment->connections , grid_name );
well_conn_collection_add_ref( connections , conn );
}
return true;
} else
return false;
}
const well_conn_collection_type * well_segment_get_connections(const well_segment_type * segment , const char * grid_name ) {
if (well_segment_has_grid_connections( segment , grid_name))
return hash_get( segment->connections , grid_name);
else
return NULL;
}
const well_conn_collection_type * well_segment_get_global_connections(const well_segment_type * segment ) {
return well_segment_get_connections( segment , ECL_GRID_GLOBAL_GRID );
}
bool well_segment_well_is_MSW(int well_nr , const ecl_kw_type * iwel_kw , const ecl_rsthead_type * rst_head) {
int iwel_offset = rst_head->niwelz * well_nr;
int segment_well_nr = ecl_kw_iget_int( iwel_kw , iwel_offset + IWEL_SEGMENTED_WELL_NR_ITEM) - 1;
if (segment_well_nr == IWEL_SEGMENTED_WELL_NR_NORMAL_VALUE)
return false;
else
return true;
}
double well_segment_get_depth( const well_segment_type * segment ) {
return segment->depth;
}
double well_segment_get_length( const well_segment_type * segment ) {
return segment->length;
}
double well_segment_get_total_length( const well_segment_type * segment ) {
return segment->total_length;
}
double well_segment_get_diameter( const well_segment_type * segment ) {
return segment->diameter;
}

View File

@ -0,0 +1,169 @@
/*
Copyright (C) 2013 Statoil ASA, Norway.
The file 'well_segment_collection.c' is part of ERT - Ensemble based Reservoir Tool.
ERT 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.
ERT 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.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#include <stdbool.h>
#include <ert/util/util.h>
#include <ert/util/vector.h>
#include <ert/ecl/ecl_kw.h>
#include <ert/ecl/ecl_rsthead.h>
#include <ert/ecl_well/well_const.h>
#include <ert/ecl_well/well_segment.h>
#include <ert/ecl_well/well_conn.h>
#include <ert/ecl_well/well_segment_collection.h>
#include <ert/ecl_well/well_conn_collection.h>
#include <ert/ecl_well/well_branch_collection.h>
struct well_segment_collection_struct {
int_vector_type * segment_index_map;
vector_type * __segment_storage;
};
well_segment_collection_type * well_segment_collection_alloc() {
well_segment_collection_type * segment_collection = util_malloc( sizeof * segment_collection );
segment_collection->__segment_storage = vector_alloc_new();
segment_collection->segment_index_map = int_vector_alloc( 0 , -1 );
return segment_collection;
}
void well_segment_collection_free(well_segment_collection_type * segment_collection ) {
vector_free( segment_collection->__segment_storage );
int_vector_free( segment_collection->segment_index_map );
free( segment_collection );
}
int well_segment_collection_get_size( const well_segment_collection_type * segment_collection ) {
return vector_get_size( segment_collection->__segment_storage );
}
void well_segment_collection_add( well_segment_collection_type * segment_collection , well_segment_type * segment) {
int segment_id = well_segment_get_id( segment );
int current_index = int_vector_safe_iget( segment_collection->segment_index_map , segment_id );
if (current_index >= 0)
vector_iset_owned_ref( segment_collection->__segment_storage , current_index , segment , well_segment_free__);
else {
int new_index = vector_get_size(segment_collection->__segment_storage);
vector_append_owned_ref( segment_collection->__segment_storage , segment , well_segment_free__);
int_vector_iset( segment_collection->segment_index_map , segment_id , new_index);
}
}
well_segment_type * well_segment_collection_iget( const well_segment_collection_type * segment_collection , int index) {
return vector_iget( segment_collection->__segment_storage , index );
}
well_segment_type * well_segment_collection_get( const well_segment_collection_type * segment_collection , int segment_id) {
int internal_index = int_vector_safe_iget( segment_collection->segment_index_map , segment_id );
if (internal_index >= 0)
return well_segment_collection_iget( segment_collection , internal_index );
else
return NULL;
}
bool well_segment_collection_has_segment( const well_segment_collection_type * segment_collection , int segment_id) {
int internal_index = int_vector_safe_iget( segment_collection->segment_index_map , segment_id );
if (internal_index >= 0)
return true;
else
return false;
}
int well_segment_collection_load_from_kw( well_segment_collection_type * segment_collection , int well_nr ,
const ecl_kw_type * iwel_kw ,
const ecl_kw_type * iseg_kw ,
const ecl_kw_type * rseg_kw ,
const ecl_rsthead_type * rst_head) {
int iwel_offset = rst_head->niwelz * well_nr;
int segment_well_nr = ecl_kw_iget_int( iwel_kw , iwel_offset + IWEL_SEGMENTED_WELL_NR_ITEM) - 1;
int segments_added = 0;
if (segment_well_nr != IWEL_SEGMENTED_WELL_NR_NORMAL_VALUE) {
int segment_id;
for (segment_id = 0; segment_id < rst_head->nsegmx; segment_id++) {
well_segment_type * segment = well_segment_alloc_from_kw( iseg_kw , rseg_kw , rst_head , segment_well_nr , segment_id );
if (well_segment_active( segment )) {
well_segment_collection_add( segment_collection , segment );
segments_added++;
} else
well_segment_free( segment );
}
}
return segments_added;
}
void well_segment_collection_link(const well_segment_collection_type * segment_collection) {
int index;
for (index = 0; index < vector_get_size( segment_collection->__segment_storage); index++) {
well_segment_type * segment = well_segment_collection_iget( segment_collection , index );
int outlet_segment_id = well_segment_get_outlet_id( segment );
if (!well_segment_nearest_wellhead(segment)) {
well_segment_type * target_segment = well_segment_collection_get( segment_collection , outlet_segment_id );
well_segment_link( segment , target_segment );
}
}
}
void well_segment_collection_add_connections(well_segment_collection_type * segment_collection ,
const char * grid_name ,
const well_conn_collection_type * connections) {
int iconn;
for (iconn = 0; iconn < well_conn_collection_get_size( connections ); iconn++) {
well_conn_type * conn = well_conn_collection_iget( connections , iconn );
if (well_conn_MSW( conn )) {
int segment_id = well_conn_get_segment( conn );
well_segment_type * segment = well_segment_collection_get( segment_collection , segment_id );
well_segment_add_connection( segment , grid_name , conn );
}
}
}
void well_segment_collection_add_branches( const well_segment_collection_type * segment_collection ,
well_branch_collection_type * branches ) {
int iseg;
for (iseg =0; iseg < well_segment_collection_get_size( segment_collection ); iseg++) {
const well_segment_type * segment = well_segment_collection_iget( segment_collection , iseg );
if (well_segment_get_link_count( segment ) == 0)
well_branch_collection_add_start_segment( branches , segment );
}
}

View File

@ -36,11 +36,126 @@
#include <ert/ecl/ecl_kw.h>
#include <ert/ecl/ecl_kw_magic.h>
#include <ert/ecl/ecl_util.h>
#include <ert/ecl/ecl_grid.h>
#include <ert/ecl_well/well_const.h>
#include <ert/ecl_well/well_conn.h>
#include <ert/ecl_well/well_state.h>
#include <ert/ecl_well/well_path.h>
#include <ert/ecl_well/well_segment_collection.h>
#include <ert/ecl_well/well_branch_collection.h>
/*
Connections, segments and branches
----------------------------------
+-----+
| | <- Wellhead
| |
+-----+ _________ Segment 2
|\ /
| \/ Segment 1 Segment 0
| \-----0---------------0--<----------------------O <-- Branch: 0
\ | | | |
\ +-----+ +-----++-----+ +-----+
\ | C3 | | C2 || C1 | | C0 |
\ | | | || | | |
\ +-----+ +-----++-----+ +-----+
\
Segment 5 \
\
\ Segment 4 Segment 3
\-<--O-------<-------O----------------<------------O <-- Branch: 1
| | | |
+-----+ +-----+ +-----+ +-----+
| C7 | | C6 | | C5 | | C4 |
| | | | | | | |
+-----+ +-----+ +-----+ +-----+
The boxes show connections C0 - C7; the connections serve as sinks (or
sources in the case of injectors) removing fluids from the
reservoir. As ind icated by the use of isolated boxes the ECLIPSE model
contains no geomtric concept linking the different connections into a
connected 'well-like' object.
Ordinary wells in the ECLIPSE model are just a collection of
connections like these illustrated boxes, and to draw a connected 1D
object heuristics of some kind must be used to determine how the
various connections should be connected. In particular for wells which
consist of multiple branches this heuristic is non obvious.
More advanced (i.e. newer) wells are modelles as multisegment wells;
the important thing about multisegment wells is that the 1D segments
constituting the flowpipe are modelled explicitly as 'segments', and
the equations of fluid flow are solved by ECLIPSE in these 1D
domains. The figure above shows a multisegment well with six segments
marked as Segment0 ... Segment5. The segments themselves are quite
abstract objects not directly linked to the grid, but indriectly
through the connections. In the figure the segment <-> connection
links are as follows:
Segment0: C0, C1
Segment1: C2
Segment2: C3
Segment3: C4, C5
Segment4: C6
Segment5: C7
Each segment has an outlet segment, which will link the segments
together into a geometry.
The connection can in general be both to the main global grid, and to
an LGR. Hence all questions about connections must be LGR aware. This
is in contrast to the segments and branches which are geometric
objects, not directly coupled to a specific grid; however the segments
have a collection of connections - and these connections are of course
coupledte implementation these objects are modelled as such:
1. The well_state has hash table which is indexed by LGR name, and
the values are well_conn_collection instances. The
well_conn_collection type is a quite simple collection which can
tell how may connections there are, and index based lookup:
well_conn_collection_type * connections = well_state_get_grid_connections( well_state , LGR_NAME);
if (connections) {
well_conn_type * conn = well_conn_collection_iget( connections , 0 );
printf("Have %d connections \n",well_conn_collection_get_size( connections );
}
The connections to the global grid are stored with the 'LGR' name
given by the symbole ECL_GRID_GLOBAL_GRID, or alternatively the
function well_state_get_global_connections( well_state ) can be
used.
2. If - AND ONLY IF - the well is a multisegment well, you can query
the well_state object for information about segments and branches:
if (well_state_is_MSW( well_state )) {
well_segment_collection_type * segments = well_state_get_segments( well_state );
well_branch_collection_type * branches = well_state_get_branches( well_state );
int branch_nr;
for (branch_nr = 0; branch_nr < well_branch_collection_get_size( branches ); branch_nr++) {
well_segment_type * segment = well_branch_collection_iget_start_segment( branches , branhc_nr );
while (segment) {
// Inspect the current segment.
segment = well_segment_get_outlet( segment );
}
}
}
*/
#define WELL_STATE_TYPE_ID 613307832
@ -49,16 +164,18 @@ struct well_state_struct {
char * name;
time_t valid_from_time;
int valid_from_report;
int global_well_nr;
bool open;
well_type_enum type;
well_path_type * null_path; // This is a valid - empty path instance returned when the well does not have any cells in a particular LGR.
hash_type * connections; // hash<grid_name,well_conn_collection>
well_segment_collection_type * segments;
well_branch_collection_type * branches;
/*****************************************************************/
vector_type * index_wellhead; // An well_conn_type instance representing the wellhead - indexed by grid_nr.
hash_type * name_wellhead; // An well_conn_type instance representing the wellhead - indexed by lgr_name.
vector_type * index_lgr_path; // Contains the various well_path instances indexed by grid_nr - global has grid_nr == 0.
hash_type * name_lgr_path; // Contains the different well_path instances indexed by lgr_name
};
@ -66,34 +183,30 @@ struct well_state_struct {
UTIL_IS_INSTANCE_FUNCTION( well_state , WELL_STATE_TYPE_ID)
static well_state_type * well_state_alloc_empty() {
well_state_type * well_state_alloc(const char * well_name , int global_well_nr , bool open, well_type_enum type , int report_nr, time_t valid_from) {
well_state_type * well_state = util_malloc( sizeof * well_state );
UTIL_TYPE_ID_INIT( well_state , WELL_STATE_TYPE_ID );
well_state->index_lgr_path = vector_alloc_new();
well_state->name_lgr_path = hash_alloc();
well_state->index_wellhead = vector_alloc_new();
well_state->name_wellhead = hash_alloc();
well_state->null_path = well_path_alloc( NULL );
well_state->name = util_alloc_string_copy( well_name );
well_state->valid_from_time = valid_from;
well_state->valid_from_report = report_nr;
well_state->open = open;
well_state->type = type;
well_state->global_well_nr = global_well_nr;
well_state->connections = hash_alloc();
well_state->segments = well_segment_collection_alloc();
well_state->branches = well_branch_collection_alloc();
/* See documentation of the 'IWEL_UNDOCUMENTED_ZERO' in well_const.h */
if ((type == UNDOCUMENTED_ZERO) && open)
util_abort("%s: Invalid type value for open wells.\n",__func__ );
return well_state;
}
/*
This function assumes that the ecl_file state has been restricted
to one LGR block with the ecl_file_subselect_block() function.
*/
well_path_type * well_state_add_path( well_state_type * well_state , const ecl_file_type * rst_file , const char * grid_name , int grid_nr) {
well_path_type * well_path;
well_path = well_path_alloc( grid_name );
vector_safe_iset_owned_ref( well_state->index_lgr_path , grid_nr , well_path , well_path_free__);
hash_insert_ref( well_state->name_lgr_path , grid_name , well_path );
return well_path;
}
void well_state_add_wellhead( well_state_type * well_state , const ecl_rsthead_type * header , const ecl_kw_type * iwel_kw , int well_nr , const char * grid_name , int grid_nr) {
@ -107,53 +220,7 @@ void well_state_add_wellhead( well_state_type * well_state , const ecl_rsthead_t
}
/*
This function assumes that the ecl_file state has been restricted
to one LGR block with the ecl_file_subselect_block() function.
*/
static void well_state_add_connections( well_state_type * well_state , const ecl_file_type * rst_file , int grid_nr, int well_nr ) {
ecl_rsthead_type * header = ecl_rsthead_alloc( rst_file );
const ecl_kw_type * icon_kw = ecl_file_iget_named_kw( rst_file , ICON_KW , 0);
const ecl_kw_type * iwel_kw = ecl_file_iget_named_kw( rst_file , IWEL_KW , 0);
const int iwel_offset = header->niwelz * well_nr;
int num_connections = ecl_kw_iget_int( iwel_kw , iwel_offset + IWEL_CONNECTIONS_ITEM );
ecl_kw_type * iseg_kw = NULL;
bool MSW = false; // MultiSegmentWell
int seg_well_nr = ecl_kw_iget_int( iwel_kw , iwel_offset + IWEL_SEGMENTED_WELL_NR_ITEM) - 1; // -1: Ordinary well.
well_path_type * path;
{
char * grid_name;
if (grid_nr > 0) {
const ecl_kw_type * lgr_kw = ecl_file_iget_named_kw( rst_file , LGR_KW , 0 );
grid_name = util_alloc_strip_copy(ecl_kw_iget_ptr( lgr_kw , 0));
} else
grid_name = util_alloc_string_copy( GLOBAL_GRID_NAME );
path = well_state_add_path( well_state , rst_file , grid_name , grid_nr );
well_state_add_wellhead( well_state , header , iwel_kw , well_nr , grid_name , grid_nr );
free( grid_name );
}
/* The MSW information is only attached to the global grid. */
if (seg_well_nr >= 0 && grid_nr == 0)
MSW = true;
if (MSW)
iseg_kw = ecl_file_iget_named_kw( rst_file , ISEG_KW , 0 );
{
int conn_nr;
for (conn_nr = 0; conn_nr < num_connections; conn_nr++) {
well_conn_type * conn = well_conn_alloc( icon_kw , iseg_kw , header , well_nr , seg_well_nr , conn_nr );
if (conn != NULL)
well_path_add_conn( path , conn );
}
}
ecl_rsthead_free( header );
}
/*
This function assumes that the ecl_file state has been restricted
@ -167,8 +234,8 @@ static int well_state_get_lgr_well_nr( const well_state_type * well_state , cons
int well_nr = -1;
if (ecl_file_has_kw( ecl_file , ZWEL_KW)) {
ecl_rsthead_type * header = ecl_rsthead_alloc( ecl_file ); //
const ecl_kw_type * zwel_kw = ecl_file_iget_named_kw( ecl_file , ZWEL_KW , 0);
ecl_rsthead_type * header = ecl_rsthead_alloc( ecl_file );
const ecl_kw_type * zwel_kw = ecl_file_iget_named_kw( ecl_file , ZWEL_KW , 0 );
int num_wells = header->nwells;
well_nr = 0;
while (true) {
@ -199,7 +266,162 @@ static int well_state_get_lgr_well_nr( const well_state_type * well_state , cons
}
well_state_type * well_state_alloc( ecl_file_type * ecl_file , int report_nr , int global_well_nr) {
well_type_enum well_state_translate_ecl_type_int(int int_type) {
well_type_enum type = UNDOCUMENTED_ZERO;
switch (int_type) {
/* See documentation of the 'IWEL_UNDOCUMENTED_ZERO' in well_const.h */
case(IWEL_UNDOCUMENTED_ZERO):
type = UNDOCUMENTED_ZERO;
break;
case(IWEL_PRODUCER):
type = PRODUCER;
break;
case(IWEL_OIL_INJECTOR):
type = OIL_INJECTOR;
break;
case(IWEL_GAS_INJECTOR):
type = GAS_INJECTOR;
break;
case(IWEL_WATER_INJECTOR):
type = WATER_INJECTOR;
break;
default:
util_abort("%s: Invalid type value %d\n",__func__ , int_type);
}
return type;
}
/*
This function assumes that the ecl_file state has been restricted
to one LGR block with the ecl_file_subselect_block() function.
*/
static void well_state_add_connections__( well_state_type * well_state ,
const ecl_file_type * rst_file ,
const char * grid_name ,
int grid_nr,
int well_nr ) {
ecl_rsthead_type * header = ecl_rsthead_alloc( rst_file );
const ecl_kw_type * icon_kw = ecl_file_iget_named_kw( rst_file , ICON_KW , 0);
const ecl_kw_type * iwel_kw = ecl_file_iget_named_kw( rst_file , IWEL_KW , 0);
//const int iwel_offset = header->niwelz * well_nr;
//int seg_well_nr = ecl_kw_iget_int( iwel_kw , iwel_offset + IWEL_SEGMENTED_WELL_NR_ITEM) - 1; // -1: Ordinary well.
well_state_add_wellhead( well_state , header , iwel_kw , well_nr , grid_name , grid_nr );
if (!well_state_has_grid_connections( well_state , grid_name ))
hash_insert_hash_owned_ref( well_state->connections , grid_name, well_conn_collection_alloc( ) , well_conn_collection_free__ );
{
well_conn_collection_type * wellcc = hash_get( well_state->connections , grid_name );
well_conn_collection_load_from_kw( wellcc , iwel_kw , icon_kw , well_nr , header );
}
ecl_rsthead_free( header );
}
static void well_state_add_global_connections( well_state_type * well_state ,
const ecl_file_type * rst_file ,
int well_nr ) {
well_state_add_connections__( well_state , rst_file , ECL_GRID_GLOBAL_GRID , 0 , well_nr );
}
static void well_state_add_LGR_connections( well_state_type * well_state , const ecl_grid_type * grid , ecl_file_type * ecl_file, int global_well_nr ) {
// Go through all the LGRs and add connections; both in the bulk
// grid and as wellhead.
int num_lgr = ecl_grid_get_num_lgr( grid );
int lgr_nr;
for (lgr_nr = 0; lgr_nr < num_lgr; lgr_nr++) {
ecl_file_push_block( ecl_file ); // <-------------------------//
{ //
ecl_file_subselect_block( ecl_file , LGR_KW , lgr_nr ); //
{ // Restrict the file view
const char * grid_name = ecl_grid_iget_lgr_name( grid , lgr_nr ); //
int well_nr = well_state_get_lgr_well_nr( well_state , ecl_file ); // to one LGR block.
if (well_nr >= 0) //
well_state_add_connections__( well_state , ecl_file , grid_name , lgr_nr + 1, well_nr ); //
} //
} //
ecl_file_pop_block( ecl_file ); // <-------------------------//
}
}
void well_state_add_connections( well_state_type * well_state ,
const ecl_grid_type * grid ,
ecl_file_type * rst_file , // Either an open .Xnnnn file or UNRST file restricted to one report step
int well_nr) {
well_state_add_global_connections( well_state , rst_file , well_nr );
well_state_add_LGR_connections( well_state , grid , rst_file , well_nr );
}
bool well_state_add_MSW( well_state_type * well_state ,
const ecl_file_type * rst_file ,
int well_nr) {
if (ecl_file_has_kw( rst_file , ISEG_KW)) {
ecl_rsthead_type * rst_head = ecl_rsthead_alloc( rst_file );
const ecl_kw_type * iwel_kw = ecl_file_iget_named_kw( rst_file , IWEL_KW , 0);
const ecl_kw_type * iseg_kw = ecl_file_iget_named_kw( rst_file , ISEG_KW , 0);
ecl_kw_type * rseg_kw = NULL;
int segments;
if (ecl_file_has_kw( rst_file , RSEG_KW ))
/*
Here we check that the file has the RSEG_KW keyword, and pass
NULL if not. The rseg_kw pointer will later be used in
well_segment_collection_load_from_kw() where we test if this
is a MSW well. If this indeed is a MSW well the rseg_kw
pointer will be used unchecked, if it is then NULL => Crash
and burn.
*/
rseg_kw = ecl_file_iget_named_kw( rst_file , RSEG_KW , 0);
segments = well_segment_collection_load_from_kw( well_state->segments ,
well_nr ,
iwel_kw ,
iseg_kw ,
rseg_kw ,
rst_head);
if (segments) {
hash_iter_type * grid_iter = hash_iter_alloc( well_state->connections );
while (!hash_iter_is_complete( grid_iter )) {
const char * grid_name = hash_iter_get_next_key( grid_iter );
const well_conn_collection_type * connections = hash_get( well_state->connections , grid_name );
well_segment_collection_add_connections( well_state->segments , grid_name , connections );
}
hash_iter_free( grid_iter );
well_segment_collection_link( well_state->segments );
well_segment_collection_add_branches( well_state->segments , well_state->branches );
}
ecl_rsthead_free( rst_head );
return true;
} else
return false;
}
bool well_state_is_MSW( const well_state_type * well_state) {
if (well_segment_collection_get_size( well_state->segments ) > 0)
return true;
else
return false;
}
well_state_type * well_state_alloc_from_file( ecl_file_type * ecl_file , const ecl_grid_type * grid , int report_nr , int global_well_nr) {
if (ecl_file_has_kw( ecl_file , IWEL_KW)) {
well_state_type * well_state = NULL;
ecl_rsthead_type * global_header = ecl_rsthead_alloc( ecl_file );
@ -208,72 +430,33 @@ well_state_type * well_state_alloc( ecl_file_type * ecl_file , int report_nr ,
const int iwel_offset = global_header->niwelz * global_well_nr;
{
const int zwel_offset = global_header->nzwelz * global_well_nr;
well_state = well_state_alloc_empty();
well_state->valid_from_time = global_header->sim_time;
well_state->valid_from_report = report_nr;
well_state->name = util_alloc_strip_copy(ecl_kw_iget_ptr( global_zwel_kw , zwel_offset )); // Hardwired max 8 characters in Well Name
char * name;
bool open;
well_type_enum type = UNDOCUMENTED_ZERO;
{
int int_state = ecl_kw_iget_int( global_iwel_kw , iwel_offset + IWEL_STATUS_ITEM );
if (int_state > 0)
well_state->open = true;
open = true;
else
well_state->open = false;
open = false;
}
{
int int_type = ecl_kw_iget_int( global_iwel_kw , iwel_offset + IWEL_TYPE_ITEM);
switch (int_type) {
/* See documentation of the 'IWEL_UNDOCUMENTED_ZERO' in well_const.h */
case(IWEL_UNDOCUMENTED_ZERO):
well_state->type = UNDOCUMENTED_ZERO;
if (well_state->open)
util_abort("%s: Invalid type value %d\n",__func__ , int_type);
break;
case(IWEL_PRODUCER):
well_state->type = PRODUCER;
break;
case(IWEL_OIL_INJECTOR):
well_state->type = OIL_INJECTOR;
break;
case(IWEL_GAS_INJECTOR):
well_state->type = GAS_INJECTOR;
break;
case(IWEL_WATER_INJECTOR):
well_state->type = WATER_INJECTOR;
break;
default:
util_abort("%s: Invalid type value %d\n",__func__ , int_type);
}
type = well_state_translate_ecl_type_int( int_type );
}
// Add global connections:
well_state_add_connections( well_state , ecl_file , 0 , global_well_nr );
// Go through all the LGRs and add connections; both in the bulk
// grid and as wellhead.
{
int num_lgr = ecl_file_get_num_named_kw( ecl_file , LGR_KW );
int lgr_nr;
for (lgr_nr = 0; lgr_nr < num_lgr; lgr_nr++) {
ecl_file_push_block( ecl_file ); // <--------------------
{ //
ecl_file_subselect_block( ecl_file , LGR_KW , lgr_nr ); //
{ // Restrict the file view
int well_nr = well_state_get_lgr_well_nr( well_state , ecl_file); // to one LGR block.
if (well_nr >= 0) //
well_state_add_connections( well_state , ecl_file , lgr_nr + 1, well_nr ); //
} //
} //
ecl_file_pop_block( ecl_file ); // <--------------------
}
const int zwel_offset = global_header->nzwelz * global_well_nr;
name = util_alloc_strip_copy(ecl_kw_iget_ptr( global_zwel_kw , zwel_offset )); // Hardwired max 8 characters in Well Name
}
well_state = well_state_alloc(name , global_well_nr , open , type , report_nr , global_header->sim_time);
free( name );
well_state_add_connections( well_state , grid , ecl_file , global_well_nr);
if (ecl_file_has_kw( ecl_file , ISEG_KW))
well_state_add_MSW( well_state , ecl_file , global_well_nr );
}
ecl_rsthead_free( global_header );
return well_state;
@ -282,14 +465,18 @@ well_state_type * well_state_alloc( ecl_file_type * ecl_file , int report_nr ,
return NULL;
}
void well_state_free( well_state_type * well ) {
hash_free( well->name_lgr_path );
vector_free( well->index_lgr_path );
void well_state_free( well_state_type * well ) {
hash_free( well->name_wellhead );
vector_free( well->index_wellhead );
well_path_free( well->null_path );
hash_free( well->connections );
well_segment_collection_free( well->segments );
well_branch_collection_free( well->branches );
free( well->name );
free( well );
@ -329,146 +516,54 @@ bool well_state_is_open( const well_state_type * well_state ) {
return well_state->open;
}
int well_state_get_well_nr( const well_state_type * well_state ) {
return well_state->global_well_nr;
}
const char * well_state_get_name( const well_state_type * well_state ) {
return well_state->name;
}
/*****************************************************************/
well_path_type * well_state_get_path( const well_state_type * well_state , const char * lgr_name) {
if (hash_has_key( well_state->name_lgr_path , lgr_name))
return hash_get( well_state->name_lgr_path , lgr_name );
else
return well_state->null_path;
}
well_path_type * well_state_iget_path( const well_state_type * well_state , int grid_nr) {
well_path_type * path = vector_safe_iget( well_state->index_lgr_path , grid_nr );
if (path != NULL)
return path;
else
return well_state->null_path;
}
const well_conn_type ** well_state_iget_lgr_connections(const well_state_type * well_state , int grid_nr , int branch_nr ) {
well_path_type * well_path = well_state_iget_path( well_state , grid_nr );
well_branch_type * branch = well_path_iget_branch( well_path , branch_nr );
if (branch != NULL)
return well_branch_get_connections( branch );
else
return NULL; // Branch does not exist - or has 0 connections.
}
const well_conn_type ** well_state_get_lgr_connections(const well_state_type * well_state , const char * lgr_name , int branch_nr) {
well_path_type * well_path = well_state_get_path( well_state , lgr_name );
well_branch_type * branch = well_path_iget_branch( well_path , branch_nr );
if (branch != NULL)
return well_branch_get_connections( branch );
else
return NULL; // Branch does not exist - or has 0 connections.
}
const well_conn_type ** well_state_get_connections(const well_state_type * well_state , int branch_nr ) {
return well_state_iget_lgr_connections(well_state , 0 , branch_nr );
}
/*****************************************************************/
int well_state_iget_num_lgr_connections(const well_state_type * well_state , int grid_nr , int branch_nr ) {
well_path_type * well_path = well_state_iget_path( well_state , grid_nr );
well_branch_type * branch = well_path_iget_branch( well_path , branch_nr );
if (branch != NULL)
return well_branch_get_length( branch );
else
return 0;
}
int well_state_get_num_lgr_connections(const well_state_type * well_state , const char * lgr_name , int branch_nr) {
well_path_type * well_path = well_state_get_path( well_state , lgr_name );
well_branch_type * branch = well_path_iget_branch( well_path , branch_nr );
if (branch != NULL)
return well_branch_get_length( branch );
else
return 0;
}
int well_state_get_num_connections(const well_state_type * well_state , int branch_nr ) {
return well_state_iget_num_lgr_connections(well_state , 0 , branch_nr );
}
/*****************************************************************/
int well_state_iget_lgr_num_branches( const well_state_type * well_state , int grid_nr) {
well_path_type * well_path = well_state_iget_path( well_state , grid_nr );
return well_path_get_max_branches( well_path );
}
int well_state_get_lgr_num_branches( const well_state_type * well_state , const char * lgr_name) {
well_path_type * well_path = well_state_get_path( well_state , lgr_name );
return well_path_get_max_branches( well_path );
}
int well_state_get_num_branches(const well_state_type * well_state ) {
return well_state_iget_lgr_num_branches( well_state , 0 );
}
/*****************************************************************/
int well_state_get_num_paths( const well_state_type * well_state ) {
return vector_get_size( well_state->index_lgr_path );
}
/*****************************************************************/
void well_state_summarize( const well_state_type * well_state , FILE * stream ) {
fprintf(stream , "Well: %s \n" , well_state->name );
{
int grid_nr;
for (grid_nr=0; grid_nr < well_state_get_num_paths( well_state ); grid_nr++) {
well_path_type * well_path = well_state_iget_path(well_state , grid_nr );
if (well_path_get_grid_name( well_path ) != NULL) {
fprintf(stream , " Grid: %-8s\n",well_path_get_grid_name( well_path ));
{
const well_conn_type * global_head = well_state_iget_wellhead( well_state , grid_nr );
if (global_head != NULL)
fprintf(stream , " Wellhead: (%3d,%3d,%3d)\n" , well_conn_get_i( global_head ) , well_conn_get_j(global_head) , well_conn_get_k( global_head) );
else
fprintf(stream , " Wellhead: ------------\n" );
}
{
int num_branches = well_path_get_max_branches(well_path);
int branch_nr;
for (branch_nr = 0; branch_nr < num_branches; branch_nr++) {
well_branch_type * branch = well_path_iget_branch( well_path , branch_nr );
if (branch != NULL) {
const well_conn_type ** connections = well_branch_get_connections( branch );
int num_connections = well_branch_get_length( branch );
int iconn;
fprintf(stream , " Branch %2d: [" , branch_nr );
for (iconn=0; iconn < num_connections; iconn++) {
const well_conn_type * conn = connections[ iconn ];
fprintf(stream, "(%3d,%3d,%3d)",well_conn_get_i( conn ) , well_conn_get_j( conn ), well_conn_get_k( conn ));
if (iconn == (num_connections - 1))
fprintf(stream , "]\n");
else {
fprintf(stream , ", ");
if ((iconn + 1) % 10 == 0)
fprintf(stream , "\n ");
}
}
}
}
}
}
}
}
}
const well_conn_collection_type * well_state_get_grid_connections( const well_state_type * well_state , const char * grid_name) {
if (hash_has_key( well_state->connections , grid_name))
return hash_get( well_state->connections , grid_name);
else
return NULL;
}
const well_conn_collection_type * well_state_get_global_connections( const well_state_type * well_state ) {
return well_state_get_grid_connections( well_state , ECL_GRID_GLOBAL_GRID );
}
bool well_state_has_grid_connections( const well_state_type * well_state , const char * grid_name) {
if (hash_has_key( well_state->connections , grid_name))
return true;
else
return false;
}
bool well_state_has_global_connections( const well_state_type * well_state ) {
return well_state_has_grid_connections( well_state , ECL_GRID_GLOBAL_GRID );
}
well_segment_collection_type * well_state_get_segments( const well_state_type * well_state ) {
return well_state->segments;
}
well_branch_collection_type * well_state_get_branches( const well_state_type * well_state ) {
return well_state->branches;
}

View File

@ -1,3 +1,97 @@
add_executable( well_conn_collection well_conn_collection.c )
target_link_libraries( well_conn_collection ecl_well )
set_target_properties( well_conn_collection PROPERTIES COMPILE_FLAGS "-Werror")
add_test( well_conn_collection ${EXECUTABLE_OUTPUT_PATH}/well_conn_collection )
add_executable( well_branch_collection well_branch_collection.c )
target_link_libraries( well_branch_collection ecl_well )
set_target_properties( well_branch_collection PROPERTIES COMPILE_FLAGS "-Werror")
add_test( well_branch_collection ${EXECUTABLE_OUTPUT_PATH}/well_branch_collection )
add_executable( well_conn well_conn.c )
target_link_libraries( well_conn ecl_well )
set_target_properties( well_conn PROPERTIES COMPILE_FLAGS "-Werror")
add_test( well_conn ${EXECUTABLE_OUTPUT_PATH}/well_conn )
add_executable( well_state well_state.c )
target_link_libraries( well_state ecl_well )
set_target_properties( well_state PROPERTIES COMPILE_FLAGS "-Werror")
add_test( well_state ${EXECUTABLE_OUTPUT_PATH}/well_state )
add_executable( well_state_load well_state_load.c )
target_link_libraries( well_state_load ecl_well )
set_target_properties( well_state_load PROPERTIES COMPILE_FLAGS "-Werror")
add_executable( well_state_load_missing_RSEG well_state_load_missing_RSEG.c )
target_link_libraries( well_state_load_missing_RSEG ecl_well )
set_target_properties( well_state_load_missing_RSEG PROPERTIES COMPILE_FLAGS "-Werror")
add_test( well_state_load1 ${EXECUTABLE_OUTPUT_PATH}/well_state_load ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/Gurbat/ECLIPSE.EGRID
${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/Gurbat/ECLIPSE.X0030)
add_test( well_state_load2 ${EXECUTABLE_OUTPUT_PATH}/well_state_load ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/MSWcase/MSW_CASE.EGRID
${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/MSWcase/MSW_CASE.X0021)
add_test( well_state_load3 ${EXECUTABLE_OUTPUT_PATH}/well_state_load ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/Troll/MSW/MSW.EGRID
${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/Troll/MSW/MSW.X0123)
add_test( well_state_load4 ${EXECUTABLE_OUTPUT_PATH}/well_state_load ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/Troll/MSW_LGR/LGR.EGRID
${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/Troll/MSW_LGR/LGR.X0095)
add_test( well_state_load5 ${EXECUTABLE_OUTPUT_PATH}/well_state_load ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/10kcase/TEST10K_FLT_LGR_NNC.EGRID
${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/10kcase/TEST10K_FLT_LGR_NNC.X0061)
add_test( well_state_load_missing_RSEG1 ${EXECUTABLE_OUTPUT_PATH}/well_state_load_missing_RSEG ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/10kcase/TEST10K_FLT_LGR_NNC.EGRID
${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/10kcase/TEST10K_FLT_LGR_NNC.X0061)
add_test( well_state_load_missing_RSEG2 ${EXECUTABLE_OUTPUT_PATH}/well_state_load_missing_RSEG ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/Troll/MSW/MSW.EGRID
${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/Troll/MSW/MSW.X0123)
add_executable( well_segment well_segment.c )
target_link_libraries( well_segment ecl_well )
set_target_properties( well_segment PROPERTIES COMPILE_FLAGS "-Werror")
add_test( well_segment ${EXECUTABLE_OUTPUT_PATH}/well_segment )
add_executable( well_segment_conn well_segment_conn.c )
target_link_libraries( well_segment_conn ecl_well )
set_target_properties( well_segment_conn PROPERTIES COMPILE_FLAGS "-Werror")
add_test( well_segment_conn ${EXECUTABLE_OUTPUT_PATH}/well_segment_conn )
add_executable( well_segment_load well_segment_load.c )
target_link_libraries( well_segment_load ecl_well )
set_target_properties( well_segment_load PROPERTIES COMPILE_FLAGS "-Werror")
add_test( well_segment_load ${EXECUTABLE_OUTPUT_PATH}/well_segment_load ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/MSWcase/MSW_CASE.X0021)
add_executable( well_segment_branch_conn_load well_segment_branch_conn_load.c )
target_link_libraries( well_segment_branch_conn_load ecl_well )
set_target_properties( well_segment_branch_conn_load PROPERTIES COMPILE_FLAGS "-Werror")
add_test( well_segment_branch_conn_load ${EXECUTABLE_OUTPUT_PATH}/well_segment_branch_conn_load ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/MSWcase/MSW_CASE.X0021)
add_executable( well_info well_info.c )
target_link_libraries( well_info ecl_well )
set_target_properties( well_info PROPERTIES COMPILE_FLAGS "-Werror")
add_test( well_info ${EXECUTABLE_OUTPUT_PATH}/well_info ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/Gurbat/ECLIPSE.EGRID )
add_executable( well_segment_collection well_segment_collection.c )
target_link_libraries( well_segment_collection ecl_well )
set_target_properties( well_segment_collection PROPERTIES COMPILE_FLAGS "-Werror")
add_test( well_segment_collection ${EXECUTABLE_OUTPUT_PATH}/well_segment_collection )
add_executable( well_conn_load well_conn_load.c )
target_link_libraries( well_conn_load ecl_well )
set_target_properties( well_conn_load PROPERTIES COMPILE_FLAGS "-Werror")
add_test( well_conn_load1 ${EXECUTABLE_OUTPUT_PATH}/well_conn_load ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/Gurbat/ECLIPSE.X0030 F)
add_test( well_conn_load2 ${EXECUTABLE_OUTPUT_PATH}/well_conn_load ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/10kcase/TEST10K_FLT_LGR_NNC.X0021 F)
add_test( well_conn_load3 ${EXECUTABLE_OUTPUT_PATH}/well_conn_load ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/MSWcase/MSW_CASE.X0021 T)
add_test( well_conn_load4 ${EXECUTABLE_OUTPUT_PATH}/well_conn_load ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/AmalgLGRcase/TESTCASE_AMALG_LGR.X0021 F)
add_test( well_conn_load5 ${EXECUTABLE_OUTPUT_PATH}/well_conn_load ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/DualPoro/DUALPORO.X0009 F)
add_test( well_conn_load6 ${EXECUTABLE_OUTPUT_PATH}/well_conn_load ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/0.9.2_LGR/BASE_REF_XY3Z1_T30_WI.X0003 F)
add_executable( well_ts well_ts.c )
target_link_libraries( well_ts ecl_well )
add_test( well_ts ${EXECUTABLE_OUTPUT_PATH}/well_ts ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/CO2case/BASE_CASE )
@ -12,10 +106,27 @@ add_test( well_dualp ${EXECUTABLE_OUTPUT_PATH}/well_dualp ${PROJECT_SOURCE_DIR}
add_executable( well_lgr_load well_lgr_load.c )
target_link_libraries( well_lgr_load ecl_well )
add_test( well_lgr_load1 ${EXECUTABLE_OUTPUT_PATH}/well_lgr_load ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/0.9.2_LGR/BASE_REF_XY3Z1_T30_WI.X0003)
add_test( well_lgr_load2 ${EXECUTABLE_OUTPUT_PATH}/well_lgr_load ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/AmalgLGRcase/TESTCASE_AMALG_LGR.X0016)
add_test( well_lgr_load1 ${EXECUTABLE_OUTPUT_PATH}/well_lgr_load ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/0.9.2_LGR/BASE_REF_XY3Z1_T30_WI.EGRID ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/0.9.2_LGR/BASE_REF_XY3Z1_T30_WI.X0003)
add_test( well_lgr_load2 ${EXECUTABLE_OUTPUT_PATH}/well_lgr_load ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/AmalgLGRcase/TESTCASE_AMALG_LGR.EGRID ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/AmalgLGRcase/TESTCASE_AMALG_LGR.X0016)
set_property( TEST well_lgr_load1 PROPERTY LABELS Statoil )
set_property( TEST well_lgr_load2 PROPERTY LABELS Statoil )
set_property( TEST well_dualp PROPERTY LABELS Statoil )
set_property( TEST well_ts PROPERTY LABELS Statoil )
set_property( TEST well_lgr_load1 PROPERTY LABELS StatoilData )
set_property( TEST well_lgr_load2 PROPERTY LABELS StatoilData )
set_property( TEST well_dualp PROPERTY LABELS StatoilData )
set_property( TEST well_state_load1 PROPERTY LABELS StatoilData )
set_property( TEST well_state_load2 PROPERTY LABELS StatoilData )
set_property( TEST well_state_load3 PROPERTY LABELS StatoilData )
set_property( TEST well_state_load4 PROPERTY LABELS StatoilData )
set_property( TEST well_state_load5 PROPERTY LABELS StatoilData )
set_property( TEST well_state_load_missing_RSEG1 PROPERTY LABELS StatoilData )
set_property( TEST well_state_load_missing_RSEG2 PROPERTY LABELS StatoilData )
set_property( TEST well_dualp PROPERTY LABELS StatoilData )
set_property( TEST well_conn_load1 PROPERTY LABELS StatoilData )
set_property( TEST well_conn_load2 PROPERTY LABELS StatoilData )
set_property( TEST well_conn_load3 PROPERTY LABELS StatoilData )
set_property( TEST well_conn_load4 PROPERTY LABELS StatoilData )
set_property( TEST well_conn_load5 PROPERTY LABELS StatoilData )
set_property( TEST well_conn_load6 PROPERTY LABELS StatoilData )
set_property( TEST well_info PROPERTY LABELS StatoilData )
set_property( TEST well_segment_load PROPERTY LABELS StatoilData )
set_property( TEST well_segment_branch_conn_load PROPERTY LABELS StatoilData )
set_property( TEST well_ts PROPERTY LABELS StatoilData )

View File

@ -0,0 +1,70 @@
/*
Copyright (C) 2013 Statoil ASA, Norway.
The file 'well_branch_collection.c' is part of ERT - Ensemble based Reservoir Tool.
ERT 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.
ERT 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.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#include <stdlib.h>
#include <stdbool.h>
#include <ert/util/test_util.h>
#include <ert/util/stringlist.h>
#include <ert/util/util.h>
#include <ert/ecl/ecl_util.h>
#include <ert/ecl_well/well_branch_collection.h>
#include <ert/ecl_well/well_conn.h>
#include <ert/ecl_well/well_const.h>
int main(int argc , char ** argv) {
test_install_SIGNALS();
well_branch_collection_type * branches = well_branch_collection_alloc();
double * rseg_data = util_calloc( 100 , sizeof * rseg_data );
const double depth = 100;
const double length = 20;
const double total_length = 200;
const double diameter = 10;
rseg_data[ RSEG_DEPTH_INDEX ] = depth;
rseg_data[ RSEG_LENGTH_INDEX ] = length;
rseg_data[ RSEG_TOTAL_LENGTH_INDEX ] = total_length;
rseg_data[ RSEG_DIAMETER_INDEX ] = diameter;
test_assert_true( well_branch_collection_is_instance( branches ));
test_assert_int_equal( well_branch_collection_get_size( branches ) , 0 );
test_assert_NULL( well_branch_collection_iget_start_segment( branches , 0 ));
test_assert_NULL( well_branch_collection_get_start_segment( branches , 0 ));
test_assert_false( well_branch_collection_has_branch( branches , 0 ));
{
well_segment_type * segment1 = well_segment_alloc(189 , 99 , 78 , rseg_data);
well_segment_type * segment2 = well_segment_alloc(200 , 189 , 78 , rseg_data);
test_assert_false( well_branch_collection_add_start_segment( branches , segment1 ));
test_assert_true( well_segment_link( segment2 , segment1 ));
test_assert_true( well_branch_collection_add_start_segment( branches , segment2 ));
test_assert_int_equal( well_branch_collection_get_size( branches ) , 1 );
test_assert_true( well_segment_is_instance( well_branch_collection_iget_start_segment( branches , 0 )));
test_assert_true( well_segment_is_instance( well_branch_collection_get_start_segment( branches , 78 )));
test_assert_true( well_branch_collection_has_branch( branches , 78 ));
}
well_branch_collection_free( branches );
exit(0);
}

View File

@ -0,0 +1,123 @@
/*
Copyright (C) 2013 Statoil ASA, Norway.
The file 'well_conn.c' is part of ERT - Ensemble based Reservoir Tool.
ERT 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.
ERT 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.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#include <stdlib.h>
#include <stdbool.h>
#include <ert/util/test_util.h>
#include <ert/util/stringlist.h>
#include <ert/util/util.h>
#include <ert/ecl/ecl_util.h>
#include <ert/ecl_well/well_conn_collection.h>
#include <ert/ecl_well/well_conn.h>
int main(int argc , char ** argv) {
int i = 10;
int j = 5;
int k = 16;
bool open = true;
test_install_SIGNALS();
{
well_conn_dir_enum dir = well_conn_dirX;
well_conn_type * conn = well_conn_alloc(i,j,k,dir,open);
well_conn_type * conn2 = well_conn_alloc(i,j,k,dir,open);
well_conn_type * conn3 = well_conn_alloc(i,j,k+1,dir,open);
test_assert_not_NULL( conn );
test_assert_true( well_conn_is_instance( conn ));
test_assert_int_equal( i , well_conn_get_i( conn ));
test_assert_int_equal( j , well_conn_get_j( conn ));
test_assert_int_equal( k , well_conn_get_k( conn ));
test_assert_int_equal( dir , well_conn_get_dir( conn ));
test_assert_bool_equal( open , well_conn_open( conn ));
test_assert_false( well_conn_MSW( conn ));
test_assert_true( well_conn_matrix_connection( conn ));
test_assert_true( well_conn_equal( conn , conn2 ));
test_assert_false( well_conn_equal( conn , conn3 ));
well_conn_free( conn );
}
{
well_conn_dir_enum dir = well_conn_fracX;
well_conn_type * conn = well_conn_alloc(i,j,k,dir,open);
test_assert_NULL( conn );
}
{
well_conn_dir_enum dir = well_conn_fracX;
well_conn_type * conn = well_conn_alloc_fracture(i,j,k,dir,open);
test_assert_not_NULL( conn );
test_assert_int_equal( i , well_conn_get_i( conn ));
test_assert_int_equal( j , well_conn_get_j( conn ));
test_assert_int_equal( k , well_conn_get_k( conn ));
test_assert_bool_equal( open , well_conn_open( conn ));
test_assert_int_equal( dir , well_conn_get_dir( conn ));
test_assert_false( well_conn_MSW( conn ));
test_assert_false( well_conn_matrix_connection( conn ));
test_assert_true( well_conn_fracture_connection( conn ));
well_conn_free( conn );
}
{
well_conn_dir_enum dir = well_conn_dirX;
well_conn_type * conn = well_conn_alloc_fracture(i,j,k,dir,open);
test_assert_not_NULL( conn );
}
{
int segment = 16;
well_conn_dir_enum dir = well_conn_dirX;
well_conn_type * conn = well_conn_alloc_MSW(i,j,k,dir,open,segment);
test_assert_not_NULL( conn );
test_assert_int_equal( i , well_conn_get_i( conn ));
test_assert_int_equal( j , well_conn_get_j( conn ));
test_assert_int_equal( k , well_conn_get_k( conn ));
test_assert_int_equal( segment , well_conn_get_segment( conn ));
test_assert_bool_equal( open , well_conn_open( conn ));
test_assert_int_equal( dir , well_conn_get_dir( conn ));
test_assert_true( well_conn_MSW( conn ));
test_assert_true( well_conn_matrix_connection( conn ));
well_conn_free( conn );
}
{
int segment = 16;
well_conn_dir_enum dir = well_conn_fracX;
well_conn_type * conn = well_conn_alloc_fracture_MSW(i,j,k,dir,open,segment);
test_assert_not_NULL( conn );
test_assert_int_equal( i , well_conn_get_i( conn ));
test_assert_int_equal( j , well_conn_get_j( conn ));
test_assert_int_equal( k , well_conn_get_k( conn ));
test_assert_int_equal( segment , well_conn_get_segment( conn ));
test_assert_bool_equal( open , well_conn_open( conn ));
test_assert_int_equal( dir , well_conn_get_dir( conn ));
test_assert_true( well_conn_MSW( conn ));
test_assert_false( well_conn_matrix_connection( conn ));
well_conn_free( conn );
}
}

View File

@ -0,0 +1,55 @@
/*
Copyright (C) 2013 Statoil ASA, Norway.
The file 'well_conn_collection.c' is part of ERT - Ensemble based Reservoir Tool.
ERT 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.
ERT 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.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#include <stdlib.h>
#include <stdbool.h>
#include <ert/util/test_util.h>
#include <ert/util/stringlist.h>
#include <ert/util/util.h>
#include <ert/ecl/ecl_util.h>
#include <ert/ecl_well/well_conn_collection.h>
#include <ert/ecl_well/well_conn.h>
void test_empty() {
well_conn_collection_type * wellcc = well_conn_collection_alloc( );
test_assert_not_NULL( wellcc );
test_assert_true( well_conn_collection_is_instance( wellcc ));
test_assert_int_equal( 0 , well_conn_collection_get_size( wellcc ));
{
well_conn_type * conn = well_conn_collection_iget( wellcc , 0 );
test_assert_NULL( conn );
}
{
const well_conn_type * conn = well_conn_collection_iget_const( wellcc , 10 );
test_assert_NULL( conn );
}
well_conn_collection_free( wellcc );
}
int main(int argc , char ** argv) {
test_empty();
exit(0);
}

View File

@ -0,0 +1,104 @@
/*
Copyright (C) 2013 Statoil ASA, Norway.
The file 'well_conn_load.c' is part of ERT - Ensemble based Reservoir Tool.
ERT 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.
ERT 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.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#include <stdlib.h>
#include <stdbool.h>
#include <ert/util/test_util.h>
#include <ert/util/stringlist.h>
#include <ert/util/util.h>
#include <ert/ecl/ecl_util.h>
#include <ert/ecl/ecl_file.h>
#include <ert/ecl/ecl_rsthead.h>
#include <ert/ecl/ecl_kw_magic.h>
#include <ert/ecl_well/well_conn.h>
#include <ert/ecl_well/well_conn_collection.h>
#include <ert/ecl_well/well_const.h>
int main(int argc , char ** argv) {
const char * Xfile = argv[1];
bool MSW;
ecl_file_type * rst_file = ecl_file_open( Xfile , 0 );
ecl_rsthead_type * rst_head = ecl_rsthead_alloc( rst_file );
test_install_SIGNALS();
test_assert_true( util_sscanf_bool( argv[2] , &MSW ));
test_assert_not_NULL( rst_file );
test_assert_not_NULL( rst_head );
{
int iwell;
const ecl_kw_type * iwel_kw = ecl_file_iget_named_kw( rst_file , IWEL_KW , 0 );
const ecl_kw_type * icon_kw = ecl_file_iget_named_kw( rst_file , ICON_KW , 0 );
bool caseMSW = false;
for (iwell = 0; iwell < rst_head->nwells; iwell++) {
const int iwel_offset = rst_head->niwelz * iwell;
int num_connections = ecl_kw_iget_int( iwel_kw , iwel_offset + IWEL_CONNECTIONS_ITEM );
int iconn;
well_conn_collection_type * wellcc = well_conn_collection_alloc( );
well_conn_collection_type * wellcc_ref = well_conn_collection_alloc();
for (iconn = 0; iconn < num_connections; iconn++) {
well_conn_type * conn = well_conn_alloc_from_kw( icon_kw , rst_head , iwell , iconn );
test_assert_true( well_conn_is_instance( conn ));
test_assert_not_NULL( conn );
if (!MSW)
test_assert_bool_equal( well_conn_MSW( conn ) , MSW);
else
caseMSW |= well_conn_MSW( conn );
well_conn_collection_add( wellcc , conn );
well_conn_collection_add_ref( wellcc_ref , conn );
test_assert_int_equal( iconn + 1 , well_conn_collection_get_size( wellcc ));
test_assert_ptr_equal( well_conn_collection_iget_const( wellcc , iconn) , conn);
test_assert_ptr_equal( well_conn_collection_iget_const( wellcc_ref , iconn) , conn);
}
well_conn_collection_free( wellcc_ref );
{
int i;
for (i=0; i < well_conn_collection_get_size( wellcc ); i++)
test_assert_true( well_conn_is_instance( well_conn_collection_iget_const( wellcc , i )));
}
{
well_conn_collection_type * wellcc2 = well_conn_collection_alloc();
int i;
test_assert_int_equal( well_conn_collection_get_size( wellcc ) ,
well_conn_collection_load_from_kw( wellcc2 , iwel_kw , icon_kw , iwell , rst_head));
for (i=0; i < well_conn_collection_get_size( wellcc2 ); i++) {
test_assert_true( well_conn_is_instance( well_conn_collection_iget_const( wellcc2 , i )));
test_assert_true( well_conn_equal( well_conn_collection_iget_const( wellcc2 , i ) , well_conn_collection_iget_const( wellcc , i )));
}
well_conn_collection_free( wellcc2 );
}
well_conn_collection_free( wellcc );
}
test_assert_bool_equal( caseMSW , MSW);
}
exit( 0 );
}

View File

@ -0,0 +1,44 @@
/*
Copyright (C) 2013 Statoil ASA, Norway.
The file 'well_conn.c' is part of ERT - Ensemble based Reservoir Tool.
ERT 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.
ERT 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.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#include <stdlib.h>
#include <stdbool.h>
#include <ert/util/test_util.h>
#include <ert/util/stringlist.h>
#include <ert/util/util.h>
#include <ert/ecl/ecl_util.h>
#include <ert/ecl/ecl_grid.h>
#include <ert/ecl_well/well_info.h>
int main(int argc , char ** argv) {
const char * grid_file = argv[1];
ecl_grid_type * grid = ecl_grid_alloc( grid_file );
test_assert_not_NULL( grid );
{
well_info_type * well_info = well_info_alloc( grid );
test_assert_not_NULL( well_info );
well_info_free( well_info );
}
ecl_grid_free( grid );
exit(0);
}

View File

@ -41,12 +41,10 @@ int main( int argc , char ** argv) {
Killing with SIGKILL (-9) will not give a backtrace.*/
signal(SIGABRT , util_abort_signal); /* Signal abort. */
{
well_info_type * well_info = well_info_alloc( NULL );
int i;
for (i=1; i < argc; i++) {
printf("Loading file: %s \n",argv[i]);
well_info_load_rstfile( well_info , argv[i]);
}
ecl_grid_type * grid = ecl_grid_alloc( argv[1] );
well_info_type * well_info = well_info_alloc( grid );
well_info_load_rstfile( well_info , argv[2]);
// List all wells:
{

View File

@ -0,0 +1,115 @@
/*
Copyright (C) 2013 Statoil ASA, Norway.
The file 'well_segment.c' is part of ERT - Ensemble based Reservoir Tool.
ERT 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.
ERT 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.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#include <stdlib.h>
#include <stdbool.h>
#include <ert/util/test_util.h>
#include <ert/util/stringlist.h>
#include <ert/util/util.h>
#include <ert/ecl/ecl_util.h>
#include <ert/ecl_well/well_segment.h>
#include <ert/ecl_well/well_const.h>
int main(int argc , char ** argv) {
test_install_SIGNALS();
double * rseg_data = util_calloc( 100 , sizeof * rseg_data );
const double depth = 100;
const double length = 20;
const double total_length = 200;
const double diameter = 10;
rseg_data[ RSEG_DEPTH_INDEX ] = depth;
rseg_data[ RSEG_LENGTH_INDEX ] = length;
rseg_data[ RSEG_TOTAL_LENGTH_INDEX ] = total_length;
rseg_data[ RSEG_DIAMETER_INDEX ] = diameter;
{
int segment_id = 78;
int outlet_segment_id = 100;
int branch_nr = ECLIPSE_WELL_SEGMENT_BRANCH_MAIN_STEM_VALUE;
well_segment_type * ws = well_segment_alloc(segment_id , outlet_segment_id , branch_nr, rseg_data);
test_assert_true( well_segment_is_instance( ws ));
test_assert_int_equal( 0 , well_segment_get_link_count( ws ));
test_assert_NULL( well_segment_get_outlet( ws ));
test_assert_int_equal( well_segment_get_outlet_id( ws ) , outlet_segment_id );
test_assert_int_equal( well_segment_get_branch_id( ws ) , branch_nr );
test_assert_int_equal( well_segment_get_id( ws ) , segment_id );
test_assert_false( well_segment_nearest_wellhead( ws ));
test_assert_true( well_segment_active( ws ));
test_assert_true( well_segment_main_stem( ws ));
test_assert_double_equal( depth , well_segment_get_depth( ws ));
test_assert_double_equal( length , well_segment_get_length( ws ));
test_assert_double_equal( total_length , well_segment_get_total_length( ws ));
test_assert_double_equal( diameter , well_segment_get_diameter( ws ));
well_segment_free( ws );
}
{
int outlet_segment_id = ECLIPSE_WELL_SEGMENT_OUTLET_END_VALUE;
int branch_nr = 100;
well_segment_type * ws = well_segment_alloc(12 , outlet_segment_id , branch_nr, rseg_data);
test_assert_true( well_segment_nearest_wellhead( ws ));
test_assert_false( well_segment_main_stem( ws ));
}
{
int outlet_segment_id = ECLIPSE_WELL_SEGMENT_OUTLET_END_VALUE;
int branch_nr = ECLIPSE_WELL_SEGMENT_BRANCH_INACTIVE_VALUE;
well_segment_type * ws = well_segment_alloc(89 , outlet_segment_id , branch_nr, rseg_data);
test_assert_false( well_segment_active( ws ));
}
{
int branch_nr = ECLIPSE_WELL_SEGMENT_BRANCH_MAIN_STEM_VALUE;
int outlet_id = 0;
well_segment_type * outlet = well_segment_alloc(outlet_id , ECLIPSE_WELL_SEGMENT_OUTLET_END_VALUE , branch_nr, rseg_data);
well_segment_type * ws = well_segment_alloc(100 , outlet_id , branch_nr, rseg_data);
test_assert_true( well_segment_link( ws , outlet ));
test_assert_ptr_equal( well_segment_get_outlet( ws ) , outlet );
test_assert_int_equal( well_segment_get_link_count( outlet ) , 1 );
test_assert_ptr_not_equal( ws , well_segment_get_outlet( ws ));
well_segment_link_strict( ws , outlet ); // This relinks - not very logical; refcount gets wrong.
well_segment_free( ws );
}
{
int branch_nr = ECLIPSE_WELL_SEGMENT_BRANCH_MAIN_STEM_VALUE;
int outlet_id = 0;
well_segment_type * outlet = well_segment_alloc(outlet_id , ECLIPSE_WELL_SEGMENT_OUTLET_END_VALUE , branch_nr , rseg_data);
well_segment_type * ws = well_segment_alloc(100 , outlet_id + 1, branch_nr, rseg_data);
test_assert_false( well_segment_link( ws , outlet ));
test_assert_NULL( well_segment_get_outlet( ws ) );
test_assert_int_equal( well_segment_get_link_count( outlet ) , 0 );
well_segment_free( ws );
}
free( rseg_data );
exit(0);
}

View File

@ -0,0 +1,106 @@
/*
Copyright (C) 2013 Statoil ASA, Norway.
The file 'well_segment_conn_load.c' is part of ERT - Ensemble based Reservoir Tool.
ERT 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.
ERT 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.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#include <stdlib.h>
#include <stdbool.h>
#include <unistd.h>
#include <ert/util/test_util.h>
#include <ert/util/stringlist.h>
#include <ert/util/util.h>
#include <ert/ecl/ecl_util.h>
#include <ert/ecl/ecl_file.h>
#include <ert/ecl/ecl_rsthead.h>
#include <ert/ecl/ecl_kw_magic.h>
#include <ert/ecl/ecl_grid.h>
#include <ert/ecl_well/well_conn_collection.h>
#include <ert/ecl_well/well_segment.h>
#include <ert/ecl_well/well_const.h>
#include <ert/ecl_well/well_segment_collection.h>
int main(int argc , char ** argv) {
const char * Xfile = argv[1];
ecl_file_type * rst_file = ecl_file_open( Xfile , 0 );
ecl_rsthead_type * rst_head = ecl_rsthead_alloc( rst_file );
const ecl_kw_type * iwel_kw = ecl_file_iget_named_kw( rst_file , IWEL_KW , 0 );
const ecl_kw_type * iseg_kw = ecl_file_iget_named_kw( rst_file , ISEG_KW , 0 );
const ecl_kw_type * rseg_kw = ecl_file_iget_named_kw( rst_file , RSEG_KW , 0 );
const ecl_kw_type * icon_kw = ecl_file_iget_named_kw( rst_file , ICON_KW , 0 );
test_install_SIGNALS();
test_assert_not_NULL( rst_file );
test_assert_not_NULL( rst_head );
{
int well_nr;
for (well_nr = 0; well_nr < rst_head->nwells; well_nr++) {
well_conn_collection_type * connections = well_conn_collection_alloc();
well_conn_collection_load_from_kw( connections , iwel_kw , icon_kw , well_nr , rst_head);
{
well_segment_collection_type * segments = well_segment_collection_alloc();
if (well_segment_collection_load_from_kw( segments , well_nr , iwel_kw , iseg_kw , rseg_kw , rst_head )) {
well_branch_collection_type * branches = well_branch_collection_alloc();
test_assert_true( well_segment_well_is_MSW( well_nr , iwel_kw , rst_head));
well_segment_collection_link( segments );
{
int is;
for (is=0; is < well_segment_collection_get_size( segments ); is++) {
well_segment_type * segment = well_segment_collection_iget( segments , is );
if (well_segment_nearest_wellhead( segment ))
test_assert_NULL( well_segment_get_outlet( segment ));
else
test_assert_not_NULL( well_segment_get_outlet( segment ));
test_assert_int_not_equal( well_segment_get_id( segment ) , well_segment_get_outlet_id( segment ));
test_assert_ptr_not_equal( segment , well_segment_get_outlet( segment ));
}
}
well_segment_collection_add_branches( segments , branches );
{
int ib;
for (ib = 0; ib < well_branch_collection_get_size( branches ); ib++) {
const well_segment_type * start_segment = well_branch_collection_iget_start_segment( branches , ib );
const well_segment_type * segment = start_segment;
printf("Branch %d " , ib );
while (segment) {
printf("%d -> ",well_segment_get_id( segment ));
segment = well_segment_get_outlet( segment );
}
printf(" X \n");
}
}
well_segment_collection_add_connections( segments , ECL_GRID_GLOBAL_GRID , connections );
well_branch_collection_free( branches );
} else
test_assert_false( well_segment_well_is_MSW( well_nr , iwel_kw , rst_head ));
well_segment_collection_free( segments );
}
well_conn_collection_free( connections );
}
}
ecl_file_close( rst_file );
ecl_rsthead_free( rst_head );
exit(0);
}

View File

@ -0,0 +1,87 @@
/*
Copyright (C) 2013 Statoil ASA, Norway.
The file 'well_segment_collection.c' is part of ERT - Ensemble based Reservoir Tool.
ERT 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.
ERT 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.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#include <stdlib.h>
#include <stdbool.h>
#include <ert/util/test_util.h>
#include <ert/util/stringlist.h>
#include <ert/util/util.h>
#include <ert/ecl/ecl_util.h>
#include <ert/ecl_well/well_segment_collection.h>
int main(int argc , char ** argv) {
test_install_SIGNALS();
double * rseg_data = util_calloc( 100 , sizeof * rseg_data );
well_segment_collection_type * sc = well_segment_collection_alloc();
test_assert_not_NULL( sc );
test_assert_int_equal( well_segment_collection_get_size( sc ) , 0 );
{
int outlet_segment_id = ECLIPSE_WELL_SEGMENT_OUTLET_END_VALUE;
int branch_nr = ECLIPSE_WELL_SEGMENT_BRANCH_INACTIVE_VALUE;
well_segment_type * ws = well_segment_alloc(89 , outlet_segment_id , branch_nr, rseg_data);
well_segment_collection_add( sc , ws );
test_assert_int_equal( well_segment_collection_get_size( sc ) , 1);
test_assert_ptr_equal( well_segment_collection_iget( sc , 0 ) , ws );
test_assert_false( well_segment_collection_has_segment( sc , 451 ));
test_assert_true( well_segment_collection_has_segment( sc , 89 ));
test_assert_ptr_equal( well_segment_collection_get( sc , 89 ) , ws );
}
{
int outlet_segment_id = ECLIPSE_WELL_SEGMENT_OUTLET_END_VALUE;
int branch_nr = ECLIPSE_WELL_SEGMENT_BRANCH_INACTIVE_VALUE;
well_segment_type * ws = well_segment_alloc(90 , outlet_segment_id , branch_nr , rseg_data);
well_segment_collection_add( sc , ws );
test_assert_int_equal( well_segment_collection_get_size( sc ) , 2);
test_assert_ptr_equal( well_segment_collection_iget( sc , 1 ) , ws );
test_assert_false( well_segment_collection_has_segment( sc , 451 ));
test_assert_true( well_segment_collection_has_segment( sc , 89 ));
test_assert_true( well_segment_collection_has_segment( sc , 90 ));
test_assert_ptr_equal( well_segment_collection_get( sc , 90 ) , ws );
test_assert_NULL( well_segment_collection_get( sc , 76 ));
}
{
int outlet_segment_id = ECLIPSE_WELL_SEGMENT_OUTLET_END_VALUE;
int branch_nr = ECLIPSE_WELL_SEGMENT_BRANCH_INACTIVE_VALUE;
well_segment_type * ws = well_segment_alloc(89 , outlet_segment_id , branch_nr, rseg_data);
well_segment_collection_add( sc , ws );
test_assert_int_equal( well_segment_collection_get_size( sc ) , 2);
test_assert_ptr_equal( well_segment_collection_iget( sc , 0 ) , ws );
test_assert_false( well_segment_collection_has_segment( sc , 451 ));
test_assert_true( well_segment_collection_has_segment( sc , 89 ));
test_assert_ptr_equal( well_segment_collection_get( sc , 89 ) , ws );
}
free( rseg_data );
well_segment_collection_free( sc );
exit(0);
}

View File

@ -0,0 +1,59 @@
/*
Copyright (C) 2013 Statoil ASA, Norway.
The file 'well_segment_conn.c' is part of ERT - Ensemble based Reservoir Tool.
ERT 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.
ERT 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.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#include <stdlib.h>
#include <stdbool.h>
#include <ert/util/test_util.h>
#include <ert/util/stringlist.h>
#include <ert/util/util.h>
#include <ert/ecl/ecl_util.h>
#include <ert/ecl/ecl_grid.h>
#include <ert/ecl_well/well_segment.h>
#include <ert/ecl_well/well_conn.h>
#include <ert/ecl_well/well_conn_collection.h>
int main(int argc , char ** argv) {
test_install_SIGNALS();
double * rseg_data = util_calloc( 100 , sizeof * rseg_data );
{
int segment_id = 78;
int outlet_segment_id = 100;
int branch_nr = ECLIPSE_WELL_SEGMENT_BRANCH_MAIN_STEM_VALUE;
well_segment_type * ws = well_segment_alloc(segment_id , outlet_segment_id , branch_nr, rseg_data);
well_conn_type * conn1 = well_conn_alloc_MSW(1,1,1,true,well_conn_dirX,segment_id);
well_conn_type * conn2 = well_conn_alloc_MSW(1,1,1,true,well_conn_dirX,segment_id + 1);
test_assert_false( well_segment_has_global_grid_connections( ws ));
test_assert_true( well_segment_add_connection( ws , ECL_GRID_GLOBAL_GRID , conn1 ));
test_assert_false( well_segment_add_connection( ws , ECL_GRID_GLOBAL_GRID , conn2 ));
test_assert_true( well_segment_has_grid_connections( ws , ECL_GRID_GLOBAL_GRID ));
test_assert_true( well_segment_has_global_grid_connections( ws ));
test_assert_false( well_segment_has_grid_connections( ws , "DoesNotExist"));
test_assert_true( well_conn_collection_is_instance( well_segment_get_connections( ws , ECL_GRID_GLOBAL_GRID)));
test_assert_true( well_conn_collection_is_instance( well_segment_get_global_connections( ws)));
test_assert_NULL( well_segment_get_connections( ws , "doesNotExist"));
}
free( rseg_data );
exit(0);
}

View File

@ -0,0 +1,107 @@
/*
Copyright (C) 2013 Statoil ASA, Norway.
The file 'well_segment_conn_load.c' is part of ERT - Ensemble based Reservoir Tool.
ERT 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.
ERT 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.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#include <stdlib.h>
#include <stdbool.h>
#include <unistd.h>
#include <ert/util/test_util.h>
#include <ert/util/stringlist.h>
#include <ert/util/util.h>
#include <ert/ecl/ecl_util.h>
#include <ert/ecl/ecl_file.h>
#include <ert/ecl/ecl_rsthead.h>
#include <ert/ecl/ecl_kw_magic.h>
#include <ert/ecl/ecl_grid.h>
#include <ert/ecl_well/well_conn_collection.h>
#include <ert/ecl_well/well_segment.h>
#include <ert/ecl_well/well_const.h>
#include <ert/ecl_well/well_segment_collection.h>
int main(int argc , char ** argv) {
const char * Xfile = argv[1];
ecl_file_type * rst_file = ecl_file_open( Xfile , 0 );
ecl_rsthead_type * rst_head = ecl_rsthead_alloc( rst_file );
const ecl_kw_type * iwel_kw = ecl_file_iget_named_kw( rst_file , IWEL_KW , 0 );
const ecl_kw_type * iseg_kw = ecl_file_iget_named_kw( rst_file , ISEG_KW , 0 );
const ecl_kw_type * rseg_kw = ecl_file_iget_named_kw( rst_file , RSEG_KW , 0 );
const ecl_kw_type * icon_kw = ecl_file_iget_named_kw( rst_file , ICON_KW , 0 );
test_install_SIGNALS();
test_assert_not_NULL( rst_file );
test_assert_not_NULL( rst_head );
{
int well_nr;
for (well_nr = 0; well_nr < rst_head->nwells; well_nr++) {
well_conn_collection_type * connections = well_conn_collection_alloc();
well_conn_collection_load_from_kw( connections , iwel_kw , icon_kw , well_nr , rst_head);
{
well_segment_collection_type * segments = well_segment_collection_alloc();
if (well_segment_collection_load_from_kw( segments , well_nr , iwel_kw , iseg_kw , rseg_kw , rst_head )) {
well_branch_collection_type * branches = well_branch_collection_alloc();
test_assert_true( well_segment_well_is_MSW( well_nr , iwel_kw , rst_head));
well_segment_collection_link( segments );
{
int is;
for (is=0; is < well_segment_collection_get_size( segments ); is++) {
well_segment_type * segment = well_segment_collection_iget( segments , is );
if (well_segment_nearest_wellhead( segment ))
test_assert_NULL( well_segment_get_outlet( segment ));
else
test_assert_not_NULL( well_segment_get_outlet( segment ));
test_assert_ptr_not_equal( segment , well_segment_get_outlet( segment ));
}
}
well_segment_collection_add_branches( segments , branches );
{
int ib;
for (ib = 0; ib < well_branch_collection_get_size( branches ); ib++) {
const well_segment_type * start_segment = well_branch_collection_iget_start_segment( branches , ib );
const well_segment_type * segment = start_segment;
printf("Branch %d/%d " , ib , well_branch_collection_get_size( branches ) );
while (segment) {
printf("[%p]%d -> \n",segment , well_segment_get_id( segment ));
segment = well_segment_get_outlet( segment );
}
printf("\n");
sleep(1);
}
}
well_segment_collection_add_connections( segments , ECL_GRID_GLOBAL_GRID , connections );
well_branch_collection_free( branches );
} else
test_assert_false( well_segment_well_is_MSW( well_nr , iwel_kw , rst_head ));
well_segment_collection_free( segments );
}
well_conn_collection_free( connections );
}
}
ecl_file_close( rst_file );
ecl_rsthead_free( rst_head );
exit(0);
}

View File

@ -0,0 +1,88 @@
/*
Copyright (C) 2013 Statoil ASA, Norway.
The file 'well_segment_load.c' is part of ERT - Ensemble based Reservoir Tool.
ERT 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.
ERT 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.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#include <stdlib.h>
#include <stdbool.h>
#include <ert/util/test_util.h>
#include <ert/util/stringlist.h>
#include <ert/util/util.h>
#include <ert/ecl/ecl_util.h>
#include <ert/ecl/ecl_file.h>
#include <ert/ecl/ecl_rsthead.h>
#include <ert/ecl/ecl_kw_magic.h>
#include <ert/ecl_well/well_segment.h>
#include <ert/ecl_well/well_const.h>
#include <ert/ecl_well/well_segment_collection.h>
int main(int argc , char ** argv) {
const char * Xfile = argv[1];
ecl_file_type * rst_file = ecl_file_open( Xfile , 0 );
ecl_rsthead_type * rst_head = ecl_rsthead_alloc( rst_file );
const ecl_kw_type * iwel_kw = ecl_file_iget_named_kw( rst_file , IWEL_KW , 0 );
const ecl_kw_type * iseg_kw = ecl_file_iget_named_kw( rst_file , ISEG_KW , 0 );
const ecl_kw_type * rseg_kw = ecl_file_iget_named_kw( rst_file , RSEG_KW , 0 );
test_install_SIGNALS();
test_assert_not_NULL( rst_file );
test_assert_not_NULL( rst_head );
{
int well_nr;
for (well_nr = 0; well_nr < rst_head->nwells; well_nr++) {
int iwel_offset = rst_head->niwelz * well_nr;
well_segment_collection_type * segments = well_segment_collection_alloc();
int seg_well_nr = ecl_kw_iget_int( iwel_kw , iwel_offset + IWEL_SEGMENTED_WELL_NR_ITEM) - 1; // -1: Ordinary well.
if (seg_well_nr >= 0) {
int segment_id;
int segment_count = 0;
for (segment_id = 0; segment_id < rst_head->nsegmx; segment_id++) {
well_segment_type * segment = well_segment_alloc_from_kw( iseg_kw , rseg_kw , rst_head , seg_well_nr , segment_id );
test_assert_true( well_segment_is_instance( segment ));
if (well_segment_active( segment )) {
well_segment_collection_add( segments , segment );
test_assert_int_equal( well_segment_collection_get_size( segments ) , segment_count + 1);
test_assert_ptr_equal( well_segment_collection_iget( segments , segment_count) , segment );
segment_count++;
} else
well_segment_free( segment );
}
}
{
well_segment_collection_type * segments2 = well_segment_collection_alloc();
test_assert_int_equal( well_segment_collection_load_from_kw( segments2 , well_nr , iwel_kw , iseg_kw , rseg_kw , rst_head ) ,
well_segment_collection_get_size( segments));
well_segment_collection_link( segments );
well_segment_collection_link( segments2 );
well_segment_collection_free( segments );
well_segment_collection_free( segments2 );
}
}
}
ecl_file_close( rst_file );
ecl_rsthead_free( rst_head );
exit(0);
}

View File

@ -0,0 +1,67 @@
/*
Copyright (C) 2013 Statoil ASA, Norway.
The file 'well_state.c' is part of ERT - Ensemble based Reservoir Tool.
ERT 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.
ERT 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.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#include <stdlib.h>
#include <stdbool.h>
#include <ert/util/test_util.h>
#include <ert/util/stringlist.h>
#include <ert/util/util.h>
#include <ert/ecl/ecl_util.h>
#include <ert/ecl_well/well_state.h>
int main(int argc , char ** argv) {
test_install_SIGNALS();
test_assert_int_equal( well_state_translate_ecl_type_int( IWEL_UNDOCUMENTED_ZERO) , UNDOCUMENTED_ZERO);
test_assert_int_equal( well_state_translate_ecl_type_int( IWEL_PRODUCER) , PRODUCER);
test_assert_int_equal( well_state_translate_ecl_type_int( IWEL_WATER_INJECTOR) , WATER_INJECTOR);
test_assert_int_equal( well_state_translate_ecl_type_int( IWEL_GAS_INJECTOR) , GAS_INJECTOR);
test_assert_int_equal( well_state_translate_ecl_type_int( IWEL_OIL_INJECTOR) , OIL_INJECTOR);
{
const char * well_name = "WELL";
int report_nr = 100;
int global_well_nr = 67;
time_t valid_from = -1;
bool open = false;
well_type_enum type = GAS_INJECTOR;
well_state_type * well_state = well_state_alloc(well_name , global_well_nr , open , type , report_nr , valid_from);
test_assert_true( well_state_is_instance( well_state) );
test_assert_false( well_state_is_MSW( well_state ));
test_assert_string_equal( well_name , well_state_get_name( well_state ));
test_assert_int_equal( global_well_nr , well_state_get_well_nr( well_state ));
test_assert_bool_equal( open , well_state_is_open( well_state ));
test_assert_int_equal( type , well_state_get_type( well_state ));
test_assert_int_equal( report_nr , well_state_get_report_nr( well_state ));
test_assert_time_t_equal( valid_from , well_state_get_sim_time( well_state ));
test_assert_NULL( well_state_get_global_connections( well_state ));
test_assert_false( well_state_has_global_connections( well_state ));
test_assert_NULL( well_state_get_grid_connections( well_state , "GRID"));
test_assert_false( well_state_has_grid_connections( well_state , "GRID"));
well_state_free( well_state );
}
exit(0);
}

View File

@ -0,0 +1,78 @@
/*
Copyright (C) 2013 Statoil ASA, Norway.
The file 'well_state_load.c' is part of ERT - Ensemble based Reservoir Tool.
ERT 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.
ERT 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.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#include <stdlib.h>
#include <stdbool.h>
#include <ert/util/test_util.h>
#include <ert/util/stringlist.h>
#include <ert/util/util.h>
#include <ert/ecl/ecl_util.h>
#include <ert/ecl/ecl_grid.h>
#include <ert/ecl/ecl_file.h>
#include <ert/ecl/ecl_kw_magic.h>
#include <ert/ecl_well/well_state.h>
int main(int argc , char ** argv) {
test_install_SIGNALS();
{
const char * grid_file = argv[1];
const char * rst_file_name = argv[2];
ecl_grid_type * grid = ecl_grid_alloc( grid_file );
ecl_file_type * rst_file = ecl_file_open( rst_file_name , 0);
ecl_rsthead_type * header = ecl_rsthead_alloc( rst_file );
const char * well_name = "WELL";
int report_nr = 100;
time_t valid_from = -1;
bool open = false;
well_type_enum type = GAS_INJECTOR;
int global_well_nr = 0;
for (global_well_nr = 0; global_well_nr < header->nwells; global_well_nr++) {
well_state_type * well_state = well_state_alloc(well_name , global_well_nr , open , type , report_nr , valid_from);
test_assert_true( well_state_is_instance( well_state) );
well_state_add_connections( well_state , grid , rst_file , 0 );
test_assert_true( well_state_has_grid_connections( well_state , ECL_GRID_GLOBAL_GRID ));
test_assert_false( well_state_has_grid_connections( well_state , "???" ));
test_assert_true( well_state_has_global_connections( well_state ));
well_state_add_MSW( well_state , rst_file , global_well_nr );
{
const well_segment_collection_type * segments = well_state_get_segments( well_state );
const well_branch_collection_type * branches = well_state_get_branches( well_state );
if (well_state_is_MSW( well_state )) {
test_assert_true( ecl_file_has_kw( rst_file , ISEG_KW ));
test_assert_int_not_equal( well_segment_collection_get_size( segments ) , 0);
test_assert_int_not_equal( well_branch_collection_get_size( branches ) , 0);
} else {
test_assert_int_equal( well_segment_collection_get_size( segments ) , 0);
test_assert_int_equal( well_branch_collection_get_size( branches ) , 0);
test_assert_false( well_state_is_MSW( well_state ));
}
}
well_state_free( well_state );
}
}
exit(0);
}

View File

@ -23,13 +23,16 @@
#include <ert/util/util.h>
#include <ert/ecl/ecl_util.h>
#include <ert/ecl/ecl_grid.h>
#include <ert/ecl_well/well_info.h>
int main(int argc , char ** argv) {
const char * case_path = argv[1];
char * grid_file = util_alloc_filename(NULL , case_path, "EGRID");
stringlist_type * file_list = stringlist_alloc_new( );
ecl_grid_type * grid = ecl_grid_alloc( grid_file );
ecl_util_select_filelist( NULL , case_path , ECL_RESTART_FILE , false , file_list);
printf("Searching in:%s \n",case_path);
@ -50,7 +53,7 @@ int main(int argc , char ** argv) {
}
}
{
well_info_type * well_info = well_info_alloc( NULL );
well_info_type * well_info = well_info_alloc( grid );
int i;
for (i=0; i < stringlist_get_size( file_list ); i++)
well_info_load_rstfile( well_info , stringlist_iget(file_list , i));
@ -58,7 +61,7 @@ int main(int argc , char ** argv) {
}
{
well_info_type * well_info = well_info_alloc( NULL );
well_info_type * well_info = well_info_alloc( grid );
int i;
stringlist_reverse( file_list );
for (i=0; i < stringlist_get_size( file_list ); i++)

View File

@ -1,93 +0,0 @@
# Copyright (C) 2011 Statoil ASA, Norway.
#
# The file 'analysis.py' is part of ERT - Ensemble based Reservoir Tool.
#
# ERT 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.
#
# ERT 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.
#
# See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
# for more details.
# ----------------------------------------------------------------------------------------------
# Analysis tab
# ----------------------------------------------------------------------------------------------
from ert_gui.widgets.checkbox import CheckBox
from ert_gui.widgets.spinnerwidgets import IntegerSpinner, DoubleSpinner, DoubleSpinner
import ert_gui.widgets.tablewidgets
from ert_gui.widgets.pathchooser import PathChooser
from ert_gui.widgets.combochoice import ComboChoice
from PyQt4 import QtGui
import ert.enkf
def createAnalysisPage(configPanel, parent):
configPanel.startPage("Analysis")
r = configPanel.addRow(CheckBox(parent, "ENKF rerun", "config/analysis/enkf_rerun", "Perform rerun"))
r.getter = lambda ert : ert.enkf.analysis_config_get_rerun(ert.analysis_config)
r.setter = lambda ert, value : ert.enkf.analysis_config_set_rerun(ert.analysis_config, value)
r = configPanel.addRow(IntegerSpinner(parent, "Rerun start", "config/analysis/rerun_start", 0, 100000))
r.getter = lambda ert : ert.enkf.analysis_config_get_rerun_start(ert.analysis_config)
r.setter = lambda ert, value : ert.enkf.analysis_config_set_rerun_start(ert.analysis_config, value)
r = configPanel.addRow(PathChooser(parent, "ENKF schedule file", "config/analysis/enkf_sched_file"))
r.getter = lambda ert : ert.enkf.model_config_get_enkf_sched_file(ert.enkf.enkf_main_get_model_config(ert.main))
r.setter = lambda ert, value : ert.enkf.model_config_set_enkf_sched_file(ert.enkf.enkf_main_get_model_config(ert.main), str(value))
r = configPanel.addRow(ert_gui.widgets.tablewidgets.KeywordList(parent, "Local config", "config/analysis/local_config"))
r.newKeywordPopup = lambda list : QtGui.QFileDialog.getOpenFileName(r, "Select a path", "")
def get_local_config_files(ert):
local_config = ert.enkf.enkf_main_get_local_config(ert.main)
config_files_pointer = ert.enkf.local_config_get_config_files(local_config)
return ert.getStringList(config_files_pointer)
r.getter = get_local_config_files
def add_config_file(ert, value):
local_config = ert.enkf.enkf_main_get_local_config(ert.main)
ert.enkf.local_config_clear_config_files(local_config)
for file in value:
ert.enkf.local_config_add_config_file(local_config, file)
r.setter = add_config_file
r = configPanel.addRow(PathChooser(parent, "Update log", "config/analysis/update_log"))
r.getter = lambda ert : ert.enkf.analysis_config_get_log_path(ert.analysis_config)
r.setter = lambda ert, value : ert.enkf.analysis_config_set_log_path(ert.analysis_config, str(value))
configPanel.startGroup("EnKF")
r = configPanel.addRow(DoubleSpinner(parent, "Alpha", "config/analysis/enkf_alpha", 0, 100000, 2))
r.getter = lambda ert : ert.enkf.analysis_config_get_alpha(ert.analysis_config)
r.setter = lambda ert, value : ert.enkf.analysis_config_set_alpha(ert.analysis_config, value)
r = configPanel.addRow(CheckBox(parent, "Merge Observations", "config/analysis/enkf_merge_observations", "Perform merge"))
r.getter = lambda ert : ert.enkf.analysis_config_get_merge_observations(ert.analysis_config)
r.setter = lambda ert, value : ert.enkf.analysis_config_set_merge_observations(ert.analysis_config, value)
enkf_mode_type = {"ENKF_STANDARD" : 10, "ENKF_SQRT" : 20}
enkf_mode_type_inverted = {10 : "ENKF_STANDARD" , 20 : "ENKF_SQRT"}
r = configPanel.addRow(ComboChoice(parent, enkf_mode_type.keys(), "Mode", "config/analysis/enkf_mode"))
r.getter = lambda ert : enkf_mode_type_inverted[ert.enkf.analysis_config_get_enkf_mode(ert.analysis_config)]
r.setter = lambda ert, value : ert.enkf.analysis_config_set_enkf_mode(ert.analysis_config, enkf_mode_type[str(value)])
r = configPanel.addRow(DoubleSpinner(parent, "Truncation", "config/analysis/enkf_truncation", 0, 1, 2))
r.getter = lambda ert : ert.enkf.analysis_config_get_truncation(ert.analysis_config)
r.setter = lambda ert, value : ert.enkf.analysis_config_set_truncation(ert.analysis_config, value)
configPanel.endGroup()
configPanel.endPage()

View File

@ -1,192 +0,0 @@
# Copyright (C) 2011 Statoil ASA, Norway.
#
# The file 'rftfetcher.py' is part of ERT - Ensemble based Reservoir Tool.
#
# ERT 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.
#
# ERT 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.
#
# See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
# for more details.
from fetcher import PlotDataFetcherHandler
import ert.ert.ertwrapper as ertwrapper
import ert.ert.enums as enums
import plotdata
from ert.ert.enums import ert_state_enum, obs_impl_type
import numpy
class RFTFetcher(PlotDataFetcherHandler):
def __init__(self):
PlotDataFetcherHandler.__init__(self)
def initialize(self, ert):
ert.prototype("long enkf_main_get_obs(long)")
ert.prototype("long enkf_main_get_fs(long)")
ert.prototype("int enkf_main_get_ensemble_size(long)")
ert.prototype("int enkf_main_get_history_length(long)")
ert.prototype("bool enkf_fs_has_node(long, long, int, int, int)")
ert.prototype("void enkf_fs_fread_node(long, long, int, int, int)")
ert.prototype("bool enkf_obs_has_key(long, char*)")
ert.prototype("long enkf_obs_get_vector(long, char*)")
ert.prototype("long enkf_obs_alloc_typed_keylist(long, int)")
ert.prototype("char* obs_vector_get_state_kw(long)")
ert.prototype("long obs_vector_iget_node(long, int)")
ert.prototype("int obs_vector_get_num_active(long)")
ert.prototype("bool obs_vector_iget_active(long, int)")
ert.prototype("long enkf_config_node_get_ref(long)")
ert.prototype("int* field_obs_get_i(long)")
ert.prototype("int* field_obs_get_j(long)")
ert.prototype("int* field_obs_get_k(long)")
ert.prototype("int field_obs_get_size(long)")
ert.prototype("void field_obs_iget(long, int, double*, double*)")
ert.prototype("double field_ijk_get_double(long, int, int, int)")
ert.prototype("long field_config_get_grid(long)")
ert.prototype("long enkf_node_alloc(long)")
ert.prototype("void enkf_node_free(long)")
ert.prototype("long enkf_node_value_ptr(long)")
ert.prototype("void ecl_grid_get_xyz3(long, int, int, int, double*, double*, double*)", lib=ert.ecl)
def isHandlerFor(self, ert, key):
enkf_obs = ert.enkf.enkf_main_get_obs(ert.main)
key_list = ert.enkf.enkf_obs_alloc_typed_keylist(enkf_obs, obs_impl_type.FIELD_OBS.value())
field_obs = ert.getStringList(key_list, free_after_use=True)
return key in field_obs
def fetch(self, ert, key, parameter, data, comparison_fs):
enkf_obs = ert.enkf.enkf_main_get_obs(ert.main)
obs_vector = ert.enkf.enkf_obs_get_vector(enkf_obs, key)
num_active = ert.enkf.obs_vector_get_num_active(obs_vector)
if num_active == 1:
report_step = ert.enkf.obs_vector_get_active_report_step(obs_vector)
elif num_active > 1:
history_length = ert.enkf.enkf_main_get_history_length(ert.main)
active = []
for index in range(history_length):
if ert.enkf.obs_vector_iget_active(obs_vector , index):
active.append(index)
print "Active:", active
report_step = active[0] #todo: enable selection from GUI
else:
return
fs = ert.enkf.enkf_main_get_fs(ert.main)
state_kw = ert.enkf.obs_vector_get_state_kw(obs_vector)
ens_size = ert.enkf.enkf_main_get_ensemble_size(ert.main)
config_node = ert.enkf.ensemble_config_get_node(ert.ensemble_config, state_kw)
field_config = ert.enkf.enkf_config_node_get_ref(config_node)
field_obs = ert.enkf.obs_vector_iget_node(obs_vector, report_step)
i = ert.enkf.field_obs_get_i(field_obs)
j = ert.enkf.field_obs_get_j(field_obs)
k = ert.enkf.field_obs_get_k(field_obs)
obs_size = ert.enkf.field_obs_get_size(field_obs)
grid = ert.enkf.field_config_get_grid(field_config)
node = ert.enkf.enkf_node_alloc(config_node)
y_obs = []
x_obs = []
x_std = []
xpos = (ertwrapper.c_double)()
ypos = (ertwrapper.c_double)()
zpos = (ertwrapper.c_double)()
value = (ertwrapper.c_double)()
std = (ertwrapper.c_double)()
for index in range(obs_size):
ert.ecl.ecl_grid_get_xyz3(grid, i[index], j[index], k[index], xpos, ypos , zpos)
y_obs.append(zpos.value)
ert.enkf.field_obs_iget(field_obs, index, value, std)
x_obs.append(value.value)
x_std.append(std.value)
data.checkMaxMin(value.value + std.value)
data.checkMaxMin(value.value - std.value)
data.obs_y = numpy.array(y_obs)
data.obs_x = numpy.array(x_obs)
data.obs_std_x = numpy.array(x_std)
data.obs_std_y = None
for member in range(ens_size):
if ert.enkf.enkf_fs_has_node(fs, config_node, report_step, member, ert_state_enum.ANALYZED.value()):
ert.enkf.enkf_fs_fread_node(fs, node, report_step, member, ert_state_enum.ANALYZED.value())
elif ert.enkf.enkf_fs_has_node(fs, config_node, report_step, member, ert_state_enum.FORECAST.value()):
ert.enkf.enkf_fs_fread_node(fs, node, report_step, member, ert_state_enum.FORECAST.value())
else:
print "No data found for member %d/%d." % (member, report_step)
continue
data.x_data[member] = []
data.y_data[member] = []
x_data = data.x_data[member]
y_data = data.y_data[member]
field = ert.enkf.enkf_node_value_ptr(node)
for index in range(obs_size):
value = ert.enkf.field_ijk_get_double(field, i[index] , j[index] , k[index])
x_data.append(value)
y_data.append(y_obs[index])
data.checkMaxMin(value)
data.x_data[member] = numpy.array(x_data)
data.y_data[member] = numpy.array(y_data)
if not comparison_fs is None:
comp_node = ert.enkf.enkf_node_alloc(config_node)
for member in range(ens_size):
if ert.enkf.enkf_fs_has_node(comparison_fs, config_node, report_step, member, ert_state_enum.ANALYZED.value()):
ert.enkf.enkf_fs_fread_node(comparison_fs, comp_node, report_step, member, ert_state_enum.ANALYZED.value())
elif ert.enkf.enkf_fs_has_node(comparison_fs, config_node, report_step, member, ert_state_enum.FORECAST.value()):
ert.enkf.enkf_fs_fread_node(comparison_fs, comp_node, report_step, member, ert_state_enum.FORECAST.value())
else:
print "No data found for member %d/%d." % (member, report_step)
continue
data.x_comp_data[member] = []
data.y_comp_data[member] = []
x_data = data.x_comp_data[member]
y_data = data.y_comp_data[member]
field = ert.enkf.enkf_node_value_ptr(comp_node)
for index in range(obs_size):
value = ert.enkf.field_ijk_get_double(field, i[index] , j[index] , k[index])
x_data.append(value)
y_data.append(y_obs[index])
data.checkMaxMin(value)
data.x_comp_data[member] = numpy.array(x_data)
data.y_comp_data[member] = numpy.array(y_data)
ert.enkf.enkf_node_free(comp_node)
ert.enkf.enkf_node_free(node)
data.x_data_type = "number"
data.inverted_y_axis = True
def getConfigurationWidget(self, context_data):
return None
def configure(self, parameter, context_data):
pass #nothing to configure, yet

View File

@ -37,6 +37,8 @@
#include <ert/plot/plot_dataset.h>
#include <ert/ecl/ecl_rft_file.h>
#include <ert/ecl/ecl_rft_node.h>
#include <ert/ecl/ecl_rft_cell.h>
#include <ert/enkf/enkf_main.h>
#include <ert/enkf/enkf_obs.h>
@ -245,7 +247,12 @@ void enkf_tui_plot_RFT_simIn(enkf_main_type * enkf_main, path_fmt_type * runpath
for (int nobs =0; nobs<lines; nobs++){
int start_index = 0;
int i; int j; int k;
int global_index = ecl_grid_get_global_index_from_xyz(grid,double_vector_iget(UTM_x,nobs) ,double_vector_iget(UTM_y,nobs) ,double_vector_iget(TVD_z,nobs) ,start_index);
int global_index = ecl_grid_get_global_index_from_xyz( grid ,
double_vector_iget(UTM_x,nobs) ,
double_vector_iget(UTM_y,nobs) ,
double_vector_iget(TVD_z,nobs) ,
start_index);
ecl_grid_get_ijk1(grid , global_index, &i, &j , &k);
int is_active = ecl_grid_get_active_index1(grid , global_index);
int_vector_iset(i_values, nobs, i);
@ -287,17 +294,16 @@ void enkf_tui_plot_RFT_simIn(enkf_main_type * enkf_main, path_fmt_type * runpath
else{
for( int nobs = 0; nobs < lines; nobs++){
if( int_vector_iget(active,nobs) > -1){
int cell_index = ecl_rft_node_lookup_ijk( rft_refcase_node ,
int_vector_iget(i_values,nobs) ,
int_vector_iget(j_values,nobs) ,
int_vector_iget(k_values,nobs) ); //lookup cell
const ecl_rft_cell_type * cell = ecl_rft_node_lookup_ijk( rft_refcase_node ,
int_vector_iget(i_values,nobs) ,
int_vector_iget(j_values,nobs) ,
int_vector_iget(k_values,nobs) );
if(cell_index > -1){
double pressure_value = ecl_rft_node_iget_pressure( rft_refcase_node , cell_index); // Pressure
if (cell) {
double pressure_value = ecl_rft_cell_get_pressure( cell );
double_vector_append(RFT_refcase, pressure_value);
bool_vector_append(refcase_has_data, true);
}
else{
} else {
double_vector_append(RFT_refcase, 0.0);
bool_vector_append(refcase_has_data, false);
}
@ -337,17 +343,19 @@ void enkf_tui_plot_RFT_simIn(enkf_main_type * enkf_main, path_fmt_type * runpath
else{
for( int nobs = 0; nobs < lines; nobs++){
if( int_vector_iget(active,nobs) > -1){
int cell_index = ecl_rft_node_lookup_ijk( rftnode , int_vector_iget(i_values,nobs), int_vector_iget(j_values,nobs),int_vector_iget(k_values,nobs) ); //lookup cell
double pressure_value = ecl_rft_node_iget_pressure( rftnode , cell_index); // Pressure
double_vector_iset(simulated_pressures,nobs , pressure_value);
if(cell_index > -1)
const ecl_rft_cell_type * cell = ecl_rft_node_lookup_ijk( rftnode ,
int_vector_iget(i_values,nobs),
int_vector_iget(j_values,nobs),
int_vector_iget(k_values,nobs) ); //lookup cell
if (cell) {
double pressure_value = ecl_rft_cell_get_pressure( cell );
double_vector_iset(simulated_pressures, nobs , pressure_value);
bool_vector_iset(has_data, nobs, true);
else
} else {
double_vector_iset(simulated_pressures,nobs ,0.0);
bool_vector_iset(has_data, nobs, false);
}
else {
double_vector_iset(simulated_pressures,nobs ,0.0);
bool_vector_iset(has_data, nobs, false);
}
}
}
}

View File

@ -110,7 +110,6 @@ extern "C" {
#define MAX_RUNNING_LOCAL_KEY "MAX_RUNNING_LOCAL"
#define MAX_RUNNING_LSF_KEY "MAX_RUNNING_LSF"
#define MAX_RUNNING_RSH_KEY "MAX_RUNNING_RSH"
#define MAX_RUNNING_TORQUE_KEY "MAX_RUNNING_TORQUE"
#define MAX_SUBMIT_KEY "MAX_SUBMIT"
#define NUM_REALIZATIONS_KEY "NUM_REALIZATIONS"
#define OBS_CONFIG_KEY "OBS_CONFIG"

View File

@ -139,6 +139,7 @@ extern "C" {
const char * enkf_config_node_get_min_std_file( const enkf_config_node_type * config_node );
const char * enkf_config_node_get_enkf_outfile( const enkf_config_node_type * conifg_node );
const char * enkf_config_node_get_enkf_infile( const enkf_config_node_type * config_node );
const char * enkf_config_node_get_init_file_fmt( const enkf_config_node_type * config_node );
char * enkf_config_node_alloc_initfile( const enkf_config_node_type * node , const char * path , int iens);
void enkf_config_node_set_internalize(enkf_config_node_type * node, int report_step);

View File

@ -91,6 +91,7 @@ extern "C" {
const char * enkf_main_get_data_file(const enkf_main_type * );
const char ** enkf_main_get_well_list_ref(const enkf_main_type * , int *);
bool enkf_main_get_endian_swap(const enkf_main_type * );
bool enkf_main_get_fmt_file(const enkf_main_type * );
bool enkf_main_has_key(const enkf_main_type * , const char *);

View File

@ -108,6 +108,7 @@ extern "C" {
bool enkf_node_user_get_vector( enkf_node_type * enkf_node , enkf_fs_type * fs , const char * key , int iens , state_enum state , double_vector_type * values);
bool enkf_node_user_get_no_id(enkf_node_type * enkf_node , enkf_fs_type * fs , const char * key , int report_step, int iens, state_enum state , double * value);
bool enkf_node_user_get(enkf_node_type * , enkf_fs_type * , const char * , node_id_type , double * );
enkf_node_type * enkf_node_alloc(const enkf_config_node_type *);
enkf_node_type * enkf_node_copyc(const enkf_node_type * );

View File

@ -74,6 +74,7 @@ extern "C" {
const char * model_config_iget_casename( const model_config_type * model_config , int index);
//void model_config_set_max_resample( model_config_type * model_config , int max_resample );
//int model_config_get_max_resample(const model_config_type * model_config );
void model_config_set_max_internal_submit(model_config_type * config, int max_resample);
int model_config_get_max_internal_submit( const model_config_type * config );
bool model_config_select_runpath( model_config_type * model_config , const char * path_key);
void model_config_add_runpath( model_config_type * model_config , const char * path_key , const char * fmt );
@ -82,6 +83,7 @@ extern "C" {
void model_config_set_refcase( model_config_type * model_config , const ecl_sum_type * refcase );
void model_config_fprintf_config( const model_config_type * model_config , int ens_size ,FILE * stream );
model_config_type * model_config_alloc_empty();
bool model_config_select_history( model_config_type * model_config , history_source_type source_type, const sched_file_type * sched_file , const ecl_sum_type * refcase);
#ifdef __cplusplus
}

View File

@ -1,102 +0,0 @@
/*
Copyright (C) 2011 Statoil ASA, Norway.
The file 'obs_vector.h' is part of ERT - Ensemble based Reservoir Tool.
ERT 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.
ERT 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.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
#ifndef __OBS_VECTOR_H__
#define __OBS_VECTOR_H__
#ifdef __cplusplus
extern "C" {
#endif
#include <time.h>
#include <ert/util/bool_vector.h>
#include <ert/sched/history.h>
#include <ert/config/conf.h>
#include <ert/ecl/ecl_sum.h>
#include <ert/enkf/enkf_fs.h>
#include <ert/enkf/enkf_types.h>
#include <ert/enkf/enkf_node.h>
#include <ert/enkf/enkf_state.h>
#include <ert/enkf/ensemble_config.h>
#include <ert/enkf/obs_data.h>
#include <ert/enkf/enkf_macros.h>
#include <ert/enkf/active_list.h>
typedef void (obs_free_ftype) (void *);
typedef void (obs_get_ftype) (const void * , obs_data_type * , int , const active_list_type * );
typedef void (obs_meas_ftype) (const void * , const void *, node_id_type , meas_data_type * , const active_list_type * );
typedef void (obs_user_get_ftype) (void * , const char * , double * , double * , bool *);
typedef double (obs_chi2_ftype) (const void * , const void *, node_id_type );
typedef enum { GEN_OBS = 1,
SUMMARY_OBS = 2,
BLOCK_OBS = 3} obs_impl_type;
typedef struct obs_vector_struct obs_vector_type;
void obs_vector_clear_nodes( obs_vector_type * obs_vector );
void obs_vector_del_node(obs_vector_type * obs_vector , int index);
void obs_vector_free(obs_vector_type * );
int obs_vector_get_num_active(const obs_vector_type * );
time_t obs_vector_iget_obs_time( const obs_vector_type * vector , int index);
bool obs_vector_iget_active(const obs_vector_type * , int );
void obs_vector_iget_observations(const obs_vector_type * , int , obs_data_type * , const active_list_type * active_list);
void obs_vector_measure(const obs_vector_type * , enkf_fs_type * fs, state_enum state , int report_step , const enkf_state_type * , meas_data_type * , const active_list_type * active_list);
const char * obs_vector_get_state_kw(const obs_vector_type * );
obs_impl_type obs_vector_get_impl_type(const obs_vector_type * );
int obs_vector_get_active_report_step(const obs_vector_type * );
void obs_vector_user_get(const obs_vector_type * obs_vector , const char * index_key , int report_step , double * value , double * std , bool * valid);
int obs_vector_get_next_active_step(const obs_vector_type * , int );
void * obs_vector_iget_node(const obs_vector_type * , int );
obs_vector_type * obs_vector_alloc_from_GENERAL_OBSERVATION(const conf_instance_type * , const history_type * , const ensemble_config_type * , const time_t_vector_type * obs_time);
void obs_vector_load_from_SUMMARY_OBSERVATION(obs_vector_type * obs_vector , const conf_instance_type * , const history_type * , ensemble_config_type * );
bool obs_vector_load_from_HISTORY_OBSERVATION(obs_vector_type * obs_vector , const conf_instance_type * , const history_type * , ensemble_config_type * , double std_cutoff );
obs_vector_type * obs_vector_alloc_from_BLOCK_OBSERVATION(const conf_instance_type * , const ecl_grid_type * grid , const ecl_sum_type * refcase , const history_type * , ensemble_config_type * , const time_t_vector_type * obs_time);
void obs_vector_set_config_node(obs_vector_type * , const enkf_config_node_type * );
obs_vector_type * obs_vector_alloc(obs_impl_type obs_type , const char * obs_key , enkf_config_node_type * config_node , const time_t_vector_type * obs_time , int num_reports);
double obs_vector_chi2(const obs_vector_type * , enkf_fs_type * , node_id_type node_id);
void obs_vector_ensemble_chi2(const obs_vector_type * obs_vector ,
enkf_fs_type * fs,
bool_vector_type * valid ,
int step1 , int step2 ,
int iens1 , int iens2 ,
state_enum load_state ,
double ** chi2);
double obs_vector_total_chi2(const obs_vector_type * , enkf_fs_type * , int , state_enum );
void obs_vector_ensemble_total_chi2(const obs_vector_type * , enkf_fs_type * , int , state_enum , double * );
enkf_config_node_type * obs_vector_get_config_node(obs_vector_type * );
const char * obs_vector_get_obs_key( const obs_vector_type * obs_vector);
UTIL_SAFE_CAST_HEADER(obs_vector);
VOID_FREE_HEADER(obs_vector);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -58,8 +58,6 @@ typedef struct site_config_struct site_config_type;
int site_config_get_max_running_rsh( const site_config_type * site_config);
void site_config_set_max_running_local( site_config_type * site_config , int max_running_local);
int site_config_get_max_running_local( const site_config_type * site_config );
void site_config_set_max_running_torque( site_config_type * site_config , int max_running_torque);
int site_config_get_max_running_torque( const site_config_type * site_config );
void site_config_setenv( site_config_type * site_config , const char * variable, const char * value);
hash_type * site_config_get_env_hash( const site_config_type * site_config );
void site_config_clear_env( site_config_type * site_config );

View File

@ -576,6 +576,10 @@ const char * enkf_config_node_get_enkf_infile( const enkf_config_node_type * con
return path_fmt_get_fmt( config_node->enkf_infile_fmt );
}
const char * enkf_config_node_get_init_file_fmt( const enkf_config_node_type * config_node)
{
return path_fmt_get_fmt( config_node->init_file_fmt );
}
void enkf_config_node_set_min_std( enkf_config_node_type * config_node , enkf_node_type * min_std ) {
if (config_node->min_std != NULL)

View File

@ -2144,7 +2144,6 @@ enkf_main_type * enkf_main_alloc_empty( ) {
enkf_main_init_subst_list( enkf_main );
enkf_main_set_verbose( enkf_main , true );
printf("enkf_main->subst_list :%p \n",enkf_main->subst_list);
return enkf_main;
}

View File

@ -341,22 +341,25 @@ void enkf_node_ecl_write(const enkf_node_type *enkf_node , const char *path , fo
bool enkf_node_user_get(enkf_node_type * enkf_node , enkf_fs_type * fs , const char * key , node_id_type node_id , double * value) {
return enkf_node_user_get_no_id( enkf_node , fs , key , node_id.report_step , node_id.iens , node_id.state , value );
}
bool enkf_node_user_get_no_id(enkf_node_type * enkf_node , enkf_fs_type * fs , const char * key , int report_step, int iens, state_enum state , double * value) {
node_id_type node_id = {.report_step = report_step , .iens = iens, .state = state };
bool loadOK;
FUNC_ASSERT( enkf_node->user_get );
{
loadOK = enkf_node_try_load( enkf_node , fs , node_id);
if (loadOK)
return enkf_node->user_get(enkf_node->data , key , node_id.report_step, node_id.state , value);
return enkf_node->user_get(enkf_node->data , key , report_step, state , value);
else {
*value = 0;
return false;
}
}
}
bool enkf_node_user_get_vector( enkf_node_type * enkf_node , enkf_fs_type * fs , const char * key , int iens , state_enum state , double_vector_type * values) {
if (enkf_node->vector_storage) {
if (enkf_node_try_load_vector( enkf_node , fs , iens , state)) {

View File

@ -1383,7 +1383,6 @@ void field_update_sum(field_type * sum , field_type * field , double lower_limit
*/
bool field_user_get(const field_type * field, const char * index_key, int report_step , state_enum state, double * value)
{
printf("index_key : %s \n",index_key);
const bool internal_value = false;
bool valid;
int i,j,k;

View File

@ -954,8 +954,6 @@ bool field_config_parse_user_key__( const char * index_key , int *i , int *j , i
*k = int_vector_iget( indices , 2) - 1;
}
int_vector_fprintf( indices , stdout , "INDEXLIST" , " %4d");
int_vector_free( indices );
}
if (length == 3)

View File

@ -286,7 +286,7 @@ int model_config_get_max_internal_submit( const model_config_type * config ) {
return config->max_internal_submit;
}
static void model_config_set_max_internal_submit( model_config_type * model_config , int max_resample ) {
void model_config_set_max_internal_submit( model_config_type * model_config , int max_resample ) {
model_config->max_internal_submit = max_resample;
}
@ -330,7 +330,7 @@ model_config_type * model_config_alloc_empty() {
}
static bool model_config_select_history( model_config_type * model_config , history_source_type source_type, const sched_file_type * sched_file , const ecl_sum_type * refcase) {
bool model_config_select_history( model_config_type * model_config , history_source_type source_type, const sched_file_type * sched_file , const ecl_sum_type * refcase) {
bool selectOK = false;
if (source_type == SCHEDULE && sched_file != NULL) {
@ -512,7 +512,6 @@ history_type * model_config_get_history(const model_config_type * config) {
}
int model_config_get_last_history_restart(const model_config_type * config) {
printf("config->history:%p \n",config->history);
return history_get_last_restart( config->history );
}

View File

@ -1,957 +0,0 @@
/*
Copyright (C) 2011 Statoil ASA, Norway.
The file 'obs_vector.c' is part of ERT - Ensemble based Reservoir Tool.
ERT 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.
ERT 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.
See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
for more details.
*/
/**
See the overview documentation of the observation system in enkf_obs.c
*/
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <time.h>
#include <ert/util/util.h>
#include <ert/util/vector.h>
#include <ert/util/double_vector.h>
#include <ert/util/bool_vector.h>
#include <ert/util/msg.h>
#include <ert/sched/history.h>
#include <ert/config/conf.h>
#include <ert/ecl/ecl_sum.h>
#include <ert/ecl/ecl_grid.h>
#include <ert/ecl/smspec_node.h>
#include <ert/enkf/obs_vector.h>
#include <ert/enkf/enkf_fs.h>
#include <ert/enkf/summary_obs.h>
#include <ert/enkf/block_obs.h>
#include <ert/enkf/gen_obs.h>
#include <ert/enkf/ensemble_config.h>
#include <ert/enkf/active_list.h>
#include <ert/enkf/enkf_state.h>
#include <ert/enkf/enkf_defaults.h>
#define OBS_VECTOR_TYPE_ID 120086
struct obs_vector_struct {
UTIL_TYPE_ID_DECLARATION;
obs_free_ftype *freef; /* Function used to free an observation node. */
obs_get_ftype *get_obs; /* Function used to build the 'd' vector. */
obs_meas_ftype *measure; /* Function used to measure on the state, and add to to the S matrix. */
obs_user_get_ftype *user_get; /* Function to get an observation based on KEY:INDEX input from user.*/
obs_chi2_ftype *chi2; /* Function to evaluate chi-squared for an observation. */
const time_t_vector_type * obs_time; /* Global vector owned by the enkf_obs structure. */
vector_type * nodes;
char * obs_key; /* The key this observation vector has in the enkf_obs layer. */
enkf_config_node_type * config_node; /* The config_node of the node type we are observing - shared reference */
obs_impl_type obs_type;
int num_active; /* The total number of timesteps where this observation is active (i.e. nodes[ ] != NULL) */
};
UTIL_IS_INSTANCE_FUNCTION(obs_vector , OBS_VECTOR_TYPE_ID)
UTIL_SAFE_CAST_FUNCTION(obs_vector , OBS_VECTOR_TYPE_ID)
/*****************************************************************/
static int __conf_instance_get_restart_nr(const conf_instance_type * conf_instance, const char * obs_key , const history_type * history , int size) {
int obs_restart_nr = -1; /* To shut up compiler warning. */
if(conf_instance_has_item(conf_instance, "RESTART")) {
obs_restart_nr = conf_instance_get_item_value_int(conf_instance, "RESTART");
if(obs_restart_nr > size)
util_abort("%s: Observation %s occurs at restart %i, but history file has only %i restarts.\n", __func__, obs_key, obs_restart_nr, size);
} else if(conf_instance_has_item(conf_instance, "DATE")) {
time_t obs_date = conf_instance_get_item_value_time_t(conf_instance, "DATE" );
obs_restart_nr = history_get_restart_nr_from_time_t( history , obs_date );
} else if (conf_instance_has_item(conf_instance, "DAYS")) {
double days = conf_instance_get_item_value_double(conf_instance, "DAYS");
obs_restart_nr = history_get_restart_nr_from_days( history , days );
} else
util_abort("%s: Internal error. Invalid conf_instance?\n", __func__);
return obs_restart_nr;
}
/*****************************************************************/
static void obs_vector_resize(obs_vector_type * vector , int new_size) {
int current_size = vector_get_size( vector->nodes );
int i;
for (i=current_size; i < new_size; i++)
vector_append_ref( vector->nodes , NULL);
}
obs_vector_type * obs_vector_alloc(obs_impl_type obs_type , const char * obs_key , enkf_config_node_type * config_node , const time_t_vector_type * obs_time , int num_reports) {
obs_vector_type * vector = util_malloc(sizeof * vector );
UTIL_TYPE_ID_INIT( vector , OBS_VECTOR_TYPE_ID);
vector->freef = NULL;
vector->measure = NULL;
vector->get_obs = NULL;
vector->user_get = NULL;
vector->chi2 = NULL;
switch (obs_type) {
case(SUMMARY_OBS):
vector->freef = summary_obs_free__;
vector->measure = summary_obs_measure__;
vector->get_obs = summary_obs_get_observations__;
vector->user_get = summary_obs_user_get__;
vector->chi2 = summary_obs_chi2__;
break;
case(BLOCK_OBS):
vector->freef = block_obs_free__;
vector->measure = block_obs_measure__;
vector->get_obs = block_obs_get_observations__;
vector->user_get = block_obs_user_get__;
vector->chi2 = block_obs_chi2__;
break;
case(GEN_OBS):
vector->freef = gen_obs_free__;
vector->measure = gen_obs_measure__;
vector->get_obs = gen_obs_get_observations__;
vector->user_get = gen_obs_user_get__;
vector->chi2 = gen_obs_chi2__;
break;
default:
util_abort("%s: internal error - obs_type:%d not recognized \n",__func__ , obs_type);
}
vector->obs_type = obs_type;
vector->config_node = config_node;
vector->obs_key = util_alloc_string_copy( obs_key );
vector->num_active = 0;
vector->nodes = vector_alloc_new();
vector->obs_time = obs_time;
obs_vector_resize(vector , num_reports + 1); /* +1 here ?? Ohh - these fucking +/- problems. */
return vector;
}
obs_impl_type obs_vector_get_impl_type(const obs_vector_type * obs_vector) {
return obs_vector->obs_type;
}
/**
This is the key for the enkf_node which this observation is
'looking at'. I.e. if this observation is an RFT pressure
measurement, this function will return "PRESSURE".
*/
const char * obs_vector_get_state_kw(const obs_vector_type * obs_vector) {
return enkf_config_node_get_key( obs_vector->config_node );
}
enkf_config_node_type * obs_vector_get_config_node(obs_vector_type * obs_vector) {
return obs_vector->config_node;
}
void obs_vector_free(obs_vector_type * obs_vector) {
vector_free( obs_vector->nodes );
free(obs_vector->obs_key);
free(obs_vector);
}
static void obs_vector_assert_node_type( const obs_vector_type * obs_vector , const void * node ) {
bool type_OK;
switch (obs_vector->obs_type) {
case(SUMMARY_OBS):
type_OK = summary_obs_is_instance( node );
break;
case(BLOCK_OBS):
type_OK = block_obs_is_instance( node );
break;
case(GEN_OBS):
type_OK = gen_obs_is_instance( node );
break;
default:
util_abort("%s: What the fuck? \n",__func__);
type_OK = false;
}
if (!type_OK)
util_abort("%s: Type mismatch when trying to add observation node to observation vector \n",__func__);
}
void obs_vector_del_node(obs_vector_type * obs_vector , int index) {
if (vector_iget_const( obs_vector->nodes , index ) != NULL) {
vector_iset_ref( obs_vector->nodes , index , NULL); /* Clear current content. */
obs_vector->num_active--;
}
}
/**
This function will clear (and free) all the summary_obs / gen_obs /
field_obs instances which have been installed in the vector;
however the vector itself is retained with keys, function pointers
and so on.
*/
void obs_vector_clear_nodes( obs_vector_type * obs_vector ) {
vector_clear( obs_vector->nodes );
obs_vector->num_active = 0;
}
static void obs_vector_install_node(obs_vector_type * obs_vector , int index , void * node) {
obs_vector_assert_node_type( obs_vector , node );
{
if (vector_iget_const( obs_vector->nodes , index ) == NULL)
obs_vector->num_active++;
vector_iset_owned_ref( obs_vector->nodes , index , node , obs_vector->freef );
}
}
/**
Observe that @summary_key is the key used to look up the
corresponding simulated value in the ensemble, and not the
observation key - the two can be different.
*/
static void obs_vector_add_summary_obs( obs_vector_type * obs_vector , int obs_index , const char * summary_key , const char * obs_key , double value , double std , const char * auto_corrf_name , double auto_corrf_param) {
summary_obs_type * summary_obs = summary_obs_alloc( summary_key , obs_key , value , std , auto_corrf_name , auto_corrf_param);
obs_vector_install_node( obs_vector , obs_index , summary_obs );
}
time_t obs_vector_iget_obs_time( const obs_vector_type * obs_vector , int report_step) {
return time_t_vector_safe_iget( obs_vector->obs_time , report_step );
}
/*****************************************************************/
int obs_vector_get_num_active(const obs_vector_type * vector) {
return vector->num_active;
}
/**
IFF - only one - report step is active this function will return
that report step. If more than report step is active, the function
is ambigous, and will fail HARD. Check with get_num_active first!
*/
int obs_vector_get_active_report_step(const obs_vector_type * vector) {
if (vector->num_active == 1) {
int active_step = -1;
int i;
for (i=0; i < vector_get_size(vector->nodes); i++) {
void * obs_node = vector_iget( vector->nodes , i);
if (obs_node != NULL) {
if (active_step >= 0)
util_abort("%s: internal error - mismatch in obs_vector->nodes and obs_vector->num_active \n",__func__);
active_step = i;
}
}
if (active_step < 0)
util_abort("%s: internal error - mismatch in obs_vector->nodes and obs_vector->num_active \n",__func__);
return active_step;
} else {
util_abort("%s: when calling this function the number of active report steps MUST BE 1 - you had: %d \n",__func__ , vector->num_active);
return 0; /* Comiler shut up. */
}
}
bool obs_vector_iget_active(const obs_vector_type * vector, int index) {
/* We accept this ... */
if (index >= vector_get_size( vector->nodes ))
return false;
{
void * obs_data = vector_iget( vector->nodes , index );
if (obs_data != NULL)
return true;
else
return false;
}
}
/*
Will happily return NULL if index is not active.
*/
void * obs_vector_iget_node(const obs_vector_type * vector, int index) {
return vector_iget( vector->nodes , index );
}
void obs_vector_user_get(const obs_vector_type * obs_vector , const char * index_key , int report_step , double * value , double * std , bool * valid) {
void * obs_node = obs_vector_iget_node( obs_vector , report_step );
obs_vector->user_get(obs_node , index_key , value , std , valid);
}
/*
This function returns the next active (i.e. node != NULL) report
step, starting with 'prev_step + 1'. If no more active steps are
found, it will return -1.
*/
int obs_vector_get_next_active_step(const obs_vector_type * obs_vector , int prev_step) {
if (prev_step >= (vector_get_size(obs_vector->nodes) - 1))
return -1;
else {
int size = vector_get_size( obs_vector->nodes );
int next_step = prev_step + 1;
while (( next_step < size) && (obs_vector_iget_node(obs_vector , next_step) == NULL))
next_step++;
if (next_step == size)
return -1; /* No more active steps. */
else
return next_step;
}
}
/*****************************************************************/
/**
All the obs_vector_load_from_XXXX() functions can safely return
NULL, in which case no observation is added to enkf_obs observation
hash table.
*/
void obs_vector_load_from_SUMMARY_OBSERVATION(obs_vector_type * obs_vector , const conf_instance_type * conf_instance , const history_type * history, ensemble_config_type * ensemble_config) {
if(!conf_instance_is_of_class(conf_instance, "SUMMARY_OBSERVATION"))
util_abort("%s: internal error. expected \"SUMMARY_OBSERVATION\" instance, got \"%s\".\n",
__func__, conf_instance_get_class_name_ref(conf_instance) );
{
double obs_value = conf_instance_get_item_value_double(conf_instance, "VALUE" );
double obs_error = conf_instance_get_item_value_double(conf_instance, "ERROR" );
double min_error = conf_instance_get_item_value_double(conf_instance, "ERROR_MIN");
const char * error_mode = conf_instance_get_item_value_ref( conf_instance, "ERROR_MODE");
const char * sum_key = conf_instance_get_item_value_ref( conf_instance, "KEY" );
const char * obs_key = conf_instance_get_name_ref(conf_instance);
int size = history_get_last_restart( history );
int obs_restart_nr = __conf_instance_get_restart_nr(conf_instance , obs_key , history , size);
if (obs_restart_nr == 0) {
int day,month,year;
time_t start_time = history_get_time_t_from_restart_nr( history , 0 );
util_set_date_values( start_time , &day , &month , &year);
fprintf(stderr,"** ERROR: It is unfortunately not possible to use summary observations from the\n");
fprintf(stderr," start of the simulation. Problem with observation:%s at %02d/%02d/%4d\n",obs_key , day,month,year);
exit(1);
}
{
if (strcmp( error_mode , "REL") == 0)
obs_error *= obs_value;
else if (strcmp( error_mode , "RELMIN") == 0)
obs_error = util_double_max( min_error , obs_error * obs_value );
obs_vector_add_summary_obs( obs_vector , obs_restart_nr , sum_key , obs_key , obs_value , obs_error , NULL , 0);
}
}
}
obs_vector_type * obs_vector_alloc_from_GENERAL_OBSERVATION(const conf_instance_type * conf_instance , const history_type * history, const ensemble_config_type * ensemble_config , const time_t_vector_type * obs_time) {
if(!conf_instance_is_of_class(conf_instance, "GENERAL_OBSERVATION"))
util_abort("%s: internal error. expected \"GENERAL_OBSERVATION\" instance, got \"%s\".\n",
__func__, conf_instance_get_class_name_ref(conf_instance) );
const char * obs_key = conf_instance_get_name_ref(conf_instance);
const char * state_kw = conf_instance_get_item_value_ref( conf_instance, "DATA" );
if (ensemble_config_has_key( ensemble_config , state_kw )) {
const char * obs_key = conf_instance_get_name_ref(conf_instance);
int size = history_get_last_restart( history );
obs_vector_type * obs_vector = obs_vector_alloc( GEN_OBS , obs_key , ensemble_config_get_node(ensemble_config , state_kw ) , obs_time , size);
int obs_restart_nr = __conf_instance_get_restart_nr(conf_instance , obs_key , history , size);
const char * index_file = NULL;
const char * index_list = NULL;
const char * obs_file = NULL;
const char * error_covar_file = NULL;
if (conf_instance_has_item(conf_instance , "INDEX_FILE"))
index_file = conf_instance_get_item_value_ref( conf_instance, "INDEX_FILE" );
if (conf_instance_has_item(conf_instance , "INDEX_LIST"))
index_list = conf_instance_get_item_value_ref( conf_instance, "INDEX_LIST" );
if (conf_instance_has_item(conf_instance , "OBS_FILE"))
obs_file = conf_instance_get_item_value_ref( conf_instance, "OBS_FILE" );
if (conf_instance_has_item(conf_instance , "ERROR_COVAR"))
error_covar_file = conf_instance_get_item_value_ref( conf_instance, "ERROR_COVAR" );
{
const enkf_config_node_type * config_node = ensemble_config_get_node( ensemble_config , state_kw);
if (enkf_config_node_get_impl_type(config_node) == GEN_DATA) {
double scalar_error = -1;
double scalar_value = -1;
gen_obs_type * gen_obs ;
if (conf_instance_has_item(conf_instance , "VALUE")) {
scalar_value = conf_instance_get_item_value_double(conf_instance , "VALUE");
scalar_error = conf_instance_get_item_value_double(conf_instance , "ERROR");
}
/** The config system has ensured that we have either OBS_FILE or (VALUE and ERROR). */
gen_obs = gen_obs_alloc( enkf_config_node_get_ref( config_node ) , obs_key , obs_file , scalar_value , scalar_error , index_file , index_list , error_covar_file);
obs_vector_install_node( obs_vector , obs_restart_nr , gen_obs );
} else {
ert_impl_type impl_type = enkf_config_node_get_impl_type(config_node);
util_abort("%s: %s has implementation type:\'%s\' - expected:\'%s\'.\n",__func__ , state_kw , enkf_types_get_impl_name(impl_type) , enkf_types_get_impl_name(GEN_DATA));
}
}
return obs_vector;
} else {
fprintf(stderr,"** Warning the ensemble key:%s does not exist - observation:%s not added \n", state_kw , obs_key);
return NULL;
}
}
// Should check the refcase for key - if it is != NULL.
bool obs_vector_load_from_HISTORY_OBSERVATION(obs_vector_type * obs_vector ,
const conf_instance_type * conf_instance ,
const history_type * history ,
ensemble_config_type * ensemble_config,
double std_cutoff ) {
if(!conf_instance_is_of_class(conf_instance, "HISTORY_OBSERVATION"))
util_abort("%s: internal error. expected \"HISTORY_OBSERVATION\" instance, got \"%s\".\n",__func__, conf_instance_get_class_name_ref(conf_instance) );
{
bool initOK = false;
int size , restart_nr;
double_vector_type * value = double_vector_alloc(0,0);
double_vector_type * std = double_vector_alloc(0,0);
bool_vector_type * valid = bool_vector_alloc(0 , false);
/* The auto_corrf parameters can not be "segmentized" */
double auto_corrf_param = -1;
const char * auto_corrf_name = NULL;
double error = conf_instance_get_item_value_double(conf_instance, "ERROR" );
double error_min = conf_instance_get_item_value_double(conf_instance, "ERROR_MIN" );
const char * error_mode = conf_instance_get_item_value_ref( conf_instance, "ERROR_MODE");
const char * sum_key = conf_instance_get_name_ref( conf_instance );
if(conf_instance_has_item(conf_instance, "AUTO_CORRF")) {
auto_corrf_name = conf_instance_get_item_value_ref( conf_instance , "AUTO_CORRF");
auto_corrf_param = conf_instance_get_item_value_double(conf_instance, "AUTO_CORRF_PARAM");
if(conf_instance_has_item(conf_instance, "AUTO_CORRF_PARAM"))
auto_corrf_param = conf_instance_get_item_value_double(conf_instance, "AUTO_CORRF_PARAM");
else
util_abort("%s: When specifying AUTO_CORRF you must also give a vlaue for AUTO_CORRF_PARAM",__func__);
}
// Get time series data from history object and allocate
size = history_get_last_restart(history);
if (history_init_ts( history , sum_key , value , valid )) {
// Create the standard deviation vector
if(strcmp(error_mode, "ABS") == 0) {
for( restart_nr = 0; restart_nr < size; restart_nr++)
double_vector_iset( std , restart_nr , error );
} else if(strcmp(error_mode, "REL") == 0) {
for( restart_nr = 0; restart_nr < size; restart_nr++)
double_vector_iset( std , restart_nr , error * abs( double_vector_iget( value , restart_nr )));
} else if(strcmp(error_mode, "RELMIN") == 0) {
for(restart_nr = 0; restart_nr < size; restart_nr++) {
double tmp_std = util_double_max( error_min , error * abs( double_vector_iget( value , restart_nr )));
double_vector_iset( std , restart_nr , tmp_std);
}
} else
util_abort("%s: Internal error. Unknown error mode \"%s\"\n", __func__, error_mode);
// Handle SEGMENTs which can be used to customize the observation error. */
{
stringlist_type * segment_keys = conf_instance_alloc_list_of_sub_instances_of_class_by_name(conf_instance, "SEGMENT");
stringlist_sort( segment_keys , NULL );
int num_segments = stringlist_get_size(segment_keys);
for(int segment_nr = 0; segment_nr < num_segments; segment_nr++)
{
const char * segment_name = stringlist_iget(segment_keys, segment_nr);
const conf_instance_type * segment_conf = conf_instance_get_sub_instance_ref(conf_instance, segment_name);
int start = conf_instance_get_item_value_int( segment_conf, "START" );
int stop = conf_instance_get_item_value_int( segment_conf, "STOP" );
double error_segment = conf_instance_get_item_value_double(segment_conf, "ERROR" );
double error_min_segment = conf_instance_get_item_value_double(segment_conf, "ERROR_MIN" );
const char * error_mode_segment = conf_instance_get_item_value_ref( segment_conf, "ERROR_MODE");
if(start < 0)
{
printf("%s: WARNING - Segment out of bounds. Truncating start of segment to 0.\n", __func__);
start = 0;
}
if(stop >= size)
{
printf("%s: WARNING - Segment out of bounds. Truncating end of segment to %d.\n", __func__, size - 1);
stop = size -1;
}
if(start > stop)
{
printf("%s: WARNING - Segment start after stop. Truncating end of segment to %d.\n", __func__, start );
stop = start;
}
// Create the standard deviation vector
if(strcmp(error_mode_segment, "ABS") == 0) {
for( restart_nr = start; restart_nr <= stop; restart_nr++)
double_vector_iset( std , restart_nr , error_segment) ;
} else if(strcmp(error_mode_segment, "REL") == 0) {
for( restart_nr = start; restart_nr <= stop; restart_nr++)
double_vector_iset( std , restart_nr , error_segment * abs(double_vector_iget( value , restart_nr)));
} else if(strcmp(error_mode_segment, "RELMIN") == 0) {
for(restart_nr = start; restart_nr <= stop ; restart_nr++) {
double tmp_std = util_double_max( error_min_segment , error_segment * abs( double_vector_iget( value , restart_nr )));
double_vector_iset( std , restart_nr , tmp_std);
}
} else
util_abort("%s: Internal error. Unknown error mode \"%s\"\n", __func__, error_mode);
}
stringlist_free(segment_keys);
}
/*
This is where the summary observations are finally added.
*/
for (restart_nr = 0; restart_nr < size; restart_nr++) {
if (bool_vector_safe_iget( valid , restart_nr)) {
if (double_vector_iget( std , restart_nr) > std_cutoff) {
obs_vector_add_summary_obs( obs_vector , restart_nr , sum_key , sum_key ,
double_vector_iget( value ,restart_nr) , double_vector_iget( std , restart_nr ) ,
auto_corrf_name , auto_corrf_param);
} else
fprintf(stderr,"** Warning: to small observation error in observation %s:%d - ignored. \n", sum_key , restart_nr);
}
}
initOK = true;
}
double_vector_free(std);
double_vector_free(value);
bool_vector_free(valid);
return initOK;
}
}
static const char * __summary_kw( const char * field_name ) {
if (strcmp( field_name , "PRESSURE") == 0)
return "BPR";
else if (strcmp( field_name , "SWAT") == 0)
return "BSWAT";
else if (strcmp( field_name , "SGAS") == 0)
return "BSGAS";
else {
util_abort("%s: sorry - could not \'translate\' field:%s to block summayr variable\n",__func__ , field_name);
return NULL;
}
}
obs_vector_type * obs_vector_alloc_from_BLOCK_OBSERVATION(const conf_instance_type * conf_instance ,
const ecl_grid_type * grid ,
const ecl_sum_type * refcase ,
const history_type * history,
ensemble_config_type * ensemble_config,
const time_t_vector_type * obs_time) {
if(!conf_instance_is_of_class(conf_instance, "BLOCK_OBSERVATION"))
util_abort("%s: internal error. expected \"BLOCK_OBSERVATION\" instance, got \"%s\".\n",
__func__, conf_instance_get_class_name_ref(conf_instance) );
block_obs_source_type source_type = SOURCE_SUMMARY;
const char * obs_label = conf_instance_get_name_ref(conf_instance);
const char * source_string = conf_instance_get_item_value_ref(conf_instance , "SOURCE");
const char * field_name = conf_instance_get_item_value_ref(conf_instance , "FIELD");
const char * sum_kw = NULL;
bool OK = true;
if (strcmp(source_string , "FIELD") == 0) {
source_type = SOURCE_FIELD;
if (!ensemble_config_has_key( ensemble_config , field_name)) {
OK = false;
fprintf(stderr,"** Warning the ensemble key:%s does not exist - observation:%s not added \n", field_name , obs_label);
}
} else if (strcmp( source_string , "SUMMARY") == 0) {
source_type = SOURCE_SUMMARY;
sum_kw = __summary_kw( field_name );
} else
util_abort("%s: internal error \n",__func__);
if (OK) {
obs_vector_type * obs_vector = NULL;
int size = history_get_last_restart( history );
int obs_restart_nr ;
stringlist_type * summary_keys = stringlist_alloc_new();
stringlist_type * obs_pt_keys = conf_instance_alloc_list_of_sub_instances_of_class_by_name(conf_instance, "OBS");
int num_obs_pts = stringlist_get_size(obs_pt_keys);
double * obs_value = util_calloc(num_obs_pts , sizeof * obs_value);
double * obs_std = util_calloc(num_obs_pts , sizeof * obs_std );
int * obs_i = util_calloc(num_obs_pts , sizeof * obs_i );
int * obs_j = util_calloc(num_obs_pts , sizeof * obs_j );
int * obs_k = util_calloc(num_obs_pts , sizeof * obs_k );
obs_restart_nr = __conf_instance_get_restart_nr(conf_instance , obs_label , history , size);
/** Build the observation. */
for(int obs_pt_nr = 0; obs_pt_nr < num_obs_pts; obs_pt_nr++) {
const char * obs_key = stringlist_iget(obs_pt_keys, obs_pt_nr);
const conf_instance_type * obs_instance = conf_instance_get_sub_instance_ref(conf_instance, obs_key);
const char * error_mode = conf_instance_get_item_value_ref(obs_instance, "ERROR_MODE");
double error = conf_instance_get_item_value_double(obs_instance, "ERROR");
double value = conf_instance_get_item_value_double(obs_instance, "VALUE");
double min_error = conf_instance_get_item_value_double(obs_instance, "ERROR_MIN");
if (strcmp( error_mode , "REL") == 0)
error *= value;
else if (strcmp( error_mode , "RELMIN") == 0)
error = util_double_max( error * value , min_error );
obs_value[obs_pt_nr] = value;
obs_std [obs_pt_nr] = error;
/**
The input values i,j,k come from the user, and are offset 1. They
are immediately shifted with -1 to become C-based offset zero.
*/
obs_i[obs_pt_nr] = conf_instance_get_item_value_int( obs_instance, "I") - 1;
obs_j[obs_pt_nr] = conf_instance_get_item_value_int( obs_instance, "J") - 1;
obs_k[obs_pt_nr] = conf_instance_get_item_value_int( obs_instance, "K") - 1;
if (source_type == SOURCE_SUMMARY) {
char * summary_key = smspec_alloc_block_ijk_key( SUMMARY_KEY_JOIN_STRING , sum_kw ,
obs_i[obs_pt_nr] + 1 ,
obs_j[obs_pt_nr] + 1 ,
obs_k[obs_pt_nr] + 1 );
stringlist_append_owned_ref( summary_keys , summary_key );
}
}
if (source_type == SOURCE_FIELD) {
const enkf_config_node_type * config_node = ensemble_config_get_node( ensemble_config , field_name);
const field_config_type * field_config = enkf_config_node_get_ref( config_node );
block_obs_type * block_obs = block_obs_alloc(obs_label, source_type , NULL , field_config , grid , num_obs_pts, obs_i, obs_j, obs_k, obs_value, obs_std);
if (block_obs != NULL) {
obs_vector = obs_vector_alloc( BLOCK_OBS , obs_label , ensemble_config_get_node(ensemble_config , field_name) , obs_time , size );
obs_vector_install_node( obs_vector , obs_restart_nr , block_obs);
}
} else if (source_type == SOURCE_SUMMARY) {
OK = true;
if (refcase != NULL) {
for (int i=0; i < stringlist_get_size( summary_keys ); i++) {
const char * sum_key = stringlist_iget( summary_keys , i );
if (!ecl_sum_has_key(refcase , sum_key)) {
/*
If the
*/
fprintf(stderr,"** Warning missing summary %s for cell: (%d,%d,%d) in refcase - make sure that \"BPR %d %d %d\" is included in ECLIPSE summary specification \n" ,
sum_key , obs_i[i]+1 , obs_j[i]+1 , obs_k[i]+1 , obs_i[i]+1 , obs_j[i]+1 , obs_k[i]+1 );
//OK = false;
}
}
}
if (OK) {
// We can create the container node and add the summary nodes.
enkf_config_node_type * container_config = ensemble_config_add_container( ensemble_config , NULL );
for (int i=0; i < stringlist_get_size( summary_keys ); i++) {
const char * sum_key = stringlist_iget( summary_keys , i );
enkf_config_node_type * child_node = ensemble_config_add_summary( ensemble_config , sum_key , LOAD_FAIL_WARN );
enkf_config_node_update_container( container_config , child_node );
}
{
block_obs_type * block_obs = block_obs_alloc(obs_label, source_type , summary_keys , container_config , grid , num_obs_pts, obs_i, obs_j, obs_k, obs_value, obs_std);
if (block_obs != NULL) {
obs_vector = obs_vector_alloc( BLOCK_OBS , obs_label , container_config , obs_time , size );
obs_vector_install_node( obs_vector , obs_restart_nr , block_obs);
}
}
}
} else
util_abort("%s: invalid source value \n",__func__);
free(obs_value);
free(obs_std);
free(obs_i);
free(obs_j);
free(obs_k);
stringlist_free(obs_pt_keys);
stringlist_free(summary_keys);
return obs_vector;
} else {
fprintf(stderr,"** Warning the ensemble key:%s does not exist - observation:%s not added \n", field_name , obs_label);
return NULL;
}
}
/*****************************************************************/
void obs_vector_iget_observations(const obs_vector_type * obs_vector , int report_step , obs_data_type * obs_data, const active_list_type * active_list) {
void * obs_node = vector_iget( obs_vector->nodes , report_step );
if ( obs_node != NULL)
obs_vector->get_obs(obs_node , obs_data , report_step , active_list);
}
void obs_vector_measure(const obs_vector_type * obs_vector , enkf_fs_type * fs , state_enum state , int report_step , const enkf_state_type * enkf_state , meas_data_type * meas_data , const active_list_type * active_list) {
void * obs_node = vector_iget( obs_vector->nodes , report_step );
if ( obs_node != NULL ) {
enkf_node_type * enkf_node = enkf_state_get_node( enkf_state , obs_vector_get_state_kw( obs_vector ));
node_id_type node_id = { .report_step = report_step ,
.state = state ,
.iens = enkf_state_get_iens( enkf_state ) };
enkf_node_load(enkf_node , fs , node_id);
obs_vector->measure(obs_node , enkf_node_value_ptr(enkf_node) , node_id , meas_data , active_list);
}
}
/*****************************************************************/
/** Here comes many different functions for misfit calculations. */
/**
This is the lowest level function:
* It is checked that the obs_vector is active for the actual report
step; if it is not active 0.0 is returned without any further
ado.
* It is assumed the enkf_node_instance contains valid data for this
report_step. This is not checked in this function, and is the
responsability of the calling scope.
* The underlying chi2 function will do a type-check of node - and
fail hard if it is not correct.
*/
static double obs_vector_chi2__(const obs_vector_type * obs_vector , int report_step , const enkf_node_type * node, node_id_type node_id) {
void * obs_node = vector_iget( obs_vector->nodes , report_step );
if ( obs_node != NULL)
return obs_vector->chi2( obs_node , enkf_node_value_ptr( node ), node_id);
else
return 0.0; /* Observation not active for this report step. */
}
double obs_vector_chi2(const obs_vector_type * obs_vector , enkf_fs_type * fs , node_id_type node_id) {
enkf_node_type * enkf_node = enkf_node_alloc( obs_vector->config_node );
double chi2 = 0;
if (enkf_node_try_load( enkf_node , fs , node_id))
chi2 = obs_vector_chi2__(obs_vector , node_id.report_step , enkf_node , node_id);
enkf_node_free( enkf_node );
return chi2;
}
/**
This function will evaluate the chi2 for the ensemble members
[iens1,iens2) and report steps [step1,step2).
Observe that the chi2 pointer is assumed to be allocated for the
complete ensemble, altough this function only operates on part of
it.
*/
//This will not work for container observations .....
void obs_vector_ensemble_chi2(const obs_vector_type * obs_vector ,
enkf_fs_type * fs,
bool_vector_type * valid ,
int step1 ,
int step2 ,
int iens1 ,
int iens2 ,
state_enum load_state ,
double ** chi2) {
int step;
enkf_node_type * enkf_node = enkf_node_alloc( obs_vector->config_node );
node_id_type node_id;
node_id.state = load_state;
for (step = step1; step <= step2; step++) {
int iens;
node_id.report_step = step;
{
void * obs_node = vector_iget( obs_vector->nodes , step);
if (obs_node == NULL) {
for (iens = iens1; iens < iens2; iens++)
chi2[step][iens] = 0;
} else {
for (iens = iens1; iens < iens2; iens++) {
node_id.iens = iens;
if (enkf_node_try_load( enkf_node , fs , node_id))
chi2[step][iens] = obs_vector_chi2__(obs_vector , step , enkf_node , node_id);
else {
chi2[step][iens] = 0;
// Missing data - this member will be marked as invalid in the misfit calculations.
bool_vector_iset( valid , iens , false );
}
}
}
}
}
enkf_node_free( enkf_node );
}
/**
This function will evaluate the total chi2 for one ensemble member
(i.e. sum over report steps).
*/
double obs_vector_total_chi2(const obs_vector_type * obs_vector , enkf_fs_type * fs , int iens, state_enum load_state) {
int report_step;
double sum_chi2 = 0;
enkf_node_type * enkf_node = enkf_node_alloc( obs_vector->config_node );
node_id_type node_id = {.report_step = 0, .iens = iens , .state = load_state };
for (report_step = 0; report_step < vector_get_size( obs_vector->nodes ); report_step++) {
if (vector_iget(obs_vector->nodes , report_step) != NULL) {
node_id.report_step = report_step;
if (enkf_node_try_load( enkf_node , fs , node_id))
sum_chi2 += obs_vector_chi2__(obs_vector , report_step , enkf_node, node_id);
}
}
enkf_node_free( enkf_node );
return sum_chi2;
}
/**
This function will sum up all timesteps of the obs_vector, for all ensemble members.
*/
void obs_vector_ensemble_total_chi2(const obs_vector_type * obs_vector , enkf_fs_type * fs , int ens_size , state_enum load_state , double * sum_chi2) {
const bool verbose = true;
msg_type * msg;
int report_step;
int iens;
char * msg_text = NULL;
for (iens = 0; iens < ens_size; iens++)
sum_chi2[iens] = 0;
if (verbose) {
msg = msg_alloc("Observation: " , false);
msg_show(msg);
}
{
node_id_type node_id = {.report_step = 0, .iens = iens , .state = load_state };
enkf_node_type * enkf_node = enkf_node_alloc( obs_vector->config_node );
for (report_step = 0; report_step < vector_get_size( obs_vector->nodes); report_step++) {
if (verbose) {
msg_text = util_realloc_sprintf( msg_text , "%s[%03d]" , obs_vector->obs_key , report_step);
msg_update(msg , msg_text);
}
if (vector_iget(obs_vector->nodes , report_step) != NULL) {
node_id.report_step = report_step;
for (iens = 0; iens < ens_size; iens++) {
node_id.iens = iens;
if (enkf_node_try_load( enkf_node , fs , node_id))
sum_chi2[iens] += obs_vector_chi2__(obs_vector , report_step , enkf_node, node_id);
}
}
}
enkf_node_free( enkf_node );
}
if (verbose) {
msg_free(msg , true);
util_safe_free( msg_text );
}
}
const char * obs_vector_get_obs_key( const obs_vector_type * obs_vector) {
return obs_vector->obs_key;
}
/*****************************************************************/
VOID_FREE(obs_vector)

View File

@ -113,10 +113,6 @@ struct site_config_struct {
int max_running_local_site;
int max_running_torque_site;
job_driver_type driver_type;
job_driver_type driver_type_site;
int max_submit;
@ -421,45 +417,36 @@ static void site_config_select_TORQUE_job_queue(site_config_type * site_config)
/*****************************************************************/
/**
This is quite awkward because the max_running variable is located
both in the job_queue instance, and in each separate driver
individually:
o If you call set_max_running - i.e. without specifiying a
particular driver, it will tell the queue system to use this
many jobs, and also look up the currently active driver and
update the internal info on that.
o If you tell a specific driver a value for max_running, it will
update the internal field for that driver, AND the queue IFF the
queue is currently running this driver; otherwise the queue will
be left untouched.
What a mess.
*/
/*****************************************************************/
static int site_config_get_queue_max_running_option(queue_driver_type * driver) {
const char * max_running_string = queue_driver_get_option(driver, MAX_RUNNING);
int max_running = 0;
if(!util_sscanf_int(max_running_string, &max_running)) {
fprintf(stderr, "** Warning: String:%s for max_running is not parsable as int, using 0\n", max_running_string);
}
return max_running;
}
void site_config_set_max_running(site_config_type * site_config, int max_running) {
queue_driver_set_max_running(site_config->current_driver, max_running); /* We set the max running of the current driver */
static void site_config_set_queue_max_running_option(site_config_type * site_config, const char* driver_name, int max_running) {
char* max_running_string = util_alloc_sprintf("%d", max_running);
site_config_set_queue_option(site_config, driver_name, MAX_RUNNING, max_running_string);
free(max_running_string);
}
void site_config_set_max_running_lsf(site_config_type * site_config, int max_running_lsf) {
queue_driver_type * lsf_driver = site_config_get_queue_driver(site_config, LSF_DRIVER_NAME);
queue_driver_set_max_running(lsf_driver, max_running_lsf);
site_config_set_queue_max_running_option(site_config, LSF_DRIVER_NAME, max_running_lsf);
if (!site_config->user_mode)
site_config->max_running_lsf_site = max_running_lsf;
}
int site_config_get_max_running_lsf(const site_config_type * site_config) {
queue_driver_type * lsf_driver = site_config_get_queue_driver(site_config, LSF_DRIVER_NAME);
return queue_driver_get_max_running(lsf_driver);
return site_config_get_queue_max_running_option(lsf_driver);
}
void site_config_set_max_running_rsh(site_config_type * site_config, int max_running_rsh) {
queue_driver_type * rsh_driver = site_config_get_queue_driver(site_config, RSH_DRIVER_NAME);
queue_driver_set_max_running(rsh_driver, max_running_rsh);
site_config_set_queue_max_running_option(site_config, RSH_DRIVER_NAME, max_running_rsh);
if (!site_config->user_mode)
site_config->max_running_rsh_site = max_running_rsh;
@ -467,12 +454,11 @@ void site_config_set_max_running_rsh(site_config_type * site_config, int max_run
int site_config_get_max_running_rsh(const site_config_type * site_config) {
queue_driver_type * rsh_driver = site_config_get_queue_driver(site_config, RSH_DRIVER_NAME);
return queue_driver_get_max_running(rsh_driver);
return site_config_get_queue_max_running_option(rsh_driver);
}
void site_config_set_max_running_local(site_config_type * site_config, int max_running_local) {
queue_driver_type * local_driver = site_config_get_queue_driver(site_config, LOCAL_DRIVER_NAME);
queue_driver_set_max_running(local_driver, max_running_local);
site_config_set_queue_max_running_option(site_config, LOCAL_DRIVER_NAME, max_running_local);
if (!site_config->user_mode)
site_config->max_running_local_site = max_running_local;
@ -480,20 +466,7 @@ void site_config_set_max_running_local(site_config_type * site_config, int max_r
int site_config_get_max_running_local(const site_config_type * site_config) {
queue_driver_type * local_driver = site_config_get_queue_driver(site_config, LOCAL_DRIVER_NAME);
return queue_driver_get_max_running(local_driver);
}
void site_config_set_max_running_torque(site_config_type * site_config, int max_running_torque) {
queue_driver_type * torque_driver = site_config_get_queue_driver(site_config, TORQUE_DRIVER_NAME);
queue_driver_set_max_running(torque_driver, max_running_torque);
if (!site_config->user_mode)
site_config->max_running_torque_site = max_running_torque;
}
int site_config_get_max_running_torque(const site_config_type * site_config) {
queue_driver_type * torque_driver = site_config_get_queue_driver(site_config, TORQUE_DRIVER_NAME);
return queue_driver_get_max_running(torque_driver);
return site_config_get_queue_max_running_option(local_driver);
}
/*****************************************************************/
@ -775,10 +748,6 @@ bool site_config_init(site_config_type * site_config, const config_type * config
}
}
/* Torque options */
if (config_item_set(config, MAX_RUNNING_TORQUE_KEY))
site_config_set_max_running_torque(site_config, config_get_value_as_int(config, MAX_RUNNING_TORQUE_KEY));
if (config_item_set(config, QUEUE_SYSTEM_KEY)) {
job_driver_type driver_type;
@ -982,25 +951,18 @@ void site_config_fprintf_config(const site_config_type * site_config, FILE * str
}
{
queue_driver_type * rsh_driver = site_config_get_queue_driver( site_config , RSH_DRIVER_NAME );
hash_type * host_list = hash_safe_cast( (void *) queue_driver_get_option( rsh_driver , RSH_HOSTLIST ) );
hash_iter_type * iter = hash_iter_alloc( host_list );
while (!hash_iter_is_complete( iter )) {
const char * host_name = hash_iter_get_next_key( iter );
fprintf(stream , CONFIG_KEY_FORMAT , RSH_HOST_KEY );
fprintf(stream , "%s:%d\n" , host_name , hash_get_int( host_list , host_name));
queue_driver_type * rsh_driver = site_config_get_queue_driver(site_config, RSH_DRIVER_NAME);
hash_type * host_list = hash_safe_cast((void *) queue_driver_get_option(rsh_driver, RSH_HOSTLIST));
hash_iter_type * iter = hash_iter_alloc(host_list);
while (!hash_iter_is_complete(iter)) {
const char * host_name = hash_iter_get_next_key(iter);
fprintf(stream, CONFIG_KEY_FORMAT, RSH_HOST_KEY);
fprintf(stream, "%s:%d\n", host_name, hash_get_int(host_list, host_name));
}
hash_iter_free(iter);
}
}
/* Storing TORQUE settings. */
{
if (site_config_get_max_running_torque(site_config) != site_config->max_running_torque_site) {
fprintf(stream, CONFIG_KEY_FORMAT, MAX_RUNNING_TORQUE_KEY);
fprintf(stream, CONFIG_INT_FORMAT, site_config_get_max_running_torque(site_config));
fprintf(stream, "\n");
}
}
fprintf(stream, "\n\n");
}
@ -1025,11 +987,6 @@ void site_config_add_queue_config_items(config_type * config, bool site_mode) {
"MAX_RUNNING_LOCAL"
}, 1);
// TODO: Hva er dette for noe greier
// stringlist_type * torque_dep = stringlist_alloc_argv_ref((const char *[1]) {
// "MAX_RUNNING_TORQUE"}, 1);
//
if (site_mode) {
config_schema_item_set_common_selection_set(item, 3, (const char *[3]) {
@ -1115,9 +1072,6 @@ void site_config_add_config_items(config_type * config, bool site_mode) {
config_schema_item_set_argc_minmax(item, 1, 1);
config_schema_item_iset_type(item, 0, CONFIG_INT);
item = config_add_schema_item(config, MAX_RUNNING_TORQUE_KEY, false);
config_schema_item_set_argc_minmax(item, 1, 1);
config_schema_item_iset_type(item, 0, CONFIG_INT);
/*****************************************************************/
item = config_add_schema_item(config, QUEUE_OPTION_KEY, false);

View File

@ -88,20 +88,20 @@ add_executable( enkf_refcase_list enkf_refcase_list.c )
target_link_libraries( enkf_refcase_list enkf )
add_test( enkf_refcase_list ${EXECUTABLE_OUTPUT_PATH}/enkf_refcase_list ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/Gurbat/ECLIPSE ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/Gurbat*/ECLIPSE)
add_test( enkf_refcase_list2 ${EXECUTABLE_OUTPUT_PATH}/enkf_refcase_list ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/Gurbat/ECLIPSE ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/Gurbat*/ECLIPSE.*)
set_property( TEST enkf_refcase_list PROPERTY LABELS Statoil )
set_property( TEST enkf_refcase_list2 PROPERTY LABELS Statoil )
set_property( TEST enkf_refcase_list PROPERTY LABELS StatoilData )
set_property( TEST enkf_refcase_list2 PROPERTY LABELS StatoilData )
add_executable( enkf_ecl_config enkf_ecl_config.c )
target_link_libraries( enkf_ecl_config enkf )
add_test( enkf_ecl_config1 ${EXECUTABLE_OUTPUT_PATH}/enkf_ecl_config )
add_test( enkf_ecl_config2 ${EXECUTABLE_OUTPUT_PATH}/enkf_ecl_config ${PROJECT_SOURCE_DIR}/test-data/Statoil/ECLIPSE/Gurbat/ECLIPSE)
set_property( TEST enkf_ecl_config2 PROPERTY LABELS Statoil )
set_property( TEST enkf_ecl_config2 PROPERTY LABELS StatoilData )
add_executable( enkf_ecl_config_config enkf_ecl_config_config.c )
target_link_libraries( enkf_ecl_config_config enkf )
add_test( enkf_ecl_config_config ${EXECUTABLE_OUTPUT_PATH}/enkf_ecl_config_config ${PROJECT_SOURCE_DIR}/test-data/Statoil/config/ecl_config )
set_property( TEST enkf_ecl_config_config PROPERTY LABELS Statoil )
set_property( TEST enkf_ecl_config_config PROPERTY LABELS StatoilData )
add_test( enkf_runpath_list ${EXECUTABLE_OUTPUT_PATH}/enkf_runpath_list )
add_test( enkf_site_config ${EXECUTABLE_OUTPUT_PATH}/enkf_site_config /project/res/etc/ERT/site-config)
@ -111,10 +111,10 @@ add_test( enkf_ensemble_GEN_PARAM ${EXECUTABLE_OUTPUT_PATH}/enkf_ensemble_GEN_P
add_test( enkf_ensemble ${EXECUTABLE_OUTPUT_PATH}/enkf_ensemble )
set_property( TEST enkf_time_map2 PROPERTY LABELS Statoil )
set_property( TEST enkf_site_config PROPERTY LABELS Statoil )
set_property( TEST enkf_forward_init_SURFACE_FALSE PROPERTY LABELS Statoil )
set_property( TEST enkf_forward_init_SURFACE_TRUE PROPERTY LABELS Statoil )
set_property( TEST enkf_forward_init_FIELD_FALSE PROPERTY LABELS Statoil )
set_property( TEST enkf_forward_init_FIELD_TRUE PROPERTY LABELS Statoil )
set_property( TEST enkf_time_map2 PROPERTY LABELS StatoilData )
set_property( TEST enkf_site_config PROPERTY LABELS StatoilData )
set_property( TEST enkf_forward_init_SURFACE_FALSE PROPERTY LABELS StatoilData )
set_property( TEST enkf_forward_init_SURFACE_TRUE PROPERTY LABELS StatoilData )
set_property( TEST enkf_forward_init_FIELD_FALSE PROPERTY LABELS StatoilData )
set_property( TEST enkf_forward_init_FIELD_TRUE PROPERTY LABELS StatoilData )

View File

@ -98,6 +98,8 @@ extern "C" {
void test_util_addr2line();
#endif
void test_install_SIGNALS(void);
#ifdef __cplusplus
}
#endif

View File

@ -95,6 +95,41 @@ const type ## _type * type ## _safe_cast_const( const void * __arg ) {
}
#define UTIL_SAFE_CAST_HEADER_CONST( type ) const type ## _type * type ## _safe_cast_const( const void * __arg )
#define UTIL_TRY_CAST_FUNCTION(type , TYPE_ID) \
type ## _type * type ## _try_cast( void * __arg ) { \
if (__arg == NULL) \
return NULL; \
{ \
type ## _type * arg = (type ## _type *) __arg; \
if ( arg->__type_id == TYPE_ID) \
return arg; \
else \
return NULL; \
} \
}
#define UTIL_TRY_CAST_HEADER( type ) type ## _type * type ## _try_cast( void * __arg )
#define UTIL_TRY_CAST_FUNCTION_CONST(type , TYPE_ID) \
const type ## _type * type ## _try_cast_const( const void * __arg ) { \
if (__arg == NULL) \
return NULL; \
{ \
const type ## _type * arg = (type ## _type *) __arg; \
if ( arg->__type_id == TYPE_ID) \
return arg; \
else \
return NULL; \
} \
}
#define UTIL_TRY_CAST_HEADER_CONST( type ) const type ## _type * type ## _try_cast_const( const void * __arg )
#define UTIL_TYPE_ID_DECLARATION int __type_id
#define UTIL_TYPE_ID_INIT(var , TYPE_ID) var->__type_id = TYPE_ID;

View File

@ -24,6 +24,7 @@ extern "C" {
#endif
#include <ert/util/node_data.h>
#include <ert/util/type_macros.h>
#include <ert/util/int_vector.h>
typedef void ( vector_func_type ) (void * , void *);
typedef int ( vector_cmp_ftype) (const void * , const void *);
@ -75,6 +76,7 @@ extern "C" {
void * vector_pop_back(vector_type * );
void * vector_pop_front(vector_type * );
void vector_sort(vector_type * vector , vector_cmp_ftype * cmp);
int_vector_type * vector_alloc_sort_perm(const vector_type * vector , vector_cmp_ftype * cmp);
void vector_inplace_reverse(vector_type * vector);
vector_type * vector_alloc_copy(const vector_type * src , bool deep_copy);

View File

@ -51,6 +51,7 @@ typedef @TYPE@ (@TYPE@_ftype) (@TYPE@);
@TYPE@_vector_type * @TYPE@_vector_alloc_copy( const @TYPE@_vector_type * src);
void @TYPE@_vector_imul(@TYPE@_vector_type * vector, int index, @TYPE@ factor);
void @TYPE@_vector_scale(@TYPE@_vector_type * vector, @TYPE@ factor);
void @TYPE@_vector_div(@TYPE@_vector_type * vector, @TYPE@ divisor);
@TYPE@ @TYPE@_vector_reverse_iget(const @TYPE@_vector_type * vector , int index);
@TYPE@ @TYPE@_vector_iget(const @TYPE@_vector_type * , int);
@TYPE@ @TYPE@_vector_safe_iget(const @TYPE@_vector_type * , int);

View File

@ -22,6 +22,7 @@
#include <stdarg.h>
#include <stdbool.h>
#include <string.h>
#include <signal.h>
#include <ert/util/util.h>
#include <ert/util/test_util.h>
@ -156,7 +157,7 @@ void test_assert_ptr_equal__( const void * p1 , const void * p2 , const char * f
void test_assert_ptr_not_equal__( const void * p1 , const void * p2 , const char * file , int line) {
bool equal = (p1 == p2);
if (equal)
test_error_exit( "%s:%d => Pointers are different p1:[%p] p2:[%p]\n" , file , line , p1 , p2 );
test_error_exit( "%s:%d => Pointers are equal p1:[%p] p2:[%p]\n" , file , line , p1 , p2 );
}
@ -204,6 +205,14 @@ void test_assert_double_not_equal__( double d1 , double d2, const char * file ,
test_error_exit( "%s:%d => double values:%15.12g %15.12g are equal.\n" , file , line , d1 , d2);
}
/*****************************************************************/
void test_install_SIGNALS(void) {
signal(SIGSEGV , util_abort_signal); /* Segmentation violation, i.e. overwriting memory ... */
signal(SIGINT , util_abort_signal); /* Control C */
signal(SIGTERM , util_abort_signal); /* If killing the program with SIGTERM (the default kill signal) you will get a backtrace.
Killing with SIGKILL (-9) will not give a backtrace.*/
}
/*****************************************************************/

View File

@ -43,6 +43,7 @@ struct vector_struct {
typedef struct {
vector_cmp_ftype * user_cmp;
node_data_type * data;
int index;
} vector_sort_node_type;
@ -555,29 +556,50 @@ static int vector_cmp(const void * s1 , const void * s2) {
*/
static vector_sort_node_type * vector_alloc_sort_data( const vector_type * vector , vector_cmp_ftype * cmp) {
vector_sort_node_type * sort_data = util_calloc( vector->size , sizeof * sort_data );
int i;
/* Fill up the temporary storage used for sorting */
for (i = 0; i < vector->size; i++) {
sort_data[i].data = vector->data[i];
sort_data[i].user_cmp = cmp;
sort_data[i].index = i;
}
/* Sort the temporary vector */
qsort(sort_data , vector->size , sizeof * sort_data , vector_cmp);
return sort_data;
}
void vector_sort(vector_type * vector , vector_cmp_ftype * cmp) {
vector_sort_node_type * sort_data = util_calloc( vector->size , sizeof * sort_data );
{
int i;
vector_sort_node_type * sort_data = vector_alloc_sort_data( vector , cmp );
int i;
/* Recover the sorted vector */
for (i = 0; i < vector->size; i++)
vector->data[i] = sort_data[i].data;
/* Fill up the temporary storage used for sorting */
for (i = 0; i < vector->size; i++) {
sort_data[i].data = vector->data[i];
sort_data[i].user_cmp = cmp;
}
/* Sort the temporary vector */
qsort(sort_data , vector->size , sizeof * sort_data , vector_cmp);
/* Recover the sorted vector */
for (i = 0; i < vector->size; i++)
vector->data[i] = sort_data[i].data;
}
free( sort_data );
}
int_vector_type * vector_alloc_sort_perm(const vector_type * vector , vector_cmp_ftype * cmp) {
vector_sort_node_type * sort_data = vector_alloc_sort_data( vector , cmp );
int_vector_type * sort_perm = int_vector_alloc(0,0);
int i;
for (i = 0; i < vector->size; i++)
int_vector_iset( sort_perm , i , sort_data[i].index);
free( sort_data );
return sort_perm;
}
void vector_inplace_reverse(vector_type * vector) {
if (vector->size > 0) {
node_data_type ** new_data = util_calloc( vector->size , sizeof * new_data );

View File

@ -500,6 +500,15 @@ void @TYPE@_vector_scale(@TYPE@_vector_type * vector, @TYPE@ factor) {
vector->data[i] *= factor;
}
/* Vector / scalar; seperate _div function to ensure correct integer division. */
void @TYPE@_vector_div(@TYPE@_vector_type * vector, @TYPE@ divisor) {
int i;
for (i=0; i < vector->size; i++)
vector->data[i] /= divisor;
}
/* vector + scalar */
void @TYPE@_vector_shift(@TYPE@_vector_type * vector, @TYPE@ delta) {
int i;

View File

@ -27,6 +27,19 @@ void assert_equal( bool equal ) {
}
void test_div() {
int_vector_type * int_vector = int_vector_alloc( 0 , 100);
int_vector_iset( int_vector , 10 , 100 );
int_vector_div( int_vector , 10 );
{
int i;
for (i=0; i < int_vector_size( int_vector ); i++)
test_assert_int_equal( 10 , int_vector_iget( int_vector , i ));
}
}
int main(int argc , char ** argv) {
int_vector_type * int_vector = int_vector_alloc( 0 , 99);
@ -100,5 +113,6 @@ int main(int argc , char ** argv) {
int_vector_free( v2 );
}
test_div();
exit(0);
}

Some files were not shown because too many files have changed in this diff Show More