Merged master into ert branch

This commit is contained in:
Joakim Hove 2012-06-27 08:22:26 +02:00
commit d06028cb49
20 changed files with 2144 additions and 1819 deletions

View File

@ -42,6 +42,7 @@ $(ERT_LDFLAGS) $(LAPACK_LIBS) $(BLAS_LIBS) $(LIBS) $(FLIBS)
#
# Please try to keep the list sorted.
<<<<<<< HEAD
libopmcore_la_SOURCES = \
opm/core/GridManager.cpp \
opm/core/eclipse/EclipseGridInspector.cpp \
@ -265,6 +266,227 @@ opm/core/wells/InjectionSpecification.hpp \
opm/core/wells/ProductionSpecification.hpp \
opm/core/wells/WellCollection.hpp \
opm/core/wells/WellsGroup.hpp \
=======
libopmcore_la_SOURCES = \
opm/core/GridManager.cpp \
opm/core/eclipse/EclipseGridInspector.cpp \
opm/core/eclipse/EclipseGridParser.cpp \
opm/core/fluid/BlackoilPropertiesBasic.cpp \
opm/core/fluid/BlackoilPropertiesFromDeck.cpp \
opm/core/fluid/IncompPropertiesBasic.cpp \
opm/core/fluid/IncompPropertiesFromDeck.cpp \
opm/core/fluid/PvtPropertiesBasic.cpp \
opm/core/fluid/PvtPropertiesIncompFromDeck.cpp \
opm/core/fluid/RockBasic.cpp \
opm/core/fluid/RockCompressibility.cpp \
opm/core/fluid/RockFromDeck.cpp \
opm/core/fluid/SaturationPropsBasic.cpp \
opm/core/fluid/SaturationPropsFromDeck.cpp \
opm/core/fluid/blackoil/BlackoilPvtProperties.cpp \
opm/core/fluid/blackoil/SinglePvtDead.cpp \
opm/core/fluid/blackoil/SinglePvtInterface.cpp \
opm/core/fluid/blackoil/SinglePvtLiveGas.cpp \
opm/core/fluid/blackoil/SinglePvtLiveOil.cpp \
opm/core/grid.c \
opm/core/grid/cart_grid.c \
opm/core/grid/cornerpoint_grid.c \
opm/core/grid/cpgpreprocess/facetopology.c \
opm/core/grid/cpgpreprocess/geometry.c \
opm/core/grid/cpgpreprocess/preprocess.c \
opm/core/grid/cpgpreprocess/uniquepoints.c \
opm/core/linalg/LinearSolverFactory.cpp \
opm/core/linalg/LinearSolverInterface.cpp \
opm/core/linalg/sparse_sys.c \
opm/core/newwells.c \
opm/core/pressure/CompressibleTpfa.cpp \
opm/core/pressure/FlowBCManager.cpp \
opm/core/pressure/IncompTpfa.cpp \
opm/core/pressure/cfsh.c \
opm/core/pressure/flow_bc.c \
opm/core/pressure/fsh.c \
opm/core/pressure/fsh_common_impl.c \
opm/core/pressure/ifsh.c \
opm/core/pressure/mimetic/hybsys.c \
opm/core/pressure/mimetic/hybsys_global.c \
opm/core/pressure/mimetic/mimetic.c \
opm/core/pressure/msmfem/coarse_conn.c \
opm/core/pressure/msmfem/coarse_sys.c \
opm/core/pressure/msmfem/dfs.c \
opm/core/pressure/msmfem/hash_set.c \
opm/core/pressure/msmfem/ifsh_ms.c \
opm/core/pressure/msmfem/partition.c \
opm/core/pressure/tpfa/cfs_tpfa.c \
opm/core/pressure/tpfa/cfs_tpfa_residual.c \
opm/core/pressure/tpfa/compr_bc.c \
opm/core/pressure/tpfa/compr_quant.c \
opm/core/pressure/tpfa/compr_quant_general.c \
opm/core/pressure/tpfa/compr_source.c \
opm/core/pressure/tpfa/ifs_tpfa.c \
opm/core/pressure/tpfa/trans_tpfa.c \
opm/core/pressure/well.c \
opm/core/simulator/SimulatorReport.cpp \
opm/core/simulator/SimulatorTimer.cpp \
opm/core/simulator/SimulatorTwophase.cpp \
opm/core/transport/reorder/TransportModelCompressibleTwophase.cpp \
opm/core/transport/reorder/TransportModelInterface.cpp \
opm/core/transport/reorder/TransportModelTwophase.cpp \
opm/core/transport/reorder/nlsolvers.c \
opm/core/transport/reorder/reordersequence.cpp \
opm/core/transport/reorder/tarjan.c \
opm/core/transport/spu_explicit.c \
opm/core/transport/spu_implicit.c \
opm/core/transport/transport_source.c \
opm/core/utility/MonotCubicInterpolator.cpp \
opm/core/utility/StopWatch.cpp \
opm/core/utility/miscUtilities.cpp \
opm/core/utility/miscUtilitiesBlackoil.cpp \
opm/core/utility/parameters/Parameter.cpp \
opm/core/utility/parameters/ParameterGroup.cpp \
opm/core/utility/parameters/ParameterTools.cpp \
opm/core/utility/parameters/ParameterXML.cpp \
opm/core/utility/parameters/tinyxml/tinystr.cpp \
opm/core/utility/parameters/tinyxml/tinyxml.cpp \
opm/core/utility/parameters/tinyxml/tinyxmlerror.cpp \
opm/core/utility/parameters/tinyxml/tinyxmlparser.cpp \
opm/core/utility/writeVtkData.cpp \
opm/core/vag_format/vag.cpp \
opm/core/wells/InjectionSpecification.cpp \
opm/core/wells/ProductionSpecification.cpp \
opm/core/wells/WellCollection.cpp \
opm/core/wells/WellsGroup.cpp \
opm/core/wells/WellsManager.cpp
nobase_include_HEADERS = \
opm/core/GridAdapter.hpp \
opm/core/GridManager.hpp \
opm/core/eclipse/CornerpointChopper.hpp \
opm/core/eclipse/EclipseGridInspector.hpp \
opm/core/eclipse/EclipseGridParser.hpp \
opm/core/eclipse/EclipseGridParserHelpers.hpp \
opm/core/eclipse/EclipseUnits.hpp \
opm/core/eclipse/SpecialEclipseFields.hpp \
opm/core/fluid/BlackoilPropertiesBasic.hpp \
opm/core/fluid/BlackoilPropertiesFromDeck.hpp \
opm/core/fluid/BlackoilPropertiesInterface.hpp \
opm/core/fluid/IncompPropertiesBasic.hpp \
opm/core/fluid/IncompPropertiesFromDeck.hpp \
opm/core/fluid/IncompPropertiesInterface.hpp \
opm/core/fluid/PvtPropertiesBasic.hpp \
opm/core/fluid/PvtPropertiesIncompFromDeck.hpp \
opm/core/fluid/RockBasic.hpp \
opm/core/fluid/RockCompressibility.hpp \
opm/core/fluid/RockFromDeck.hpp \
opm/core/fluid/SaturationPropsBasic.hpp \
opm/core/fluid/SaturationPropsFromDeck.hpp \
opm/core/fluid/SimpleFluid2p.hpp \
opm/core/fluid/blackoil/BlackoilPhases.hpp \
opm/core/fluid/blackoil/BlackoilPvtProperties.hpp \
opm/core/fluid/blackoil/SinglePvtConstCompr.hpp \
opm/core/fluid/blackoil/SinglePvtDead.hpp \
opm/core/fluid/blackoil/SinglePvtInterface.hpp \
opm/core/fluid/blackoil/SinglePvtLiveGas.hpp \
opm/core/fluid/blackoil/SinglePvtLiveOil.hpp \
opm/core/fluid/blackoil/phaseUsageFromDeck.hpp \
opm/core/grid.h \
opm/core/grid/cart_grid.h \
opm/core/grid/cornerpoint_grid.h \
opm/core/grid/cpgpreprocess/facetopology.h \
opm/core/grid/cpgpreprocess/geometry.h \
opm/core/grid/cpgpreprocess/grdecl.h \
opm/core/grid/cpgpreprocess/preprocess.h \
opm/core/grid/cpgpreprocess/uniquepoints.h \
opm/core/linalg/LinearSolverFactory.hpp \
opm/core/linalg/LinearSolverInterface.hpp \
opm/core/linalg/blas_lapack.h \
opm/core/linalg/sparse_sys.h \
opm/core/newwells.h \
opm/core/pressure/CompressibleTpfa.hpp \
opm/core/pressure/FlowBCManager.hpp \
opm/core/pressure/HybridPressureSolver.hpp \
opm/core/pressure/IncompTpfa.hpp \
opm/core/pressure/TPFACompressiblePressureSolver.hpp \
opm/core/pressure/TPFAPressureSolver.hpp \
opm/core/pressure/flow_bc.h \
opm/core/pressure/fsh.h \
opm/core/pressure/fsh_common_impl.h \
opm/core/pressure/mimetic/hybsys.h \
opm/core/pressure/mimetic/hybsys_global.h \
opm/core/pressure/mimetic/mimetic.h \
opm/core/pressure/msmfem/coarse_conn.h \
opm/core/pressure/msmfem/coarse_sys.h \
opm/core/pressure/msmfem/dfs.h \
opm/core/pressure/msmfem/hash_set.h \
opm/core/pressure/msmfem/ifsh_ms.h \
opm/core/pressure/msmfem/partition.h \
opm/core/pressure/tpfa/cfs_tpfa.h \
opm/core/pressure/tpfa/cfs_tpfa_residual.h \
opm/core/pressure/tpfa/compr_bc.h \
opm/core/pressure/tpfa/compr_quant.h \
opm/core/pressure/tpfa/compr_quant_general.h \
opm/core/pressure/tpfa/compr_source.h \
opm/core/pressure/tpfa/ifs_tpfa.h \
opm/core/pressure/tpfa/trans_tpfa.h \
opm/core/simulator/BlackoilState.hpp \
opm/core/simulator/SimulatorReport.hpp \
opm/core/simulator/SimulatorTimer.hpp \
opm/core/simulator/SimulatorTwophase.hpp \
opm/core/simulator/TwophaseState.hpp \
opm/core/simulator/WellState.hpp \
opm/core/transport/CSRMatrixBlockAssembler.hpp \
opm/core/transport/CSRMatrixUmfpackSolver.hpp \
opm/core/transport/GravityColumnSolver.hpp \
opm/core/transport/GravityColumnSolver_impl.hpp \
opm/core/transport/ImplicitAssembly.hpp \
opm/core/transport/ImplicitTransport.hpp \
opm/core/transport/JacobianSystem.hpp \
opm/core/transport/NormSupport.hpp \
opm/core/transport/SimpleFluid2pWrapper.hpp \
opm/core/transport/SinglePointUpwindTwoPhase.hpp \
opm/core/transport/reorder/TransportModelCompressibleTwophase.hpp \
opm/core/transport/reorder/TransportModelInterface.hpp \
opm/core/transport/reorder/TransportModelTwophase.hpp \
opm/core/transport/reorder/nlsolvers.h \
opm/core/transport/reorder/reordersequence.h \
opm/core/transport/reorder/tarjan.h \
opm/core/transport/spu_explicit.h \
opm/core/transport/spu_implicit.h \
opm/core/transport/transport_source.h \
opm/core/utility/Average.hpp \
opm/core/utility/ColumnExtract.hpp \
opm/core/utility/ErrorMacros.hpp \
opm/core/utility/Factory.hpp \
opm/core/utility/MonotCubicInterpolator.hpp \
opm/core/utility/RootFinders.hpp \
opm/core/utility/SparseTable.hpp \
opm/core/utility/SparseVector.hpp \
opm/core/utility/StopWatch.hpp \
opm/core/utility/UniformTableLinear.hpp \
opm/core/utility/Units.hpp \
opm/core/utility/buildUniformMonotoneTable.hpp \
opm/core/utility/initState.hpp \
opm/core/utility/initState_impl.hpp \
opm/core/utility/linInt.hpp \
opm/core/utility/linearInterpolation.hpp \
opm/core/utility/miscUtilities.hpp \
opm/core/utility/miscUtilitiesBlackoil.hpp \
opm/core/utility/parameters/Parameter.hpp \
opm/core/utility/parameters/ParameterGroup.hpp \
opm/core/utility/parameters/ParameterGroup_impl.hpp \
opm/core/utility/parameters/ParameterMapItem.hpp \
opm/core/utility/parameters/ParameterRequirement.hpp \
opm/core/utility/parameters/ParameterStrings.hpp \
opm/core/utility/parameters/ParameterTools.hpp \
opm/core/utility/parameters/ParameterXML.hpp \
opm/core/utility/parameters/tinyxml/tinystr.h \
opm/core/utility/parameters/tinyxml/tinyxml.h \
opm/core/utility/writeVtkData.hpp \
opm/core/vag_format/vag.hpp \
opm/core/well.h \
opm/core/wells/InjectionSpecification.hpp \
opm/core/wells/ProductionSpecification.hpp \
opm/core/wells/WellCollection.hpp \
opm/core/wells/WellsGroup.hpp \
>>>>>>> master
opm/core/wells/WellsManager.hpp
# ----------------------------------------------------------------------

