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
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()
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()
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
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):
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)
def __init__(self, scheme): self.model = scheme.model self.jacobian = linearOperator(scheme)
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
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
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])
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)