File: nullspace.py

package info (click to toggle)
ngspetsc 0.1.1-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 27,120 kB
  • sloc: python: 3,391; makefile: 42; sh: 29
file content (55 lines) | stat: -rw-r--r-- 1,995 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
'''
This module contains all the function and class needed to wrap a PETSc Nullspace in NGSolve
'''
from petsc4py import PETSc
from ngsPETSc import VectorMapping

class NullSpace:
    '''
    This class creates a PETSc Null space from NGSolve vectors

    :arg fes: NGSolve finite element space.
    :arg span: list NGSolve grid functions spanning the null space.

    '''
    def __init__(self, fes, span, near=False):
        constant = False
        self.vecMap = VectorMapping(fes)
        self.near = near
        if isinstance(span, list):
            nullspace = list(span)
            petscNullspace = []
            for vec in nullspace:
                if isinstance(vec, str):
                    if vec == "constant":
                        constant = True
                    else:
                        raise ValueError("Invalid nullspace string")
                else:
                    petscVec  = self.vecMap.petscVec(vec)
                    petscNullspace.append(petscVec)
        elif isinstance(span, str):
            if span == "constant":
                constant = True
                petscNullspace = []
            else:
                raise ValueError("Invalid nullspace string")
        else:
            raise ValueError("Invalid nullspace type")
            # Create vector space basis and orthogonalize
        self.constant = constant
        self.orthonormalize(petscNullspace)
        self.nullspace = PETSc.NullSpace().create(constant=constant, vectors=petscNullspace)
    def orthonormalize(self, basis):
        """Orthonormalize the basis."""
        for i, vec in enumerate(basis):
            alphas = []
            for vec_ in basis[:i]:
                alphas.append(vec.dot(vec_))
            for alpha, vec_ in zip(alphas, basis[:i]):
                vec.axpy(-alpha, vec_)
            if self.constant:
                # Subtract constant mode
                alpha = vec.sum()
                vec.array -= alpha
            vec.normalize()