def get_v_conv_conts(prev_v=None, V=None, invinds=None, diribcs=None, Picard=False): """ get and condense the linearized convection to be used in a Newton scheme .. math:: (u \\cdot \\nabla) u \\to (u_0 \\cdot \\nabla) u + \ (u \\cdot \\nabla) u_0 - (u_0 \\cdot \\nabla) u_0 or in a Picard scheme .. math:: (u \\cdot \\nabla) u \\to (u_0 \\cdot \\nabla) u Parameters ---------- prev_v : (N,1) ndarray convection velocity V : dolfin.VectorFunctionSpace FEM space of the velocity invinds : (N,) ndarray or list indices of the inner nodes diribcs : list of dolfin Dirichlet boundary conditons Picard : boolean whether Picard linearization is applied, defaults to `False` Returns ------- convc_mat : (N,N) sparse matrix representing the linearized convection at the inner nodes rhs_con : (N,1) array representing :math:`(u_0 \\cdot \\nabla )u_0` at the inner nodes rhsv_conbc : (N,1) ndarray representing the boundary conditions """ N1, N2, rhs_con = dts.get_convmats(u0_vec=prev_v, V=V, invinds=invinds, diribcs=diribcs) if Picard: convc_mat, rhsv_conbc = \ dts.condense_velmatsbybcs(N1, diribcs) return convc_mat, 0 * rhs_con[invinds, ], rhsv_conbc else: convc_mat, rhsv_conbc = \ dts.condense_velmatsbybcs(N1 + N2, diribcs) return convc_mat, rhs_con[invinds, ], rhsv_conbc
def get_v_conv_conts(prev_v=None, V=None, invinds=None, diribcs=None, Picard=False): """ get and condense the linearized convection to be used in a Newton scheme .. math:: (u \\cdot \\nabla) u \\to (u_0 \\cdot \\nabla) u + \ (u \\cdot \\nabla) u_0 - (u_0 \\cdot \\nabla) u_0 or in a Picard scheme .. math:: (u \\cdot \\nabla) u \\to (u_0 \\cdot \\nabla) u Parameters ---------- prev_v : (N,1) ndarray convection velocity V : dolfin.VectorFunctionSpace FEM space of the velocity invinds : (N,) ndarray or list indices of the inner nodes diribcs : list of dolfin Dirichlet boundary conditons Picard : boolean whether Picard linearization is applied, defaults to `False` Returns ------- convc_mat : (N,N) sparse matrix representing the linearized convection at the inner nodes rhs_con : (N,1) array representing :math:`(u_0 \\cdot \\nabla )u_0` at the inner nodes rhsv_conbc : (N,1) ndarray representing the boundary conditions """ N1, N2, rhs_con = dts.get_convmats(u0_vec=prev_v, V=V, invinds=invinds, diribcs=diribcs) if Picard: convc_mat, rhsv_conbc = \ dts.condense_velmatsbybcs(N1, diribcs) return convc_mat, 0*rhs_con[invinds, ], rhsv_conbc else: convc_mat, rhsv_conbc = \ dts.condense_velmatsbybcs(N1 + N2, diribcs) return convc_mat, rhs_con[invinds, ], rhsv_conbc
def test_linearized_mat_NSE_form(self): """check the conversion: dolfin form <-> numpy arrays and the linearizations""" import dolfin_navier_scipy.dolfin_to_sparrays as dts u = self.fenics_sol_u u.t = 1.0 ufun = dolfin.project(u, self.V) uvec = ufun.vector().get_local().reshape(len(ufun.vector()), 1) N1, N2, fv = dts.get_convmats(u0_dolfun=ufun, V=self.V) conv = dts.get_convvec(u0_dolfun=ufun, V=self.V) self.assertTrue(np.allclose(conv, N1 * uvec)) self.assertTrue(np.allclose(conv, N2 * uvec))
def test_linearized_mat_NSE_form(self): """check the conversion: dolfin form <-> numpy arrays and the linearizations""" import dolfin_navier_scipy.dolfin_to_sparrays as dts u = self.fenics_sol_u u.t = 1.0 ufun = dolfin.project(u, self.V) uvec = ufun.vector().get_local().reshape(len(ufun.vector()), 1) N1, N2, fv = dts.get_convmats(u0_dolfun=ufun, V=self.V) conv = dts.get_convvec(u0_dolfun=ufun, V=self.V) self.assertTrue(np.allclose(conv, N1 * uvec)) self.assertTrue(np.allclose(conv, N2 * uvec))
def get_v_conv_conts(prev_v=None, V=None, invinds=None, diribcs=None, dbcvals=None, dbcinds=None, semi_explicit=False, Picard=False, retparts=False, zerodiribcs=False): """ get and condense the linearized convection to be used in a Newton scheme .. math:: (u \\cdot \\nabla) u \\to (u_0 \\cdot \\nabla) u + \ (u \\cdot \\nabla) u_0 - (u_0 \\cdot \\nabla) u_0 or in a Picard scheme .. math:: (u \\cdot \\nabla) u \\to (u_0 \\cdot \\nabla) u Parameters ---------- prev_v : (N,1) ndarray convection velocity V : dolfin.VectorFunctionSpace FEM space of the velocity invinds : (N,) ndarray or list indices of the inner nodes diribcs : list of dolfin Dirichlet boundary conditons Picard : Boolean whether Picard linearization is applied, defaults to `False` semi_explicit: Boolean, optional whether to return minus the convection vector, and zero convmats as needed for semi-explicit integration, defaults to `False` retparts : Boolean, optional whether to return both components of the matrices and contributions to the rhs through the boundary conditions, defaults to `False` Returns ------- convc_mat : (N,N) sparse matrix representing the linearized convection at the inner nodes rhs_con : (N,1) array representing :math:`(u_0 \\cdot \\nabla )u_0` at the inner nodes rhsv_conbc : (N,1) ndarray representing the boundary conditions """ if semi_explicit: rhs_con = dts.get_convvec(V=V, u0_vec=prev_v, diribcs=diribcs, dbcinds=dbcinds, dbcvals=dbcvals, invinds=invinds) return 0., -rhs_con, 0. N1, N2, rhs_con = dts.get_convmats(u0_vec=prev_v, V=V, invinds=invinds, dbcinds=dbcinds, dbcvals=dbcvals, diribcs=diribcs) if zerodiribcs: def _cndnsmts(mat, diribcs, **kw): return mat[invinds, :][:, invinds], np.zeros((invinds.size, 1)) else: _cndnsmts = dts.condense_velmatsbybcs if Picard: convc_mat, rhsv_conbc = _cndnsmts(N1, velbcs=diribcs, dbcinds=dbcinds, dbcvals=dbcvals) # return convc_mat, rhs_con[invinds, ], rhsv_conbc return convc_mat, None, rhsv_conbc elif retparts: picrd_convc_mat, picrd_rhsv_conbc = _cndnsmts(N1, velbcs=diribcs, dbcinds=dbcinds, dbcvals=dbcvals) anti_picrd_convc_mat, anti_picrd_rhsv_conbc = \ _cndnsmts(N2, velbcs=diribcs, dbcinds=dbcinds, dbcvals=dbcvals) return ((picrd_convc_mat, anti_picrd_convc_mat), rhs_con[invinds, ], (picrd_rhsv_conbc, anti_picrd_rhsv_conbc)) else: convc_mat, rhsv_conbc = _cndnsmts(N1+N2, velbcs=diribcs, dbcinds=dbcinds, dbcvals=dbcvals) return convc_mat, rhs_con[invinds, ], rhsv_conbc
def ass_convmat_asmatquad(W=None, invindsw=None): """ assemble the convection matrix H, so that N(v)v = H[v.v] note that the boundary conditions have to be treated properly """ mesh = W.mesh() V = dolfin.FunctionSpace(mesh, 'CG', 2) # this is very specific for V being a 2D VectorFunctionSpace invindsv = invindsw[::2]/2 v = dolfin.TrialFunction(V) vt = dolfin.TestFunction(V) w = dolfin.TrialFunction(W) wt = dolfin.TestFunction(W) def _pad_csrmats_wzerorows(smat, wheretoput='before'): """add zero rows before/after each row """ indpeter = smat.indptr auxindp = np.c_[indpeter, indpeter].flatten() if wheretoput == 'after': smat.indptr = auxindp[1:] else: smat.indptr = auxindp[:-1] smat._shape = (2*smat.shape[0], smat.shape[1]) return smat def _shuff_mrg_csrmats(xm, ym): """shuffle merge csr mats [xxx],[yyy] -> [xyxyxy] """ xm.indices = 2*xm.indices ym.indices = 2*ym.indices + 1 xm._shape = (xm.shape[0], 2*xm.shape[1]) ym._shape = (ym.shape[0], 2*ym.shape[1]) return xm + ym nklist = [] for i in invindsv: # for i in range(V.dim()): # iterate for the columns bi = dolfin.Function(V) bvec = np.zeros((V.dim(), )) bvec[i] = 1 bi.vector()[:] = bvec nxi = dolfin.assemble(v * bi.dx(0) * vt * dx) nyi = dolfin.assemble(v * bi.dx(1) * vt * dx) rows, cols, values = nxi.data() nxim = sps.csr_matrix((values, cols, rows)) rows, cols, values = nyi.data() nyim = sps.csr_matrix((values, cols, rows)) nxyim = _shuff_mrg_csrmats(nxim, nyim) nxyim = nxyim[invindsv, :][:, invindsw] nyxxim = _pad_csrmats_wzerorows(nxyim.copy(), wheretoput='after') nyxyim = _pad_csrmats_wzerorows(nxyim.copy(), wheretoput='before') nklist.extend([nyxxim, nyxyim]) hmat = sps.hstack(nklist, format='csc') xexp = '(1-x[0])*x[0]*(1-x[1])*x[1]*x[0]*0' yexp = '(1-x[0])*x[0]*(1-x[1])*x[1]*x[1]+1' # yexp = 'x[0]*x[0]*x[1]*x[1]' f = dolfin.Expression((xexp, yexp)) u = dolfin.interpolate(f, W) uvec = np.atleast_2d(u.vector().array()).T uvec_gamma = uvec.copy() uvec_gamma[invindsw] = 0 u_gamma = dolfin.Function(W) u_gamma.vector().set_local(uvec_gamma) uvec_i = 0*uvec uvec_i[invindsw, :] = uvec[invindsw] u_i = dolfin.Function(W) u_i.vector().set_local(uvec_i) # Assemble the 'actual' form nform = dolfin.assemble(inner(grad(w) * u, wt) * dx) rows, cols, values = nform.data() nmat = sps.csr_matrix((values, cols, rows)) nmatrc = nmat[invindsw, :][:, :] # nmatrccc = nmatrc[:, :][:, invindsw] # nmatc = nmat[invindsw, :][:, :] N1, N2, fv = dnsts.get_convmats(u0_dolfun=u_gamma, V=W) # print np.linalg.norm(nmatc * uvec[invindsw]) print np.linalg.norm(nmatrc * uvec) print np.linalg.norm(nmatrc * uvec_i + nmatrc * uvec_gamma) print np.linalg.norm(hmat * np.kron(uvec[invindsw], uvec[invindsw]) + ((N1+N2)*uvec_i)[invindsw, :] + fv[invindsw, :]) # print np.linalg.norm((hmat * np.kron(uvec, uvec))[invindsw, :]) # print np.linalg.norm(((N1+N2)*uvec)[invindsw, :] + fv[invindsw, :]) print 'consistency tests' print np.linalg.norm(uvec[invindsw]) - np.linalg.norm(uvec_i) print np.linalg.norm(uvec - uvec_gamma - uvec_i)