void assign_bc(const GI& g, BCS& bcs) { typedef Dune::FlowBC BC; typedef typename GI::CellIterator CI; typedef typename CI::FaceIterator FI; int max_bid = 0; for (CI c = g.cellbegin(); c != g.cellend(); ++c) { for (FI f = c->facebegin(); f != c->faceend(); ++f) { int bid = f->boundaryId(); if (bid > max_bid) { max_bid = bid; bcs.resize(bid + 1); } bcs.flowCond(bid) = BC(BC::Dirichlet, u(f->centroid())); } } }
inline void setupRegionBasedConditions(const Opm::parameter::ParameterGroup& param, const GridInterface& g, BCs& bcs) { // Extract region and pressure value for Dirichlet bcs. typedef typename GridInterface::Vector Vector; Vector low; low[0] = param.getDefault("dir_block_low_x", 0.0); low[1] = param.getDefault("dir_block_low_y", 0.0); low[2] = param.getDefault("dir_block_low_z", 0.0); Vector high; high[0] = param.getDefault("dir_block_high_x", 1.0); high[1] = param.getDefault("dir_block_high_y", 1.0); high[2] = param.getDefault("dir_block_high_z", 1.0); double dir_block_pressure = param.get<double>("dir_block_pressure"); // Set flow conditions for that region. // For this to work correctly, unique boundary ids should be used, // otherwise conditions may spread outside the given region, to all // faces with the same bid as faces inside the region. typedef typename GridInterface::CellIterator CI; typedef typename CI::FaceIterator FI; int max_bid = 0; std::vector<int> dir_bids; for (CI c = g.cellbegin(); c != g.cellend(); ++c) { for (FI f = c->facebegin(); f != c->faceend(); ++f) { int bid = f->boundaryId(); max_bid = std::max(bid, max_bid); if (bid != 0 && isInside(low, high, f->centroid())) { dir_bids.push_back(bid); } } } bcs.resize(max_bid + 1); for (std::vector<int>::const_iterator it = dir_bids.begin(); it != dir_bids.end(); ++it) { bcs.flowCond(*it) = FlowBC(FlowBC::Dirichlet, dir_block_pressure); } // Transport BCs are defaulted. }
/// @brief /// Main evaluation routine. Computes the inverse of the /// matrix representation of the mimetic inner product in a /// single cell with kown permeability @f$K@f$. Adds a /// regularization term in order to guarantee a positive /// definite matrix. /// /// @tparam RockInterface /// Type representing rock properties. Assumed to /// expose a method @code permeability(i) @endcode which /// retrieves the static permeability tensor of cell @code /// i @endcode. The permeability tensor, @$K@$, is in /// turn, assumed to expose a method @code operator()(int /// i, int j) @endcode such that the call @code K(i,j) /// @endcode retrieves the @f$ij@f$'th component of the /// cell permeability @f$K@f$. /// /// @param [in] c /// Cell for which to evaluate the inverse of the mimetic /// inner product. /// /// @param [in] r /// Specific reservoir properties. Only the permeability /// is used in method @code buildMatrix() @endcode. /// /// @param [in] nf /// Number of faces (i.e., number of neighbours) of cell /// @code *c @endcode. void buildStaticContrib(const CellIter& c, const RockInterface& r, const typename CellIter::Vector& grav, const int nf) { // Binv = (N*lambda*K*N' + t*diag(A)*(I - Q*Q')*diag(A))/vol // ^ ^^^^^^^^^^^^^^^^^^^^^^^^^^ // precompute: n_ precompute: second_term_ // t = 6/dim * trace(lambda*K) typedef typename CellIter::FaceIterator FI; typedef typename CellIter::Vector CV; typedef typename FI ::Vector FV; // Now we need to remember the rocks, since we will need // the permeability for dynamic assembly. prock_ = &r; const int ci = c->index(); static_assert (FV::dimension == int(dim), ""); assert (int(t1_.size()) >= nf * dim); assert (int(t2_.size()) >= nf * dim); assert (int(fa_.size()) >= nf * nf); SharedFortranMatrix T2 (nf, dim, &t2_ [0]); SharedFortranMatrix fa (nf, nf , &fa_ [0]); SharedFortranMatrix second_term(nf, nf, &second_term_[ci][0]); SharedFortranMatrix n(nf, dim, &n_[ci][0]); // Clear matrices of any residual data. zero(second_term); zero(n); zero(T2); zero(fa); // Setup: second_term <- I, n <- N, T2 <- C const CV cc = c->centroid(); int i = 0; for (FI f = c->facebegin(); f != c->faceend(); ++f, ++i) { second_term(i,i) = Scalar(1.0); fa(i,i) = f->area(); FV fc = f->centroid(); fc -= cc; fc *= fa(i,i); FV fn = f->normal (); fn *= fa(i,i); for (int j = 0; j < dim; ++j) { n (i,j) = fn[j]; T2(i,j) = fc[j]; } } assert (i == nf); // T2 <- orth(T2) if (orthogonalizeColumns(T2) != 0) { assert (false); } // second_term <- second_term - T2*T2' == I - Q*Q' symmetricUpdate(Scalar(-1.0), T2, Scalar(1.0), second_term); // second_term <- diag(A) * second_term * diag(A) symmetricUpdate(fa, second_term); // Gravity term: Kg_ = K * grav vecMulAdd_N(Scalar(1.0), r.permeability(ci), &grav[0], Scalar(0.0), &Kg_[ci][0]); }