include capillary pressure in the PDEs

I'm neither sure that this is fully correct nor that I found all
occurences (so far, the output writing code is missing in this patch),
but it seems to work for SPE1...
This commit is contained in:
Andreas Lauser
2013-11-26 13:51:10 +01:00
parent 96454a8496
commit 977395fccd
7 changed files with 215 additions and 15 deletions

View File

@@ -686,5 +686,63 @@ namespace Opm
return relperms;
}
std::vector<ADB> BlackoilPropsAdFromDeck::capPress(const ADB& sw,
const ADB& so,
const ADB& sg,
const Cells& cells) const
{
const int numCells = cells.size();
const int numActivePhases = numPhases();
const int numBlocks = so.numBlocks();
Block activeSat(numCells, numActivePhases);
if (phase_usage_.phase_used[Water]) {
assert(sw.value().size() == numCells);
activeSat.col(phase_usage_.phase_pos[Water]) = sw.value();
}
if (phase_usage_.phase_used[Oil]) {
assert(so.value().size() == numCells);
activeSat.col(phase_usage_.phase_pos[Oil]) = so.value();
} else {
OPM_THROW(std::runtime_error, "BlackoilPropsAdFromDeck::relperm() assumes oil phase is active.");
}
if (phase_usage_.phase_used[Gas]) {
assert(sg.value().size() == numCells);
activeSat.col(phase_usage_.phase_pos[Gas]) = sg.value();
}
Block pc(numCells, numActivePhases);
Block dpc(numCells, numActivePhases*numActivePhases);
satprops_->capPress(numCells, activeSat.data(), cells.data(), pc.data(), dpc.data());
std::vector<ADB> adbCapPressures;
adbCapPressures.reserve(3);
const ADB* s[3] = { &sw, &so, &sg };
for (int phase1 = 0; phase1 < 3; ++phase1) {
if (phase_usage_.phase_used[phase1]) {
const int phase1_pos = phase_usage_.phase_pos[phase1];
std::vector<ADB::M> jacs(numBlocks);
for (int block = 0; block < numBlocks; ++block) {
jacs[block] = ADB::M(numCells, s[phase1]->derivative()[block].cols());
}
for (int phase2 = 0; phase2 < 3; ++phase2) {
if (!phase_usage_.phase_used[phase2])
continue;
const int phase2_pos = phase_usage_.phase_pos[phase2];
// Assemble dpc1/ds2.
const int column = phase1_pos + numActivePhases*phase2_pos; // Recall: Fortran ordering from props_.relperm()
ADB::M dpc1_ds2_diag = spdiag(dpc.col(column));
for (int block = 0; block < numBlocks; ++block) {
jacs[block] += dpc1_ds2_diag * s[phase2]->derivative()[block];
}
}
adbCapPressures.emplace_back(ADB::function(pc.col(phase1_pos), jacs));
} else {
adbCapPressures.emplace_back(ADB::null());
}
}
return adbCapPressures;
}
} // namespace Opm