mirror of
https://github.com/OPM/opm-simulators.git
synced 2025-02-25 18:55:30 -06:00
Make vertcatCollapseJacs() handle constants properly.
With this, any or all of the input vector element may have an empty jacobian vector. Any element with a non-empty jacobian vector must still have the same block pattern.
This commit is contained in:
parent
085c279a0a
commit
eb9b62697e
@ -447,21 +447,31 @@ vertcatCollapseJacs(const std::vector<AutoDiffBlock<double> >& x)
|
|||||||
|
|
||||||
// Count sizes, nonzeros.
|
// Count sizes, nonzeros.
|
||||||
const int nx = x.size();
|
const int nx = x.size();
|
||||||
const int nb = x[0].numBlocks();
|
|
||||||
int size = 0;
|
int size = 0;
|
||||||
int nnz = 0;
|
int nnz = 0;
|
||||||
|
int elem_with_deriv = -1;
|
||||||
|
int num_blocks = 0;
|
||||||
for (int elem = 0; elem < nx; ++elem) {
|
for (int elem = 0; elem < nx; ++elem) {
|
||||||
size += x[elem].size();
|
size += x[elem].size();
|
||||||
if (x[elem].blockPattern() != x[0].blockPattern()) {
|
if (x[elem].derivative().empty()) {
|
||||||
|
// No nnz contributions from this element.
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
if (elem_with_deriv == -1) {
|
||||||
|
elem_with_deriv = elem;
|
||||||
|
num_blocks = x[elem].numBlocks();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (x[elem].blockPattern() != x[elem_with_deriv].blockPattern()) {
|
||||||
OPM_THROW(std::runtime_error, "vertcatCollapseJacs(): all arguments must have the same block pattern");
|
OPM_THROW(std::runtime_error, "vertcatCollapseJacs(): all arguments must have the same block pattern");
|
||||||
}
|
}
|
||||||
for (int block = 0; block < nb; ++block) {
|
for (int block = 0; block < num_blocks; ++block) {
|
||||||
nnz += x[elem].derivative()[block].nonZeros();
|
nnz += x[elem].derivative()[block].nonZeros();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
int num_cols = 0;
|
int num_cols = 0;
|
||||||
for (int block = 0; block < nb; ++block) {
|
for (int block = 0; block < num_blocks; ++block) {
|
||||||
num_cols += x[0].derivative()[block].cols();
|
num_cols += x[elem_with_deriv].derivative()[block].cols();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build value for result.
|
// Build value for result.
|
||||||
@ -474,6 +484,11 @@ vertcatCollapseJacs(const std::vector<AutoDiffBlock<double> >& x)
|
|||||||
}
|
}
|
||||||
assert(pos == size);
|
assert(pos == size);
|
||||||
|
|
||||||
|
// Return a constant if we have no derivatives at all.
|
||||||
|
if (num_blocks == 0) {
|
||||||
|
return ADB::constant(std::move(val));
|
||||||
|
}
|
||||||
|
|
||||||
// Set up for batch insertion of all Jacobian elements.
|
// Set up for batch insertion of all Jacobian elements.
|
||||||
typedef Eigen::Triplet<double> Tri;
|
typedef Eigen::Triplet<double> Tri;
|
||||||
std::vector<Tri> t;
|
std::vector<Tri> t;
|
||||||
@ -481,7 +496,8 @@ vertcatCollapseJacs(const std::vector<AutoDiffBlock<double> >& x)
|
|||||||
int block_row_start = 0;
|
int block_row_start = 0;
|
||||||
for (int elem = 0; elem < nx; ++elem) {
|
for (int elem = 0; elem < nx; ++elem) {
|
||||||
int block_col_start = 0;
|
int block_col_start = 0;
|
||||||
for (int block = 0; block < nb; ++block) {
|
if (!x[elem].derivative().empty()) {
|
||||||
|
for (int block = 0; block < num_blocks; ++block) {
|
||||||
const ADB::M& jac = x[elem].derivative()[block];
|
const ADB::M& jac = x[elem].derivative()[block];
|
||||||
for (ADB::M::Index k = 0; k < jac.outerSize(); ++k) {
|
for (ADB::M::Index k = 0; k < jac.outerSize(); ++k) {
|
||||||
for (ADB::M::InnerIterator i(jac, k); i ; ++i) {
|
for (ADB::M::InnerIterator i(jac, k); i ; ++i) {
|
||||||
@ -492,6 +508,7 @@ vertcatCollapseJacs(const std::vector<AutoDiffBlock<double> >& x)
|
|||||||
}
|
}
|
||||||
block_col_start += jac.cols();
|
block_col_start += jac.cols();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
block_row_start += x[elem].size();
|
block_row_start += x[elem].size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user