setupBoundaryConditions.hpp
Go to the documentation of this file.
1//===========================================================================
2//
3// File: setupBoundaryConditions.hpp
4//
5// Created: Fri Aug 21 09:07:09 2009
6//
7// Author(s): Atgeirr F Rasmussen <atgeirr@sintef.no>
8// Bård Skaflestad <bard.skaflestad@sintef.no>
9//
10// $Date$
11//
12// $Revision$
13//
14//===========================================================================
15
16/*
17 Copyright 2009, 2010 SINTEF ICT, Applied Mathematics.
18 Copyright 2009, 2010 Statoil ASA.
19
20 This file is part of The Open Reservoir Simulator Project (OpenRS).
21
22 OpenRS is free software: you can redistribute it and/or modify
23 it under the terms of the GNU General Public License as published by
24 the Free Software Foundation, either version 3 of the License, or
25 (at your option) any later version.
26
27 OpenRS is distributed in the hope that it will be useful,
28 but WITHOUT ANY WARRANTY; without even the implied warranty of
29 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30 GNU General Public License for more details.
31
32 You should have received a copy of the GNU General Public License
33 along with OpenRS. If not, see <http://www.gnu.org/licenses/>.
34*/
35
36#ifndef OPENRS_SETUPBOUNDARYCONDITIONS_HEADER
37#define OPENRS_SETUPBOUNDARYCONDITIONS_HEADER
38
39#include <opm/common/utility/parameters/ParameterGroup.hpp>
40#include <opm/input/eclipse/Units/Units.hpp>
43
44namespace Opm
45{
46
50 template <class GridInterface, class BCs>
51 inline void setupBoundaryConditions(const Opm::ParameterGroup& param,
52 const GridInterface& g,
53 BCs& bcs)
54 {
55 if (param.getDefault("upscaling", false)) {
56 int bct = param.get<int>("boundary_condition_type");
57 int pddir = param.getDefault("pressure_drop_direction", 0);
58 double pdrop = param.getDefault("boundary_pressuredrop", 1.0e5);
59 double bdy_sat = param.getDefault("boundary_saturation", 1.0);
60 bool twodim_hack = param.getDefault("2d_hack", false);
61 setupUpscalingConditions(g, bct, pddir, pdrop, bdy_sat, twodim_hack, bcs);
62 return;
63 }
64 if (param.getDefault("region_based_bcs", false)) {
65 setupRegionBasedConditions(param, g, bcs);
66 return;
67 }
68 // Make flow equation boundary conditions.
69 // Default is pressure 1.0e5 on the left, 0.0 on the right.
70 // Recall that the boundary ids range from 1 to 6 for the cartesian edges,
71 // and that boundary id 0 means interiour face/intersection.
72 std::string flow_bc_type = param.getDefault<std::string>("flow_bc_type", "dirichlet");
74 double leftval = 1.0*Opm::unit::barsa;
75 double rightval = 0.0;
76 if (flow_bc_type == "neumann") {
77 bct = FlowBC::Neumann;
78 leftval = param.get<double>("left_flux");
79 rightval = param.getDefault<double>("right_flux", -leftval);
80 } else if (flow_bc_type == "dirichlet") {
81 leftval = param.getDefault<double>("left_pressure", leftval);
82 rightval = param.getDefault<double>("right_pressure", rightval);
83 } else if (flow_bc_type == "periodic") {
84 OPM_THROW(std::runtime_error, "Periodic conditions not here yet.");
85 } else {
86 OPM_THROW(std::runtime_error, "Unknown flow boundary condition type " + flow_bc_type);
87 }
88 bcs.resize(7);
89 bcs.flowCond(1) = FlowBC(bct, leftval);
90 bcs.flowCond(2) = FlowBC(bct, rightval);
91
92 // Default transport boundary conditions are used.
93 }
94
98 template <class GridInterface, class BCs>
99 inline void setupUpscalingConditions(const GridInterface& g,
100 int bct,
101 int pddir,
102 double pdrop,
103 double bdy_sat,
104 bool twodim_hack,
105 BCs& bcs)
106 {
107 // Caution: This enum is copied from Upscaler.hpp.
108 enum BoundaryConditionType { Fixed = 0, Linear = 1, Periodic = 2, PeriodicSingleDirection = 3, Noflow = 4 };
109 if (bct < 0 || bct > 2) {
110 OPM_THROW(std::runtime_error,
111 "Illegal boundary condition type (0-2 are legal): " + std::to_string(bct)); // Later on, we may allow 3 and 4.
112 }
113 BoundaryConditionType bctype = static_cast<BoundaryConditionType>(bct);
114 assert(pddir >=0 && pddir <= 2);
115
116 // Flow conditions.
117 switch (bctype) {
118 case Fixed:
119 {
120 // assert(!g.uniqueBoundaryIds());
121 bcs.clear();
122 bcs.resize(7);
123 bcs.flowCond(2*pddir + 1) = FlowBC(FlowBC::Dirichlet, pdrop);
124 bcs.flowCond(2*pddir + 2) = FlowBC(FlowBC::Dirichlet, 0.0);
125 bcs.satCond(2*pddir + 1) = SatBC(SatBC::Dirichlet, bdy_sat); // The only possible inflow location.
126 for (int i = 0; i < 7; ++i) {
127 bcs.setCanonicalBoundaryId(i, i);
128 }
129 break;
130 }
131 case Linear:
132 {
133 // assert(g.uniqueBoundaryIds());
134 createLinear(bcs, g, pdrop, pddir, bdy_sat, twodim_hack);
135 break;
136 }
137 case Periodic:
138 {
139 // assert(g.uniqueBoundaryIds());
140 FlowBC fb(FlowBC::Periodic, 0.0);
141 std::array<FlowBC, 6> fcond = {{ fb, fb, fb, fb, fb, fb }};
142 fcond[2*pddir] = FlowBC(FlowBC::Periodic, pdrop);
143 fcond[2*pddir + 1] = FlowBC(FlowBC::Periodic, -pdrop);
144 SatBC sb(SatBC::Periodic, 0.0);
145 std::array<SatBC, 6> scond = {{ sb, sb, sb, sb, sb, sb }};
146 if (twodim_hack) {
147// fcond[2] = FlowBC(FlowBC::Neumann, 0.0);
148// fcond[3] = FlowBC(FlowBC::Neumann, 0.0);
149 fcond[4] = FlowBC(FlowBC::Neumann, 0.0);
150 fcond[5] = FlowBC(FlowBC::Neumann, 0.0);
151// scond[2] = SatBC(SatBC::Dirichlet, 1.0);
152// scond[3] = SatBC(SatBC::Dirichlet, 1.0);
153 scond[4] = SatBC(SatBC::Dirichlet, 1.0);
154 scond[5] = SatBC(SatBC::Dirichlet, 1.0);
155 }
156 createPeriodic(bcs, g, fcond, scond);
157 break;
158 }
159 default:
160 OPM_THROW(std::runtime_error, "Error in switch statement, should never be here.");
161 }
162
163 // Default transport boundary conditions are used.
164 }
165
166
167
168 namespace
169 {
170 template <class Vector>
171 bool isInside(const Vector& low, const Vector& high, const Vector& pt)
172 {
173 return low[0] < pt[0]
174 && low[1] < pt[1]
175 && low[2] < pt[2]
176 && high[0] > pt[0]
177 && high[1] > pt[1]
178 && high[2] > pt[2];
179 }
180 } // anon namespace
181
182
183 template <class GridInterface, class BCs>
184 inline void setupRegionBasedConditions(const Opm::ParameterGroup& param,
185 const GridInterface& g,
186 BCs& bcs)
187 {
188 // Extract region and pressure value for Dirichlet bcs.
189 typedef typename GridInterface::Vector Vector;
190 Vector low;
191 low[0] = param.getDefault("dir_block_low_x", 0.0);
192 low[1] = param.getDefault("dir_block_low_y", 0.0);
193 low[2] = param.getDefault("dir_block_low_z", 0.0);
194 Vector high;
195 high[0] = param.getDefault("dir_block_high_x", 1.0);
196 high[1] = param.getDefault("dir_block_high_y", 1.0);
197 high[2] = param.getDefault("dir_block_high_z", 1.0);
198 double dir_block_pressure = param.get<double>("dir_block_pressure");
199
200 // Set flow conditions for that region.
201 // For this to work correctly, unique boundary ids should be used,
202 // otherwise conditions may spread outside the given region, to all
203 // faces with the same bid as faces inside the region.
204 typedef typename GridInterface::CellIterator CI;
205 typedef typename CI::FaceIterator FI;
206 int max_bid = 0;
207 std::vector<int> dir_bids;
208 for (CI c = g.cellbegin(); c != g.cellend(); ++c) {
209 for (FI f = c->facebegin(); f != c->faceend(); ++f) {
210 int bid = f->boundaryId();
211 max_bid = std::max(bid, max_bid);
212 if (bid != 0 && isInside(low, high, f->centroid())) {
213 dir_bids.push_back(bid);
214 }
215 }
216 }
217 bcs.resize(max_bid + 1);
218 for (std::vector<int>::const_iterator it = dir_bids.begin(); it != dir_bids.end(); ++it) {
219 bcs.flowCond(*it) = FlowBC(FlowBC::Dirichlet, dir_block_pressure);
220 }
221
222 // Transport BCs are defaulted.
223 }
224
225
226
227} // namespace Opm
228
229
230#endif // OPENRS_SETUPBOUNDARYCONDITIONS_HEADER
BCType
Enum for the allowed boundary condition types. So far, we support Dirichlet, Neumann and Periodic con...
Definition: BoundaryConditions.hpp:58
@ Periodic
Definition: BoundaryConditions.hpp:58
@ Neumann
Definition: BoundaryConditions.hpp:58
@ Dirichlet
Definition: BoundaryConditions.hpp:58
A class for representing a flow boundary condition.
Definition: BoundaryConditions.hpp:122
A class for representing a saturation boundary condition.
Definition: BoundaryConditions.hpp:176
Dune::BlockVector< Dune::FieldVector< double, 1 > > Vector
A vector holding our RHS.
Definition: matrixops.hpp:33
Definition: ImplicitAssembly.hpp:43
void setupRegionBasedConditions(const Opm::ParameterGroup &param, const GridInterface &g, BCs &bcs)
Definition: setupBoundaryConditions.hpp:184
void createLinear(BCs &fbcs, const GridInterface &g, const double pdrop, const int pddir, const double bdy_sat, const bool twodim_hack=false, const double spatial_tolerance=1e-6)
Makes a boundary condition object representing linear boundary conditions in any cartesian direction....
Definition: PeriodicHelpers.hpp:220
void setupBoundaryConditions(const Opm::ParameterGroup &param, const GridInterface &g, BCs &bcs)
Setup boundary conditions for a simulation. It is assumed that the boundary ids are 1-6,...
Definition: setupBoundaryConditions.hpp:51
void setupUpscalingConditions(const GridInterface &g, int bct, int pddir, double pdrop, double bdy_sat, bool twodim_hack, BCs &bcs)
Definition: setupBoundaryConditions.hpp:99
void createPeriodic(BCs &fbcs, const GridInterface &g, const std::array< FlowBC, 2 *GridInterface::Dimension > &fconditions, const std::array< SatBC, 2 *GridInterface::Dimension > &sconditions, double spatial_tolerance=1e-6)
Makes a boundary condition object representing periodic boundary conditions in any cartesian directio...
Definition: PeriodicHelpers.hpp:105