Пример #1
0
def test(model, spaceName, dimD, dimR, storage):
    # print("########################################")
    # print("#### ",spaceName,storage,dimD,dimR,flush=True)
    spaceD = create.space(spaceName,
                          grid,
                          dimRange=dimD,
                          order=1,
                          storage=storage)
    spaceR = create.space(spaceName,
                          grid,
                          dimRange=dimR,
                          order=1,
                          storage=storage)
    scheme = create.operator("galerkin", model, spaceD, spaceR)
    uD = create.function("discrete", spaceD, name=storage)
    uD.clear()
    start = time.time()
    for i in range(testLoop):
        A = linearOperator(scheme)  # , parameters={"petsc.blockedmode":False})
    end = time.time()
    # print( "setup+assembly:",(end-start)/testLoop, flush=True )
    start = time.time()
    for i in range(testLoop):
        jacobian(scheme, uD, A)
    end = time.time()
    # print( "assembly only: ",(end-start)/testLoop, flush=True )
    # sys.stdout.flush()

    try:
        import petsc4py
        from petsc4py import PETSc
        mat = A.as_petsc
        # print(mat.getInfo(), flush=True)
    except:
        pass
Пример #2
0
 def __init__(self, scheme):
     self.model = scheme.model
     self.res = scheme.space.interpolate([0],name="residual")
     self.scheme = scheme
     self.jacobian = linearOperator(self.scheme)
     self.snes = PETSc.SNES().create()
     self.snes.setFunction(self.f, self.res.as_petsc.duplicate())
     self.snes.setUseMF(False)
     self.snes.setJacobian(self.Df, self.jacobian.as_petsc, self.jacobian.as_petsc)
     self.snes.getKSP().setType("cg")
     self.snes.setFromOptions()
Пример #3
0
 def __init__(self, scheme):
     self.model = scheme.model
     self.jacobian = linearOperator(scheme)
     self.ksp = PETSc.KSP()
     self.ksp.create(PETSc.COMM_WORLD)
     # use conjugate gradients method
     self.ksp.setType("cg")
     # and incomplete Cholesky
     self.ksp.getPC().setType("icc")
     self.ksp.setOperators(self.jacobian.as_petsc)
     self.ksp.setFromOptions()