View File

@ -13,39 +13,38 @@
//===========================================================================*/
/*
Copyright 2009, 2010 SINTEF ICT, Applied Mathematics.
Copyright 2009, 2010 Statoil ASA.
Copyright 2009, 2010 SINTEF ICT, Applied Mathematics.
Copyright 2009, 2010 Statoil ASA.
This file is part of The Open Reservoir Simulator Project (OpenRS).
This file is part of The Open Reservoir Simulator Project (OpenRS).
OpenRS 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.
OpenRS 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.
OpenRS 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 for more details.
OpenRS 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 for more details.
You should have received a copy of the GNU General Public License
along with OpenRS. If not, see <http://www.gnu.org/licenses/>.
You should have received a copy of the GNU General Public License
along with OpenRS. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <assert.h>
#include <stdio.h>
#include <limits.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "preprocess.h"
#include "sparsetable.h"
#include "facetopology.h"
/* No checking of input arguments in this code! */
#define min(i,j) ((i)<(j) ? (i) : (j))
#define max(i,j) ((i)>(j) ? (i) : (j))
#define MIN(i,j) ((i)<(j) ? (i) : (j))
#define MAX(i,j) ((i)>(j) ? (i) : (j))
#define DEBUG 1
@ -59,17 +58,18 @@ along with OpenRS. If not, see <http://www.gnu.org/licenses/>.
/*------------------------------------------------------*/
/* Determine face geometry first, then compute intersections. */
/* Determine face topology first, then compute intersection. */
/* All intersections that occur are present in the final face geometry.*/
static int *computeFaceTopology(int *a1,
int *a2,
int *b1,
int *b2,
int intersect[4],
int *faces)
static int *
computeFaceTopology(const int *a1, const int *a2,
const int *b1, const int *b2,
int intersect[4], int *faces)
{
int mask[8] = {-1};
int k, *f;
int mask[8];
int k;
int *f;
for (k = 0; k < 8; k++) { mask[k] = -1; }
/* Which pillar points should we use? */
if (a1[1] > b1[1]){ mask[0] = b1[1]; } else { mask[0] = a1[1]; }
@ -146,7 +146,6 @@ static int *computeFaceTopology(int *a1,
#if DEBUG>1
/* Check for repeated nodes:*/
{
int i;
fprintf(stderr, "face: ");
for (i=0; i<8; ++i){
@ -158,7 +157,6 @@ static int *computeFaceTopology(int *a1,
}
}
fprintf(stderr, "\n");
}
#endif
@ -171,27 +169,37 @@ static int *computeFaceTopology(int *a1,
/* a) If we assume that the index increase when z increase for
each pillar (but only separately), we can use only the point indices.
/* a) If we assume that the index increase when z increase for each
pillar (but only separately), we can use only the point indices,
since we only need to compare z-values on one pillar at a time.
b) We assume no intersections occur on the first and last lines.
This is convenient in the identification of (unique) intersections.
b) We assume input is preprocessed such that no intersections occur
on the first and last lines, for instance by padding the grid with
extra cells. This is convenient in the identification of (unique)
intersections.
*/
#define lineintersection(a1,a2,b1,b2)(((a1>b1)&&(a2<b2))||((a1<b1)&&(a2>b2)))
static int faceintersection(int *a1, int *a2, int *b1, int *b2)
#define LINE_INTERSECTION(a1, a2, b1, b2) \
(((a1 > b1) && (a2 < b2)) || \
((a1 < b1) && (a2 > b2)))
static int
faceintersection(const int *a1, const int *a2,
const int *b1, const int *b2)
{
return
max(a1[0],b1[0]) < min(a1[1],b1[1]) ||
max(a2[0],b2[0]) < min(a2[1],b2[1]) ||
lineintersection(a1[0], a2[0], b1[0], b2[0]) ||
lineintersection(a1[1], a2[1], b1[1], b2[1]);
MAX(a1[0], b1[0]) < MIN(a1[1], b1[1]) ||
MAX(a2[0], b2[0]) < MIN(a2[1], b2[1]) ||
LINE_INTERSECTION(a1[0], a2[0], b1[0], b2[0]) ||
LINE_INTERSECTION(a1[1], a2[1], b1[1], b2[1]);
}
#define meaningful_face !((a1[i] ==INT_MIN) && (b1[j] ==INT_MIN)) && \
!((a1[i+1]==INT_MAX) && (b1[j+1]==INT_MAX))
#define MEANINGFUL_FACE(i, j) \
(! ((a1[i] == INT_MIN) && (b1[j] == INT_MIN)) && \
! ((a1[i+1] == INT_MAX) && (b1[j+1] == INT_MAX)))
/* work should be pointer to 2n ints initialised to zero . */
void findconnections(int n, int *pts[4],
@ -210,24 +218,34 @@ void findconnections(int n, int *pts[4],
int *ibottom = work + n;
int *f = out->face_nodes + out->face_ptr[out->number_of_faces];
int *c = out->face_neighbors + 2*out->number_of_faces;
int *tmp;
int k1 = 0;
int k2 = 0;
int i,j=0;
int intersect[4]= {-1};
int intersect[4];
int *tmp;
/* for (i=0; i<2*n; work[i++]=-1); */
for (i = 0; i<n-1; ++i){
if (a1[i] == a1[i+1] && a2[i] == a2[i+1]) continue;
for (i = 0; i < 4; i++) { intersect[i] = -1; }
for (i = 0; i < n - 1; ++i) {
/* pinched a-cell */
if ((a1[i] == a1[i + 1]) &&
(a2[i] == a2[i + 1])) {
continue;
}
while ((j < n-1) &&
((b1[j] < a1[i + 1]) ||
(b2[j] < a2[i + 1])))
{
/* pinched b-cell */
if ((b1[j] == b1[j + 1]) &&
(b2[j] == b2[j + 1])) {
while(j<n-1 && (b1[j] < a1[i+1] || b2[j] < a2[i+1])){
if (b1[j] == b1[j+1] && b2[j] == b2[j+1]){
itop[j+1] = itop[j];
++j;
continue;
@ -241,14 +259,13 @@ void findconnections(int n, int *pts[4],
/* Completely matching faces */
if (a1[i]==b1[j] && a1[i+1]==b1[j+1] &&
a2[i]==b2[j] && a2[i+1]==b2[j+1]){
if (((a1[i] == b1[j]) && (a1[i+1] == b1[j+1])) &&
((a2[i] == b2[j]) && (a2[i+1] == b2[j+1]))) {
/* Add face to list of faces if not any first or last points are involved. */
if (meaningful_face){
if (MEANINGFUL_FACE(i, j)) {
int cell_a = i%2 ? (i-1)/2 : -1;
int cell_b = j%2 ? (j-1)/2 : -1;
int cell_a = i%2 != 0 ? (i-1)/2 : -1;
int cell_b = j%2 != 0 ? (j-1)/2 : -1;
if (cell_a != -1 || cell_b != -1){
*c++ = cell_a;
@ -257,21 +274,17 @@ void findconnections(int n, int *pts[4],
/* face */
*f++ = a1[i];
*f++ = a2[i];
/* avoid duplicating nodes in pinched faces */
if (a2[i+1] != a2[i]) *f++ = a2[i+1];
if (a1[i+1] != a1[i]) *f++ = a1[i+1];
if (a2[i+1] != a2[i]) { *f++ = a2[i+1]; }
if (a1[i+1] != a1[i]) { *f++ = a1[i+1]; }
out->face_ptr[++out->number_of_faces] = f - out->face_nodes;
}
else{
;
/*
fprintf(stderr,
"Warning. For some reason we get face connecting void spaces\n");
*/
}
}
}
@ -279,7 +292,8 @@ void findconnections(int n, int *pts[4],
else{
/* Find new intersection */
if (lineintersection(a1[i+1],a2[i+1],b1[j+1],b2[j+1])) {
if (LINE_INTERSECTION(a1[i+1], a2[i+1],
b1[j+1], b2[j+1])) {
itop[j+1] = out->number_of_nodes++;
/* store point numbers of intersecting lines */
@ -300,15 +314,16 @@ void findconnections(int n, int *pts[4],
intersect[3] = itop[j+1]; /* i+1 x j+1 */
/* Add face to list of faces if no INT_MIN or INT_MAX appear in a or b. */
if (meaningful_face){
/* Add face to list of faces if no INT_MIN or
* INT_MAX appear in a or b. */
if (MEANINGFUL_FACE(i,j)) {
/*
Even indices refer to space between cells,
odd indices refer to cells
*/
int cell_a = i%2 ? (i-1)/2 : -1;
int cell_b = j%2 ? (j-1)/2 : -1;
int cell_a = i%2 != 0 ? (i-1)/2 : -1;
int cell_b = j%2 != 0 ? (j-1)/2 : -1;
@ -322,32 +337,29 @@ void findconnections(int n, int *pts[4],
}
else{
;
/*
fprintf(stderr,
"Warning. For some reason we get face connecting void spaces\n");
*/
}
}
}
}
/* Update candidates for restart of j for in next i-iteration */
if (b1[j] < a1[i+1]) k1 = j;
if (b2[j] < a2[i+1]) k2 = j;
if (b1[j] < a1[i+1]) { k1 = j; }
if (b2[j] < a2[i+1]) { k2 = j; }
j = j+1;
}
/* Swap intersection records: top line of a[i,i+1] is bottom line of a[i+1,i+2] */
/* Swap intersection records: top line of a[i,i+1] is bottom
* line of a[i+1,i+2] */
tmp = itop; itop = ibottom; ibottom = tmp;
/* Zero out the "new" itop */
for(j=0;j<n; ++j) itop[j]=-1;
for(j=0;j<n; ++j) { itop[j]=-1; }
/* Set j to appropriate start position for next i */
j = min(k1, k2);
j = MIN(k1, k2);
}
}

View File

@ -13,27 +13,27 @@
//===========================================================================*/
/*
Copyright 2009, 2010 SINTEF ICT, Applied Mathematics.
Copyright 2009, 2010 Statoil ASA.
Copyright 2009, 2010 SINTEF ICT, Applied Mathematics.
Copyright 2009, 2010 Statoil ASA.
This file is part of The Open Reservoir Simulator Project (OpenRS).
This file is part of The Open Reservoir Simulator Project (OpenRS).
OpenRS 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.
OpenRS 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.
OpenRS 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 for more details.
OpenRS 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 for more details.
You should have received a copy of the GNU General Public License
along with OpenRS. If not, see <http://www.gnu.org/licenses/>.
You should have received a copy of the GNU General Public License
along with OpenRS. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OPENRS_FACETOPOLOGY_HEADER
#define OPENRS_FACETOPOLOGY_HEADER
#ifndef OPM_FACETOPOLOGY_HEADER
#define OPM_FACETOPOLOGY_HEADER
void findconnections(int n, int *pts[4],
@ -41,7 +41,7 @@ void findconnections(int n, int *pts[4],
int *work,
struct processed_grid *out);
#endif /* OPENRS_FACETOPOLOGY_HEADER */
#endif /* OPM_FACETOPOLOGY_HEADER */
/* Local Variables: */
/* c-basic-offset:4 */

View File

@ -131,6 +131,12 @@ compute_cell_geometry(int ndims, double *coords,
double ccell[3];
double cface[3] = {0};
const double twothirds = 0.666666666666666666666666666667;
int ndigits;
ndigits = ((int) (log(ncells) / log(10.0))) + 1;
for (c=0; c<ncells; ++c)
{
int num_faces;
@ -192,31 +198,25 @@ compute_cell_geometry(int ndims, double *coords,
cross(u,v,w);
tet_volume = 0;
for(i=0; i<ndims; ++i){
tet_volume += 0.5/3 * w[i]*(x[i]-xcell[i]);
/*tet_volume += 0.5/3 * w[i]*(x[i]-xcell[i]);*/
tet_volume += w[i] * (x[i] - xcell[i]);
}
/*tet_volume = fabs(tet_volume);*/
tet_volume *= 0.5 / 3;
subnormal_sign=0.0;
for(i=0; i<ndims; ++i){
subnormal_sign += w[i]*fnormals[3*face+i];
}
if(subnormal_sign<0){
tet_volume*=-1.0;
if (subnormal_sign < 0.0) {
tet_volume = - tet_volume;
}
if(!(neighbors[2*face+0]==c)){
tet_volume*=-1.0;
if (neighbors[2*face + 0] != c) {
tet_volume = - tet_volume;
}
volume += tet_volume;
if(!(volume>0)){
fprintf(stderr, "Internal error in compute_cell_geometry: negative volume\n");
}
/* face centroid of triangle */
for (i=0; i<ndims; ++i) cface[i] = (x[i]+twothirds*0.5*(u[i]+v[i]));
@ -229,6 +229,13 @@ compute_cell_geometry(int ndims, double *coords,
for (i=0; i<ndims; ++i) u[i] = v[i];
}
}
if (! (volume > 0.0)) {
fprintf(stderr,
"Internal error in mex_compute_geometry(%*d): "
"negative volume\n", ndigits, c);
}
for (i=0; i<ndims; ++i) ccentroids[3*c+i] = xcell[i] + ccell[i]/volume;
cvolumes[c] = volume;
}

View File

@ -1,5 +1,5 @@
#ifndef GRDECL_H
#define GRDECL_H
#ifndef GRDECL_H_INCLUDED
#define GRDECL_H_INCLUDED
struct grdecl{
int dims[3];
@ -9,4 +9,8 @@ struct grdecl{
};
#endif
#endif /* GRDECL_H_INCLUDED */
/* Local Variables: */
/* c-basic-offset:4 */
/* End: */

View File

@ -1,4 +1,4 @@
//===========================================================================
/*=========================================================================
//
// File: mxgrdecl.c
//
@ -10,58 +10,55 @@
//
// $Revision$
//
//===========================================================================
//=======================================================================*/
/*
Copyright 2009, 2010 SINTEF ICT, Applied Mathematics.
Copyright 2009, 2010 Statoil ASA.
Copyright 2009, 2010 SINTEF ICT, Applied Mathematics.
Copyright 2009, 2010 Statoil ASA.
This file is part of The Open Reservoir Simulator Project (OpenRS).
This file is part of The Open Reservoir Simulator Project (OpenRS).
OpenRS 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.
OpenRS 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.
OpenRS 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 for more details.
OpenRS 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 for more details.
You should have received a copy of the GNU General Public License
along with OpenRS. If not, see <http://www.gnu.org/licenses/>.
You should have received a copy of the GNU General Public License
along with OpenRS. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <assert.h>
#include <math.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <mex.h>
#include <grdecl.h>
#include "grdecl.h"
#include "mxgrdecl.h"
/* Get COORD, ZCORN, ACTNUM and DIMS from mxArray. */
/*-------------------------------------------------------*/
void mx_init_grdecl(struct grdecl *g, const mxArray *s)
{
int i,n;
mxArray *field;
int numel;
size_t numel;
mxArray *cartdims=NULL, *actnum=NULL, *coord=NULL, *zcorn=NULL;
if (!mxIsStruct(s)
|| !(cartdims = mxGetField(s, 0, "cartDims"))
|| !(actnum = mxGetField(s, 0, "ACTNUM"))
|| !(coord = mxGetField(s, 0, "COORD"))
|| !(zcorn = mxGetField(s, 0, "ZCORN"))
)
{
char str[]="Input must be a single Matlab struct with fields\n"
"cartDims, ACTNUM, COORD and ZCORN\n";
char str[]="Input must be a single MATLAB struct with fields\n"
"'cartDims', 'COORD' and 'ZCORN'. ACTNUM may be included.\n";
mexErrMsgTxt(str);
}
@ -71,36 +68,49 @@ void mx_init_grdecl(struct grdecl *g, const mxArray *s)
mexErrMsgTxt("cartDims field must be 3 numbers");
}
if (mxIsDouble(cartdims)) {
double *tmp = mxGetPr(cartdims);
n = 1;
for (i=0; i<3; ++i){
g->dims[i] = tmp[i];
n *= tmp[i];
for (i = 0; i < 3; ++i) {
g->dims[i] = (int) tmp[i];
}
}
else if (mxIsInt32(cartdims)) {
int *tmp = mxGetData(cartdims);
memcpy(g->dims, tmp, 3 * sizeof *g->dims);
}
n = g->dims[0];
for (i = 1; i < 3; i++) { n *= g->dims[ i ]; }
if ((actnum = mxGetField(s, 0, "ACTNUM")) != NULL) {
numel = mxGetNumberOfElements(actnum);
if (mxGetClassID(actnum) != mxINT32_CLASS ||
numel != g->dims[0]*g->dims[1]*g->dims[2] ){
if ((! mxIsInt32(actnum)) || (numel != (size_t)(n))) {
mexErrMsgTxt("ACTNUM field must be nx*ny*nz numbers int32");
}
g->actnum = mxGetData(actnum);
}
else {
g->actnum = NULL;
}
field = mxGetField(s, 0, "COORD");
numel = mxGetNumberOfElements(coord);
if (mxGetClassID(coord) != mxDOUBLE_CLASS ||
numel != 6*(g->dims[0]+1)*(g->dims[1]+1)){
if ((! mxIsDouble(coord)) ||
numel != (size_t)(6*(g->dims[0]+1)*(g->dims[1]+1))) {
mexErrMsgTxt("COORD field must have 6*(nx+1)*(ny+1) doubles.");
}
g->coord = mxGetPr(coord);
numel = mxGetNumberOfElements(zcorn);
if (mxGetClassID(zcorn) != mxDOUBLE_CLASS ||
numel != 8*g->dims[0]*g->dims[1]*g->dims[2]){
if ((! mxIsDouble(zcorn)) ||
numel != (size_t)(8*g->dims[0]*g->dims[1]*g->dims[2])) {
mexErrMsgTxt("ZCORN field must have 8*nx*ny*nz doubles.");
}
g->zcorn = mxGetPr(zcorn);
}
/* Local Variables: */
/* c-basic-offset:4 */
/* End: */

View File

@ -1,4 +1,4 @@
//===========================================================================
/*=========================================================================
//
// File: mxgrdecl.h
//
@ -10,33 +10,35 @@
//
// $Revision$
//
//===========================================================================
//=======================================================================*/
/*
Copyright 2009, 2010 SINTEF ICT, Applied Mathematics.
Copyright 2009, 2010 Statoil ASA.
Copyright 2009, 2010 SINTEF ICT, Applied Mathematics.
Copyright 2009, 2010 Statoil ASA.
This file is part of The Open Reservoir Simulator Project (OpenRS).
This file is part of The Open Reservoir Simulator Project (OpenRS).
OpenRS 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.
OpenRS 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.
OpenRS 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 for more details.
OpenRS 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 for more details.
You should have received a copy of the GNU General Public License
along with OpenRS. If not, see <http://www.gnu.org/licenses/>.
You should have received a copy of the GNU General Public License
along with OpenRS. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OPENRS_MXGRDECL_HEADER
#define OPENRS_MXGRDECL_HEADER
#ifndef OPM_MXGRDECL_HEADER
#define OPM_MXGRDECL_HEADER
void mx_init_grdecl (struct grdecl *g, const mxArray *s);
#endif // OPENRS_MXGRDECL_HEADER
#endif /* OPM_MXGRDECL_HEADER */
/* Local Variables: */
/* c-basic-offset:4 */
/* End: */

File diff suppressed because it is too large Load Diff

View File

@ -53,8 +53,8 @@ extern "C" {
/* Output structure holding grid topology */
struct processed_grid{
int m;
int n;
int m; /** Upper bound on "number_of_faces" */
int n; /** Upper bound on "number_of_nodes" */
int dimensions[3]; /* Cartesian dimension */
int number_of_faces;
int *face_nodes; /* Nodes numbers of each face sequentially. */
@ -63,7 +63,7 @@ extern "C" {
enum face_tag *face_tag;
int number_of_nodes;
int number_of_nodes_on_pillars;
int number_of_nodes_on_pillars; /** Total number of unique cell vertices that lie on pillars. */
double *node_coordinates; /* 3 doubles per node, sequentially */
int number_of_cells; /* number of active cells */

View File

@ -13,255 +13,453 @@
//===========================================================================*/
/*
Copyright 2009, 2010 SINTEF ICT, Applied Mathematics.
Copyright 2009, 2010 Statoil ASA.
Copyright 2009, 2010, 2011, 2012 SINTEF ICT, Applied Mathematics.
Copyright 2009, 2010, 2011, 2012 Statoil ASA.
This file is part of The Open Reservoir Simulator Project (OpenRS).
This file is part of The Open Reservoir Simulator Project (OpenRS).
OpenRS 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.
OpenRS 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.
OpenRS 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 for more details.
OpenRS 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 for more details.
You should have received a copy of the GNU General Public License
along with OpenRS. If not, see <http://www.gnu.org/licenses/>.
You should have received a copy of the GNU General Public License
along with OpenRS. If not, see <http://www.gnu.org/licenses/>.
*/
/* Copyright 2009, 2010 SINTEF ICT, Applied Mathematics. */
/* Mex gateway by Jostein R. Natvig, SINTEF ICT. */
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <assert.h>
#include <math.h>
#include <stdlib.h>
#include <string.h>
#include <mex.h>
#include "preprocess.h"
#include "mxgrdecl.h"
void fill_grid(mxArray **out, struct processed_grid *grid)
/* ---------------------------------------------------------------------- */
static mxArray *
allocate_nodes(size_t nnodes)
/* ---------------------------------------------------------------------- */
{
const char *names[] = {"nodes", "faces", "cells", "cartDims", "type"};
mxArray *G = mxCreateStructMatrix(1,1,sizeof names / sizeof names[0],names);
size_t nflds;
const char *fields[] = { "num", "coords" };
int i,j;
double *ptr;
mxArray *nodes, *num, *coords;
nflds = sizeof(fields) / sizeof(fields[0]);
nodes = mxCreateStructMatrix(1, 1, nflds, fields);
num = mxCreateDoubleScalar(nnodes);
coords = mxCreateDoubleMatrix(nnodes, 3, mxREAL);
if ((nodes != NULL) && (num != NULL) && (coords != NULL)) {
mxSetField(nodes, 0, "num" , num);
mxSetField(nodes, 0, "coords", coords);
} else {
if (coords != NULL) { mxDestroyArray(coords); }
if (num != NULL) { mxDestroyArray(num); }
if (nodes != NULL) { mxDestroyArray(nodes); }
nodes = NULL;
}
return nodes;
}
/* nodes */
const char *n2[] = {"num", "coords"};
mxArray *nodes = mxCreateStructMatrix(1,1,sizeof n2 / sizeof n2[0],n2);
mxSetField(nodes, 0, "num", mxCreateDoubleScalar(grid->number_of_nodes));
/* ---------------------------------------------------------------------- */
static void
fill_nodes(mxArray *nodes, struct processed_grid *grid)
/* ---------------------------------------------------------------------- */
{
size_t i, j, nnodes;
double *coords;
mxArray *nodecoords = mxCreateDoubleMatrix(grid->number_of_nodes, 3, mxREAL);
ptr = mxGetPr(nodecoords);
nnodes = grid->number_of_nodes;
coords = mxGetPr(mxGetField(nodes, 0, "coords"));
for (j=0;j<3;++j)
{
for(i=0; i<grid->number_of_nodes; ++i)
{
ptr[i+grid->number_of_nodes*j] = grid->node_coordinates[3*i+j];
for (j = 0; j < 3; ++j) {
for (i = 0; i < nnodes; ++i) {
*coords++ = grid->node_coordinates[3*i + j];
}
}
mxSetField(nodes, 0, "coords", nodecoords);
mxSetField(G, 0, "nodes", nodes);
}
/* faces */
const char *n3[] = {"num", "neighbors", "nodes", "numNodes", "nodePos", "tag"};
mxArray *faces = mxCreateStructMatrix(1,1,sizeof n3 / sizeof n3[0], n3);
/* ---------------------------------------------------------------------- */
static mxArray *
allocate_faces(size_t nf, size_t nfacenodes)
/* ---------------------------------------------------------------------- */
{
size_t nflds;
const char *fields[] = { "num", "neighbors", "nodePos", "nodes", "tag" };
mxArray *faces, *num, *neighbors, *nodePos, *nodes, *tag;
nflds = sizeof(fields) / sizeof(fields[0]);
faces = mxCreateStructMatrix(1, 1, nflds, fields);
num = mxCreateDoubleScalar (nf);
neighbors = mxCreateNumericMatrix(nf , 2, mxINT32_CLASS, mxREAL);
nodePos = mxCreateNumericMatrix(nf + 1 , 1, mxINT32_CLASS, mxREAL);
nodes = mxCreateNumericMatrix(nfacenodes, 1, mxINT32_CLASS, mxREAL);
tag = mxCreateNumericMatrix(nf , 1, mxINT32_CLASS, mxREAL);
if ((faces != NULL) && (num != NULL) && (neighbors != NULL) &&
(nodePos != NULL) && (nodes != NULL) && (tag != NULL)) {
mxSetField(faces, 0, "num" , num);
mxSetField(faces, 0, "neighbors", neighbors);
mxSetField(faces, 0, "nodePos" , nodePos);
mxSetField(faces, 0, "nodes" , nodes);
mxSetField(faces, 0, "tag" , tag);
} else {
if (tag != NULL) { mxDestroyArray(tag); }
if (nodes != NULL) { mxDestroyArray(nodes); }
if (nodePos != NULL) { mxDestroyArray(nodePos); }
if (neighbors != NULL) { mxDestroyArray(neighbors); }
if (num != NULL) { mxDestroyArray(num); }
if (faces != NULL) { mxDestroyArray(faces); }
faces = NULL;
}
return faces;
}
mxSetField(faces, 0, "num", mxCreateDoubleScalar(grid->number_of_faces));
/* ---------------------------------------------------------------------- */
static void
fill_faces(mxArray *faces, struct processed_grid *grid)
/* ---------------------------------------------------------------------- */
{
size_t i, f, nf, nfn;
mxArray *faceneighbors = mxCreateNumericMatrix(grid->number_of_faces, 2,
mxINT32_CLASS, mxREAL);
{
int *iptr = mxGetData(faceneighbors);
for(j=0; j<2; ++j)
{
for (i=0; i<grid->number_of_faces; ++i)
{
int ix = grid->face_neighbors[2*i+j];
if (ix == -1)
{
iptr[i+grid->number_of_faces*j] = 0;
}
else
{
iptr[i+grid->number_of_faces*j] = ix+1;
}
}
}
}
mxSetField(faces, 0, "neighbors", faceneighbors);
mxArray *numnodes = mxCreateNumericMatrix(grid->number_of_faces, 1,
mxINT32_CLASS, mxREAL);
mxArray *nodepos = mxCreateNumericMatrix(grid->number_of_faces+1, 1,
mxINT32_CLASS, mxREAL);
{
int *iptr1 = mxGetData(numnodes);
int *iptr2 = mxGetData(nodepos);
iptr2[0] = 1;
for (i=0; i<grid->number_of_faces; ++i)
{
iptr1[i] = grid->face_ptr[i+1] - grid->face_ptr[i];
iptr2[i+1] = iptr2[i] + iptr1[i];
}
}
mxSetField(faces, 0, "numNodes", numnodes);
mxSetField(faces, 0, "nodePos", nodepos);
int *pi;
mxArray *tags = mxCreateNumericMatrix(grid->number_of_faces, 1,
mxINT32_CLASS, mxREAL);
{
int *iptr = mxGetData(tags);
for (i = 0; i < grid->number_of_faces; ++i)
{
iptr[i] = grid->face_tag[i] + 1;
}
}
mxSetField(faces, 0, "tag", tags);
nf = grid->number_of_faces;
const char *n4[] = {"num", "faces", "facePos", "indexMap"};
mxArray *cells = mxCreateStructMatrix(1,1,sizeof n4 / sizeof n4[0], n4);
mxSetField(cells, 0, "num", mxCreateDoubleScalar(grid->number_of_cells));
mxArray *map = mxCreateNumericMatrix(grid->number_of_cells, 1,
mxINT32_CLASS, mxREAL);
{
int *iptr = mxGetData(map);
for(i=0; i<grid->number_of_cells; ++i)
{
iptr[i] = grid->local_cell_index[i]+1;
}
}
mxSetField(cells, 0, "indexMap", map);
mxArray *facepos = mxCreateNumericMatrix(grid->number_of_cells+1, 1,
mxINT32_CLASS, mxREAL);
{
int *iptr = mxGetData(facepos);
for(i=0; i<grid->number_of_cells+1; ++i)
{
iptr[i] = 0;
}
for (i=0; i<2*grid->number_of_faces; ++i)
{
int c=grid->face_neighbors[i];
if(c != -1)
{
iptr[c+1]++;
}
}
iptr[0] = 1;
for(i=0; i<grid->number_of_cells; ++i)
{
iptr[i+1] += iptr[i];
}
}
mxSetField(cells, 0, "facePos", facepos);
int *counter = calloc(grid->number_of_cells, sizeof(*counter));
int num_half_faces = 0;
{
int *iptr = mxGetData(facepos);
for(i=0; i<grid->number_of_cells; ++i)
{
counter[i] = num_half_faces;
num_half_faces += iptr[i+1]-iptr[i];
/* Fill faces.neighbors */
pi = mxGetData(mxGetField(faces, 0, "neighbors"));
for (i = 0; i < 2; i++) {
for (f = 0; f < nf; f++) {
/* Add one for one-based indexing in M */
*pi++ = grid->face_neighbors[2*f + i] + 1;
}
}
mxArray *cellfaces = mxCreateNumericMatrix(num_half_faces, 1,
mxINT32_CLASS, mxREAL);
{
int *iptr = mxGetData(cellfaces);
for (i=0; i<grid->number_of_faces; ++i)
{
int c1 = grid->face_neighbors[2*i];
int c2 = grid->face_neighbors[2*i+1];
if(c1 != -1) iptr[counter[c1]++] = i+1;
if(c2 != -1) iptr[counter[c2]++] = i+1;
/* Fill faces.nodePos */
pi = mxGetData(mxGetField(faces, 0, "nodePos"));
for (i = 0; i <= nf; i++) { pi[i] = grid->face_ptr[i] + 1; }
/* Fill faces.nodes */
pi = mxGetData(mxGetField(faces, 0, "nodes"));
nfn = grid->face_ptr[nf]; /* Total number of face nodes */
for (i = 0; i < nfn; i++) { pi[i] = grid->face_nodes[i] + 1; }
/* Fill faces.tag */
pi = mxGetData(mxGetField(faces, 0, "tag"));
for (f = 0; f < nf; f++) { pi[f] = grid->face_tag[f] + 1; }
}
/* ---------------------------------------------------------------------- */
static size_t
count_halffaces(size_t nf, const int *neighbors)
/* ---------------------------------------------------------------------- */
{
int c1, c2;
size_t nhf, f;
for (f = nhf = 0; f < nf; f++) {
c1 = neighbors[2*f + 0];
c2 = neighbors[2*f + 1];
nhf += c1 >= 0;
nhf += c2 >= 0;
}
return nhf;
}
/* ---------------------------------------------------------------------- */
static mxArray *
allocate_cells(size_t nc, size_t ncf)
/* ---------------------------------------------------------------------- */
{
size_t nflds;
const char *fields[] = { "num", "facePos", "faces", "indexMap" };
mxArray *cells, *num, *facePos, *faces, *indexMap;
nflds = sizeof(fields) / sizeof(fields[0]);
cells = mxCreateStructMatrix(1, 1, nflds, fields);
num = mxCreateDoubleScalar (nc);
facePos = mxCreateNumericMatrix(nc + 1, 1, mxINT32_CLASS, mxREAL);
faces = mxCreateNumericMatrix(ncf , 2, mxINT32_CLASS, mxREAL);
indexMap = mxCreateNumericMatrix(nc , 1, mxINT32_CLASS, mxREAL);
if ((cells != NULL) && (num != NULL) && (facePos != NULL) &&
(faces != NULL) && (indexMap != NULL)) {
mxSetField(cells, 0, "num" , num );
mxSetField(cells, 0, "facePos" , facePos );
mxSetField(cells, 0, "faces" , faces );
mxSetField(cells, 0, "indexMap", indexMap);
} else {
if (indexMap != NULL) { mxDestroyArray(indexMap); }
if (faces != NULL) { mxDestroyArray(faces); }
if (facePos != NULL) { mxDestroyArray(facePos); }
if (num != NULL) { mxDestroyArray(num); }
if (cells != NULL) { mxDestroyArray(cells); }
cells = NULL;
}
return cells;
}
/* ---------------------------------------------------------------------- */
static void
fill_cells(mxArray *cells, struct processed_grid *grid)
/* ---------------------------------------------------------------------- */
{
size_t c, nc, f, nf, i;
int c1, c2, cf_tag, nhf;
int *pi1, *pi2;
nc = grid->number_of_cells;
nf = grid->number_of_faces;
/* Simultaneously fill cells.facePos and cells.faces by transposing the
* neighbours mapping. */
pi1 = mxGetData(mxGetField(cells, 0, "facePos"));
pi2 = mxGetData(mxGetField(cells, 0, "faces" ));
for (i = 0; i < nc + 1; i++) { pi1[i] = 0; }
/* 1) Count connections (i.e., faces per cell). */
for (f = 0; f < nf; f++) {
c1 = grid->face_neighbors[2*f + 0];
c2 = grid->face_neighbors[2*f + 1];
if (c1 >= 0) { pi1[c1 + 1] += 1; }
if (c2 >= 0) { pi1[c2 + 1] += 1; }
}
/* 2) Define start pointers (really, position *end* pointers at start). */
for (c = 1; c <= nc; c++) {
pi1[0] += pi1[c];
pi1[c] = pi1[0] - pi1[c];
}
/* 3) Fill connection structure whilst advancing end pointers. */
nhf = pi1[0];
pi1[0] = 0;
mxAssert (((size_t) nhf) == mxGetM(mxGetField(cells, 0, "faces")),
"Number of half faces (SIZE(cells.faces,1)) incorrectly "
"determined earlier.");
for (f = 0; f < nf; f++) {
cf_tag = 2*grid->face_tag[f] + 1; /* [1, 3, 5] */
c1 = grid->face_neighbors[2*f + 0];
c2 = grid->face_neighbors[2*f + 1];
if (c1 >= 0) {
pi2[ pi1[ c1 + 1 ] + 0*nhf ] = f + 1;
pi2[ pi1[ c1 + 1 ] + 1*nhf ] = cf_tag + 1; /* out */
pi1[ c1 + 1 ] += 1;
}
if (c2 >= 0) {
pi2[ pi1[ c2 + 1 ] + 0*nhf ] = f + 1;
pi2[ pi1[ c2 + 1 ] + 1*nhf ] = cf_tag + 0; /* in */
pi1[ c2 + 1 ] += 1;
}
}
mxSetField(cells, 0, "faces", cellfaces);
mxSetField(G, 0, "cells", cells);
/* Finally, adjust pointer array for one-based indexing in M. */
for (i = 0; i < nc + 1; i++) { pi1[i] += 1; }
int n = grid->face_ptr[grid->number_of_faces];
mxArray *facenodes = mxCreateNumericMatrix(n, 1,
mxINT32_CLASS, mxREAL);
{
int *iptr = mxGetData(facenodes);
for (i=0; i<n; ++i)
{
iptr[i] = grid->face_nodes[i]+1;
}
}
mxSetField(faces, 0, "nodes", facenodes);
mxSetField(G, 0, "faces", faces);
/* Fill cells.indexMap. Note that despite the name, 'local_cell_index'
* really *is* the (zero-based) indexMap of the 'processed_grid'. */
pi1 = mxGetData(mxGetField(cells, 0, "indexMap"));
for (c = 0; c < nc; c++) { pi1[c] = grid->local_cell_index[c] + 1; }
}
free(counter);
/* ---------------------------------------------------------------------- */
static mxArray *
allocate_grid(struct processed_grid *grid, const char *func)
/* ---------------------------------------------------------------------- */
{
size_t nflds, nhf;
const char *fields[] = { "nodes", "faces", "cells",
"type", "cartDims", "griddim" };
/* cartDims */
mxArray *cartDims = mxCreateDoubleMatrix(1, 3, mxREAL);
ptr = mxGetPr(cartDims);
ptr[0] = grid->dimensions[0];
ptr[1] = grid->dimensions[1];
ptr[2] = grid->dimensions[2];
mxArray *G, *nodes, *faces, *cells;
mxArray *type, *typestr, *cartDims, *griddim;
nflds = sizeof(fields) / sizeof(fields[0]);
nhf = count_halffaces(grid->number_of_faces, grid->face_neighbors);
G = mxCreateStructMatrix(1, 1, nflds, fields);
nodes = allocate_nodes(grid->number_of_nodes);
faces = allocate_faces(grid->number_of_faces,
grid->face_ptr[ grid->number_of_faces ]);
cells = allocate_cells(grid->number_of_cells, nhf);
type = mxCreateCellMatrix(1, 1);
typestr = mxCreateString(func);
cartDims = mxCreateDoubleMatrix(1, 3, mxREAL);
griddim = mxCreateDoubleScalar(3);
if ((G != NULL) && (nodes != NULL) && (faces != NULL) &&
(cells != NULL) && (type != NULL) && (typestr != NULL) &&
(cartDims != NULL) && (griddim != NULL)) {
mxSetCell(type, 0, typestr);
mxSetField(G, 0, "nodes" , nodes );
mxSetField(G, 0, "faces" , faces );
mxSetField(G, 0, "cells" , cells );
mxSetField(G, 0, "type" , type );
mxSetField(G, 0, "cartDims", cartDims);
mxSetField(G, 0, "griddim" , griddim );
} else {
if (griddim != NULL) { mxDestroyArray(griddim); }
if (cartDims != NULL) { mxDestroyArray(cartDims); }
if (typestr != NULL) { mxDestroyArray(typestr); }
if (type != NULL) { mxDestroyArray(type); }
if (cells != NULL) { mxDestroyArray(cells); }
if (faces != NULL) { mxDestroyArray(faces); }
if (nodes != NULL) { mxDestroyArray(nodes); }
if (G != NULL) { mxDestroyArray(G); }
/* type */
mxArray *type = mxCreateCellMatrix(1, 1);
mxSetCell(type, 0, mxCreateString("processgrid"));
G = NULL;
}
mxSetField(G, 0, "type", type);
out[0] = G;
return G;
}
/* Gateway routine for Matlab mex function. */
/*-------------------------------------------------------*/
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
/* ---------------------------------------------------------------------- */
static void
fill_grid(mxArray *G, struct processed_grid *grid)
/* ---------------------------------------------------------------------- */
{
/* Set up data passed from Matlab */
struct grdecl g;
struct processed_grid out;
double tolerance = 0.0;
double *pr;
mx_init_grdecl(&g, prhs[0]);
if (nrhs == 2)
{
tolerance = mxGetScalar (prhs[1]);
}
pr = mxGetPr(mxGetField(G, 0, "cartDims"));
pr[0] = grid->dimensions[0];
pr[1] = grid->dimensions[1];
pr[2] = grid->dimensions[2];
process_grdecl(&g, tolerance, &out);
if (plhs >0)
{
/* write to matlab struct */
fill_grid(plhs, &out);
}
/* Free whatever was allocated in initGrdecl. */
free_processed_grid(&out);
fill_nodes(mxGetField(G, 0, "nodes"), grid);
fill_faces(mxGetField(G, 0, "faces"), grid);
fill_cells(mxGetField(G, 0, "cells"), grid);
}
/* ---------------------------------------------------------------------- */
static int
args_ok(int nlhs, int nrhs, const mxArray *prhs[])
/* ---------------------------------------------------------------------- */
{
int ok;
ok = (nlhs == 1) && ((nrhs == 1) || (nrhs == 2));
ok = ok && !mxIsEmpty(prhs[0]);
ok = ok && mxIsStruct(prhs[0]);
ok = ok && (mxGetFieldNumber(prhs[0], "cartDims") >= 0);
ok = ok && (mxGetFieldNumber(prhs[0], "COORD" ) >= 0);
ok = ok && (mxGetFieldNumber(prhs[0], "ZCORN" ) >= 0);
if (ok && (nrhs == 2)) {
ok = mxIsDouble(prhs[1]) && (mxGetNumberOfElements(prhs[1]) == 1);
}
return ok;
}
/* ---------------------------------------------------------------------- */
static double
define_tolerance(int nrhs, const mxArray *prhs[])
/* ---------------------------------------------------------------------- */
{
double tol;
tol = 0.0;
if (nrhs == 2) {
tol = mxGetScalar(prhs[1]);
}
return tol;
}
/* G = processgrid(grdecl)
G = processgrid(grdecl, tolerance)
*/
/* ---------------------------------------------------------------------- */
void
mexFunction(int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[])
/* ---------------------------------------------------------------------- */
{
double tolerance;
char errmsg[1023 + 1];
struct grdecl grdecl;
struct processed_grid g;
if (args_ok(nlhs, nrhs, prhs)) {
mx_init_grdecl(&grdecl, prhs[0]);
tolerance = define_tolerance(nrhs, prhs);
process_grdecl(&grdecl, tolerance, &g);
plhs[0] = allocate_grid(&g, mexFunctionName());
if (plhs[0] != NULL) {
fill_grid(plhs[0], &g);
} else {
/* Failed to create grid structure. Return empty. */
plhs[0] = mxCreateDoubleMatrix(0, 0, mxREAL);
}
free_processed_grid(&g);
} else {
sprintf(errmsg,
"Calling sequence is\n\t"
"G = %s(grdecl)\t%%or\n\t"
"G = %s(grdecl, tolerance)\n"
"The 'grdecl' must be a valid structure with fields\n"
"\t'cartDims', 'COORD', 'ZCORN'",
mexFunctionName(), mexFunctionName());
mexErrMsgTxt(errmsg);
}
}
/* Local Variables: */
/* c-basic-offset:4 */
/* End: */

View File

@ -1,12 +1,14 @@
function varargout = processgrid(varargin)
function G = processgrid(varargin)
%Compute grid topology and geometry from pillar grid description.
%
% SYNOPSIS:
% G = processGRDECL(grdecl)
% G = processgrid(grdecl)
% G = processgrid(grdecl,ztol)
%
% PARAMETERS:
% grdecl - Raw pillar grid structure, as defined by function
% 'readGRDECL', with fields COORDS, ZCORN and, possibly, ACTNUM.
% ztol - tolerance for unique points
%
% RETURNS:
% G - Valid grid definition containing connectivity, cell
@ -32,10 +34,33 @@ function varargout = processgrid(varargin)
% $Date$
% $Revision$
% Build MEX edition of same.
%
buildmex CFLAGS='$CFLAGS -Wall -fPIC' processgrid.c preprocess.c ...
uniquepoints.c facetopology.c sparsetable.c mxgrdecl.c
G = processgrid_mex(varargin{:});
G.griddim = 3;
G = splitDisconnectedGrid(G, false);
end
% Call MEX edition.
[varargout{1:nargout}] = processgrid(varargin{:});
function G = splitDisconnectedGrid(G, verbose)
% Check if grid is connected
ix = all(G.faces.neighbors~=0, 2);
I = [G.faces.neighbors(ix,1);G.faces.neighbors(ix,2)];
J = [G.faces.neighbors(ix,2);G.faces.neighbors(ix,1)];
N = double(max(G.faces.neighbors(:)));
A = sparse(double(I),double(J),1,N,N)+speye(N);
clear ix I J
[a,b,c,d]=dmperm(A); %#ok
clear A b d
if numel(c) > 2,
dispif(verbose, '\nGrid has %d disconnected components\n', ...
numel(c)- 1);
% Partition grid into connected subgrids
for i = 1:numel(c) - 1,
g(i) = extractSubgrid(G, a(c(i):c(i+1)-1)); %#ok
sz(i) = g(i).cells.num; %#ok
g(i).cartDims = G.cartDims; %#ok
end
% Return largest (in number of cells) grid first
[i,i] = sort(-sz); %#ok
G = g(i);
end
end

View File

@ -1,282 +0,0 @@
/*===========================================================================
//
// Author: Jostein R. Natvig <Jostein.R.Natvig@sintef.no>
//
//==========================================================================*/
/*
Copyright 2011 SINTEF ICT, Applied Mathematics.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <assert.h>
#include <vector>
#include "readvector.hpp"
struct ParserState {
int error;
};
template <typename T>
static void parse_next_token (FILE *fp, struct ParserState *s,
T *v, int *count);
static char *get_token_string (FILE *fp, struct ParserState *s, char *buf);
static void skip_line (FILE *fp, struct ParserState *s);
static char *convert_string (int *value, char *str);
static char *convert_string (double *value, char *str);
static void split_token_string(char *str, char *rstr, char *vstr);
static int get_repeat_count (char *rstr, struct ParserState *s);
template <typename T>
static void get_value (char *vstr, struct ParserState *s, T *v);
/* ------------------------------------------------------------------ */
static const int bufsz = 1024;
/* ------------------------------------------------------------------ */
template <typename T>
static void readvector(FILE *fp, struct ParserState *s, std::vector<T>& v)
{
T value;
int count, i;
count = 1;
s->error = 0;
while (count > 0){
parse_next_token(fp, s, &value, &count);
for (i=0; i<count; ++i)
{
v.push_back(value);
}
}
if (s->error) {
assert(0);
}
}
/* ------------------------------------------------------------------ */
template <typename T>
static void parse_next_token(FILE *fp, struct ParserState *s, T *v, int *r)
{
char str[bufsz];
char rstr[bufsz];
char vstr[bufsz];
str[0]='\0';
while (strlen(str)==0)
{
get_token_string(fp, s, str);
}
if (str[0] == '/')
{
/* end-of-vector marker */
*r = 0;
}
else
{
split_token_string(str, rstr, vstr);
*r = get_repeat_count(rstr, s);
get_value(vstr, s, v);
if (s->error)
{
/* signal abort to caller */
*r = 0;
}
}
}
/* ------------------------------------------------------------------ */
/* split string 'rrrr*vvvv' in strings 'rrrr' and 'vvvv' */
static void split_token_string(char *str, char *rstr, char *vstr)
{
char *ptr;
ptr=strchr(str, '*');
if ((ptr != NULL) && (ptr!=str)) {
while(str!=ptr)
{
*rstr++=*str++;
}
*rstr='\0';
str++;
}
else
{
rstr[0]='\0';
}
while((*vstr++=*str++) )
{
continue ;
}
*vstr='\0';
}
/* ------------------------------------------------------------------ */
static int get_repeat_count(char *rstr, struct ParserState *s)
{
int r;
char *ptr;
if (strlen(rstr)>0)
{
ptr=convert_string(&r, rstr);
if ((ptr==rstr) || (strlen(ptr)>0) || (r<1))
{
s->error = 1;
}
}
else
{
r = 1;
}
return r;
}
/* ------------------------------------------------------------------ */
template <typename T>
static void get_value(char *vstr, struct ParserState *s, T *v)
{
char *ptr;
if (strlen(vstr)>0)
{
/* Convert FORTRAN style floats 3.13D-6 to IEEE */
for(ptr=vstr; *ptr; ++ptr)
{
if (*ptr=='D')
{
*ptr='E';
}
}
ptr = convert_string(v, vstr);
if ((ptr==vstr) || (strlen(ptr)>0))
{
s->error = 1;
}
}
else
{
s->error = 1;
}
}
/* ------------------------------------------------------------------ */
static char *get_token_string(FILE *fp, struct ParserState *s, char *str)
{
char *ptr = str;
int c;
/* Skip leading blanks */
while((c = fgetc(fp)) != EOF && isspace(c))
{
;
}
*ptr++ = c;
/* Catch end marker */
if (c == '/') {
skip_line(fp, s);
*ptr++ = '\0';
return str;
}
while((c = fgetc(fp)) != EOF && !isspace(c))
{
*ptr++ = c;
/* Break and skip rest of line if '--' if encountered */
if (*(ptr-1) == '-' && ptr-str>1 && *(ptr-2) == '-'){
ptr = ptr - 2;
skip_line(fp, s);
break;
}
/* If end marker is encontered, push character back onto stream. */
if (c=='/') {
ungetc(c, fp);
ptr--;
break;
}
assert(ptr-str < bufsz);
}
*ptr='\0';
return str;
}
/* ------------------------------------------------------------------ */
static void skip_line(FILE *fp, struct ParserState *s)
{
static_cast<void>(s);
int c;
while((c = fgetc(fp))!=EOF && c != '\n') {
;
}
}
/* ------------------------------------------------------------------ */
// int version
static char *convert_string(int *value, char *str)
{
char *q;
*value = strtol(str, &q, 10);
return q;
}
/* ------------------------------------------------------------------ */
// double version
static char *convert_string(double *value, char *str)
{
char *q;
*value = strtod(str, &q);
return q;
}
/* ------------------------------------------------------------------ */
template <typename T>
void read_vector_from_file(const std::string& fn, std::vector<T>& v)
{
FILE *fp = fopen(fn.c_str(), "r");
struct ParserState s = { 0 };
readvector(fp, &s, v);
fclose(fp);
}
void read_vector_from_file(const std::string& fn, std::vector<int>& v)
{
read_vector_from_file<int>(fn, v);
}
void read_vector_from_file(const std::string& fn, std::vector<double>& v)
{
read_vector_from_file<double>(fn, v);
}

View File

@ -1,24 +0,0 @@
/*===========================================================================
//
// File: readvector.hpp
//
// Created: 2011-11-30 09:35:14+0100
//
// Author: Jostein R. Natvig <Jostein.R.Natvig@sintef.no>
//
//==========================================================================*/
/*
Copyright 2011 SINTEF ICT, Applied Mathematics.
*/
#ifndef READVECTOR_HPP_HEADER
#define READVECTOR_HPP_HEADER
#include <string>
void read_vector_from_file(const std::string&, std::vector<int>& v);
void read_vector_from_file(const std::string&, std::vector<double>& v);
#endif /* READVECTOR_HPP_HEADER */

View File

@ -1,100 +0,0 @@
/*===========================================================================
//
// File: sparsetable.c
//
// Created: Fri Jun 19 08:48:04 2009
//
// Author: Jostein R. Natvig <Jostein.R.Natvig@sintef.no>
//
// $Date$
//
// $Revision$
//
//==========================================================================*/
/*
Copyright 2009, 2010 SINTEF ICT, Applied Mathematics.
Copyright 2009, 2010 Statoil ASA.
This file is part of The Open Reservoir Simulator Project (OpenRS).
OpenRS 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.
OpenRS 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 for more details.
You should have received a copy of the GNU General Public License
along with OpenRS. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <assert.h>
#include <stdio.h>
#include "sparsetable.h"
void free_sparse_table (sparse_table_t *tab)
{
if(tab->ptr) free(tab->ptr);
if(tab->data) free(tab->data);
free(tab);
}
sparse_table_t *malloc_sparse_table(int m, int n, int datasz)
{
size_t alloc_sz;
sparse_table_t *tab = malloc(sizeof *tab);
tab->m = m;
tab->n = n;
tab->position = 0;
if (!(tab->ptr = malloc((m+1) * sizeof (*tab->ptr)))){
fprintf(stderr, "Could not allocate space for sparse ptr\n");
free_sparse_table(tab);
return NULL;
}
alloc_sz = datasz;
alloc_sz *= n;
if(!(tab->data = malloc(alloc_sz))){
fprintf(stderr, "Could not allocate space for sparse data(%d)\n", n);
free_sparse_table(tab);
return NULL;
}
return tab;
}
sparse_table_t *realloc_sparse_table(sparse_table_t *tab, int m, int n, int datasz)
{
void *p = realloc(tab->ptr, (m+1) * sizeof (*tab->ptr));
if (p){
tab->ptr = p;
}else{
fprintf(stderr, "Could not reallocate space for sparse ptr\n");
free_sparse_table(tab);
return NULL;
}
p = realloc(tab->data, n * datasz);
if(p){
tab->data = p;
}else{
fprintf(stderr, "Could not reallocate space for sparse data(%d)\n", n);
free_sparse_table(tab);
return NULL;
}
tab->m = m;
tab->n = n;
return tab;
}

View File

@ -1,53 +0,0 @@
/*===========================================================================
//
// File: sparsetable.h
//
// Created: Fri Jun 19 08:47:45 2009
//
// Author: Jostein R. Natvig <Jostein.R.Natvig@sintef.no>
//
// $Date$
//
// $Revision$
//
//===========================================================================*/
/*
Copyright 2009, 2010 SINTEF ICT, Applied Mathematics.
Copyright 2009, 2010 Statoil ASA.
This file is part of The Open Reservoir Simulator Project (OpenRS).
OpenRS 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.
OpenRS 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 for more details.
You should have received a copy of the GNU General Public License
along with OpenRS. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OPENRS_SPARSETABLE_HEADER
#define OPENRS_SPARSETABLE_HEADER
typedef struct{
int m; /* number of rows */
int *ptr; /* row pointer of size m+1 */
int position; /* first position in ptr that is not filled. */
int n; /* size of data */
void *data; /* sparse table data */
} sparse_table_t;
void free_sparse_table (sparse_table_t *tab);
sparse_table_t *malloc_sparse_table (int m, int n, int datasz);
sparse_table_t *realloc_sparse_table (sparse_table_t *tab, int m, int n, int datasz);
#endif /* OPENRS_SPARSETABLE_HEADER */

View File

@ -33,35 +33,35 @@
*/
#include <assert.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <limits.h>
#include <float.h>
#include <limits.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "sparsetable.h"
#include "preprocess.h"
#include "uniquepoints.h"
#define min(i,j) ((i)<(j) ? (i) : (j))
#define max(i,j) ((i)>(j) ? (i) : (j))
#define overlap(a1,a2,b1,b2) max(a1,b1) < min(a2,b2)
#define MIN(i,j) (((i) < (j)) ? (i) : (j))
#define MAX(i,j) (((i) > (j)) ? (i) : (j))
/*-----------------------------------------------------------------
Compare function passed to qsort
*/
Compare function passed to qsortx */
static int compare(const void *a, const void *b)
{
if (*(const double*)a < *(const double*) b) return -1;
else return 1;
const double a0 = *(const double*) a;
const double b0 = *(const double*) b;
/* { -1, a < b
* compare(a,b) = { 0, a = b
* { 1, a > b */
return (a0 > b0) - (a0 < b0);
}
/*-----------------------------------------------------------------
Creat sorted list of z-values in zcorn with actnum==1
*/
Creat sorted list of z-values in zcorn with actnum==1x */
static int createSortedList(double *list, int n, int m,
const double *z[], const int *a[])
{
@ -81,17 +81,17 @@ static int createSortedList(double *list, int n, int m,
/*-----------------------------------------------------------------
Remove points less than <tolerance> apart in <list> of increasing
doubles.
*/
doubles. */
static int uniquify(int n, double *list, double tolerance)
{
int i, pos = 0;
int i;
int pos;
double val;
assert (!(tolerance < 0.0));
if (n<1) return 0;
pos = 0;
val = list[pos++];/* Keep first value */
for (i=1; i<n; ++i){
@ -120,8 +120,7 @@ static int uniquify(int n, double *list, double tolerance)
/*-----------------------------------------------------------------
Along single pillar:
*/
Along single pillar: */
static int assignPointNumbers(int begin,
int end,
const double *zlist,
@ -149,7 +148,8 @@ static int assignPointNumbers(int begin,
/* Skip inactive cells */
if (!a[i/2]) {
p[0] = p[-1]; /* Inactive cells are collapsed leaving void space.*/
p[0] = p[-1]; /* Inactive cells are collapsed leaving
* void space.*/
++p;
continue;
}
@ -175,26 +175,25 @@ static int assignPointNumbers(int begin,
}
/*-----------------------------------------------------------------
Given a vector <field> with k index running faster than i running
faster than j, and Cartesian dimensions <dims>, find pointers to the
(i-1, j-1, 0), (i-1, j, 0), (i, j-1, 0) and (i, j, 0) elements of
field.
*/
static void igetvectors(const int dims[3], int i, int j,
const int *field, const int *v[])
/* ---------------------------------------------------------------------- */
static void
vector_positions(const int dims[3] ,
const int i ,
const int j ,
size_t start[4])
/* ---------------------------------------------------------------------- */
{
size_t im, ip, jm, jp;
int im = max(1, i ) - 1;
int ip = min(dims[0], i+1) - 1;
int jm = max(1, j ) - 1;
int jp = min(dims[1], j+1) - 1;
im = MAX(1, i ) - 1;
jm = MAX(1, j ) - 1;
ip = MIN(dims[0], i+1) - 1;
jp = MIN(dims[1], j+1) - 1;
v[0] = field + dims[2]*(im + dims[0]* jm);
v[1] = field + dims[2]*(im + dims[0]* jp);
v[2] = field + dims[2]*(ip + dims[0]* jm);
v[3] = field + dims[2]*(ip + dims[0]* jp);
start[ 0 ] = dims[2] * (im + dims[0]*jm);
start[ 1 ] = dims[2] * (im + dims[0]*jp);
start[ 2 ] = dims[2] * (ip + dims[0]*jm);
start[ 3 ] = dims[2] * (ip + dims[0]*jp);
}
@ -202,21 +201,35 @@ static void igetvectors(const int dims[3], int i, int j,
Given a vector <field> with k index running faster than i running
faster than j, and Cartesian dimensions <dims>, find pointers to the
(i-1, j-1, 0), (i-1, j, 0), (i, j-1, 0) and (i, j, 0) elements of
field.
*/
field. */
static void igetvectors(const int dims[3], int i, int j,
const int *field, const int *v[])
{
size_t p, start[4];
vector_positions(dims, i, j, start);
for (p = 0; p < 4; p++) {
v[p] = field + start[p];
}
}
/*-----------------------------------------------------------------
Given a vector <field> with k index running faster than i running
faster than j, and Cartesian dimensions <dims>, find pointers to the
(i-1, j-1, 0), (i-1, j, 0), (i, j-1, 0) and (i, j, 0) elements of
field. */
static void dgetvectors(const int dims[3], int i, int j,
const double *field, const double *v[])
{
size_t p, start[4];
int im = max(1, i ) - 1;
int ip = min(dims[0], i+1) - 1;
int jm = max(1, j ) - 1;
int jp = min(dims[1], j+1) - 1;
vector_positions(dims, i, j, start);
v[0] = field + dims[2]*(im + dims[0]* jm);
v[1] = field + dims[2]*(im + dims[0]* jp);
v[2] = field + dims[2]*(ip + dims[0]* jm);
v[3] = field + dims[2]*(ip + dims[0]* jp);
for (p = 0; p < 4; p++) {
v[p] = field + start[p];
}
}
@ -226,10 +239,18 @@ static void dgetvectors(const int dims[3], int i, int j,
*/
static void interpolate_pillar(const double *coord, double *pt)
{
double a = (pt[2]-coord[2])/(coord[5]-coord[2]);
if (isinf(a) || isnan(a)){
double a;
if (fabs(coord[5] - coord[2]) > 0) {
a = (pt[2] - coord[2]) / (coord[5] - coord[2]);
} else {
a = 0;
}
#if 0
pt[0] = coord[0] + a*(coord[3]-coord[0]);
pt[1] = coord[1] + a*(coord[4]-coord[1]);
@ -240,34 +261,34 @@ static void interpolate_pillar(const double *coord, double *pt)
}
/*-----------------------------------------------------------------
Assign point numbers p such that "zlist(p)==zcorn".
Assume that coordinate number is arranged in a
sequence such that the natural index is (k,i,j)
*/
Assign point numbers p such that "zlist(p)==zcorn". Assume that
coordinate number is arranged in a sequence such that the natural
index is (k,i,j) */
int finduniquepoints(const struct grdecl *g,
/* return values: */
int *plist, /* list of point numbers on each pillar*/
int *plist, /* list of point numbers on
* each pillar*/
double tolerance,
struct processed_grid *out)
{
int nx = out->dimensions[0];
int ny = out->dimensions[1];
int nz = out->dimensions[2];
/* ztab->data may need extra space temporarily due to simple boundary treatement */
const int nx = out->dimensions[0];
const int ny = out->dimensions[1];
const int nz = out->dimensions[2];
const int nc = g->dims[0]*g->dims[1]*g->dims[2];
/* zlist may need extra space temporarily due to simple boundary
* treatement */
int npillarpoints = 8*(nx+1)*(ny+1)*nz;
int npillars = (nx+1)*(ny+1);
sparse_table_t *ztab = malloc_sparse_table(npillars,
npillarpoints,
sizeof(double));
double *zlist = malloc(npillarpoints*sizeof *zlist);
int *zptr = malloc((npillars+1)*sizeof *zptr);
int nc = g->dims[0]*g->dims[1]*g->dims[2];
double *zlist = ztab->data; /* casting void* to double* */
int *zptr = ztab->ptr;
int i,j,k;
@ -275,14 +296,21 @@ int finduniquepoints(const struct grdecl *g,
int len = 0;
double *zout = zlist;
int pos = 0;
double *pt;
const double *z[4];
const int *a[4];
int *p;
int pix, cix;
int zix;
const double *coord = g->coord;
double *pt;
int *p;
d1[0] = 2*g->dims[0]; d1[1] = 2*g->dims[1]; d1[2] = 2*g->dims[2];
d1[0] = 2*g->dims[0];
d1[1] = 2*g->dims[1];
d1[2] = 2*g->dims[2];
out->node_coordinates = malloc (3*8*nc*sizeof(*out->node_coordinates));
zptr[pos++] = zout - zlist;
pt = out->node_coordinates;
@ -291,9 +319,6 @@ int finduniquepoints(const struct grdecl *g,
for (j=0; j < g->dims[1]+1; ++j){
for (i=0; i < g->dims[0]+1; ++i){
const int *a[4];
const double *z[4];
/* Get positioned pointers for actnum and zcorn data */
igetvectors(g->dims, i, j, g->actnum, a);
dgetvectors(d1, 2*i, 2*j, g->zcorn, z);
@ -308,7 +333,8 @@ int finduniquepoints(const struct grdecl *g,
pt += 3;
}
/* Increment pointer to sparse table of unique zcorn values */
/* Increment pointer to sparse table of unique zcorn
* values */
zout = zout + len;
zptr[pos++] = zout - zlist;
@ -318,25 +344,25 @@ int finduniquepoints(const struct grdecl *g,
out->number_of_nodes_on_pillars = zptr[pos-1];
out->number_of_nodes = zptr[pos-1];
/* Loop over all vertical sets of zcorn values, assign point numbers */
/* Loop over all vertical sets of zcorn values, assign point
* numbers */
p = plist;
for (j=0; j < 2*g->dims[1]; ++j){
for (i=0; i < 2*g->dims[0]; ++i){
/* pillar index */
int pix = (i+1)/2 + (g->dims[0]+1)*((j+1)/2);
pix = (i+1)/2 + (g->dims[0]+1)*((j+1)/2);
/* cell column position */
int cix = g->dims[2]*((i/2) + (j/2)*g->dims[0]);
cix = g->dims[2]*((i/2) + (j/2)*g->dims[0]);
/* zcorn column position */
int zix = 2*g->dims[2]*(i+2*g->dims[0]*j);
const int *a = g->actnum + cix;
const double *z = g->zcorn + zix;
zix = 2*g->dims[2]*(i+2*g->dims[0]*j);
if (!assignPointNumbers(zptr[pix], zptr[pix+1], zlist,
2*g->dims[2], z, a, p, tolerance)){
2*g->dims[2],
g->zcorn + zix, g->actnum + cix,
p, tolerance)){
fprintf(stderr, "Something went wrong in assignPointNumbers");
return 0;
}
@ -345,9 +371,8 @@ int finduniquepoints(const struct grdecl *g,
}
}
free_sparse_table(ztab);
free(zptr);
free(zlist);
return 1;
}
@ -355,4 +380,3 @@ int finduniquepoints(const struct grdecl *g,
/* Local Variables: */
/* c-basic-offset:4 */
/* End: */

View File

@ -13,34 +13,34 @@
//==========================================================================*/
/*
Copyright 2009, 2010 SINTEF ICT, Applied Mathematics.
Copyright 2009, 2010 Statoil ASA.
Copyright 2009, 2010 SINTEF ICT, Applied Mathematics.
Copyright 2009, 2010 Statoil ASA.
This file is part of The Open Reservoir Simulator Project (OpenRS).
This file is part of The Open Reservoir Simulator Project (OpenRS).
OpenRS 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.
OpenRS 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.
OpenRS 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 for more details.
OpenRS 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 for more details.
You should have received a copy of the GNU General Public License
along with OpenRS. If not, see <http://www.gnu.org/licenses/>.
You should have received a copy of the GNU General Public License
along with OpenRS. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OPENRS_UNIQUEPOINTS_HEADER
#define OPENRS_UNIQUEPOINTS_HEADER
#ifndef OPM_UNIQUEPOINTS_HEADER
#define OPM_UNIQUEPOINTS_HEADER
int finduniquepoints(const struct grdecl *g, /* input */
int *p, /* for each z0 in zcorn, z0 = z[p0] */
double t, /* tolerance*/
struct processed_grid *out);
#endif /* OPENRS_UNIQUEPOINTS_HEADER */
#endif /* OPM_UNIQUEPOINTS_HEADER */
/* Local Variables: */
/* c-basic-offset:4 */

View File

@ -37,13 +37,13 @@ extern "C" {
*/
struct CSRMatrix
{
size_t m; /** Number of rows */
size_t nnz; /** Number of structurally non-zero elements */
size_t m; /**< Number of rows */
size_t nnz; /**< Number of structurally non-zero elements */
int *ia; /** Row pointers */
int *ja; /** Column indices */
int *ia; /**< Row pointers */
int *ja; /**< Column indices */
double *sa; /** Matrix elements */
double *sa; /**< Matrix elements */
};

View File

@ -52,8 +52,6 @@ test_lapack_LDADD = $(LAPACK_LIBS) $(BLAS_LIBS) $(LIBS) $(FLIBS)
test_readpolymer_SOURCES = test_readpolymer.cpp
test_read_vag_SOURCES = test_read_vag.cpp
test_readvector_SOURCES = test_readvector.cpp
test_sf2p_SOURCES = test_sf2p.cpp
test_writeVtkData_SOURCES = test_writeVtkData.cpp

View File

@ -1,67 +0,0 @@
#include <iostream>
#include <string>
#include <vector>
#include <opm/core/grid.h>
#include <opm/core/grid/cpgpreprocess/preprocess.h>
#include <opm/core/grid/cornerpoint_grid.h>
#include <opm/core/grid/cpgpreprocess/readvector.hpp>
static struct UnstructuredGrid*
read_grid(const std::string& dir)
{
std::string fn;
fn = dir + '/' + "zcorn.txt";
std::vector<double> zcorn;
read_vector_from_file(fn, zcorn);
fn = dir + '/' + "coord.txt";
::std::vector<double> coord;
read_vector_from_file(fn, coord);
fn = dir + '/' + "actnum.txt";
std::vector<int> actnum;
read_vector_from_file(fn, actnum);
fn = dir + '/' + "dimens.txt";
::std::vector<int> dimens;
read_vector_from_file(fn, dimens);
struct grdecl grdecl;
grdecl.zcorn = &zcorn[0];
grdecl.coord = &coord[0];
grdecl.actnum = &actnum[0];
grdecl.dims[0] = dimens[0];
grdecl.dims[1] = dimens[1];
grdecl.dims[2] = dimens[2];
struct UnstructuredGrid *g = create_grid_cornerpoint(&grdecl, 0.0);
double vol = 0.0;
for (int c = 0; c < g->number_of_cells; c++) {
vol += g->cell_volumes[c];
}
std::cout << "Sum volumes = " << vol << '\n';
for (int c = 0, i = 0; c < g->number_of_cells; c++) {
for (; i < g->cell_facepos[c + 1]; i++) {
std::cout << "(c,i) = (" << c << "," << g->cell_facetag[i] << ")\n";
}
}
return g;
}
int main()
{
struct UnstructuredGrid *g;
g = read_grid(std::string("example"));
destroy_grid(g);
return 0;
}