opm-upscaling
setupBoundaryConditions.hpp
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>
41 #include <opm/porsol/common/BoundaryConditions.hpp>
42 #include <opm/porsol/common/PeriodicHelpers.hpp>
43 
44 namespace 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");
73  FlowBC::BCType bct = FlowBC::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
A class for representing a flow boundary condition.
Definition: BoundaryConditions.hpp:121
BCType
Enum for the allowed boundary condition types.
Definition: BoundaryConditions.hpp:58
Dune::BlockVector< Dune::FieldVector< double, 1 > > Vector
A vector holding our RHS.
Definition: matrixops.hpp:33
void setupUpscalingConditions(const GridInterface &g, int bct, int pddir, double pdrop, double bdy_sat, bool twodim_hack, BCs &bcs)
Definition: setupBoundaryConditions.hpp:99
void setupBoundaryConditions(const Opm::ParameterGroup &param, const GridInterface &g, BCs &bcs)
Setup boundary conditions for a simulation.
Definition: setupBoundaryConditions.hpp:51
Inverting small matrices.
Definition: ImplicitAssembly.hpp:43
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
A class for representing a saturation boundary condition.
Definition: BoundaryConditions.hpp:175
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