Beispiel #1
0
def getMinMax(vals, fmin=None, fmax=None):
    funcmin, funcmax = ngs.Vector(vals, copy=False).MinMax(True)
    if fmin is not None:
        funcmin = min(funcmin, fmin)
    if fmax is not None:
        funcmax = max(funcmax, fmax)
    return funcmin, funcmax
Beispiel #2
0
 def calcSolution(k):
     mat = ngsolve.Matrix(k + 1, k + 1, is_complex)
     for i in range(k + 1):
         mat[:, i] = H[i][:k + 1]
     rs = ngsolve.Vector(k + 1, is_complex)
     rs[:] = beta[:k + 1]
     y = mat.I * rs
     if xstart:
         x.data = xstart
     for i in range(k + 1):
         x.data += y[i] * Q[i]
Beispiel #3
0
def updatePMinMax(pmat, pmima=None):
    pmima_new = [
        ngs.Vector(pmat[:, i], copy=False).MinMax(ignore_inf=True)
        for i in range(3)
    ]

    if pmima is not None:
        for i in range(3):
            minmax = (min(pmima[i][0],
                          pmima_new[i][0]), max(pmima[i][1], pmima_new[i][1]))
            pmima_new[i] = minmax

    return pmima_new
Beispiel #4
0
 def arnoldi(A, Q, k):
     q = b.CreateVector()
     tmp.data = A * Q[k]
     q.data = pre * tmp
     h = ngsolve.Vector(m + 1, is_complex)
     h[:] = 0
     for i in range(k + 1):
         h[i] = innerproduct(Q[i], q)
         q.data += (-1) * h[i] * Q[i]
     h[k + 1] = norm(q)
     if abs(h[k + 1]) < 1e-12:
         return h, None
     q *= 1. / h[k + 1].real
     return h, q
Beispiel #5
0
def getParameters():
    from headless import _headless
    if _headless:
        settings = RenderingSettings()
        settings.initGL()
    else:
        from ngsgui.gui import gui
        settings = ngsgui.gui.gui.getCurrentGLWindow().glWidget._settings
    settings.setColormapMin(-0.3)
    settings.setColormapMax(1.0)
    settings.min = ngs.Vector([0, 0, 0])
    settings.max = ngs.Vector([1, 1, 1])
    settings.rotateCamera(-30, 30)
    settings.zoom = -50
    settings.dx = -0.2
    settings.dy = 0.1
    settings.setLightAmbient(0.5)
    settings.setLightDiffuse(0.5)
    settings.setShowCross(False)
    settings.setShowVersion(False)
    settings.setShowColorbar(False)
    settings.setOrder(3)
    settings.setSubdivision(3)
    return settings
Beispiel #6
0
import ngsolve as ng
import numpy as np

W1r = ng.Matrix(3, 1)
W1z = ng.Matrix(3, 1)
b1 = ng.Vector(3)

W2 = ng.Matrix(1, 3)
b2 = ng.Vector(1)

r = ng.x
z = ng.y


def sigmoid(x):
    for i in range(0, len(x)):
        x[i] = 1 / (1 + np.exp(-x[i]))