Пример #4
0
def test(space):
    if test_numpy:
        numpySpace = create.space(space,
                                  grid,
                                  dimRange=1,
                                  order=1,
                                  storage='numpy')
        numpyScheme = create.scheme("galerkin", model, numpySpace)
        numpy_h = create.function("discrete", numpySpace, name="numpy")
        numpy_dofs = numpy_h.as_numpy
        # numpyScheme.solve(target = numpy_h)
        start = time.time()
        for i in range(testLoop):
            linOp = linearOperator(numpyScheme)
            numpyScheme.jacobian(numpy_h, linOp)
            numpy_mat = linOp.as_numpy
        end = time.time()
        # print( "numpy:", (end-start)/testLoop, flush=True )
        # sys.stdout.flush()
        numpy_coo = numpy_mat.tocoo()
        # for i,j,v in zip(numpy_coo.row,numpy_coo.col,numpy_coo.data):
        #     print(i,j,v)
        # print("****************************",flush=True)

    if test_istl:
        istlSpace = create.space(space,
                                 grid,
                                 dimRange=1,
                                 order=1,
                                 storage='istl')
        istlScheme = create.scheme("galerkin", model, istlSpace)
        istl_h = create.function("discrete", istlSpace, name="istl")
        istl_dofs = istl_h.as_istl
        # istlScheme.solve(target = istl_h)
        start = time.time()
        for i in range(testLoop):
            linOp = linearOperator(istlScheme)
            istlScheme.jacobian(istl_h, linOp)
            istl_mat = linOp.as_istl
        end = time.time()
        # print( "istl:", (end-start)/testLoop, flush=True )
        # sys.stdout.flush()
        # there is no way yet to go from istl to scipy - would be nice to have
        # istl_coo = istl_mat.tocoo()
        # for i,j,v in zip(eigen_coo.row,eigen_coo.col,eigen_coo.data):
        #     print(i,j,v)
        # print("****************************",flush=True)

    if test_petsc:
        import petsc4py
        from petsc4py import PETSc
        petsc4py.init(sys.argv)
        petscSpace = create.space(space,
                                  grid,
                                  dimRange=1,
                                  order=1,
                                  storage='petsc')
        petscScheme = create.scheme("galerkin", model, petscSpace)
        petsc_h = create.function("discrete", petscSpace, name="petsc")
        petsc_dofs = petsc_h.as_petsc
        # petscScheme.solve(target = petsc_h)
        linOp = linearOperator(petscScheme)
        petscScheme.jacobian(petsc_h, linOp)
        petsc_mat = linOp.as_petsc
        rptr, cind, vals = petsc_mat.getValuesCSR()
        petsc_coo = scipy.sparse.csr_matrix((vals, cind, rptr)).tocoo()
        start = time.time()
        for i in range(testLoop):
            linOp = linearOperator(petscScheme)
            petscScheme.jacobian(petsc_h, linOp)
            petsc_mat = linOp.as_petsc
        end = time.time()
        # print( "petsc:", (end-start)/testLoop, flush=True )
        # sys.stdout.flush()

        ksp = PETSc.KSP()
        ksp.create(PETSc.COMM_WORLD)
        ksp.setType("cg")
        # ksp.getPC().setType("icc")
        petsc_h.clear()
        res = petsc_h.copy()
        petscScheme(petsc_h, res)
        petscScheme.jacobian(petsc_h, linOp)
        petsc_mat = linOp.as_petsc
        ksp.setOperators(petsc_mat, petsc_mat)
        ksp.setFromOptions()
        ksp.solve(res.as_petsc, petsc_h.as_petsc)

        # print("****************************",flush=True)
        # print(petsc_mat.size, petsc_mat.getSize(), petsc_mat.getSizes())
        # print(petsc_mat.getType())
        # print(type(petsc_mat))
        # print(petscSpace.size)
        # print(petsc_mat.assembled)
        # rptr, cind, vals = petsc_mat.getValuesCSR()
        # petsc_coo = scipy.sparse.csr_matrix((vals,cind,rptr),shape=(100,100)).tocoo()
        # for i,j,v in zip(petsc_coo.row,petsc_coo.col,petsc_coo.data):
        #     print(i,j,v)

    if test_istl:
        try:  # istl_coo does not exist
            assert (istl_coo.row == numpy_coo.row).all()
            assert (istl_coo.col == numpy_coo.col).all()
            assert np.allclose(istl_coo.data, numpy_coo.data)
        except:
            # print("issue between istl and numpy matrices")
            pass
    if test_petsc:
        try:
            assert (petsc_coo.row == numpy_coo.row).all()
            assert (petsc_coo.col == numpy_coo.col).all()
            assert np.allclose(petsc_coo.data, numpy_coo.data)
        except:
            # print("issue between petsc and numpy matrices")
            pass
Пример #5
0
velocity = spcU.interpolate([
    0,
] * spcU.dimRange, name="velocity")
pressure = spcP.interpolate([0], name="pressure")
rhsVelo = velocity.copy()
rhsPress = pressure.copy()

sol_u = velocity.as_numpy
sol_p = pressure.as_numpy
rhs_u = rhsVelo.as_numpy
rhs_p = rhsPress.as_numpy
r = numpy.copy(rhs_p)
d = numpy.copy(rhs_p)
precon = numpy.copy(rhs_p)
xi = numpy.copy(rhs_u)
A = linearOperator(mainOp).as_numpy
G = linearOperator(gradOp).as_numpy
D = linearOperator(divOp).as_numpy
M = linearOperator(massOp).as_numpy
P = linearOperator(preconOp).as_numpy


