def burgers_spacedisc(N=10, nu=None, x0=0.0, xE=1.0, retfemdict=False,
                      condensemats=True):

    mesh = dolfin.IntervalMesh(N, x0, xE)
    V = dolfin.FunctionSpace(mesh, 'CG', 1)

    u = dolfin.TrialFunction(V)
    v = dolfin.TestFunction(V)

    # boundaries and conditions
    ugamma = dolfin.Expression('0', degree=1)

    def _spaceboundary(x, on_boundary):
        return on_boundary
    diribc = dolfin.DirichletBC(V, ugamma, _spaceboundary)

    mass = assemble(v*u*dx)
    stif = assemble(nu*inner(nabla_grad(v), nabla_grad(u))*dx)

    M = dts.mat_dolfin2sparse(mass)
    A = dts.mat_dolfin2sparse(stif)

    M, _, bcdict = dts.condense_velmatsbybcs(M, [diribc], return_bcinfo=True)
    ininds = bcdict['ininds']
    A, rhsa = dts.condense_velmatsbybcs(A, [diribc])

    def burger_nonl(vvec, t):
        v0 = expandvfunc(vvec, V=V, ininds=ininds)
        bnl = assemble(0.5*v*((v0*v0).dx(0))*dx)
        return bnl.array()[ininds]

    if retfemdict:
        return M, A, rhsa, burger_nonl, dict(V=V, diribc=diribc, ininds=ininds)
    else:
        return M, A, rhsa, burger_nonl
def get_burgertensor_spacecomp(V=None, podmat=None, ininds=None, diribc=None,
                               Ukyleft=None, bwd=False,
                               **kwargs):

    if not podmat.shape[0] == len(ininds):
        raise Warning("Looks like this is not the right POD basis")
    if Ukyleft is None:
        Ukyleft = podmat

    v = dolfin.TestFunction(V)
    u = dolfin.TrialFunction(V)

    if bwd:
        uvvdxl = []
        for ui in podmat.T:
            hatui = expandvfunc(ui, V=V, ininds=ininds)
            uivvdx = assemble(hatui*v*((u).dx(0))*dx)
            Uivvdx = dts.mat_dolfin2sparse(uivvdx)
            Uivvdx, _ = dts.condense_velmatsbybcs(Uivvdx, [diribc])
            uvvdxl.append(np.dot(Ukyleft.T, Uivvdx*podmat))
    else:
        uvvdxl = []
        for ui in podmat.T:
            hatui = expandvfunc(ui, V=V, ininds=ininds)
            uivvdx = assemble(0.5*hatui*((v*u).dx(0))*dx)
            Uivvdx = dts.mat_dolfin2sparse(uivvdx)
            Uivvdx, _ = dts.condense_velmatsbybcs(Uivvdx, [diribc])
            uvvdxl.append(np.dot(Ukyleft.T, Uivvdx*podmat))
    return uvvdxl
