Merge pull request #54 from atgeirr/allow-empty-jac

Add new AutoDiffBlock::constant() overload without block sizes.
This commit is contained in:
Bård Skaflestad 2013-10-25 07:15:09 -07:00
commit 82d0ade060
2 changed files with 63 additions and 8 deletions

View File

@ -1,6 +1,6 @@
Module: opm-autodiff Module: opm-autodiff
Description: Utilities for automatic differentiation and simulators based on AD Description: Utilities for automatic differentiation and simulators based on AD
Version: 1.0 Version: 0.9
Label: 2013.10 Label: 2013.10
Maintainer: atgeirr@sintef.no Maintainer: atgeirr@sintef.no
Depends: opm-core Depends: opm-core

View File

@ -98,6 +98,16 @@ namespace Opm
/// Create an AutoDiffBlock representing a constant. /// Create an AutoDiffBlock representing a constant.
/// \param[in] val values /// \param[in] val values
static AutoDiffBlock constant(const V& val)
{
return AutoDiffBlock(val);
}
/// Create an AutoDiffBlock representing a constant.
/// This variant requires specifying the block sizes used
/// for the Jacobians even though the Jacobian matrices
/// themselves will be zero.
/// \param[in] val values
/// \param[in] blocksizes block pattern /// \param[in] blocksizes block pattern
static AutoDiffBlock constant(const V& val, const std::vector<int>& blocksizes) static AutoDiffBlock constant(const V& val, const std::vector<int>& blocksizes)
{ {
@ -165,14 +175,18 @@ namespace Opm
/// Elementwise operator += /// Elementwise operator +=
AutoDiffBlock& operator+=(const AutoDiffBlock& rhs) AutoDiffBlock& operator+=(const AutoDiffBlock& rhs)
{ {
assert (numBlocks() == rhs.numBlocks()); if (jac_.empty()) {
assert (value().size() == rhs.value().size()); jac_ = rhs.jac_;
} else if (!rhs.jac_.empty()) {
assert (numBlocks() == rhs.numBlocks());
assert (value().size() == rhs.value().size());
const int num_blocks = numBlocks(); const int num_blocks = numBlocks();
for (int block = 0; block < num_blocks; ++block) { for (int block = 0; block < num_blocks; ++block) {
assert(jac_[block].rows() == rhs.jac_[block].rows()); assert(jac_[block].rows() == rhs.jac_[block].rows());
assert(jac_[block].cols() == rhs.jac_[block].cols()); assert(jac_[block].cols() == rhs.jac_[block].cols());
jac_[block] += rhs.jac_[block]; jac_[block] += rhs.jac_[block];
}
} }
val_ += rhs.val_; val_ += rhs.val_;
@ -183,6 +197,15 @@ namespace Opm
/// Elementwise operator + /// Elementwise operator +
AutoDiffBlock operator+(const AutoDiffBlock& rhs) const AutoDiffBlock operator+(const AutoDiffBlock& rhs) const
{ {
if (jac_.empty() && rhs.jac_.empty()) {
return constant(val_ + rhs.val_);
}
if (jac_.empty()) {
return val_ + rhs;
}
if (rhs.jac_.empty()) {
return *this + rhs.val_;
}
std::vector<M> jac = jac_; std::vector<M> jac = jac_;
assert(numBlocks() == rhs.numBlocks()); assert(numBlocks() == rhs.numBlocks());
int num_blocks = numBlocks(); int num_blocks = numBlocks();
@ -197,6 +220,15 @@ namespace Opm
/// Elementwise operator - /// Elementwise operator -
AutoDiffBlock operator-(const AutoDiffBlock& rhs) const AutoDiffBlock operator-(const AutoDiffBlock& rhs) const
{ {
if (jac_.empty() && rhs.jac_.empty()) {
return constant(val_ - rhs.val_);
}
if (jac_.empty()) {
return val_ - rhs;
}
if (rhs.jac_.empty()) {
return *this - rhs.val_;
}
std::vector<M> jac = jac_; std::vector<M> jac = jac_;
assert(numBlocks() == rhs.numBlocks()); assert(numBlocks() == rhs.numBlocks());
int num_blocks = numBlocks(); int num_blocks = numBlocks();
@ -211,6 +243,15 @@ namespace Opm
/// Elementwise operator * /// Elementwise operator *
AutoDiffBlock operator*(const AutoDiffBlock& rhs) const AutoDiffBlock operator*(const AutoDiffBlock& rhs) const
{ {
if (jac_.empty() && rhs.jac_.empty()) {
return constant(val_ * rhs.val_);
}
if (jac_.empty()) {
return val_ * rhs;
}
if (rhs.jac_.empty()) {
return *this * rhs.val_;
}
int num_blocks = numBlocks(); int num_blocks = numBlocks();
std::vector<M> jac(num_blocks); std::vector<M> jac(num_blocks);
assert(numBlocks() == rhs.numBlocks()); assert(numBlocks() == rhs.numBlocks());
@ -228,6 +269,15 @@ namespace Opm
/// Elementwise operator / /// Elementwise operator /
AutoDiffBlock operator/(const AutoDiffBlock& rhs) const AutoDiffBlock operator/(const AutoDiffBlock& rhs) const
{ {
if (jac_.empty() && rhs.jac_.empty()) {
return constant(val_ / rhs.val_);
}
if (jac_.empty()) {
return val_ / rhs;
}
if (rhs.jac_.empty()) {
return *this / rhs.val_;
}
int num_blocks = numBlocks(); int num_blocks = numBlocks();
std::vector<M> jac(num_blocks); std::vector<M> jac(num_blocks);
assert(numBlocks() == rhs.numBlocks()); assert(numBlocks() == rhs.numBlocks());
@ -292,6 +342,11 @@ namespace Opm
} }
private: private:
AutoDiffBlock(const V& val)
: val_(val)
{
}
AutoDiffBlock(const V& val, AutoDiffBlock(const V& val,
const std::vector<M>& jac) const std::vector<M>& jac)
: val_(val), jac_(jac) : val_(val), jac_(jac)