My Project
EclThermalLawManager.hpp
Go to the documentation of this file.
1 // -*- mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 // vi: set et ts=4 sw=4 sts=4:
3 /*
4  This file is part of the Open Porous Media project (OPM).
5 
6  OPM is free software: you can redistribute it and/or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 2 of the License, or
9  (at your option) any later version.
10 
11  OPM is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with OPM. If not, see <http://www.gnu.org/licenses/>.
18 
19  Consult the COPYING file in the top-level source directory of this
20  module for the precise wording of the license and the list of
21  copyright holders.
22 */
27 #ifndef OPM_ECL_THERMAL_LAW_MANAGER_HPP
28 #define OPM_ECL_THERMAL_LAW_MANAGER_HPP
29 
30 #if ! HAVE_ECL_INPUT
31 #error "Eclipse input support in opm-common is required to use the ECL thermal law manager!"
32 #endif
33 
36 
39 
40 #include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
41 #include <opm/parser/eclipse/EclipseState/Tables/TableManager.hpp>
42 #include <opm/parser/eclipse/Deck/Deck.hpp>
43 
44 namespace Opm {
45 
52 template <class Scalar, class FluidSystem>
54 {
55 public:
57  typedef typename SolidEnergyLaw::Params SolidEnergyLawParams;
58  typedef typename SolidEnergyLawParams::HeatcrLawParams HeatcrLawParams;
59  typedef typename SolidEnergyLawParams::SpecrockLawParams SpecrockLawParams;
60 
62  typedef typename ThermalConductionLaw::Params ThermalConductionLawParams;
63 
65  {
66  solidEnergyApproach_ = SolidEnergyLawParams::undefinedApproach;
67  thermalConductivityApproach_ = ThermalConductionLawParams::undefinedApproach;
68  }
69 
70  void initParamsForElements(const EclipseState& eclState, size_t numElems)
71  {
72  const auto& fp = eclState.fieldProps();
73  const auto& tableManager = eclState.getTableManager();
74  bool has_heatcr = fp.has_double("HEATCR");
75  bool has_thconr = fp.has_double("THCONR");
76  bool has_thc = fp.has_double("THCROCK") || fp.has_double("THCOIL") || fp.has_double("THCGAS") || fp.has_double("THCWATER");
77 
78  if (has_heatcr)
79  initHeatcr_(eclState, numElems);
80  else if (tableManager.hasTables("SPECROCK"))
81  initSpecrock_(eclState, numElems);
82  else
83  initNullRockEnergy_();
84 
85  if (has_thconr)
86  initThconr_(eclState, numElems);
87  else if (has_thc)
88  initThc_(eclState, numElems);
89  else
90  initNullCond_();
91  }
92 
93  const SolidEnergyLawParams& solidEnergyLawParams(unsigned elemIdx) const
94  {
95  switch (solidEnergyApproach_) {
96  case SolidEnergyLawParams::heatcrApproach:
97  assert(elemIdx < solidEnergyLawParams_.size());
98  return solidEnergyLawParams_[elemIdx];
99 
100  case SolidEnergyLawParams::specrockApproach:
101  {
102  assert(elemIdx < elemToSatnumIdx_.size());
103  unsigned satnumIdx = elemToSatnumIdx_[elemIdx];
104  assert(satnumIdx < solidEnergyLawParams_.size());
105  return solidEnergyLawParams_[satnumIdx];
106  }
107 
108  case SolidEnergyLawParams::nullApproach:
109  return solidEnergyLawParams_[0];
110 
111  default:
112  throw std::runtime_error("Attempting to retrieve solid energy storage parameters "
113  "without a known approach being defined by the deck.");
114  }
115  }
116 
117  const ThermalConductionLawParams& thermalConductionLawParams(unsigned elemIdx) const
118  {
119  switch (thermalConductivityApproach_) {
120  case ThermalConductionLawParams::thconrApproach:
121  case ThermalConductionLawParams::thcApproach:
122  assert(elemIdx < thermalConductionLawParams_.size());
123  return thermalConductionLawParams_[elemIdx];
124 
125  case ThermalConductionLawParams::nullApproach:
126  return thermalConductionLawParams_[0];
127 
128  default:
129  throw std::runtime_error("Attempting to retrieve thermal conduction parameters without "
130  "a known approach being defined by the deck.");
131  }
132  }
133 
134 private:
138  void initHeatcr_(const EclipseState& eclState,
139  size_t numElems)
140  {
141  solidEnergyApproach_ = SolidEnergyLawParams::heatcrApproach;
142  // actually the value of the reference temperature does not matter for energy
143  // conservation. We set it anyway to faciliate comparisons with ECL
144  HeatcrLawParams::setReferenceTemperature(FluidSystem::surfaceTemperature);
145 
146  const auto& fp = eclState.fieldProps();
147  const std::vector<double>& heatcrData = fp.get_double("HEATCR");
148  const std::vector<double>& heatcrtData = fp.get_double("HEATCRT");
149  solidEnergyLawParams_.resize(numElems);
150  for (unsigned elemIdx = 0; elemIdx < numElems; ++elemIdx) {
151  auto& elemParam = solidEnergyLawParams_[elemIdx];
152  elemParam.setSolidEnergyApproach(SolidEnergyLawParams::heatcrApproach);
153  auto& heatcrElemParams = elemParam.template getRealParams<SolidEnergyLawParams::heatcrApproach>();
154 
155  heatcrElemParams.setReferenceRockHeatCapacity(heatcrData[elemIdx]);
156  heatcrElemParams.setDRockHeatCapacity_dT(heatcrtData[elemIdx]);
157  heatcrElemParams.finalize();
158  elemParam.finalize();
159  }
160  }
161 
165  void initSpecrock_(const EclipseState& eclState,
166  size_t numElems)
167  {
168  solidEnergyApproach_ = SolidEnergyLawParams::specrockApproach;
169 
170  // initialize the element index -> SATNUM index mapping
171  const auto& fp = eclState.fieldProps();
172  const std::vector<int>& satnumData = fp.get_int("SATNUM");
173  elemToSatnumIdx_.resize(numElems);
174  for (unsigned elemIdx = 0; elemIdx < numElems; ++ elemIdx) {
175  // satnumData contains Fortran-style indices, i.e., they start with 1 instead
176  // of 0!
177  elemToSatnumIdx_[elemIdx] = satnumData[elemIdx] - 1;
178  }
179  // internalize the SPECROCK table
180  unsigned numSatRegions = eclState.runspec().tabdims().getNumSatTables();
181  const auto& tableManager = eclState.getTableManager();
182  solidEnergyLawParams_.resize(numSatRegions);
183  for (unsigned satnumIdx = 0; satnumIdx < numSatRegions; ++satnumIdx) {
184  const auto& specrockTable = tableManager.getSpecrockTables()[satnumIdx];
185 
186  auto& multiplexerParams = solidEnergyLawParams_[satnumIdx];
187 
188  multiplexerParams.setSolidEnergyApproach(SolidEnergyLawParams::specrockApproach);
189 
190  auto& specrockParams = multiplexerParams.template getRealParams<SolidEnergyLawParams::specrockApproach>();
191  const auto& temperatureColumn = specrockTable.getColumn("TEMPERATURE");
192  const auto& cvRockColumn = specrockTable.getColumn("CV_ROCK");
193  specrockParams.setHeatCapacities(temperatureColumn, cvRockColumn);
194  specrockParams.finalize();
195 
196  multiplexerParams.finalize();
197  }
198  }
199 
203  void initNullRockEnergy_()
204  {
205  solidEnergyApproach_ = SolidEnergyLawParams::nullApproach;
206 
207  solidEnergyLawParams_.resize(1);
208  solidEnergyLawParams_[0].finalize();
209  }
210 
214  void initThconr_(const EclipseState& eclState,
215  size_t numElems)
216  {
217  thermalConductivityApproach_ = ThermalConductionLawParams::thconrApproach;
218 
219  const auto& fp = eclState.fieldProps();
220  std::vector<double> thconrData;
221  std::vector<double> thconsfData;
222  if (fp.has_double("THCONR"))
223  thconrData = fp.get_double("THCONR");
224 
225  if (fp.has_double("THCONSF"))
226  thconsfData = fp.get_double("THCONSF");
227 
228  thermalConductionLawParams_.resize(numElems);
229  for (unsigned elemIdx = 0; elemIdx < numElems; ++elemIdx) {
230  auto& elemParams = thermalConductionLawParams_[elemIdx];
231  elemParams.setThermalConductionApproach(ThermalConductionLawParams::thconrApproach);
232  auto& thconrElemParams = elemParams.template getRealParams<ThermalConductionLawParams::thconrApproach>();
233 
234  double thconr = thconrData.empty() ? 0.0 : thconrData[elemIdx];
235  double thconsf = thconsfData.empty() ? 0.0 : thconsfData[elemIdx];
236  thconrElemParams.setReferenceTotalThermalConductivity(thconr);
237  thconrElemParams.setDTotalThermalConductivity_dSg(thconsf);
238 
239  thconrElemParams.finalize();
240  elemParams.finalize();
241  }
242  }
243 
247  void initThc_(const EclipseState& eclState,
248  size_t numElems)
249  {
250  thermalConductivityApproach_ = ThermalConductionLawParams::thcApproach;
251 
252  const auto& fp = eclState.fieldProps();
253  std::vector<double> thcrockData;
254  std::vector<double> thcoilData;
255  std::vector<double> thcgasData;
256  std::vector<double> thcwaterData = fp.get_double("THCWATER");
257 
258  if (fp.has_double("THCROCK"))
259  thcrockData = fp.get_double("THCROCK");
260 
261  if (fp.has_double("THCOIL"))
262  thcoilData = fp.get_double("THCOIL");
263 
264  if (fp.has_double("THCGAS"))
265  thcgasData = fp.get_double("THCGAS");
266 
267  if (fp.has_double("THCWATER"))
268  thcwaterData = fp.get_double("THCWATER");
269 
270  const std::vector<double>& poroData = fp.get_double("PORO");
271 
272  thermalConductionLawParams_.resize(numElems);
273  for (unsigned elemIdx = 0; elemIdx < numElems; ++elemIdx) {
274  auto& elemParams = thermalConductionLawParams_[elemIdx];
275  elemParams.setThermalConductionApproach(ThermalConductionLawParams::thcApproach);
276  auto& thcElemParams = elemParams.template getRealParams<ThermalConductionLawParams::thcApproach>();
277 
278  thcElemParams.setPorosity(poroData[elemIdx]);
279  double thcrock = thcrockData.empty() ? 0.0 : thcrockData[elemIdx];
280  double thcoil = thcoilData.empty() ? 0.0 : thcoilData[elemIdx];
281  double thcgas = thcgasData.empty() ? 0.0 : thcgasData[elemIdx];
282  double thcwater = thcwaterData.empty() ? 0.0 : thcwaterData[elemIdx];
283  thcElemParams.setThcrock(thcrock);
284  thcElemParams.setThcoil(thcoil);
285  thcElemParams.setThcgas(thcgas);
286  thcElemParams.setThcwater(thcwater);
287 
288  thcElemParams.finalize();
289  elemParams.finalize();
290  }
291  }
292 
296  void initNullCond_()
297  {
298  thermalConductivityApproach_ = ThermalConductionLawParams::nullApproach;
299 
300  thermalConductionLawParams_.resize(1);
301  thermalConductionLawParams_[0].finalize();
302  }
303 
304 private:
305  typename ThermalConductionLawParams::ThermalConductionApproach thermalConductivityApproach_;
306  typename SolidEnergyLawParams::SolidEnergyApproach solidEnergyApproach_;
307 
308  std::vector<unsigned> elemToSatnumIdx_;
309 
310  std::vector<SolidEnergyLawParams> solidEnergyLawParams_;
311  std::vector<ThermalConductionLawParams> thermalConductionLawParams_;
312 };
313 } // namespace Opm
314 
315 #endif
The default implementation of a parameter object for the ECL thermal law.
Provides the energy storage relation of rock.
The default implementation of a parameter object for the ECL thermal law.
Implements the total thermal conductivity and rock enthalpy relations used by ECL.
Provides the energy storage relation of rock.
Definition: EclSolidEnergyLawMultiplexer.hpp:49
Implements the total thermal conductivity and rock enthalpy relations used by ECL.
Definition: EclThermalConductionLawMultiplexer.hpp:49
Provides an simple way to create and manage the thermal law objects for a complete ECL deck.
Definition: EclThermalLawManager.hpp:54