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
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)