Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Grid independent well specification #3384

Merged
merged 43 commits into from
Apr 10, 2023
Merged

Grid independent well specification #3384

merged 43 commits into from
Apr 10, 2023

Conversation

plgbrts
Copy link
Contributor

@plgbrts plgbrts commented Jan 31, 2023

The functionality of this PR allows to specify a geometrical (grid independent) well trajectory and completion data.
For that two new tables WELTRAJ and COMPTRAJ are introduced. Examples of such tables:

WELTRAJ
-- WELL	BRANCHNO	X	Y	 TVD 		MD 
'PROD'	1*		9500	9500	-10.0		0.0 /
'PROD'	1*		9500	9500    8425.0		8425.0 /
'INJ' 	1*		500	500	-100.0		0.0 /
'INJ' 	1*		500	500	8325.0		8325.0/
'INJ'   1*		2500  	2500	8425.0		8450.0 /
/
COMPTRAJ 
-- WELL	 BRANCH  PERF	  PERF    PERF COMPL STATE SAT    CONN DIAM KH SKIN DFACT 
-- NAME  NO      TOP      BOT     REF  NO    --    TABLE  FACT --   --  --   --     
  'PROD' 1*	 8325.0   8425.0  1*   1*    1*    1*     1*   0.5  1*  0.1  1*   /
  'INJ'	 1* 	 8325.0   8400.0  1*   1*    1*    1*     1*   0.5  1*  0.1  1*   /
/

An example case is opm-common/tests/SPE1CASE1_WELTRAJ.DATA and unit test is added to ConnectionTests.cpp.

Most (if not all) suggestions of @OPMUSER (see #3321) are included. In WELTRAJ and COMPTRAJ the BRANCHNO column is added to anticipates on multi-laterals PERFTOP and PERFBOT are top and bottom of the perforation. PERFREF column is introduced to allow a choice of specifying perforations in terms of MD or e.g. TVD. Currently only MD is implemented. Purpose of COMPLNO column is to allow lumping of completions, this is not implemented. Also DFACT (non-Darcy factor for gas wells) is not implemented (is also not implemented for COMPDAT)

CONNFACT and KH are either both specified or both negative/defaulted. In the latter case the connection factor CF (and Kh) is calculated according to CF = sqrt(CFx^2+CFy^2+CFz^2) with CFx, CFy and CFz the Peaceman connection factors for the well line-segment in the grid cell composed in three projected line-segments on the local (x,y,z) coordinate system.

Part of the code of Resinsight is re-used for the calculation of the IJK coordinates of intersected cells and the well line-segment. The resinsight code is put in external/resinsight. Some code modification was needed to remove some dependencies e.g. on the QT library.

@plgbrts
Copy link
Contributor Author

plgbrts commented Jan 31, 2023

jenkins build this please

@plgbrts
Copy link
Contributor Author

plgbrts commented Jan 31, 2023

jenkins build this please

@plgbrts
Copy link
Contributor Author

plgbrts commented Jan 31, 2023

jenkins build this please

@plgbrts plgbrts changed the title Well traj Grid independent well specification Jan 31, 2023
@plgbrts
Copy link
Contributor Author

plgbrts commented Jan 31, 2023

jenkins build this please

@plgbrts
Copy link
Contributor Author

plgbrts commented Jan 31, 2023

jenkins build this please

@plgbrts
Copy link
Contributor Author

plgbrts commented Feb 2, 2023

jenkins build this please

@plgbrts
Copy link
Contributor Author

plgbrts commented Feb 2, 2023

This PR relies on a large number of files of ResInsight that is placed under external/resinsight. Locally I can build successfully but the Jenkins build fails as it cannot find certain header files in (sub folders) of external/resinsight. Because of the large number of header files (and that they will likely not be changed) it was tried to include them at once using file(GLOB) instead of explicitly listing all files. I tried a few things without success. Do you @akva2 have an advice how I can proceed best?

@akva2
Copy link
Member

akva2 commented Feb 2, 2023

no globbing.

@plgbrts
Copy link
Contributor Author

plgbrts commented Feb 2, 2023

no globbing.

Very clear :) .Going to list the files manually

@plgbrts
Copy link
Contributor Author

plgbrts commented Feb 2, 2023

jenkins build this please

