Derive from 'Model' in stead of partially reading from it.
This commit is contained in:
parent
43c6e00109
commit
a30a9c0941
@ -40,50 +40,62 @@
|
||||
#include <vector>
|
||||
|
||||
namespace Opm {
|
||||
template <int DofPerCell = 1>
|
||||
class ImplicitAssembly {
|
||||
template <class Model>
|
||||
class ImplicitAssembly : private Model {
|
||||
enum { DofPerCell = Model::DofPerCell };
|
||||
|
||||
public:
|
||||
template <class Grid ,
|
||||
class JacobianSystem>
|
||||
void
|
||||
createSystem(const Grid& g ,
|
||||
JacobianSystem& sys) const {
|
||||
|
||||
typedef typename JacobianSystem::matrix_type::size_type sz_t;
|
||||
sz_t m = g.number_of_cells;
|
||||
sz_t nnz = g.number_of_cells + countConnections(g);
|
||||
|
||||
m *= DofPerCell;
|
||||
nnz *= DofPerCell * DofPerCell;
|
||||
|
||||
sys.matrix().setSize(m, m, nnz);
|
||||
sys.vector().setSize(m);
|
||||
}
|
||||
|
||||
template <class ReservoirState,
|
||||
class Grid ,
|
||||
class Model ,
|
||||
class SourceTerms ,
|
||||
class JacobianSystem>
|
||||
void
|
||||
assemble(const ReservoirState* state,
|
||||
const Grid* g ,
|
||||
const Model* model,
|
||||
const SourceTerms* src ,
|
||||
assemble(const ReservoirState& state,
|
||||
const Grid& g ,
|
||||
const SourceTerms& src ,
|
||||
const double dt ,
|
||||
JacobianSystem* sys ) {
|
||||
|
||||
size_t m = g->number_of_cells * DofPerCell;
|
||||
|
||||
sys->matrix()->setSize(m, m);
|
||||
sys->vector()->setSize(m);
|
||||
JacobianSystem& sys ) {
|
||||
|
||||
for (int c = 0; c < g->number_of_cells; ++c) {
|
||||
const int nconn = computeCellContrib(g, model, c, dt);
|
||||
assembleCellContrib(g, c, nconn, sys);
|
||||
this->computeCellContrib(g, c, dt);
|
||||
this->assembleCellContrib(g, c, sys);
|
||||
}
|
||||
|
||||
sys->matrix()->finalizeStructure();
|
||||
sys.matrix().finalizeStructure();
|
||||
|
||||
if (src != 0) {
|
||||
assembleSourceContrib(g, model, src, dt, sys);
|
||||
this->assembleSourceContrib(g, src, dt, sys);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
template <class Grid>
|
||||
int
|
||||
countConnections(const Grid* g, int c) {
|
||||
countConnections(const Grid& g, int c) const {
|
||||
int i, f, c1, c2, n;
|
||||
|
||||
for (i = g->cell_facepos[c + 0], n = 0;
|
||||
i < g->cell_facepos[c + 1]; ++i) {
|
||||
f = g->cell_faces[i];
|
||||
c1 = g->face_cells[2*f + 0];
|
||||
c2 = g->face_cells[2*f + 1];
|
||||
for (i = g.cell_facepos[c + 0], n = 0;
|
||||
i < g.cell_facepos[c + 1]; ++i) {
|
||||
f = g.cell_faces[i];
|
||||
c1 = g.face_cells[2*f + 0];
|
||||
c2 = g.face_cells[2*f + 1];
|
||||
|
||||
n += (c1 >= 0) && (c2 >= 0);
|
||||
}
|
||||
@ -91,16 +103,27 @@ namespace Opm {
|
||||
return n;
|
||||
}
|
||||
|
||||
template <class ReservoirState, class Grid, class Model>
|
||||
template <class Grid>
|
||||
int
|
||||
computeCellContrib(const ReservoirState* state,
|
||||
const Grid* g ,
|
||||
const Model* model,
|
||||
countConnections(const Grid& g) const {
|
||||
int n = 0;
|
||||
|
||||
for (int c = 0; c < g.number_of_cells; ++c) {
|
||||
n += countConnections(g, c);
|
||||
}
|
||||
|
||||
return n;
|
||||
}
|
||||
|
||||
template <class ReservoirState, class Grid>
|
||||
int
|
||||
computeCellContrib(const ReservoirState& state,
|
||||
const Grid& g ,
|
||||
const double dt ,
|
||||
const int c ) {
|
||||
const int ndof = DofPerCell;
|
||||
const int ndof2 = ndof * ndof;
|
||||
const int nconn = countConnections(g, c);
|
||||
nconn_ = countConnections(g, c);
|
||||
|
||||
row_structure_.resize (0);
|
||||
row_structure_.reserve (nconn + 1);
|
||||
@ -113,37 +136,34 @@ namespace Opm {
|
||||
double* J1 = &asm_buffer_[(0*nconn + 1) * ndof2];
|
||||
double* J2 = J1 + (1*nconn + 0) * ndof2 ;
|
||||
|
||||
model->initResidual(c, F);
|
||||
this->initResidual(c, F);
|
||||
F += ndof;
|
||||
|
||||
for (int i = g->cell_facepos[c + 0];
|
||||
i < g->cell_facepos[c + 1]; ++i) {
|
||||
int f = g->cell_faces[i];
|
||||
int c1 = g->face_cells[2*f + 0];
|
||||
int c2 = g->face_cells[2*f + 1];
|
||||
for (int i = g.cell_facepos[c + 0];
|
||||
i < g.cell_facepos[c + 1]; ++i) {
|
||||
int f = g.cell_faces[i];
|
||||
int c1 = g.face_cells[2*f + 0];
|
||||
int c2 = g.face_cells[2*f + 1];
|
||||
|
||||
if ((c1 >= 0) && (c2 >= 0)) {
|
||||
row_structure_.push_back((c1 == c) ? c2 : c1);
|
||||
connections_.push_back((c1 == c) ? c2 : c1);
|
||||
|
||||
model->fluxConnection(state, g, dt, c, f, J1, J2, F);
|
||||
this->fluxConnection(state, g, dt, c, f, J1, J2, F);
|
||||
J1 += ndof2; J2 += ndof2; F += ndof;
|
||||
}
|
||||
}
|
||||
|
||||
model->accumulation(g, c, &asm_buffer_[0], F);
|
||||
|
||||
return nconn;
|
||||
this->accumulation(g, c, &asm_buffer_[0], F);
|
||||
}
|
||||
|
||||
template <class Grid, class System>
|
||||
assembleCellContrib(const Grid* g,
|
||||
const int c,
|
||||
const int nconn,
|
||||
System* sys) const {
|
||||
assembleCellContrib(const Grid& g ,
|
||||
const int c ,
|
||||
System& sys) const {
|
||||
const int ndof = DofPerCell;
|
||||
const int ndof2 = ndof * ndof;
|
||||
|
||||
sys->matrix()->createBlockRow(c, connections_, ndof);
|
||||
sys.matrix().createBlockRow(c, connections_, ndof);
|
||||
|
||||
typedef std::vector<int>::size_type sz_t;
|
||||
|
||||
@ -151,20 +171,20 @@ namespace Opm {
|
||||
const double* J2 = J1 + ((1*nconn + 1) * ndof2);
|
||||
|
||||
// Assemble contributions from accumulation term
|
||||
sys->matrix()->assembleBlock(ndof, c, c, J1); J1 += ndof2;
|
||||
sys.matrix().assembleBlock(ndof, c, c, J1); J1 += ndof2;
|
||||
|
||||
// Assemble connection contributions.
|
||||
for (int i = g->cell_facepos[c + 0];
|
||||
i < g->cell_facepos[c + 1]; ++i) {
|
||||
int f = g->cell_faces[i];
|
||||
int c1 = g->face_cell[2*f + 0];
|
||||
int c2 = g->face_cell[2*f + 1];
|
||||
for (int i = g.cell_facepos[c + 0];
|
||||
i < g.cell_facepos[c + 1]; ++i) {
|
||||
int f = g.cell_faces[i];
|
||||
int c1 = g.face_cell[2*f + 0];
|
||||
int c2 = g.face_cell[2*f + 1];
|
||||
|
||||
c2 = (c1 == c) ? c2 : c1;
|
||||
|
||||
if (c2 >= 0) {
|
||||
sys->matrix()->assembleBlock(ndof, c, c , J1);
|
||||
sys->matrix()->assembleBlock(ndof, c, c2, J2);
|
||||
sys.matrix().assembleBlock(ndof, c, c , J1);
|
||||
sys.matrix().assembleBlock(ndof, c, c2, J2);
|
||||
|
||||
J1 += ndof2;
|
||||
J2 += ndof2;
|
||||
@ -174,37 +194,37 @@ namespace Opm {
|
||||
// Assemble residual
|
||||
const double* F = &asm_buffer_[(2*nconn + 1) * ndof2];
|
||||
for (int conn = 0; conn < nconn + 2; ++conn, F += ndof) {
|
||||
sys->vector.assembleBlock(ndof, c, F);
|
||||
sys.vector().assembleBlock(ndof, c, F);
|
||||
}
|
||||
}
|
||||
|
||||
template <class Grid, class SourceTerms, class System>
|
||||
void
|
||||
assembleSourceContrib(const Grid* g,
|
||||
const Model* model,
|
||||
const SourceTerms* src,
|
||||
assembleSourceContrib(const Grid& g,
|
||||
const SourceTerms& src,
|
||||
const double dt,
|
||||
System* sys) {
|
||||
System& sys) {
|
||||
const int ndof = DofPerCell;
|
||||
const int ndof2 = ndof * ndof;
|
||||
|
||||
for (int i = 0; i < src->nsrc; ++i) {
|
||||
for (int i = 0; i < src.nsrc; ++i) {
|
||||
std::fill_n(asm_buffer_.begin(), ndof2 + ndof, 0.0);
|
||||
|
||||
double *J = &asm_buffer_[0];
|
||||
double *F = J + ndof2;
|
||||
|
||||
model->sourceTerms(g, src, i, dt, J, F);
|
||||
this->sourceTerms(g, src, i, dt, J, F);
|
||||
|
||||
const int c = src->cell[i];
|
||||
const int c = src.cell[i];
|
||||
|
||||
sys->matrix()->assembleBlock(ndof, c, c, J);
|
||||
sys->vector()->assembleBlock(ndof, c, F);
|
||||
sys.matrix().assembleBlock(ndof, c, c, J);
|
||||
sys.vector().assembleBlock(ndof, c, F);
|
||||
}
|
||||
}
|
||||
|
||||
int nconn_ ;
|
||||
std::vector<int> connections_;
|
||||
std::vector<double> asm_buffer_;
|
||||
std::vector<double> asm_buffer_ ;
|
||||
};
|
||||
}
|
||||
#endif // OPM_IMPLICITASSEMBLY_HPP_HEADER
|
||||
|
Loading…
Reference in New Issue
Block a user