Пример #1
0
    def _apply_ad(self, cellwise_field) -> Ad_array:
        """ Compute transmissibility via harmonic averaging over faces."""

        # References to private variables
        data = self._data
        tpfa = self._tpfa

        if data.get("Aavatsmark_transmissibilities", False):
            raise RuntimeError(
                "AD version of Aavatsmark_transmissibilities not implemented.")

        # Get connectivity and grid based data
        ci = tpfa.ci
        ci_periodic = tpfa.ci_periodic
        fc_cc = tpfa.fc_cc
        dist_face_cell = np.power(np.power(fc_cc, 2).sum(axis=0), 0.5)

        # Consider two cases: scalar and tensor valued fields.

        # assert (cellwise_field.val, np.ndarray)
        # Case 1: Scalar valued fields.
        if len(cellwise_field.val.shape) == 1:
            t_cf_val = cellwise_field.val[ci]
            t_cf_jac = cellwise_field.jac[ci]
            t_cf_val /= dist_face_cell
            t_cf_jac /= dist_face_cell

        # Case 2: Tensor valued fields.
        elif len(cellwise_field.val.shape) == 3 and all(
            [cellwise_field.val.shape[i] == 3 for i in range(0, 2)]):
            t_cf_tensor_val = cellwise_field.val[::, ::, ci]
            t_cf_tensor_jac = cellwise_field.jac[::, ::, ci]
            tn_cf_val = (t_cf_tensor_val * fc_cc).sum(axis=1)
            tn_cf_jac = (t_cf_tensor_jac * fc_cc).sum(axis=1)
            ntn_cf_val = (tn_cf_val * fc_cc).sum(axis=0)
            ntn_cf_jac = (tn_cf_jac * fc_cc).sum(axis=0)
            dist_face_cell_3 = np.power(dist_face_cell, 3)
            t_cf_val = np.divide(ntn_cf_val, dist_face_cell_3)
            t_cf_jac = np.divide(ntn_cf_jac, dist_face_cell_3)

        else:
            raise RuntimeError("Type of cell-wise field not supported.")

        # Continue with AD representation and utilize chain rule.
        t_face = Ad_array(t_cf_val, sps.diags(t_cf_jac).tocsc())

        # The final harmonic averaging using a linear operator representation of bincount.
        # TODO test!
        t_face = (self.bincount_fi_periodic * dist_face_cell) * (
            (self.bincount_fi_periodic * t_face**(-1))**(-1))

        # Project column space of t.jac onto the actual cell
        # TODO is there not a better way to create the projection matrix? By correct indexing?
        c = np.arange(len(ci_periodic))
        proj = sps.coo_matrix((np.ones_like(c), (c, ci_periodic))).tocsr()
        t_face.jac = t_face.jac * proj

        return t_face
Пример #2
0
 def test_copy_scalar(self):
     a = Ad_array(1, 0)
     b = a.copy()
     self.assertTrue(a.val == b.val)
     self.assertTrue(a.jac == b.jac)
     a.val = 2
     a.jac = 3
     self.assertTrue(b.val == 1)
     self.assertTrue(b.jac == 0)