示例#3
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
示例#4
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
示例#5
0
def get_sysmats(problem='drivencavity', N=10, scheme=None, ppin=None,
                Re=None, nu=None, bccontrol=False, mergerhs=False,
                onlymesh=False):
    """ retrieve the system matrices for stokes flow

    Parameters
    ----------
    problem : {'drivencavity', 'cylinderwake'}
        problem class
    N : int
        mesh parameter
    nu : real, optional
        kinematic viscosity, is set to `L/Re` if `Re` is provided
    Re : real, optional
        Reynoldsnumber, is set to `L/nu` if `nu` is provided
    bccontrol : boolean, optional
        whether to consider boundary control via penalized Robin \
        defaults to `False`
    mergerhs : boolean, optional
        whether to merge the actual rhs and the contribution from the \
        boundary conditions into one rhs, defaults to `False`
    onlymesh : boolean, optional
        whether to only return `femp`, containing the mesh and FEM spaces, \
        defaults to `False`

    Returns
    -------
    femp : dict
        with the keys:
         * `V`: FEM space of the velocity
         * `Q`: FEM space of the pressure
         * `diribcs`: list of the (Dirichlet) boundary conditions
         * `bcinds`: indices of the boundary nodes
         * `bcvals`: values of the boundary nodes
         * `invinds`: indices of the inner nodes
         * `fv`: right hand side of the momentum equation
         * `fp`: right hand side of the continuity equation
         * `charlen`: characteristic length of the setup
         * `nu`: the kinematic viscosity
         * `Re`: the Reynolds number
         * `odcoo`: dictionary with the coordinates of the domain of \
                 observation
         * `cdcoo`: dictionary with the coordinates of the domain of \
         * `ppin` : {int, None}
                which dof of `p` is used to pin the pressure, typically \
                `-1` for internal flows, and `None` for flows with outflow
                         control
    stokesmatsc : dict
        a dictionary of the condensed matrices:
         * `M`: the mass matrix of the velocity space,
         * `MP`: the mass matrix of the pressure space,
         * `A`: the stiffness matrix,
         * `JT`: the gradient matrix, and
         * `J`: the divergence matrix
         * `Jfull`: the uncondensed divergence matrix
        and, if `bccontrol=True`, the boundary control matrices that weakly \
        impose `Arob*v = Brob*u`, where
         * `Arob`: contribution to `A`
         * `Brob`: input operator
    `if mergerhs`
    rhsd : dict
        `rhsd_vfrc` and `rhsd_stbc` merged
    `else`
    rhsd_vfrc : dict
        of the dirichlet and pressure fix reduced right hand sides
    rhsd_stbc : dict
        of the contributions of the boundary data to the rhs:
         * `fv`: contribution to momentum equation,
         * `fp`: contribution to continuity equation


    Examples
    --------
    femp, stokesmatsc, rhsd_vfrc, rhsd_stbc \
        = get_sysmats(problem='drivencavity', N=10, nu=1e-2)

    """

    problemdict = dict(drivencavity=drivcav_fems,
                       cylinderwake=cyl_fems)
    problemfem = problemdict[problem]
    femp = problemfem(N, scheme=scheme, bccontrol=bccontrol)
    if onlymesh:
        return femp

    # setting some parameters
    if Re is not None:
        nu = femp['charlen']/Re
    else:
        Re = femp['charlen']/nu

    if bccontrol:
        cbclist = femp['contrbcssubdomains']
        cbshapefuns = femp['contrbcsshapefuns']
    else:
        cbclist, cbshapefuns = None, None

    stokesmats = dts.get_stokessysmats(femp['V'], femp['Q'], nu,
                                       cbclist=cbclist,
                                       cbshapefuns=cbshapefuns,
                                       bccontrol=bccontrol)

    rhsd_vf = dts.setget_rhs(femp['V'], femp['Q'],
                             femp['fv'], femp['fp'], t=0)

    # remove the freedom in the pressure if required
    if problem == 'cylinderwake':
        print('cylinderwake: pressure need not be pinned')
        if ppin is not None:
            raise UserWarning('pinning the p will give wrong results')
    elif ppin is None:
        print('pressure is not pinned - `J` may be singular for internal flow')
    elif ppin == -1:
        stokesmats['J'] = stokesmats['J'][:-1, :][:, :]
        stokesmats['JT'] = stokesmats['JT'][:, :-1][:, :]
        rhsd_vf['fp'] = rhsd_vf['fp'][:-1, :]
        print('pressure pinned at last dof `-1`')
    else:
        raise NotImplementedError('Cannot pin `p` other than at `-1`')

    # reduce the matrices by resolving the BCs
    (stokesmatsc,
     rhsd_stbc,
     invinds,
     bcinds,
     bcvals) = dts.condense_sysmatsbybcs(stokesmats,
                                         femp['diribcs'])
    stokesmatsc.update({'Jfull': stokesmats['J']})

    # pressure freedom and dirichlet reduced rhs
    rhsd_vfrc = dict(fpr=rhsd_vf['fp'], fvc=rhsd_vf['fv'][invinds, ])
    if bccontrol:
        Arob, fvrob = dts.condense_velmatsbybcs(stokesmats['amatrob'],
                                                femp['diribcs'])
        if np.linalg.norm(fvrob) > 1e-15:
            raise UserWarning('diri and control bc must not intersect')

        Brob = stokesmats['bmatrob'][invinds, :]
        stokesmatsc.update({'Brob': Brob, 'Arob': Arob})

    # add the info on boundary and inner nodes
    bcdata = {'bcinds': bcinds,
              'bcvals': bcvals,
              'invinds': invinds,
              'ppin': ppin}
    femp.update(bcdata)
    femp.update({'nu': nu})
    femp.update({'Re': Re})

    if mergerhs:
        rhsd = dict(fv=rhsd_vfrc['fvc']+rhsd_stbc['fv'],
                    fp=rhsd_vfrc['fpr']+rhsd_stbc['fp'])
        return femp, stokesmatsc, rhsd
    else:
        return femp, stokesmatsc, rhsd_vfrc, rhsd_stbc
