示例#1
0
    def Mult(self, x, y):
        globals()['max_char_speed'] = 0.;
        num_equation = globals()['num_equation']
        # 1. Create the vector z with the face terms -<F.n(u), [w]>.
        self.A.Mult(x, self.z);

        # 2. Add the element terms.
        # i.  computing the flux approximately as a grid function by interpolating
        #     at the solution nodes.
        # ii. multiplying this grid function by a (constant) mixed bilinear form for
        #     each of the num_equation, computing (F(u), grad(w)) for each equation.

        xmat = mfem.DenseMatrix(x.GetData(), self.vfes.GetNDofs(), num_equation)
        self.GetFlux(xmat, self.flux)

        for k in range(num_equation):
           fk = mfem.Vector(self.flux[k].GetData(), self.dim * self.vfes.GetNDofs())
           o = k * self.vfes.GetNDofs()
           zk = self.z[o: o+self.vfes.GetNDofs()]
           self.Aflux.AddMult(fk, zk)

        # 3. Multiply element-wise by the inverse mass matrices.
        zval = mfem.Vector()
        vdofs = mfem.intArray()
        dof = self.vfes.GetFE(0).GetDof()
        zmat = mfem.DenseMatrix()
        ymat = mfem.DenseMatrix(dof, num_equation)        

        for i in range(self.vfes.GetNE()):
            # Return the vdofs ordered byNODES
            vdofs = mfem.intArray(self.vfes.GetElementVDofs(i))
            self.z.GetSubVector(vdofs, zval)
            zmat.UseExternalData(zval.GetData(), dof, num_equation)
            mfem.Mult(self.Me_inv[i], zmat, ymat);
            y.SetSubVector(vdofs, ymat.GetData())
示例#2
0
    def AssembleElementMatrix2(self, trial_fe, test_fe, Tr, elmat):
        # Assemble the form (vec(v), grad(w))

        # Trial space = vector L2 space (mesh dim)
        # Test space  = scalar L2 space

        dof_trial = trial_fe.GetDof()
        dof_test = test_fe.GetDof()
        dim = trial_fe.GetDim()

        self.shape.SetSize(dof_trial)
        self.dshapedr.SetSize(dof_test, dim)
        self.dshapedx.SetSize(dof_test, dim)

        elmat.SetSize(dof_test, dof_trial * dim)
        elmat.Assign(0.0)

        maxorder = max(trial_fe.GetOrder(), test_fe.GetOrder())
        intorder = 2 * maxorder
        ir = mfem.IntRules.Get(trial_fe.GetGeomType(), intorder)

        for i in range(ir.GetNPoints()):
            ip = ir.IntPoint(i)

            # Calculate the shape functions
            trial_fe.CalcShape(ip, self.shape)
            self.shape *= ip.weight

            # Compute the physical gradients of the test functions
            Tr.SetIntPoint(ip)
            test_fe.CalcDShape(ip, self.dshapedr)
            mfem.Mult(self.dshapedr, Tr.AdjugateJacobian(), self.dshapedx)

            for d in range(dim):
                for j in range(dof_test):
                    for k in range(dof_trial):
                        elmat[j, k + d *
                              dof_trial] += self.shape[k] * self.dshapedx[j, d]
示例#3
0
bVarf.Finalize()
B = bVarf.SpMat()
B *= -1
BT = mfem.Transpose(B)

darcyOp = mfem.BlockOperator(block_offsets)
darcyOp.SetBlock(0, 0, M)
darcyOp.SetBlock(0, 1, BT)
darcyOp.SetBlock(1, 0, B)

MinvBt = mfem.Transpose(B)
Md = mfem.Vector(M.Height())
M.GetDiag(Md)
for i in range(Md.Size()):
    MinvBt.ScaleRow(i, 1 / Md[i])
S = mfem.Mult(B, MinvBt)

invM = mfem.DSmoother(M)
invS = mfem.GSSmoother(S)
invM.iterative_mode = False
invS.iterative_mode = False

darcyPrec = mfem.BlockDiagonalPreconditioner(block_offsets)
darcyPrec.SetDiagonalBlock(0, invM)
darcyPrec.SetDiagonalBlock(1, invS)

maxIter = 500
rtol = 1e-6
atol = 1e-10

stime = clock()