Copy link
Member

@blattms blattms left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is only a partial review, more to come. You will need to rebase on current master (and run into conflicts). Might be easier to use my version rebased on current master, see https://github.com/blattms/opm-common/tree/well-traj. Please yell if you need further instructions (e.g. for git reset).

It is still a lot of files from ResInsight and drags in quite some baggage (e.g. own smart pointer class, etc.) because of ResInsight being developed on Windows.

@@ -20,6 +20,7 @@
#define SCHEDULE_GRID

#include <opm/input/eclipse/Schedule/CompletedCells.hpp>
#include <opm/input/eclipse/EclipseState/Grid/EclipseGrid.hpp>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure we need this include? There seems to be a forward declaration below. Maybe try to delete this line?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The include file seems indeed not needed. I removed it.

Comment on lines 59 to 66
cvf::Vec3d calculateLengthInCell( const std::array<cvf::Vec3d, 8>& hexCorners,
const cvf::Vec3d& startPoint,
const cvf::Vec3d& endPoint ) const;

void findCellLocalXYZ( const std::array<cvf::Vec3d, 8>& hexCorners,
cvf::Vec3d& localXdirection,
cvf::Vec3d& localYdirection,
cvf::Vec3d& localZdirection ) const;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nitpick: Indentation looks a bit off. Maybe you are using tabs?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed it

@@ -189,6 +191,67 @@ namespace {
}
}