sigmoid(W1r * r + W1z * z + b1)
Beispiel #7
0
def BuildRenderData(mesh,
                    func,
                    order=2,
                    draw_surf=True,
                    draw_vol=True,
                    deformation=None,
                    region=True,
                    objects=[]):
    timer.Start()

    if isinstance(deformation,
                  ngs.CoefficientFunction) and deformation.dim == 2:
        deformation = ngs.CoefficientFunction((deformation, 0.0))

    #TODO: handle quads and non-smooth functions
    #TODO: subdivision

    d = {}
    d['ngsolve_version'] = ngs.__version__
    d['mesh_dim'] = mesh.dim
    # order = order or mesh.GetCurveOrder()
    if (not func) and (mesh.GetCurveOrder() == 1) and (mesh.nv == len(
            mesh.ngmesh.Points())):
        order = 1
    order2d = min(order, 3)
    order3d = min(order, 2)
    d['order2d'] = order2d
    d['order3d'] = order3d

    d['draw_vol'] = func and mesh.dim == 3 and draw_vol and mesh.ne > 0
    d['draw_surf'] = func and draw_surf

    d['objects'] = []
    for obj in objects:
        if isinstance(obj, dict):
            d['objects'].append(obj)
        else:
            d['objects'].append(obj._GetWebguiData())

    if isinstance(deformation, bool):
        d['deformation'] = deformation
        deformation = None

    func0 = None
    func2 = None
    if func and func.is_complex:
        d['is_complex'] = True
        func1 = func[0].real
        func2 = ngs.CoefficientFunction((func[0].imag, 0.0))
        d['funcdim'] = 2
    elif func and func.dim > 1:
        func1 = func[0]
        func2 = ngs.CoefficientFunction(
            tuple(func[i] if i < func.dim else 0.0
                  for i in range(1, 3)))  # max 3-dimensional functions
        d['funcdim'] = func.dim
    elif func:
        func1 = func
        d['funcdim'] = 1
    else:
        # no function at all -> we are just drawing a mesh, eval mesh element index instead
        mats = mesh.GetMaterials()
        bnds = mesh.GetBoundaries()
        bbnds = mesh.GetBBoundaries()
        nmats = len(mesh.GetMaterials())
        nbnds = len(mesh.GetBoundaries())
        n = max(nmats, nbnds, len(bbnds))
        func1 = ngs.CoefficientFunction(list(range(n)))
        n_regions = [0, 0, nmats, nbnds]
        d['mesh_regions_2d'] = n_regions[mesh.dim]
        d['mesh_regions_3d'] = nmats if mesh.dim == 3 else 0
        d['names'] = bnds if mesh.dim == 3 else mats
        d['edge_names'] = bbnds if mesh.dim == 3 else bnds
        d['funcdim'] = 0
        func0 = func1

    if func0 is None:
        func0 = ngs.CoefficientFunction(0.0)

    func1 = ngs.CoefficientFunction((ngs.x, ngs.y, ngs.z, func1))
    func0 = ngs.CoefficientFunction((ngs.x, ngs.y, ngs.z, func0))

    if deformation is not None:
        func1 += ngs.CoefficientFunction((deformation, 0.0))
        func0 += ngs.CoefficientFunction((deformation, 0.0))

    d['show_wireframe'] = False
    d['show_mesh'] = False
    if order2d > 0:
        og = order2d
        d['show_wireframe'] = True
        d['show_mesh'] = True
        timer2.Start()

        timer3Bvals.Start()

        # transform point-values to Bernsteinbasis
        def Binomial(n, i):
            return math.factorial(n) / math.factorial(i) / math.factorial(n -
                                                                          i)

        def Bernstein(x, i, n):
            return Binomial(n, i) * x**i * (1 - x)**(n - i)

        Bvals = ngs.Matrix(og + 1, og + 1)
        for i in range(og + 1):
            for j in range(og + 1):
                Bvals[i, j] = Bernstein(i / og, j, og)
        iBvals = Bvals.I
        timer3Bvals.Stop()
        # print (Bvals)
        # print (iBvals)

        Bezier_points = []

        # TODO: Quads
        ipts = [(i / og, 0) for i in range(og + 1)] + [
            (0, i / og) for i in range(og + 1)
        ] + [(i / og, 1.0 - i / og) for i in range(og + 1)]
        ir_trig = ngs.IntegrationRule(ipts, [
            0,
        ] * len(ipts))
        ipts = [(i / og, 0) for i in range(og + 1)] + [
            (0, i / og) for i in range(og + 1)
        ] + [(i / og, 1.0) for i in range(og + 1)] + [(1.0, i / og)
                                                      for i in range(og + 1)]
        ir_quad = ngs.IntegrationRule(ipts, [
            0,
        ] * len(ipts))

        vb = [ngs.VOL, ngs.BND][mesh.dim - 2]
        if region and region.VB() == vb:
            vb = region
        cf = func1 if draw_surf else func0
        timer2map.Start()
        pts = mesh.MapToAllElements(
            {
                ngs.ET.TRIG: ir_trig,
                ngs.ET.QUAD: ir_quad
            }, vb)
        timer2map.Stop()
        pmat = cf(pts)

        pmima = updatePMinMax(pmat)

        timermult.Start()
        pmat = pmat.reshape(-1, og + 1, 4)
        if False:
            BezierPnts = np.tensordot(iBvals.NumPy(), pmat, axes=(1, 1))
        else:
            BezierPnts = np.zeros((og + 1, pmat.shape[0], 4))
            for i in range(4):
                ngsmat = ngs.Matrix(pmat[:, :, i].transpose())
                BezierPnts[:, :, i] = iBvals * ngsmat
        timermult.Stop()

        timer2list.Start()
        for i in range(og + 1):
            Bezier_points.append(encodeData(BezierPnts[i]))
        timer2list.Stop()

        if func2 and draw_surf:
            pmat = func2(pts)
            pmat = pmat.reshape(-1, og + 1, 2)
            timermult.Start()
            BezierPnts = np.tensordot(iBvals.NumPy(), pmat, axes=(1, 1))
            timermult.Stop()
            timer2list.Start()
            for i in range(og + 1):
                Bezier_points.append(encodeData(BezierPnts[i]))
            timer2list.Stop()

        d['Bezier_points'] = Bezier_points

        ipts = [(i / og, 0) for i in range(og + 1)]
        ir_seg = ngs.IntegrationRule(ipts, [
            0,
        ] * len(ipts))
        vb = [ngs.VOL, ngs.BND, ngs.BBND][mesh.dim - 1]
        if region and region.VB() == vb:
            vb = region
        pts = mesh.MapToAllElements(ir_seg, vb)
        pmat = func0(pts)
        pmima = updatePMinMax(pmat)
        pmat = pmat.reshape(-1, og + 1, 4)
        edge_data = np.tensordot(iBvals.NumPy(), pmat, axes=(1, 1))
        edges = []
        for i in range(og + 1):
            edges.append(encodeData(edge_data[i]))
        d['edges'] = edges

        timer2.Stop()
        timer3.Start()

        ndtrig = int((og + 1) * (og + 2) / 2)

        if og in bezier_trig_trafos.keys():
            iBvals_trig = bezier_trig_trafos[og]
        else:

            def BernsteinTrig(x, y, i, j, n):
                return math.factorial(n)/math.factorial(i)/math.factorial(j)/math.factorial(n-i-j) \
                  * x**i*y**j*(1-x-y)**(n-i-j)

            Bvals = ngs.Matrix(ndtrig, ndtrig)
            ii = 0
            for ix in range(og + 1):
                for iy in range(og + 1 - ix):
                    jj = 0
                    for jx in range(og + 1):
                        for jy in range(og + 1 - jx):
                            Bvals[ii,
                                  jj] = BernsteinTrig(ix / og, iy / og, jx, jy,
                                                      og)
                            jj += 1
                    ii += 1
            iBvals_trig = Bvals.I
            bezier_trig_trafos[og] = iBvals_trig

        # Bezier_points = [ [] for i in range(ndtrig) ]
        Bezier_points = []

        ipts = [(i / og, j / og) for j in range(og + 1)
                for i in range(og + 1 - j)]
        ir_trig = ngs.IntegrationRule(ipts, [
            0,
        ] * len(ipts))
        ipts = ([(i / og, j / og) for j in range(og + 1)
                 for i in range(og + 1 - j)] + [(1 - i / og, 1 - j / og)
                                                for j in range(og + 1)
                                                for i in range(og + 1 - j)])
        ir_quad = ngs.IntegrationRule(ipts, [
            0,
        ] * len(ipts))

        vb = [ngs.VOL, ngs.BND][mesh.dim - 2]
        if region and region.VB() == vb:
            vb = region
        pts = mesh.MapToAllElements(
            {
                ngs.ET.TRIG: ir_trig,
                ngs.ET.QUAD: ir_quad
            }, vb)

        pmat = ngs.CoefficientFunction(func1 if draw_surf else func0)(pts)

        timer3minmax.Start()
        pmima = updatePMinMax(pmat, pmima)
        funcmin, funcmax = getMinMax(pmat[:, 3])
        timer3minmax.Stop()

        pmin, pmax = [ngs.Vector(p) for p in zip(*pmima)]
        mesh_center = 0.5 * (pmin + pmax)
        mesh_radius = np.linalg.norm(pmax - pmin) / 2

        pmat = pmat.reshape(-1, len(ir_trig), 4)

        if False:
            timer3multnumpy.Start()
            BezierPnts = np.tensordot(iBvals_trig.NumPy(), pmat, axes=(1, 1))
            timer3multnumpy.Stop()
        else:
            timer3multngs.Start()
            BezierPnts = np.zeros((len(ir_trig), pmat.shape[0], 4))
            for i in range(4):
                ngsmat = ngs.Matrix(pmat[:, :, i].transpose())
                BezierPnts[:, :, i] = iBvals_trig * ngsmat
            timer3multngs.Stop()

        timer3list.Start()
        for i in range(ndtrig):
            Bezier_points.append(encodeData(BezierPnts[i]))
        timer3list.Stop()

        if func2 and draw_surf:
            pmat = ngs.CoefficientFunction(func2)(pts)

            pmat = pmat.reshape(-1, len(ir_trig), 2)

            funcmin, funcmax = getMinMax(pmat.flatten(), funcmin, funcmax)
            BezierPnts = np.tensordot(iBvals_trig.NumPy(), pmat, axes=(1, 1))
            if og == 1:
                for i in range(ndtrig):
                    Bezier_points.append(encodeData(BezierPnts[i]))
            else:
                BezierPnts = BezierPnts.transpose(
                    (1, 0, 2)).reshape(-1,
                                       len(ir_trig) // 2, 4).transpose(
                                           (1, 0, 2))

                for i in range(ndtrig // 2):
                    Bezier_points.append(encodeData(BezierPnts[i]))

        d['Bezier_trig_points'] = Bezier_points
        d['mesh_center'] = list(mesh_center)
        d['mesh_radius'] = mesh_radius
        timer3.Stop()

    timer4.Start()

    if d['draw_vol']:
        p0 = []
        p1 = []
        p2 = []
        p3 = []
        values = []
        tets = []

        midpoint = lambda p0, p1: tuple(
            (0.5 * (p0[i] + p1[i]) for i in range(3)))

        def makeP2Tets(p1_tets):
            p2_tets = []
            for tet in p1_tets:
                tet.append(midpoint(tet[0], tet[3]))
                tet.append(midpoint(tet[1], tet[3]))
                tet.append(midpoint(tet[2], tet[3]))
                tet.append(midpoint(tet[0], tet[1]))
                tet.append(midpoint(tet[0], tet[2]))
                tet.append(midpoint(tet[1], tet[2]))
                p2_tets.append(tet)
            return p2_tets

        # divide any element into tets
        p1_tets = {}
        p1_tets[ngs.ET.TET] = [[(1, 0, 0), (0, 1, 0), (0, 0, 1), (0, 0, 0)]]
        p1_tets[ngs.ET.PYRAMID] = [[(1, 0, 0), (0, 1, 0), (0, 0, 1),
                                    (0, 0, 0)],
                                   [(1, 0, 0), (0, 1, 0), (0, 0, 1),
                                    (1, 1, 0)]]
        p1_tets[ngs.ET.PRISM] = [[(1, 0, 0), (0, 1, 0), (0, 0, 1), (0, 0, 0)],
                                 [(0, 0, 1), (0, 1, 0), (0, 1, 1), (1, 0, 0)],
                                 [(1, 0, 1), (0, 1, 1), (1, 0, 0), (0, 0, 1)]]
        p1_tets[ngs.ET.HEX] = [[(1, 0, 0), (0, 1, 0), (0, 0, 1), (0, 0, 0)],
                               [(0, 1, 1), (1, 1, 1), (1, 1, 0), (1, 0, 1)],
                               [(1, 0, 1), (0, 1, 1), (1, 0, 0), (0, 0, 1)],
                               [(0, 1, 1), (1, 1, 0), (0, 1, 0), (1, 0, 0)],
                               [(0, 0, 1), (0, 1, 0), (0, 1, 1), (1, 0, 0)],
                               [(1, 0, 1), (1, 1, 0), (0, 1, 1), (1, 0, 0)]]

        intrules = {}
        for eltype in p1_tets:
            points = p1_tets[eltype]
            if order3d > 1:
                points = makeP2Tets(points)
            intrules[eltype] = ngs.IntegrationRule(sum(points, []))

        pts = mesh.MapToAllElements(intrules, ngs.VOL)

        pmat = func1(pts)

        np_per_tet = len(intrules[ngs.ET.TET])

        ne = mesh.GetNE(ngs.VOL)
        pmat = pmat.reshape(-1, np_per_tet, 4)

        funcmin, funcmax = getMinMax(pmat[:, :, 3].flatten(), funcmin, funcmax)
        points3d = []
        for i in range(np_per_tet):
            points3d.append(encodeData(pmat[:, i, :]))

        if func2:
            pmat = func2(pts).reshape(-1, np_per_tet // 2, 4)
            funcmin, funcmax = getMinMax(pmat.flatten(), funcmin, funcmax)
            for i in range(np_per_tet // 2):
                points3d.append(encodeData(pmat[:, i, :]))
        d['points3d'] = points3d
    if func:
        d['funcmin'] = funcmin
        d['funcmax'] = funcmax
    timer4.Stop()
    timer.Stop()
    return d
Beispiel #8
0
def GMRes(A,
          b,
          pre=None,
          freedofs=None,
          x=None,
          maxsteps=100,
          tol=1e-7,
          innerproduct=None,
          callback=None,
          restart=None,
          startiteration=0,
          printrates=True):
    """ Restarting preconditioned gmres solver for A*x=b. Minimizes the preconditioned
residuum pre*(b-A*x)

Parameters
----------

A : BaseMatrix
  The left hand side of the linear system.

b : BaseVector
  The right hand side of the linear system.

pre : BaseMatrix = None
  The preconditioner for the system. If no preconditioner is given, the freedofs
  of the system must be given.

freedofs : BitArray = None
  Freedofs to solve on, only necessary if no preconditioner is given.

x : BaseVector = None
  Startvector, if given it will be modified in the routine and returned. Will be created
  if not given.

maxsteps : int = 100
  Maximum iteration steps.

tol : float = 1e-7
  Tolerance to be computed to. Gmres breaks if norm(pre*(b-A*x)) < tol.

innerproduct : function = None
  Innerproduct to be used in iteration, all orthogonalizations/norms are computed with
  respect to that inner product.

callback : function = None
  If given, this function is called with the solution vector x in each step. Only for debugging
  purposes, since it requires the overhead of computing x in every step.

restart : int = None
  If given, gmres is restarted with the current solution x every 'restart' steps.

startiteration : int = 0
  Internal value to count total number of iterations in restarted setup, no user input required
  here.

printrates : bool = True
  Print norm of preconditioned residual in each step.
"""

    if not innerproduct:
        innerproduct = lambda x, y: y.InnerProduct(x, conjugate=True)
        norm = ngsolve.Norm
    else:
        norm = lambda x: ngsolve.sqrt(innerproduct(x, x).real)
    # is_complex = isinstance(b.FV(), ngsolve.bla.FlatVectorC)
    is_complex = b.is_complex
    if not pre:
        assert freedofs
        pre = ngsolve.Projector(freedofs, True)
    n = len(b)
    m = maxsteps
    if not x:
        x = b.CreateVector()
        x[:] = 0

    if callback:
        xstart = x.CreateVector()
        xstart.data = x
    else:
        xstart = None
    sn = ngsolve.Vector(m, is_complex)
    cs = ngsolve.Vector(m, is_complex)
    sn[:] = 0
    cs[:] = 0

    r = b.CreateVector()
    tmp = b.CreateVector()
    tmp.data = b - A * x
    r.data = pre * tmp

    Q = []
    H = []
    Q.append(b.CreateVector())
    r_norm = norm(r)
    if abs(r_norm) < tol:
        return x
    Q[0].data = 1. / r_norm * r
    beta = ngsolve.Vector(m + 1, is_complex)
    beta[:] = 0
    beta[0] = r_norm

    def arnoldi(A, Q, k):
        q = b.CreateVector()
        tmp.data = A * Q[k]
        q.data = pre * tmp
        h = ngsolve.Vector(m + 1, is_complex)
        h[:] = 0
        for i in range(k + 1):
            h[i] = innerproduct(Q[i], q)
            q.data += (-1) * h[i] * Q[i]
        h[k + 1] = norm(q)
        if abs(h[k + 1]) < 1e-12:
            return h, None
        q *= 1. / h[k + 1].real
        return h, q

    def givens_rotation(v1, v2):
        if v2 == 0:
            return 1, 0
        elif v1 == 0:
            return 0, v2 / abs(v2)
        else:
            t = ngsolve.sqrt((v1.conjugate() * v1 + v2.conjugate() * v2).real)
            cs = abs(v1) / t
            sn = v1 / abs(v1) * v2.conjugate() / t
            return cs, sn

    def apply_givens_rotation(h, cs, sn, k):
        for i in range(k):
            temp = cs[i] * h[i] + sn[i] * h[i + 1]
            h[i + 1] = -sn[i].conjugate() * h[i] + cs[i].conjugate() * h[i + 1]
            h[i] = temp
        cs[k], sn[k] = givens_rotation(h[k], h[k + 1])
        h[k] = cs[k] * h[k] + sn[k] * h[k + 1]
        h[k + 1] = 0

    def calcSolution(k):
        mat = ngsolve.Matrix(k + 1, k + 1, is_complex)
        for i in range(k + 1):
            mat[:, i] = H[i][:k + 1]
        rs = ngsolve.Vector(k + 1, is_complex)
        rs[:] = beta[:k + 1]
        y = mat.I * rs
        if xstart:
            x.data = xstart
        for i in range(k + 1):
            x.data += y[i] * Q[i]

    for k in range(m):
        startiteration += 1
        h, q = arnoldi(A, Q, k)
        H.append(h)
        if q is None:
            break
        Q.append(q)
        apply_givens_rotation(h, cs, sn, k)
        beta[k + 1] = -sn[k].conjugate() * beta[k]
        beta[k] = cs[k] * beta[k]
        error = abs(beta[k + 1])
        if printrates:
            print("Step", startiteration, ", error = ", error)
        if callback:
            calcSolution(k)
            callback(x)
        if error < tol:
            break
        if restart and k + 1 == restart and not (restart == maxsteps):
            calcSolution(k)
            del Q
            return GMRes(A,
                         b,
                         freedofs=freedofs,
                         pre=pre,
                         x=x,
                         maxsteps=maxsteps - restart,
                         callback=callback,
                         tol=tol,
                         innerproduct=innerproduct,
                         restart=restart,
                         startiteration=startiteration,
                         printrates=printrates)
    calcSolution(k)
    return x
def MyGMRes(A,
            b,
            pre=None,
            freedofs=None,
            x=None,
            maxsteps=100,
            tol=1e-7,
            innerproduct=None,
            callback=None,
            restart=None,
            startiteration=0,
            printrates=True):
    """
    Important Note: This version of GMRes only differs from NGSolve's
    current version of GMRes in that the assert statement for freedofs is
    now

        assert freedofs is not None

    Otherwise, everything else remains the same.
    """
    if not innerproduct:
        innerproduct = lambda x, y: y.InnerProduct(x, conjugate=True)
        norm = ngsolve.Norm
    else:
        norm = lambda x: ngsolve.sqrt(innerproduct(x, x).real)
    # is_complex = isinstance(b.FV(), ngsolve.bla.FlatVectorC)
    is_complex = b.is_complex
    if not pre:
        assert freedofs is not None
        pre = ngsolve.Projector(freedofs, True)
    n = len(b)
    m = maxsteps
    if not x:
        x = b.CreateVector()
        x[:] = 0

    if callback:
        xstart = x.CreateVector()
        xstart.data = x
    else:
        xstart = None
    sn = ngsolve.Vector(m, is_complex)
    cs = ngsolve.Vector(m, is_complex)
    sn[:] = 0
    cs[:] = 0

    r = b.CreateVector()
    tmp = b.CreateVector()
    tmp.data = b - A * x
    r.data = pre * tmp

    Q = []
    H = []
    Q.append(b.CreateVector())
    r_norm = norm(r)
    if abs(r_norm) < tol:
        return x
    Q[0].data = 1. / r_norm * r
    beta = ngsolve.Vector(m + 1, is_complex)
    beta[:] = 0
    beta[0] = r_norm

    def arnoldi(A, Q, k):
        q = b.CreateVector()
        tmp.data = A * Q[k]
        q.data = pre * tmp
        h = ngsolve.Vector(m + 1, is_complex)
        h[:] = 0
        for i in range(k + 1):
            h[i] = innerproduct(Q[i], q)
            q.data += (-1) * h[i] * Q[i]
        h[k + 1] = norm(q)
        if abs(h[k + 1]) < 1e-12:
            return h, None
        q *= 1. / h[k + 1].real
        return h, q

    def givens_rotation(v1, v2):
        if v2 == 0:
            return 1, 0
        elif v1 == 0:
            return 0, v2 / abs(v2)
        else:
            t = ngsolve.sqrt((v1.conjugate() * v1 + v2.conjugate() * v2).real)
            cs = abs(v1) / t
            sn = v1 / abs(v1) * v2.conjugate() / t
            return cs, sn

    def apply_givens_rotation(h, cs, sn, k):
        for i in range(k):
            temp = cs[i] * h[i] + sn[i] * h[i + 1]
            h[i + 1] = -sn[i].conjugate() * h[i] + cs[i].conjugate() * h[i + 1]
            h[i] = temp
        cs[k], sn[k] = givens_rotation(h[k], h[k + 1])
        h[k] = cs[k] * h[k] + sn[k] * h[k + 1]
        h[k + 1] = 0

    def calcSolution(k):
        mat = ngsolve.Matrix(k + 1, k + 1, is_complex)
        for i in range(k + 1):
            mat[:, i] = H[i][:k + 1]
        rs = ngsolve.Vector(k + 1, is_complex)
        rs[:] = beta[:k + 1]
        y = mat.I * rs
        if xstart:
            x.data = xstart
        for i in range(k + 1):
            x.data += y[i] * Q[i]

    for k in range(m):
        startiteration += 1
        h, q = arnoldi(A, Q, k)
        H.append(h)
        if q is None:
            break
        Q.append(q)
        apply_givens_rotation(h, cs, sn, k)
        beta[k + 1] = -sn[k].conjugate() * beta[k]
        beta[k] = cs[k] * beta[k]
        error = abs(beta[k + 1])
        if printrates:
            print("Step", startiteration, ", error = ", error)
        if callback:
            calcSolution(k)
            callback(x)
        if error < tol:
            break
        if restart and k + 1 == restart and not (restart == maxsteps):
            calcSolution(k)
            del Q
            return MyGMRes(A,
                           b,
                           freedofs=freedofs,
                           pre=pre,
                           x=x,
                           maxsteps=maxsteps - restart,
                           callback=callback,
                           tol=tol,
                           innerproduct=innerproduct,
                           restart=restart,
                           startiteration=startiteration,
                           printrates=printrates)
    calcSolution(k)
    return x
Beispiel #10
0
 def P2N(self, psc_vector, ngs_vector=None):
     if ngs_vector is None:
         ngs_vector = ngs.la.CreateParallelVector(self.pardofs)
     psc_loc = psc_vector.getSubVector(self.iset)
     ngs_vector.FV()[:] = ngs.Vector(psc_loc.getArray())
     return ngs_vector