示例#6
0
def get_sysmats(problem='drivencavity', N=10, scheme=None, ppin=None,
                Re=None, nu=None, bccontrol=False, mergerhs=False,
                onlymesh=False):
    """ retrieve the system matrices for stokes flow

    Parameters
    ----------
    problem : {'drivencavity', 'cylinderwake'}
        problem class
    N : int
        mesh parameter
    nu : real, optional
        kinematic viscosity, is set to `L/Re` if `Re` is provided
    Re : real, optional
        Reynoldsnumber, is set to `L/nu` if `nu` is provided
    bccontrol : boolean, optional
        whether to consider boundary control via penalized Robin \
        defaults to `False`
    mergerhs : boolean, optional
        whether to merge the actual rhs and the contribution from the \
        boundary conditions into one rhs
    onlymesh : boolean, optional
        whether to only return `femp`, containing the mesh and FEM spaces, \
        defaults to `False`

    Returns
    -------
    femp : dict
        with the keys:
         * `V`: FEM space of the velocity
         * `Q`: FEM space of the pressure
         * `diribcs`: list of the (Dirichlet) boundary conditions
         * `bcinds`: indices of the boundary nodes
         * `bcvals`: values of the boundary nodes
         * `invinds`: indices of the inner nodes
         * `fv`: right hand side of the momentum equation
         * `fp`: right hand side of the continuity equation
         * `charlen`: characteristic length of the setup
         * `nu`: the kinematic viscosity
         * `Re`: the Reynolds number
         * `odcoo`: dictionary with the coordinates of the domain of \
                 observation
         * `cdcoo`: dictionary with the coordinates of the domain of \
         * `ppin` : {int, None}
                which dof of `p` is used to pin the pressure, typically \
                `-1` for internal flows, and `None` for flows with outflow
                         control
    stokesmatsc : dict
        a dictionary of the condensed matrices:
         * `M`: the mass matrix of the velocity space,
         * `A`: the stiffness matrix,
         * `JT`: the gradient matrix, and
         * `J`: the divergence matrix
         * `Jfull`: the uncondensed divergence matrix
        and, if `bccontrol=True`, the boundary control matrices that weakly \
        impose `Arob*v = Brob*u`, where
         * `Arob`: contribution to `A`
         * `Brob`: input operator
    `if mergerhs`
    rhsd : dict
        `rhsd_vfrc` and `rhsd_stbc` merged
    `else`
    rhsd_vfrc : dict
        of the dirichlet and pressure fix reduced right hand sides
    rhsd_stbc : dict
        of the contributions of the boundary data to the rhs:
         * `fv`: contribution to momentum equation,
         * `fp`: contribution to continuity equation


    Examples
    --------
    femp, stokesmatsc, rhsd_vfrc, rhsd_stbc \
        = get_sysmats(problem='drivencavity', N=10, nu=1e-2)

    """

    problemdict = dict(drivencavity=drivcav_fems,
                       cylinderwake=cyl_fems)
    problemfem = problemdict[problem]
    femp = problemfem(N, scheme=scheme, bccontrol=bccontrol)
    if onlymesh:
        return femp

    # setting some parameters
    if Re is not None:
        nu = femp['charlen']/Re
    else:
        Re = femp['charlen']/nu

    if bccontrol:
        cbclist = femp['contrbcssubdomains']
        cbshapefuns = femp['contrbcsshapefuns']
    else:
        cbclist, cbshapefuns = None, None

    stokesmats = dts.get_stokessysmats(femp['V'], femp['Q'], nu,
                                       cbclist=cbclist,
                                       cbshapefuns=cbshapefuns,
                                       bccontrol=bccontrol)

    rhsd_vf = dts.setget_rhs(femp['V'], femp['Q'],
                             femp['fv'], femp['fp'], t=0)

    # remove the freedom in the pressure if required
    if problem == 'cylinderwake':
        print 'cylinderwake: pressure need not be pinned'
        if ppin is not None:
            raise UserWarning('pinning the p will give wrong results')
    elif ppin is None:
        print 'pressure is not pinned - `J` may be singular for internal flow'
    elif ppin == -1:
        stokesmats['J'] = stokesmats['J'][:-1, :][:, :]
        stokesmats['JT'] = stokesmats['JT'][:, :-1][:, :]
        rhsd_vf['fp'] = rhsd_vf['fp'][:-1, :]
        print 'pressure pinned at last dof `-1`'
    else:
        raise NotImplementedError('Cannot pin `p` other than at `-1`')

    # reduce the matrices by resolving the BCs
    (stokesmatsc,
     rhsd_stbc,
     invinds,
     bcinds,
     bcvals) = dts.condense_sysmatsbybcs(stokesmats,
                                         femp['diribcs'])
    stokesmatsc.update({'Jfull': stokesmats['J']})

    # pressure freedom and dirichlet reduced rhs
    rhsd_vfrc = dict(fpr=rhsd_vf['fp'], fvc=rhsd_vf['fv'][invinds, ])
    if bccontrol:
        Arob, fvrob = dts.condense_velmatsbybcs(stokesmats['amatrob'],
                                                femp['diribcs'])
        if np.linalg.norm(fvrob) > 1e-15:
            raise UserWarning('diri and control bc must not intersect')

        Brob = stokesmats['bmatrob'][invinds, :]
        stokesmatsc.update({'Brob': Brob, 'Arob': Arob})

    # add the info on boundary and inner nodes
    bcdata = {'bcinds': bcinds,
              'bcvals': bcvals,
              'invinds': invinds,
              'ppin': ppin}
    femp.update(bcdata)
    femp.update({'nu': nu})
    femp.update({'Re': Re})

    if mergerhs:
        rhsd = dict(fv=rhsd_vfrc['fvc']+rhsd_stbc['fv'],
                    fp=rhsd_vfrc['fpr']+rhsd_stbc['fp'])
        return femp, stokesmatsc, rhsd
    else:
        return femp, stokesmatsc, rhsd_vfrc, rhsd_stbc
 def vdxop(vvec):
     v0 = expandvfunc(vvec, V=V, ininds=ininds)
     bnl = assemble((v*v0*u.dx(0))*dx)
     Bnl = dts.mat_dolfin2sparse(bnl)
     Bnl, rhsa = dts.condense_velmatsbybcs(Bnl, [diribc])
     return Bnl