void Schedule::handleWELTRAJ(HandlerContext& handlerContext) {
std::unordered_set<std::string> wells;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does not really seem to be used besides adding well names to it. Is that intentional?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It calls the method loadWELTRAJ that reads in the well trajectory data x,y,z and md (measured depth) provided in table WELTRAJ. This data is used in handleCOMPTRAJ together with data from table COMPTRAJ.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for not being clear. I was talking about the local variable wells, and not this method. It gets populated but is not used for anything else.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I get it now. This was not intentional. I removed it.

src/opm/input/eclipse/Schedule/KeywordHandlers.cpp Outdated Show resolved Hide resolved
src/opm/input/eclipse/Schedule/KeywordHandlers.cpp Outdated Show resolved Hide resolved
src/opm/input/eclipse/Schedule/Well/WellConnections.cpp Outdated Show resolved Hide resolved
if (defaultSatTable)
satTableId = props->satnum;

auto same_ijk = [&]( const Connection& c ) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe just capture what you need? Even by value should be fine ... = [I, J, K](...)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This inline function returns a boolean and is used later in std::find_if. This construction is also there in loadCOMPDAT.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there might be a misunderstanding. I was talking about [&], which captures all local variable by reference to make them usable inside your lambda. As you are just using I, j, and K, I was suggesting to only capturing them.

Anyway, this is probably not a big deal, and just me justifying my existence as a reviewer 😅. Hence feel free to leave as is.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah I see, indeed I did misunderstood. I followed your suggestion.

src/opm/input/eclipse/Schedule/Well/WellConnections.cpp Outdated Show resolved Hide resolved
…o well-traj-markus

Use Markus' rebased version
Copy link
Member

@blattms blattms left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Concerning the [RigEclipseWellLogExtractor.* files: May I suggest to add some documentation to the methods to make it easier for collaborators to see what they are doing?

These files seem to also originate from ResInsight but already have diverged quite a bit when compared to the curretnt ResInsight version. Maybe we should add a comment to those files saying where they come from and from which version, and what was changed and why?

This completes my review. Please note that I have not reviewed anything under external.

RigHexIntersectionTools::lineHexCellIntersection( p1, p2, hexCorners, globalCellIndex, &intersections );
}

if ( !isCellFaceNormalsOut )
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

t seems that this is alwys false because of line 53

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed it.

const cvf::Vec3d& endPoint ) const
{
const auto[i,j,k] = m_grid.getIJK(cellIndex);
cvf::Vec3d hexCorners_opm[8]; //opm numbering
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See my previous suggestion. Should maybe become a const static class member even.

Might also be good to put this recurring translation into its own function for reuse.

Comment on lines +244 to +247
cvf::Vec3d crossPoductIZ;
crossPoductIZ.cross( faceCenterCenterVectorI, localZdirection );
localYdirection = faceCenterCenterVectorJ - crossPoductIZ;
localYdirection.normalize();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Somehow I have the feeling that calculating localYdircection is redundant, as both localXdirection and localZdirection are already perpendicular to faceCenterVectorJ.

I am not 100% sure what you aim to compute here and for what it is needed. But please be aware that depending on your faces localZdirection might be quite skewed (i.e. very different from the direction of the columns used to define the cornerpoint grid.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The aim of calculating the local X,Y,Z axes of a cell is to project the well line segment onto these axes. Then for each projected line segment a Peaceman connection factor is calculated ( CFx, CFy and CFz) that is combined into a single connection factor CF = sqrt(CFx^2+CFy^2+CFz^2).

Comment on lines +295 to +297
cellIndicesForBoundingBoxes.insert( cellIndicesForBoundingBoxes.end(),
threadIndicesForBoundingBoxes.begin(),
threadIndicesForBoundingBoxes.end() );
Copy link
Member

@blattms blattms Apr 3, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand this construction.
As threadIndicesForBoundingBoxes is declared outside of the for loop, never cleared, and entries are always added with emplace_back, I am assuming that cellIndicesForBoundingBoxes contains a lot of duplicates. I am even assuming that in the worst case it will contain cellCount*cellCount entries. Is this what we want? Or am I missing something here?

threadIndicesForBoundingBoxes.begin(),
threadIndicesForBoundingBoxes.end() );

cellBoundingBoxes.insert( cellBoundingBoxes.end(), threadBoundingBoxes.begin(), threadBoundingBoxes.end() );
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

errh, and this one might suffer from the same problem.
I must be missing something.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did not touch upon these constructions of ResInsight but don't see it growing beyond cellCount size.

@blattms
Copy link
Member

blattms commented Apr 3, 2023

Concerning licenses. As resinsight has multiple licenses (LGPL-2.1, GPL 3+, and MIT), I think it might make sense to only choose only GPLv3+ for the stuff copied to opm-common to make life easier. Comments?

@plgbrts
Copy link
Contributor Author

plgbrts commented Apr 3, 2023

Concerning licenses. As resinsight has multiple licenses (LGPL-2.1, GPL 3+, and MIT), I think it might make sense to only choose only GPLv3+ for the stuff copied to opm-common to make life easier. Comments?

May be @magnesj or @alfbr could advise here?

@alfbr
Copy link
Member

alfbr commented Apr 3, 2023

Yes, I agree that GPLv3+ makes most sense here. Multiple licenses is confusing.

@plgbrts
Copy link
Contributor Author

plgbrts commented Apr 4, 2023

jenkins build this please

@plgbrts
Copy link
Contributor Author

plgbrts commented Apr 5, 2023

jenkins build this please

@blattms blattms merged commit 24d25f7 into OPM:master Apr 10, 2023
@magnesj
Copy link
Member

magnesj commented Apr 10, 2023

Well done, I appreciate that this work is now merged. Thanks for your efforts, looking forward to see how users will work with the new funktionality.

@plgbrts
Copy link
Contributor Author

plgbrts commented Apr 11, 2023

Thanks @blattms for your helpful review!

@plgbrts
Copy link
Contributor Author

plgbrts commented Apr 11, 2023

Well done, I appreciate that this work is now merged. Thanks for your efforts, looking forward to see how users will work with the new funktionality.

The plan is to test the functionality in well trajectory optimization workflows and to extend it to mult-segment wells

@blattms blattms mentioned this pull request Apr 11, 2023
@blattms
Copy link
Member

blattms commented Apr 11, 2023

@magnesj I am curious: As opm-common is a dependency for ResInsight, do you intend to use the merged code within resinsight eventually?

@magnesj
Copy link
Member

magnesj commented Apr 12, 2023

@magnesj I am curious: As opm-common is a dependency for ResInsight, do you intend to use the merged code within resinsight eventually?

As we compile for Windows, we need to do several adjustments to source files in opm-common. As this is quite time consuming we do not update often. We compile a subset of source files, and currently opm-common is used to import some keywords (VFPPROD, VFPINJ, WSEGLINK) and read/write of ESMRY to improve performance for summary data.

Here is the modified branch we use https://github.com/CeetronSolutions/opm-common/tree/windows-build-2022-01

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

7 participants