示例#1
0
文件: pcg.py 项目: SpuqTeam/spuq
def pcg(A, f, P, w0, eps=1e-4, maxiter=100):
    # for most quantities in PCG (except zeta) only the most recent 
    # values needs to be kept in memory
    w = ForgetfulVector(1)
    rho = ForgetfulVector(1)
    s = ForgetfulVector(1)
    v = ForgetfulVector(1)
    z = ForgetfulVector(1)
    alpha = ForgetfulVector(1)
    zeta = ForgetfulVector(2)

    w[0] = w0
    rho[0] = f - A * w[0]
    s[0] = P * rho[0]
    v[0] = s[0]
    zeta[0] = inner(rho[0], s[0])
    for i in xrange(1, maxiter):
        logger.info("pcg iter: %s -> zeta=%s, rho^2=%s" % (i, zeta[i - 1], inner(rho[i - 1], rho[i - 1])))
        if zeta[i - 1] < 0:
            for mu in rho[i - 1].active_indices():
                print i, mu, inner(rho[i - 1][mu], s[i - 1][mu])
            raise Exception("Preconditioner for PCG is not positive definite (%s)" % zeta[i - 1])
        if zeta[i - 1] <= eps ** 2:
            return (w[i - 1], zeta[i - 1], i)

        z[i - 1] = A * v[i - 1]
        alpha[i - 1] = inner(z[i - 1], v[i - 1])
        if alpha[i - 1] == 0:
            raise Exception("Matrix for PCG is singular (%s)" % alpha[i - 1])
        elif alpha[i - 1] < 0:
            raise Exception("Matrix for PCG is not positive definite (%s)" % alpha[i - 1])

        w[i] = w[i - 1] + zeta[i - 1] / alpha[i - 1] * v[i - 1]
        rho[i] = rho[i - 1] - zeta[i - 1] / alpha[i - 1] * z[i - 1]
        s[i] = P * rho[i]
        zeta[i] = inner(rho[i], s[i])
        v[i] = s[i] + zeta[i] / zeta[i - 1] * v[i - 1]

    raise Exception("PCG did not converge")
示例#2
0
#coeff_field = CoefficientField(a, rvs)
a0 = Constant("1.0")
a = (Expression('A*cos(pi*I*x[0])*cos(pi*I*x[1])', A=1 / i ** 2, I=i, degree=2) for i in count(1))
rvs = (UniformRV() for _ in count())
coeff_field = ParametricCoefficientField(func_func=a, rv_func=rvs, mean_func=a0)

pde = FEMPoisson()
A = MultiOperator(coeff_field, pde.assemble_operator)
mis = [Multiindex([0]),
       Multiindex([1]),
       Multiindex([0, 1]),
       Multiindex([0, 2])]
mesh = UnitSquare(4, 4)
fs = FunctionSpace(mesh, "CG", 1)
F = [interpolate(Expression("*".join(["x[0]"] * i)), fs) for i in range(1, 5)]
vecs = [FEniCSVector(f) for f in F]

w = MultiVectorWithProjection()
for mi, vec in zip(mis, vecs):
    w[mi] = vec
v = A * w
#P = MultiplicationOperator(1, vecs[0].basis)
P = PreconditioningOperator(a0, pde.assemble_solve_operator)
w2, zeta, numit = pcg(A, v, P, 0 * v)

print
print zeta, numit
print inner(w - w2, w - w2) / inner(w, w)
v2 = A * w2
print inner(v - v2, v - v2) / inner(v, v)
示例#3
0
 def __inner__(self, other):
     assert isinstance(other, MultiVector)
     s = 0.0
     for mi in self.keys():
         s += inner(self[mi], other[mi])
     return s
示例#4
0
def norm(v):
    return math.sqrt(inner(v, v))