Real
AuxChemElastic::computeDifferential(const Real & coupled_conserved, const Real & coupled_nonconserved)
{
  // partial derivative of f_chem with respect to conserved variable
  Real dfchem_dcons(0.0);
  // partial derivative of f_chem with respect to nonconserved variable
  Real dfchem_dnoncons(0.0);

  // partial derivatives of self-elastic energies
  Real dself_dcons(0.0);
  Real dself_dnoncons(0.0);

  // partial derivative of interaction elastic energy
  Real dint_dcons(0.0);
  Real dint_dnoncons(0.0);

  Real first_term(0.0);
  Real second_term(0.0);

  dfchem_dcons = computeDfchemDcons(coupled_conserved, coupled_nonconserved);
  dself_dcons = computeDselfDcons();
  dint_dcons = computeDintDcons();

  dfchem_dnoncons = computeDfchemDnoncons(coupled_conserved, coupled_nonconserved);
  dself_dnoncons = computeDselfDnoncons();
  dint_dnoncons = computeDintDnoncons();

  first_term = (dfchem_dcons + dself_dcons + dint_dcons)*(_precip_conserved - coupled_conserved);
  second_term = (dfchem_dnoncons + dself_dnoncons + dint_dnoncons)*(_precip_nonconserved - coupled_nonconserved);

  return first_term + second_term;
}
Exemple #2
0
Real
AuxChem::computeDifferential(const Real & coupled_conserved, const Real & coupled_nonconserved)
{
  // partial derivative of f_chem with respect to conserved variable
  Real dfchem_dcons(0.0);
  // partial derivative of f_chem with respect to nonconserved variable
  Real dfchem_dnoncons(0.0);

  Real first_term(0.0);
  Real second_term(0.0);

  dfchem_dcons = computeDfchemDcons(coupled_conserved, coupled_nonconserved);

  dfchem_dnoncons = computeDfchemDnoncons(coupled_conserved, coupled_nonconserved);

  first_term = (dfchem_dcons)*(_precip_conserved - coupled_conserved);
  second_term = (dfchem_dnoncons)*(_precip_nonconserved - coupled_nonconserved);

  return first_term + second_term;
}
        /// @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]);
        }