Пример #1
0
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
Пример #2
0
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)