AutoDiffHelpers.hpp
Go to the documentation of this file.
1 /*
2  Copyright 2013 SINTEF ICT, Applied Mathematics.
3  Copyright 2015 IRIS
4 
5  This file is part of the Open Porous Media project (OPM).
6 
7  OPM is free software: you can redistribute it and/or modify
8  it under the terms of the GNU General Public License as published by
9  the Free Software Foundation, either version 3 of the License, or
10  (at your option) any later version.
11 
12  OPM is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with OPM. If not, see <http://www.gnu.org/licenses/>.
19 */
20 
21 #ifndef OPM_AUTODIFFHELPERS_HEADER_INCLUDED
22 #define OPM_AUTODIFFHELPERS_HEADER_INCLUDED
23 
26 #include <opm/core/grid.h>
27 #include <opm/common/ErrorMacros.hpp>
28 #include <opm/parser/eclipse/EclipseState/Grid/NNC.hpp>
29 #include <opm/parser/eclipse/EclipseState/EclipseState.hpp>
30 #include <iostream>
31 #include <vector>
32 
33 namespace Opm
34 {
35 
36 // -------------------- class HelperOps --------------------
37 
40 struct HelperOps
41 {
42  typedef Eigen::SparseMatrix<double> M;
44 
46  typedef Eigen::Array<int, Eigen::Dynamic, 1> IFaces;
48 
50  M ngrad;
52  M grad;
54  M caver;
56  M div;
62 
64  typedef Eigen::Array<int, Eigen::Dynamic, 2, Eigen::RowMajor> TwoColInt;
65  TwoColInt nnc_cells;
66 
69 
71  template<class Grid>
72  HelperOps(const Grid& grid, Opm::EclipseStateConstPtr eclState = EclipseStateConstPtr () )
73  {
74  using namespace AutoDiffGrid;
75  const int nc = numCells(grid);
76  const int nf = numFaces(grid);
77  // Define some neighbourhood-derived helper arrays.
78 
79  TwoColInt nbi;
80  extractInternalFaces(grid, internal_faces, nbi);
81  int num_internal = internal_faces.size();
82  // num_connections may also include non-neighboring connections
83  int num_connections = num_internal;
84  int numNNC = 0;
85 
86  // handle non-neighboring connections
87  std::shared_ptr<const NNC> nnc = eclState ? eclState->getNNC()
88  : std::shared_ptr<const Opm::NNC>();
89  const bool has_nnc = nnc && nnc->hasNNC();
90  if (has_nnc) {
91  numNNC = nnc->numNNC();
92  num_connections += numNNC;
93  //std::cout << "Added " << numNNC << " NNC" <<std::endl;
94  nbi.resize(num_internal, 2);
95 
96  // the nnc's acts on global indicies and must be mapped to cell indicies
97  size_t cartesianSize = eclState->getEclipseGrid()->getCartesianSize();
98  std::vector<int> global2localIdx(cartesianSize,0);
99  for (int i = 0; i< nc; ++i) {
100  global2localIdx[ globalCell( grid )[i] ] = i;
101  }
102  const std::vector<size_t>& NNC1 = nnc->nnc1();
103  const std::vector<size_t>& NNC2 = nnc->nnc2();
104  nnc_cells.resize(numNNC,2);
105  for (int i = 0; i < numNNC; ++i) {
106  nnc_cells(i,0) = global2localIdx[NNC1[i]];
107  nnc_cells(i,1) = global2localIdx[NNC2[i]];
108  }
109  // store the nnc transmissibilities for later usage.
110  nnc_trans = Eigen::Map<const V>(nnc->trans().data(), numNNC);
111  } else {
112  nnc_trans.resize(0);
113  nnc_cells.resize(0, 2); // Required to have two columns.
114  }
115 
116 
117  // std::cout << "nbi = \n" << nbi << std::endl;
118  // Create matrices.
119  ngrad.resize(num_connections, nc);
120  caver.resize(num_connections, nc);
121  typedef Eigen::Triplet<double> Tri;
122  std::vector<Tri> ngrad_tri;
123  std::vector<Tri> caver_tri;
124  ngrad_tri.reserve(2*num_connections);
125  caver_tri.reserve(2*num_connections);
126  for (int i = 0; i < num_internal; ++i) {
127  ngrad_tri.emplace_back(i, nbi(i,0), 1.0);
128  ngrad_tri.emplace_back(i, nbi(i,1), -1.0);
129  caver_tri.emplace_back(i, nbi(i,0), 0.5);
130  caver_tri.emplace_back(i, nbi(i,1), 0.5);
131  }
132  // add contribution from NNC
133  if (has_nnc) {
134  for (int i = 0; i < numNNC; ++i) {
135  ngrad_tri.emplace_back(i+num_internal, nnc_cells(i,0), 1.0);
136  ngrad_tri.emplace_back(i+num_internal, nnc_cells(i,1), -1.0);
137  caver_tri.emplace_back(i+num_internal, nnc_cells(i,0), 0.5);
138  caver_tri.emplace_back(i+num_internal, nnc_cells(i,1), 0.5);
139  }
140  }
141  ngrad.setFromTriplets(ngrad_tri.begin(), ngrad_tri.end());
142  caver.setFromTriplets(caver_tri.begin(), caver_tri.end());
143  grad = -ngrad;
144  div = ngrad.transpose();
145 
146  std::vector<Tri> fullngrad_tri;
147  fullngrad_tri.reserve(2*(nf+numNNC));
148  typename ADFaceCellTraits<Grid>::Type nb = faceCellsToEigen(grid);
149  for (int i = 0; i < nf; ++i) {
150  if (nb(i,0) >= 0) {
151  fullngrad_tri.emplace_back(i, nb(i,0), 1.0);
152  }
153  if (nb(i,1) >= 0) {
154  fullngrad_tri.emplace_back(i, nb(i,1), -1.0);
155  }
156  }
157  // add contribution from NNC
158  if (has_nnc) {
159  for (int i = 0; i < numNNC; ++i) {
160  fullngrad_tri.emplace_back(i+nf, nnc_cells(i,0), 1.0);
161  fullngrad_tri.emplace_back(i+nf, nnc_cells(i,1), -1.0);
162  }
163  }
164  fullngrad.resize(nf+numNNC, nc);
165  fullngrad.setFromTriplets(fullngrad_tri.begin(), fullngrad_tri.end());
166  fulldiv = fullngrad.transpose();
167  }
168 };
169 
170 // -------------------- upwinding helper class --------------------
171 
172 
175  template <typename Scalar>
177  public:
179 
180  template<class Grid>
181  UpwindSelector(const Grid& g,
182  const HelperOps& h,
183  const typename ADB::V& ifaceflux)
184  {
185  using namespace AutoDiffGrid;
186  typedef HelperOps::IFaces::Index IFIndex;
187  const IFIndex nif = h.internal_faces.size();
188  typename ADFaceCellTraits<Grid>::Type
189  face_cells = faceCellsToEigen(g);
190 
191  // num connections may possibly include NNCs
192  int num_nnc = h.nnc_trans.size();
193  int num_connections = nif + num_nnc;
194  assert(num_connections == ifaceflux.size());
195 
196  // Define selector structure.
197  typedef typename Eigen::Triplet<Scalar> Triplet;
198  std::vector<Triplet> s; s.reserve(num_connections);
199  for (IFIndex iface = 0; iface < nif; ++iface) {
200  const int f = h.internal_faces[iface];
201  const int c1 = face_cells(f,0);
202  const int c2 = face_cells(f,1);
203 
204  assert ((c1 >= 0) && (c2 >= 0));
205 
206  // Select upwind cell.
207  const int c = (ifaceflux[iface] >= 0) ? c1 : c2;
208 
209  s.push_back(Triplet(iface, c, Scalar(1)));
210  }
211  if (num_nnc > 0) {
212  for (int i = 0; i < num_nnc; ++i) {
213  const int c = (ifaceflux[i+nif] >= 0) ? h.nnc_cells(i,0) : h.nnc_cells(i,1);
214  s.push_back(Triplet(i+nif,c,Scalar(1)));
215  }
216  }
217 
218  // Assemble explicit selector operator.
219  select_.resize(num_connections, numCells(g));
220  select_.setFromTriplets(s.begin(), s.end());
221  }
222 
224  std::vector<ADB>
225  select(const std::vector<ADB>& xc) const
226  {
227  // Absence of counter-current flow means that the same
228  // selector applies to all quantities, 'x', defined per
229  // cell.
230  std::vector<ADB> xf; xf.reserve(xc.size());
231  for (typename std::vector<ADB>::const_iterator
232  b = xc.begin(), e = xc.end(); b != e; ++b)
233  {
234  xf.push_back(select_ * (*b));
235  }
236 
237  return xf;
238  }
239 
241  ADB select(const ADB& xc) const
242  {
243  return select_*xc;
244  }
245 
247  typename ADB::V select(const typename ADB::V& xc) const
248  {
249  return (select_*xc.matrix()).array();
250  }
251 
252  private:
253  Eigen::SparseMatrix<double> select_;
254  };
255 
256 
257 
258 namespace {
259 
260 
261  template <typename Scalar, class IntVec>
262  typename Eigen::SparseMatrix<Scalar>
263  constructSupersetSparseMatrix(const int full_size, const IntVec& indices)
264  {
265  const int subset_size = indices.size();
266 
267  if (subset_size == 0) {
268  Eigen::SparseMatrix<Scalar> mat(full_size, 0);
269  return mat;
270  }
271 
272  Eigen::SparseMatrix<Scalar> mat(full_size, subset_size);
273  mat.reserve(Eigen::VectorXi::Constant(subset_size, 1));
274  for (int i = 0; i < subset_size; ++i) {
275  mat.insert(indices[i], i) = 1;
276  }
277  return mat;
278  }
279 
280 } // anon namespace
281 
282 
283 
285 template <typename Scalar, class IntVec>
286 Eigen::Array<Scalar, Eigen::Dynamic, 1>
287 subset(const Eigen::Array<Scalar, Eigen::Dynamic, 1>& x,
288  const IntVec& indices)
289 {
290  typedef typename Eigen::Array<Scalar, Eigen::Dynamic, 1>::Index Index;
291  const Index size = indices.size();
292  Eigen::Array<Scalar, Eigen::Dynamic, 1> ret( size );
293  for( Index i=0; i<size; ++i )
294  ret[ i ] = x[ indices[ i ] ];
295 
296  return std::move(ret);
297 }
298 
300 template <typename Scalar, class IntVec>
301 AutoDiffBlock<Scalar>
303  const IntVec& indices)
304 {
305  const Eigen::SparseMatrix<Scalar> sub
306  = constructSupersetSparseMatrix<Scalar>(x.value().size(), indices).transpose().eval();
307  return sub * x;
308 }
309 
310 
312 template <typename Scalar, class IntVec>
313 AutoDiffBlock<Scalar>
315  const IntVec& indices,
316  const int n)
317 {
318  return constructSupersetSparseMatrix<Scalar>(n, indices) * x;
319 }
320 
321 
322 
324 template <typename Scalar, class IntVec>
325 Eigen::Array<Scalar, Eigen::Dynamic, 1>
326 superset(const Eigen::Array<Scalar, Eigen::Dynamic, 1>& x,
327  const IntVec& indices,
328  const int n)
329 {
330  return constructSupersetSparseMatrix<Scalar>(n, indices) * x.matrix();
331 }
332 
333 
334 
338 inline
339 Eigen::SparseMatrix<double>
341 {
342  typedef Eigen::SparseMatrix<double> M;
343 
344  const int n = d.size();
345  M mat(n, n);
346  mat.reserve(Eigen::ArrayXi::Ones(n, 1));
347  for (M::Index i = 0; i < n; ++i) {
348  mat.insert(i, i) = d[i];
349  }
350 
351  return mat;
352 }
353 
354 
355 
356 
358  template <typename Scalar>
359  class Selector {
360  public:
362 
363  enum CriterionForLeftElement { GreaterEqualZero, GreaterZero, Zero, NotEqualZero, LessZero, LessEqualZero, NotNaN };
364 
365  Selector(const typename ADB::V& selection_basis,
366  CriterionForLeftElement crit = GreaterEqualZero)
367  {
368  // Define selector structure.
369  const int n = selection_basis.size();
370  // Over-reserving so we do not have to count.
371  left_elems_.reserve(n);
372  right_elems_.reserve(n);
373  for (int i = 0; i < n; ++i) {
374  bool chooseleft = false;
375  switch (crit) {
376  case GreaterEqualZero:
377  chooseleft = selection_basis[i] >= 0.0;
378  break;
379  case GreaterZero:
380  chooseleft = selection_basis[i] > 0.0;
381  break;
382  case Zero:
383  chooseleft = selection_basis[i] == 0.0;
384  break;
385  case NotEqualZero:
386  chooseleft = selection_basis[i] != 0.0;
387  break;
388  case LessZero:
389  chooseleft = selection_basis[i] < 0.0;
390  break;
391  case LessEqualZero:
392  chooseleft = selection_basis[i] <= 0.0;
393  break;
394  case NotNaN:
395  chooseleft = !isnan(selection_basis[i]);
396  break;
397  default:
398  OPM_THROW(std::logic_error, "No such criterion: " << crit);
399  }
400  if (chooseleft) {
401  left_elems_.push_back(i);
402  } else {
403  right_elems_.push_back(i);
404  }
405  }
406  }
407 
409  ADB select(const ADB& x1, const ADB& x2) const
410  {
411  if (right_elems_.empty()) {
412  return x1;
413  } else if (left_elems_.empty()) {
414  return x2;
415  } else {
416  return superset(subset(x1, left_elems_), left_elems_, x1.size())
417  + superset(subset(x2, right_elems_), right_elems_, x2.size());
418  }
419  }
420 
422  typename ADB::V select(const typename ADB::V& x1, const typename ADB::V& x2) const
423  {
424  if (right_elems_.empty()) {
425  return x1;
426  } else if (left_elems_.empty()) {
427  return x2;
428  } else {
429  return superset(subset(x1, left_elems_), left_elems_, x1.size())
430  + superset(subset(x2, right_elems_), right_elems_, x2.size());
431  }
432  }
433 
434  private:
435  std::vector<int> left_elems_;
436  std::vector<int> right_elems_;
437  };
438 
439 
440 
441 
443 template <class Matrix>
444 inline
445 void
446 collapseJacs(const AutoDiffBlock<double>& x, Matrix& jacobian)
447 {
448  typedef AutoDiffBlock<double> ADB;
449  const int nb = x.numBlocks();
450  typedef Eigen::Triplet<double> Tri;
451  int nnz = 0;
452  for (int block = 0; block < nb; ++block) {
453  nnz += x.derivative()[block].nonZeros();
454  }
455  std::vector<Tri> t;
456  t.reserve(nnz);
457  int block_col_start = 0;
458  for (int block = 0; block < nb; ++block) {
459  const ADB::M& jac1 = x.derivative()[block];
460  Eigen::SparseMatrix<double> jac;
461  jac1.toSparse(jac);
462  for (Eigen::SparseMatrix<double>::Index k = 0; k < jac.outerSize(); ++k) {
463  for (Eigen::SparseMatrix<double>::InnerIterator i(jac, k); i ; ++i) {
464  if (i.value() != 0.0) {
465  t.push_back(Tri(i.row(),
466  i.col() + block_col_start,
467  i.value()));
468  }
469  }
470  }
471  block_col_start += jac.cols();
472  }
473  // Build final jacobian.
474  jacobian = Matrix(x.size(), block_col_start);
475  jacobian.setFromTriplets(t.begin(), t.end());
476 }
477 
478 
479 
481 inline
482 AutoDiffBlock<double>
484 {
485  Eigen::SparseMatrix<double> comb_jac;
486  collapseJacs( x, comb_jac );
487  // Build final jacobian.
488  typedef AutoDiffBlock<double> ADB;
489  std::vector<ADB::M> jacs(1);
490  jacs[0] = AutoDiffMatrix(std::move(comb_jac));
491  ADB::V val = x.value();
492  return ADB::function(std::move(val), std::move(jacs));
493 }
494 
495 
496 
498 inline
499 AutoDiffBlock<double>
501  const AutoDiffBlock<double>& y)
502 {
503  const int nx = x.size();
504  const int ny = y.size();
505  const int n = nx + ny;
506  std::vector<int> xind(nx);
507  for (int i = 0; i < nx; ++i) {
508  xind[i] = i;
509  }
510  std::vector<int> yind(ny);
511  for (int i = 0; i < ny; ++i) {
512  yind[i] = nx + i;
513  }
514  return superset(x, xind, n) + superset(y, yind, n);
515 }
516 
517 
518 
519 
522 inline
523 AutoDiffBlock<double>
525 {
526  typedef AutoDiffBlock<double> ADB;
527  if (x.empty()) {
528  return ADB::null();
529  }
530 
531  // Count sizes, nonzeros.
532  const int nx = x.size();
533  int size = 0;
534  int nnz = 0;
535  int elem_with_deriv = -1;
536  int num_blocks = 0;
537  for (int elem = 0; elem < nx; ++elem) {
538  size += x[elem].size();
539  if (x[elem].derivative().empty()) {
540  // No nnz contributions from this element.
541  continue;
542  } else {
543  if (elem_with_deriv == -1) {
544  elem_with_deriv = elem;
545  num_blocks = x[elem].numBlocks();
546  }
547  }
548  if (x[elem].blockPattern() != x[elem_with_deriv].blockPattern()) {
549  OPM_THROW(std::runtime_error, "vertcatCollapseJacs(): all arguments must have the same block pattern");
550  }
551  for (int block = 0; block < num_blocks; ++block) {
552  nnz += x[elem].derivative()[block].nonZeros();
553  }
554  }
555  int num_cols = 0;
556  for (int block = 0; block < num_blocks; ++block) {
557  num_cols += x[elem_with_deriv].derivative()[block].cols();
558  }
559 
560  // Build value for result.
561  ADB::V val(size);
562  int pos = 0;
563  for (int elem = 0; elem < nx; ++elem) {
564  const int loc_size = x[elem].size();
565  val.segment(pos, loc_size) = x[elem].value();
566  pos += loc_size;
567  }
568  assert(pos == size);
569 
570  // Return a constant if we have no derivatives at all.
571  if (num_blocks == 0) {
572  return ADB::constant(std::move(val));
573  }
574 
575  // Set up for batch insertion of all Jacobian elements.
576  typedef Eigen::SparseMatrix<double> M;
577  typedef Eigen::Triplet<double> Tri;
578  std::vector<Tri> t;
579  t.reserve(nnz);
580  {
581  int block_row_start = 0;
582  M jac;
583  for (int elem = 0; elem < nx; ++elem) {
584  int block_col_start = 0;
585  if (!x[elem].derivative().empty()) {
586  for (int block = 0; block < num_blocks; ++block) {
587  x[elem].derivative()[block].toSparse(jac);
588  for (M::Index k = 0; k < jac.outerSize(); ++k) {
589  for (M::InnerIterator i(jac, k); i ; ++i) {
590  t.push_back(Tri(i.row() + block_row_start,
591  i.col() + block_col_start,
592  i.value()));
593  }
594  }
595  block_col_start += jac.cols();
596  }
597  }
598  block_row_start += x[elem].size();
599  }
600  }
601 
602  // Build final jacobian.
603  M comb_jac = M(size, num_cols);
604  comb_jac.reserve(nnz);
605  comb_jac.setFromTriplets(t.begin(), t.end());
606  std::vector<ADB::M> jac(1);
607  jac[0] = ADB::M(std::move(comb_jac));
608 
609  // Use move semantics to return result efficiently.
610  return ADB::function(std::move(val), std::move(jac));
611 }
612 
613 
614 
615 
616 
617 class Span
618 {
619 public:
620  explicit Span(const int num)
621  : num_(num),
622  stride_(1),
623  start_(0)
624  {
625  }
626  Span(const int num, const int stride, const int start)
627  : num_(num),
628  stride_(stride),
629  start_(start)
630  {
631  }
632  int operator[](const int i) const
633  {
634  assert(i >= 0 && i < num_);
635  return start_ + i*stride_;
636  }
637  int size() const
638  {
639  return num_;
640  }
641 
642 
644  {
645  public:
646  SpanIterator(const Span* span, const int index)
647  : span_(span),
648  index_(index)
649  {
650  }
652  {
653  ++index_;
654  return *this;
655  }
657  {
658  SpanIterator before_increment(*this);
659  ++index_;
660  return before_increment;
661  }
662  bool operator<(const SpanIterator& rhs) const
663  {
664  assert(span_ == rhs.span_);
665  return index_ < rhs.index_;
666  }
667  bool operator==(const SpanIterator& rhs) const
668  {
669  assert(span_ == rhs.span_);
670  return index_ == rhs.index_;
671  }
672  bool operator!=(const SpanIterator& rhs) const
673  {
674  assert(span_ == rhs.span_);
675  return index_ != rhs.index_;
676  }
677  int operator*()
678  {
679  return (*span_)[index_];
680  }
681  private:
682  const Span* span_;
683  int index_;
684  };
685 
688 
690  {
691  return SpanIterator(this, 0);
692  }
693 
695  {
696  return SpanIterator(this, num_);
697  }
698 
699  bool operator==(const Span& rhs)
700  {
701  return num_ == rhs.num_ && start_ == rhs.start_ && stride_ == rhs.stride_;
702  }
703 
704 private:
705  const int num_;
706  const int stride_;
707  const int start_;
708 };
709 
710 
711 
713 inline Eigen::ArrayXd sign (const Eigen::ArrayXd& x)
714 {
715  const int n = x.size();
716  Eigen::ArrayXd retval(n);
717  for (int i = 0; i < n; ++i) {
718  retval[i] = x[i] < 0.0 ? -1.0 : (x[i] > 0.0 ? 1.0 : 0.0);
719  }
720  return retval;
721 }
722 
723 } // namespace Opm
724 
725 #endif // OPM_AUTODIFFHELPERS_HEADER_INCLUDED
Eigen::Array< Scalar, Eigen::Dynamic, 1 > subset(const Eigen::Array< Scalar, Eigen::Dynamic, 1 > &x, const IntVec &indices)
Returns x(indices).
Definition: AutoDiffHelpers.hpp:287
SpanIterator begin() const
Definition: AutoDiffHelpers.hpp:689
SpanIterator end() const
Definition: AutoDiffHelpers.hpp:694
Eigen::Array< int, Eigen::Dynamic, 2, Eigen::RowMajor > TwoColInt
Non-neighboring connections.
Definition: AutoDiffHelpers.hpp:64
M caver
Extract for each face the average of its adjacent cells' values.
Definition: AutoDiffHelpers.hpp:54
AutoDiffBlock< double > ADB
Definition: BlackoilModelBase_impl.hpp:83
Eigen::Array< Scalar, Eigen::Dynamic, 1 > V
Underlying type for values.
Definition: AutoDiffBlock.hpp:98
Definition: AdditionalObjectDeleter.hpp:22
AutoDiffMatrix M
Underlying type for jacobians.
Definition: AutoDiffBlock.hpp:100
AutoDiffBlock< Scalar > ADB
Definition: AutoDiffHelpers.hpp:178
int cols() const
Definition: AutoDiffMatrix.hpp:563
static AutoDiffBlock null()
Construct an empty AutoDiffBlock.
Definition: AutoDiffBlock.hpp:103
CriterionForLeftElement
Definition: AutoDiffHelpers.hpp:363
SpanIterator iterator
Definition: AutoDiffHelpers.hpp:686
int size() const
Definition: AutoDiffHelpers.hpp:637
int numBlocks() const
Number of Jacobian blocks.
Definition: AutoDiffBlock.hpp:419
Definition: AutoDiffHelpers.hpp:617
void toSparse(Eigen::SparseMatrix< Scalar, Options, Index > &s) const
Definition: AutoDiffMatrix.hpp:530
ADFaceCellTraits< UnstructuredGrid >::Type faceCellsToEigen(const UnstructuredGrid &grid)
Get the face to cell mapping of a grid.
Definition: AutoDiffHelpers.hpp:363
Selection. Choose first of two elements if selection basis element is nonnegative.
Definition: AutoDiffHelpers.hpp:359
TwoColInt nnc_cells
Definition: AutoDiffHelpers.hpp:65
Eigen::Array< int, Eigen::Dynamic, 1 > IFaces
A list of internal faces.
Definition: AutoDiffHelpers.hpp:46
M grad
Extract for each face the difference of its adjacent cells' values (second - first).
Definition: AutoDiffHelpers.hpp:52
SpanIterator const_iterator
Definition: AutoDiffHelpers.hpp:687
ADB select(const ADB &x1, const ADB &x2) const
Apply selector to ADB quantities.
Definition: AutoDiffHelpers.hpp:409
bool operator==(const SpanIterator &rhs) const
Definition: AutoDiffHelpers.hpp:667
UpwindSelector(const Grid &g, const HelperOps &h, const typename ADB::V &ifaceflux)
Definition: AutoDiffHelpers.hpp:181
int size() const
Number of elements.
Definition: AutoDiffBlock.hpp:413
AutoDiffBlock< double >::V V
Definition: AutoDiffHelpers.hpp:43
Span(const int num)
Definition: AutoDiffHelpers.hpp:620
AutoDiffBlock< Scalar > superset(const AutoDiffBlock< Scalar > &x, const IntVec &indices, const int n)
Returns v where v(indices) == x, v(!indices) == 0 and v.size() == n.
Definition: AutoDiffHelpers.hpp:314
Selector(const typename ADB::V &selection_basis, CriterionForLeftElement crit=GreaterEqualZero)
Definition: AutoDiffHelpers.hpp:365
bool operator!=(const SpanIterator &rhs) const
Definition: AutoDiffHelpers.hpp:672
HelperOps(const Grid &grid, Opm::EclipseStateConstPtr eclState=EclipseStateConstPtr())
Constructs all helper vectors and matrices.
Definition: AutoDiffHelpers.hpp:72
static AutoDiffBlock constant(V &&val)
Definition: AutoDiffBlock.hpp:110
Eigen::ArrayXd sign(const Eigen::ArrayXd &x)
Return a vector of (-1.0, 0.0 or 1.0), depending on sign per element.
Definition: AutoDiffHelpers.hpp:713
int operator*()
Definition: AutoDiffHelpers.hpp:677
Definition: AutoDiffMatrix.hpp:43
bool operator<(const SpanIterator &rhs) const
Definition: AutoDiffHelpers.hpp:662
M ngrad
Extract for each internal face the difference of its adjacent cells' values (first - second)...
Definition: AutoDiffHelpers.hpp:50
SpanIterator operator++()
Definition: AutoDiffHelpers.hpp:651
Eigen::SparseMatrix< double > spdiag(const AutoDiffBlock< double >::V &d)
Definition: AutoDiffHelpers.hpp:340
V nnc_trans
The NNC transmissibilities.
Definition: AutoDiffHelpers.hpp:68
AutoDiffBlock< Scalar > ADB
Definition: AutoDiffHelpers.hpp:361
M div
Extract for each cell the sum of its adjacent interior faces' (signed) values.
Definition: AutoDiffHelpers.hpp:56
std::vector< ADB > select(const std::vector< ADB > &xc) const
Apply selector to multiple per-cell quantities.
Definition: AutoDiffHelpers.hpp:225
Definition: AutoDiffHelpers.hpp:40
int operator[](const int i) const
Definition: AutoDiffHelpers.hpp:632
ADB::V select(const typename ADB::V &x1, const typename ADB::V &x2) const
Apply selector to ADB quantities.
Definition: AutoDiffHelpers.hpp:422
void collapseJacs(const AutoDiffBlock< double > &x, Matrix &jacobian)
Returns the input expression, but with all Jacobians collapsed to one.
Definition: AutoDiffHelpers.hpp:446
static AutoDiffBlock function(V &&val, std::vector< M > &&jac)
Definition: AutoDiffBlock.hpp:183
IFaces internal_faces
Definition: AutoDiffHelpers.hpp:47
ADB::V select(const typename ADB::V &xc) const
Apply selector to single per-cell constant quantity.
Definition: AutoDiffHelpers.hpp:247
AutoDiffBlock< double > vertcatCollapseJacs(const std::vector< AutoDiffBlock< double > > &x)
Definition: AutoDiffHelpers.hpp:524
ADB select(const ADB &xc) const
Apply selector to single per-cell ADB quantity.
Definition: AutoDiffHelpers.hpp:241
Definition: AutoDiffHelpers.hpp:176
SpanIterator operator++(int)
Definition: AutoDiffHelpers.hpp:656
Definition: AutoDiffHelpers.hpp:643
Eigen::SparseMatrix< double > M
Definition: AutoDiffHelpers.hpp:42
Definition: AutoDiffBlock.hpp:94
Span(const int num, const int stride, const int start)
Definition: AutoDiffHelpers.hpp:626
const V & value() const
Function value.
Definition: AutoDiffBlock.hpp:436
bool operator==(const Span &rhs)
Definition: AutoDiffHelpers.hpp:699
M fullngrad
Definition: AutoDiffHelpers.hpp:59
M fulldiv
Extract for each cell the sum of all its adjacent faces' (signed) values.
Definition: AutoDiffHelpers.hpp:61
AutoDiffBlock< double > vertcat(const AutoDiffBlock< double > &x, const AutoDiffBlock< double > &y)
Returns the vertical concatenation [ x; y ] of the inputs.
Definition: AutoDiffHelpers.hpp:500
SpanIterator(const Span *span, const int index)
Definition: AutoDiffHelpers.hpp:646
void extractInternalFaces(const UnstructuredGrid &grid, Eigen::Array< int, Eigen::Dynamic, 1 > &internal_faces, Eigen::Array< int, Eigen::Dynamic, 2, Eigen::RowMajor > &nbi)
extracts the internal faces of a grid.
const std::vector< M > & derivative() const
Function derivatives.
Definition: AutoDiffBlock.hpp:442