def Ainv(rhs, target):
    target[:] = linalg.spsolve(A, rhs)


def Minv(rhs, target):
    target[:] = linalg.spsolve(M, rhs)


def Pinv(rhs, target):
Пример #6
0
 def __init__(self, x_coeff):
     self.shape = (x_coeff.shape[0], x_coeff.shape[0])
     self.dtype = x_coeff.dtype
     x = space.function("tmp", dofVector=x_coeff)
     self.jacobian = linearOperator(scheme, ubar=x)
Пример #7
0
 def __init__(self, scheme):
     self.model = scheme.model
     self.jacobian = linearOperator(scheme)
Пример #8
0
def monolithicSolve(schemes,
                    targets,
                    callback=None,
                    iter=10,
                    f_tol=1e-8,
                    eps=1e-6,
                    verbose=0):
    """Helper function to solve bulk and interface scheme coupled monolithically.
       A newton method based on scipy.
       The coupling jacobian blocks are evalutaed by finite difference on demand.
       The Schur complement is used for the inversion of the block-wise jacobian.

    Args:
        schemes:  pair of schemes
        targets:  pair of discrete functions that should be solved for AND that are used in the coupling forms
        callback: update function that is called every time before solving a scheme
        iter:     maximum number of iterations
        f_tol:    objective residual two norm
        eps:      step size for finite difference
        verbose:  1: print residuum for each iteration, 2: and for each Schur iteration

    Returns:
        if converged
    """
    assert len(schemes) == 2
    assert len(targets) == 2

    (scheme, ischeme) = schemes
    (uh, th) = targets

    n = len(uh.as_numpy)
    m = len(th.as_numpy)

    if m == 0:
        if verbose:
            print("second scheme is empty, forward to scheme.solve()",
                  flush=True)
        scheme.solve(target=uh)
        return

    from dune.fem.operator import linear as linearOperator
    A = linearOperator(scheme)
    D = linearOperator(ischeme)

    def updateJacobians():
        scheme.jacobian(uh, A)
        ischeme.jacobian(th, D)

    def call():
        if callback is not None:
            callback()

    # Evaluate the coupling blocks by finite difference on-demand
    Bz = uh.copy()

    def B(z):
        norm = np.sqrt(z.dot(z))
        if norm == 0:
            return np.zeros(n)
        th.as_numpy[:] += z * eps / norm
        call()
        scheme(uh, Bz)
        th.as_numpy[:] -= z * eps / norm
        Bz.as_numpy[:] -= f.as_numpy
        Bz.as_numpy[:] /= eps
        return Bz.as_numpy * norm

    Cz = th.copy()

    def C(z):
        norm = np.sqrt(z.dot(z))
        if norm == 0:
            return np.zeros(m)
        uh.as_numpy[:] += z * eps / norm
        call()
        ischeme(th, Cz)
        uh.as_numpy[:] -= z * eps / norm
        Cz.as_numpy[:] -= g.as_numpy
        Cz.as_numpy[:] /= eps
        return Cz.as_numpy * norm

    # Evaluate
    f = uh.copy()
    g = th.copy()

    call()
    scheme(uh, f)
    ischeme(th, g)

    i = 0

    def checkResiduum():
        a = f.as_numpy
        b = g.as_numpy
        res = np.sqrt(np.dot(a, a) + np.dot(b, b))

        if verbose > 0:
            print(" i:", i, " | f | =", res)

        if res < f_tol:
            return True

    if checkResiduum():
        return True

    from scipy.sparse.linalg import LinearOperator, spsolve, lgmres

    for i in range(1, iter):

        updateJacobians()

        def eval(x):
            return

        S = LinearOperator((n + m, n + m), lambda x: np.concatenate(
            (A.as_numpy.dot(x[:n]) + B(x[n:]), C(x[:n]) + D.as_numpy.dot(x[n:])
             )))
        M = LinearOperator((n + m, n + m), lambda x: np.concatenate(
            (spsolve(A.as_numpy, x[:n]), spsolve(D.as_numpy, x[n:]))))

        r = np.concatenate((f.as_numpy, g.as_numpy))
        x0 = np.concatenate((uh.as_numpy, th.as_numpy))

        x, _ = lgmres(S, r, x0=x0, M=M, tol=f_tol)

        uh.as_numpy[:] -= x[:n]
        th.as_numpy[:] -= x[n:]

        call()
        scheme(uh, f)
        ischeme(th, g)

        if checkResiduum():
            return True

    return False
