def NSMatrixSetup(P, FS, A, nu, iter, Type): if Type['precond'] == 'PCD': u = TrialFunction(FS['Velocity']) v = TestFunction(FS['Velocity']) p = TrialFunction(FS['Pressure']) q = TestFunction(FS['Pressure']) IS = common.IndexSet([FS['Velocity']]) mesh = FS['Velocity'].mesh() n = FacetNormal(mesh) if iter == 1: if FS['Pressure'].ufl_element().degree( ) == 0 or FS['Pressure'].ufl_element().family() == 'DG': PrintFuncs.Errors( 'Navier-Stokes PCD preconditioner not implemented for DG pressure elements' ) P['L'] = PETScFunc.Assemble( assemble(nu * inner(grad(p), grad(q)) * dx)) P['M'] = PETScFunc.Assemble(assemble((1. / nu) * inner(p, q) * dx)) P['Fp'] = PETScFunc.Assemble( assemble(nu * inner(grad(q), grad(p)) * dx(mesh) + inner((Type['u_k'][0] * grad(p)[0] + Type['u_k'][1] * grad(p)[1]), q) * dx(mesh) + (1. / 2) * div(Type['u_k']) * inner(p, q) * dx(mesh) - (1. / 2) * (Type['u_k'][0] * n[0] + Type['u_k'][1] * n[1]) * inner(p, q) * ds(mesh))) P['F'] = A.getSubMatrix(IS[0], IS[0]) elif Type['precond'] == 'LSC': u = TrialFunction(FS['Velocity']) v = TestFunction(FS['Velocity']) IS = common.IndexSet(FS) if iter == 1: Qdiag = PETScFunc.Assemble(assemble(inner(u, v) * dx)).getDiagonal() Bt = A.getSubMatrix(IS['Velocity'], IS['Pressure']) B = A.getSubMatrix(IS['Pressure'], IS['Velocity']) Bt.diagonalScale(Qdiag) P['scaledBt'] = Bt P['L'] = B * Bt P['F'] = A.getSubMatrix(IS['Velocity'], IS['Velocity']) else: PrintFuncs.Errors('Navier-Stokes preconditioner has to be LSC or PCD') P['precond'] = Type['precond'] return P
def PETScToNLiter(x,FS): n = len(FS) IS = common.IndexSet(FS) u = {} for i in range(n): v = Function(FS.values()[i]) v.vector()[:] = x.getSubVector(IS.values()[i]).array if FS.keys()[i] == 'Pressure': ones = Function(FS['Pressure']) ones.vector()[:] = 1 vv = Function(FS['Pressure']) vv.vector()[:] = v.vector().array() - assemble(v*dx)/assemble(ones*dx) u[FS.keys()[i]] = vv else: u[FS.keys()[i]] = v return u
def NLtol(x, u, FS, Type=None): IS = common.IndexSet(FS) if Type == 'Update': v = x.getSubVector(IS['Velocity']).array p = x.getSubVector(IS['Pressure']).array pa = Function(FS['Pressure']) pa.vector()[:] = p ones = Function(FS['Pressure']) ones.vector()[:] = (0 * p + 1) pp = Function(FS['Pressure']) pp.vector( )[:] = pa.vector().array() - assemble(pa * dx) / assemble(ones * dx) vnorm = norm(v) pnorm = norm(pp.vector().array()) V = [vnorm, pnorm] eps = PrintFuncs.NormPrint(V, Type) x.axpy(1.0, u) return x, eps else: vcurrent = x.getSubVector(IS['Velocity']).array pcurrent = x.getSubVector(IS['Pressure']).array vprev = u.getSubVector(IS['Velocity']).array pprev = u.getSubVector(IS['Pressure']).array pa = Function(FS['Pressure']) pa.vector()[:] = pcurrent ones = Function(FS['Pressure']) ones.vector()[:] = (0 * pcurrent + 1) pp = Function(FS['Pressure']) pp.vector( )[:] = pa.vector().array() - assemble(pa * dx) / assemble(ones * dx) vnorm = norm(vcurrent - vprev) pnorm = norm(pp.vector().array() - pprev) V = [vnorm, pnorm] eps = PrintFuncs.NormPrint(V, Type) return x, eps
def __init__(self, W, KSP): self.W = W self.IS = common.IndexSet(W) self.KSP = KSP