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())
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]
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()