Пример #9
0
gradOp      = galerkinOperator(gradModel)
divOp       = galerkinOperator(divModel)
massOp      = galerkinScheme(massModel==0)
preconOp    = galerkinScheme(preconModel==0)

velocity = spcU.interpolate([0,]*spcU.dimRange, name="velocity")
pressure = spcP.interpolate([0], name="pressure")
rhsVelo  = velocity.copy()
rhsPress = pressure.copy()

r      = rhsPress.copy()
d      = rhsPress.copy()
precon = rhsPress.copy()
xi     = rhsVelo.copy()

A = linearOperator(mainOp)
G = linearOperator(gradOp)
D = linearOperator(divOp)
M = linearOperator(massOp)
P = linearOperator(preconOp)

# Note issue with using 'cg' due to
# (a) missing mainOp.setConstraints(velocity)
# (b) no bc for pressure preconder....
solver = {"method":"cg","tolerance":1e-10, "verbose":False}
Ainv   = mainOp.inverseLinearOperator(A,parameters=solver)
Minv   = massOp.inverseLinearOperator(M,parameters=solver)
Pinv   = preconOp.inverseLinearOperator(P,solver)

mainOp(velocity,rhsVelo)
rhsVelo *= -1
Пример #10
0
a = (inner((u) / dt, v) + inner(u, v)) * dx
exact = as_vector([
    exp(-2 * t) * (initial - 1) + 1,
] * dimR)
b = replace(a, {u: exact})

solverParam = {"newton.verbose": 0, "newton.linear.verbose": 0}
scheme = create.scheme("galerkin",
                       a == b,
                       space,
                       solver='cg',
                       parameters=solverParam)
scheme.setQuadratureOrders(quadOrder, quadOrder)

scheme.model.dt = 0.05

grid.writeVTK('initial', pointdata={'initial': initial})

start = time.time()
t = 0
A = linearOperator(scheme)
while t < 1.0:
    scheme.model.t = t
    u_h_n.assign(u_h)
    scheme.solve(target=u_h)
    scheme.jacobian(u_h_n, A)
    t += scheme.model.dt
print("time loop:", time.time() - start)

grid.writeVTK('forchheimer', pointdata=[u_h])
Пример #11
0
    0,
] * dimR), name='destD')
destE = space.interpolate(as_vector([
    0,
] * dimR), name='destE')

u = TrialFunction(space)
v = TestFunction(space)
x = SpatialCoordinate(space.cell())

ubar = space.interpolate(as_vector([
    dot(x, x),
] * dimR), name="ubar")
a = (inner(0.5 * dot(u, u), v[0]) + inner(u[0] * grad(u), grad(v))) * dx
op = create.operator("galerkin", a, space)
A = linearOperator(op)
op.jacobian(ubar, A)
A(arg, destA)

da = apply_derivatives(derivative(action(a, ubar), ubar, u))
dop = create.operator("galerkin", da, space)
dop(arg, destB)
err = integrate(grid, (destA - destB)**2, 5)
# print("error=",err)
assert (err < 1e-15)

A = linearOperator(dop)
dop.jacobian(arg, A)
A(arg, destC)
err = integrate(grid, (destA - destC)**2, 5)
# print("error=",err)