def _initializePETScScatters(self): """ First, defines the PETSc Vec application ordering objects """ getLinspace = lambda m1, m2: numpy.array( numpy.linspace(m1, m2 - 1, m2 - m1), 'i') varSizes = self.varSizes appIndices = [] i = self.rank for j in xrange(len(self.variables)): m1 = numpy.sum(varSizes[:, :j]) + numpy.sum(varSizes[:i, j]) m2 = m1 + varSizes[i, j] appIndices.append(getLinspace(m1, m2)) appIndices = numpy.concatenate(appIndices) m1 = numpy.sum(varSizes[:self.rank, :]) m2 = m1 + numpy.sum(varSizes[self.rank, :]) petscIndices = getLinspace(m1, m2) ISapp = PETSc.IS().createGeneral(appIndices, comm=self.comm) ISpetsc = PETSc.IS().createGeneral(petscIndices, comm=self.comm) self.AOvarPETSc = PETSc.AO().createBasic(ISapp, ISpetsc, comm=self.comm) """ Next, the scatters are defined """ def createScatter(self, varInds, argInds): merge = lambda x: numpy.concatenate(x) if len(x) > 0 else [] ISvar = PETSc.IS().createGeneral(merge(varInds), comm=self.comm) ISarg = PETSc.IS().createGeneral(merge(argInds), comm=self.comm) ISvar = self.AOvarPETSc.app2petsc(ISvar) if ISvar.array.shape[0] == 0: return None else: return PETSc.Scatter().create(self.vVarPETSc, ISvar, self.vArgPETSc, ISarg) variableIndex = self.variables.keys().index varIndsFull = [] argIndsFull = [] i1, i2 = 0, 0 for system in self.subsystems: varIndsFwd = [] argIndsFwd = [] varIndsRev = [] argIndsRev = [] for (n1, c1) in system.variables: args = system.variables[n1, c1]['args'] for (n2, c2) in args: if (n2, c2) not in system.variables \ and (n2, c2) in self.variables: j = variableIndex((n1, c1)) i2 += args[n2, c2].shape[0] varInds = numpy.sum(varSizes[:, :j]) + args[n2, c2] argInds = getLinspace(i1, i2) i1 += args[n2, c2].shape[0] if variableIndex((n1, c1)) > variableIndex((n2, c2)): varIndsFwd.append(varInds) argIndsFwd.append(argInds) else: varIndsRev.append(varInds) argIndsRev.append(argInds) varIndsFull.append(varInds) argIndsFull.append(argInds) system.scatterFwd = createScatter(self, varIndsFwd, argIndsFwd) system.scatterRev = createScatter(self, varIndsRev, argIndsRev) self.scatterFull = createScatter(self, varIndsFull, argIndsFull) for system in self.localSubsystems: system._initializePETScScatters()
def foo(): m = 6 errL2u =np.zeros((m-1,1)) errH1u =np.zeros((m-1,1)) errL2p =np.zeros((m-1,1)) errL2b =np.zeros((m-1,1)) errCurlb =np.zeros((m-1,1)) errL2r =np.zeros((m-1,1)) errH1r =np.zeros((m-1,1)) l2uorder = np.zeros((m-1,1)) H1uorder =np.zeros((m-1,1)) l2porder = np.zeros((m-1,1)) l2border = np.zeros((m-1,1)) Curlborder =np.zeros((m-1,1)) l2rorder = np.zeros((m-1,1)) H1rorder = np.zeros((m-1,1)) NN = np.zeros((m-1,1)) DoF = np.zeros((m-1,1)) Velocitydim = np.zeros((m-1,1)) Magneticdim = np.zeros((m-1,1)) Pressuredim = np.zeros((m-1,1)) Lagrangedim = np.zeros((m-1,1)) Wdim = np.zeros((m-1,1)) iterations = np.zeros((m-1,1)) SolTime = np.zeros((m-1,1)) udiv = np.zeros((m-1,1)) MU = np.zeros((m-1,1)) level = np.zeros((m-1,1)) NSave = np.zeros((m-1,1)) Mave = np.zeros((m-1,1)) TotalTime = np.zeros((m-1,1)) nn = 2 dim = 2 ShowResultPlots = 'yes' split = 'Linear' MU[0]= 1e0 for xx in xrange(1,m): print xx level[xx-1] = xx+ 2 nn = 2**(level[xx-1]) # Create mesh and define function space nn = int(nn) NN[xx-1] = nn/2 # parameters["form_compiler"]["quadrature_degree"] = 6 # parameters = CP.ParameterSetup() mesh = UnitSquareMesh(nn,nn) order = 1 parameters['reorder_dofs_serial'] = False Velocity = VectorFunctionSpace(mesh, "CG", order) Pressure = FunctionSpace(mesh, "DG", order-1) Magnetic = FunctionSpace(mesh, "N1curl", order) Lagrange = FunctionSpace(mesh, "CG", order) W = MixedFunctionSpace([Velocity, Pressure, Magnetic,Lagrange]) # W = Velocity*Pressure*Magnetic*Lagrange Velocitydim[xx-1] = Velocity.dim() Pressuredim[xx-1] = Pressure.dim() Magneticdim[xx-1] = Magnetic.dim() Lagrangedim[xx-1] = Lagrange.dim() Wdim[xx-1] = W.dim() print "\n\nW: ",Wdim[xx-1],"Velocity: ",Velocitydim[xx-1],"Pressure: ",Pressuredim[xx-1],"Magnetic: ",Magneticdim[xx-1],"Lagrange: ",Lagrangedim[xx-1],"\n\n" dim = [Velocity.dim(), Pressure.dim(), Magnetic.dim(), Lagrange.dim()] def boundary(x, on_boundary): return on_boundary u0, p0,b0, r0, Laplacian, Advection, gradPres,CurlCurl, gradR, NS_Couple, M_Couple = ExactSol.MHD2D(4,1) bcu = DirichletBC(W.sub(0),u0, boundary) bcb = DirichletBC(W.sub(2),b0, boundary) bcr = DirichletBC(W.sub(3),r0, boundary) # bc = [u0,p0,b0,r0] bcs = [bcu,bcb,bcr] FSpaces = [Velocity,Pressure,Magnetic,Lagrange] (u, b, p, r) = TrialFunctions(W) (v, c, q, s) = TestFunctions(W) kappa = 1.0 Mu_m =1e1 MU = 1.0/1 IterType = 'Full' F_NS = -MU*Laplacian+Advection+gradPres-kappa*NS_Couple if kappa == 0: F_M = Mu_m*CurlCurl+gradR -kappa*M_Couple else: F_M = Mu_m*kappa*CurlCurl+gradR -kappa*M_Couple params = [kappa,Mu_m,MU] # MO.PrintStr("Preconditioning MHD setup",5,"+","\n\n","\n\n") Hiptmairtol = 1e-5 HiptmairMatrices = PrecondSetup.MagneticSetup(Magnetic, Lagrange, b0, r0, Hiptmairtol, params) MO.PrintStr("Setting up MHD initial guess",5,"+","\n\n","\n\n") u_k,p_k,b_k,r_k = common.InitialGuess(FSpaces,[u0,p0,b0,r0],[F_NS,F_M],params,HiptmairMatrices,1e-6,Neumann=Expression(("0","0")),options ="New", FS = "DG") #plot(p_k, interactive = True) b_t = TrialFunction(Velocity) c_t = TestFunction(Velocity) #print assemble(inner(b,c)*dx).array().shape #print mat #ShiftedMass = assemble(inner(mat*b,c)*dx) #as_vector([inner(b,c)[0]*b_k[0],inner(b,c)[1]*(-b_k[1])]) ones = Function(Pressure) ones.vector()[:]=(0*ones.vector().array()+1) # pConst = - assemble(p_k*dx)/assemble(ones*dx) p_k.vector()[:] += - assemble(p_k*dx)/assemble(ones*dx) x = Iter.u_prev(u_k,p_k,b_k,r_k) KSPlinearfluids, MatrixLinearFluids = PrecondSetup.FluidLinearSetup(Pressure, MU) kspFp, Fp = PrecondSetup.FluidNonLinearSetup(Pressure, MU, u_k) #plot(b_k) ns,maxwell,CoupleTerm,Lmaxwell,Lns = forms.MHD2D(mesh, W,F_M,F_NS, u_k,b_k,params,IterType,"DG") RHSform = forms.PicardRHS(mesh, W, u_k, p_k, b_k, r_k, params,"DG") bcu = DirichletBC(W.sub(0),Expression(("0.0","0.0")), boundary) bcb = DirichletBC(W.sub(2),Expression(("0.0","0.0")), boundary) bcr = DirichletBC(W.sub(3),Expression(("0.0")), boundary) bcs = [bcu,bcb,bcr] eps = 1.0 # error measure ||u-u_k|| tol = 1.0E-4 # tolerance iter = 0 # iteration counter maxiter = 40 # max no of iterations allowed SolutionTime = 0 outer = 0 # parameters['linear_algebra_backend'] = 'uBLAS' # FSpaces = [Velocity,Magnetic,Pressure,Lagrange] if IterType == "CD": AA, bb = assemble_system(maxwell+ns, (Lmaxwell + Lns) - RHSform, bcs) A,b = CP.Assemble(AA,bb) # u = b.duplicate() # P = CP.Assemble(PP) u_is = PETSc.IS().createGeneral(range(Velocity.dim())) NS_is = PETSc.IS().createGeneral(range(Velocity.dim()+Pressure.dim())) M_is = PETSc.IS().createGeneral(range(Velocity.dim()+Pressure.dim(),W.dim())) OuterTol = 1e-5 InnerTol = 1e-5 NSits =0 Mits =0 TotalStart =time.time() SolutionTime = 0 while eps > tol and iter < maxiter: iter += 1 MO.PrintStr("Iter "+str(iter),7,"=","\n\n","\n\n") tic() if IterType == "CD": bb = assemble((Lmaxwell + Lns) - RHSform) for bc in bcs: bc.apply(bb) FF = AA.sparray()[0:dim[0],0:dim[0]] A,b = CP.Assemble(AA,bb) # if iter == 1 if iter == 1: u = b.duplicate() F = A.getSubMatrix(u_is,u_is) kspF = NSprecondSetup.LSCKSPnonlinear(F) else: AA, bb = assemble_system(maxwell+ns+CoupleTerm, (Lmaxwell + Lns) - RHSform, bcs) A,b = CP.Assemble(AA,bb) # if iter == 1: if iter == 1: u = b.duplicate() print ("{:40}").format("MHD assemble, time: "), " ==> ",("{:4f}").format(toc()), ("{:9}").format(" time: "), ("{:4}").format(time.strftime('%X %x %Z')[0:5]) kspFp, Fp = PrecondSetup.FluidNonLinearSetup(Pressure, MU, u_k) print "Inititial guess norm: ", u.norm() #A,Q if IterType == 'Full': n = FacetNormal(mesh) mat = as_matrix([[b_k[1]*b_k[1],-b_k[1]*b_k[0]],[-b_k[1]*b_k[0],b_k[0]*b_k[0]]]) F = A.getSubMatrix(u_is,u_is) a = params[2]*inner(grad(b_t), grad(c_t))*dx(W.mesh()) + inner((grad(b_t)*u_k),c_t)*dx(W.mesh()) +(1/2)*div(u_k)*inner(c_t,b_t)*dx(W.mesh()) - (1/2)*inner(u_k,n)*inner(c_t,b_t)*ds(W.mesh())+kappa/Mu_m*inner(mat*b_t,c_t)*dx(W.mesh()) ShiftedMass = assemble(a) bcu.apply(ShiftedMass) kspF = NSprecondSetup.LSCKSPnonlinear(F) stime = time.time() u, mits,nsits = S.solve(A,b,u,params,W,"Direct",IterType,OuterTol,InnerTol,HiptmairMatrices,Hiptmairtol,KSPlinearfluids, Fp,kspF) Soltime = time.time()- stime Mits += mits NSits += nsits SolutionTime += Soltime u1, p1, b1, r1, eps= Iter.PicardToleranceDecouple(u,x,FSpaces,dim,"2",iter) p1.vector()[:] += - assemble(p1*dx)/assemble(ones*dx) u_k.assign(u1) p_k.assign(p1) b_k.assign(b1) r_k.assign(r1) uOld= np.concatenate((u_k.vector().array(),p_k.vector().array(),b_k.vector().array(),r_k.vector().array()), axis=0) x = IO.arrayToVec(uOld) XX= np.concatenate((u_k.vector().array(),p_k.vector().array(),b_k.vector().array(),r_k.vector().array()), axis=0) SolTime[xx-1] = SolutionTime/iter NSave[xx-1] = (float(NSits)/iter) Mave[xx-1] = (float(Mits)/iter) iterations[xx-1] = iter TotalTime[xx-1] = time.time() - TotalStart dim = [Velocity.dim(), Pressure.dim(), Magnetic.dim(),Lagrange.dim()] # # ExactSolution = [u0,p0,b0,r0] # errL2u[xx-1], errH1u[xx-1], errL2p[xx-1], errL2b[xx-1], errCurlb[xx-1], errL2r[xx-1], errH1r[xx-1] = Iter.Errors(XX,mesh,FSpaces,ExactSolution,order,dim, "DG") # # if xx > 1: # l2uorder[xx-1] = np.abs(np.log2(errL2u[xx-2]/errL2u[xx-1])) # H1uorder[xx-1] = np.abs(np.log2(errH1u[xx-2]/errH1u[xx-1])) # # l2porder[xx-1] = np.abs(np.log2(errL2p[xx-2]/errL2p[xx-1])) # # l2border[xx-1] = np.abs(np.log2(errL2b[xx-2]/errL2b[xx-1])) # Curlborder[xx-1] = np.abs(np.log2(errCurlb[xx-2]/errCurlb[xx-1])) # # l2rorder[xx-1] = np.abs(np.log2(errL2r[xx-2]/errL2r[xx-1])) # H1rorder[xx-1] = np.abs(np.log2(errH1r[xx-2]/errH1r[xx-1])) import pandas as pd # LatexTitles = ["l","DoFu","Dofp","V-L2","L2-order","V-H1","H1-order","P-L2","PL2-order"] # LatexValues = np.concatenate((level,Velocitydim,Pressuredim,errL2u,l2uorder,errH1u,H1uorder,errL2p,l2porder), axis=1) # LatexTable = pd.DataFrame(LatexValues, columns = LatexTitles) # pd.set_option('precision',3) # LatexTable = MO.PandasFormat(LatexTable,"V-L2","%2.4e") # LatexTable = MO.PandasFormat(LatexTable,'V-H1',"%2.4e") # LatexTable = MO.PandasFormat(LatexTable,"H1-order","%1.2f") # LatexTable = MO.PandasFormat(LatexTable,'L2-order',"%1.2f") # LatexTable = MO.PandasFormat(LatexTable,"P-L2","%2.4e") # LatexTable = MO.PandasFormat(LatexTable,'PL2-order',"%1.2f") # print LatexTable # # # print "\n\n Magnetic convergence" # MagneticTitles = ["l","B DoF","R DoF","B-L2","L2-order","B-Curl","HCurl-order"] # MagneticValues = np.concatenate((level,Magneticdim,Lagrangedim,errL2b,l2border,errCurlb,Curlborder),axis=1) # MagneticTable= pd.DataFrame(MagneticValues, columns = MagneticTitles) # pd.set_option('precision',3) # MagneticTable = MO.PandasFormat(MagneticTable,"B-Curl","%2.4e") # MagneticTable = MO.PandasFormat(MagneticTable,'B-L2',"%2.4e") # MagneticTable = MO.PandasFormat(MagneticTable,"L2-order","%1.2f") # MagneticTable = MO.PandasFormat(MagneticTable,'HCurl-order',"%1.2f") # print MagneticTable # # # # # import pandas as pd # print "\n\n Iteration table" if IterType == "Full": IterTitles = ["l","DoF","AV solve Time","Total picard time","picard iterations","Av Outer its","Av Inner its",] else: IterTitles = ["l","DoF","AV solve Time","Total picard time","picard iterations","Av NS iters","Av M iters"] IterValues = np.concatenate((level,Wdim,SolTime,TotalTime,iterations,Mave,NSave),axis=1) IterTable= pd.DataFrame(IterValues, columns = IterTitles) if IterType == "Full": IterTable = MO.PandasFormat(IterTable,'Av Outer its',"%2.1f") IterTable = MO.PandasFormat(IterTable,'Av Inner its',"%2.1f") else: IterTable = MO.PandasFormat(IterTable,'Av NS iters',"%2.1f") IterTable = MO.PandasFormat(IterTable,'Av M iters',"%2.1f") print IterTable.to_latex() print " \n Outer Tol: ",OuterTol, "Inner Tol: ", InnerTol # # # if (ShowResultPlots == 'yes'): # plot(u_k) # plot(interpolate(u0,Velocity)) # # plot(p_k) # # plot(interpolate(p0,Pressure)) # # plot(b_k) # plot(interpolate(b0,Magnetic)) # # plot(r_k) # plot(interpolate(r0,Lagrange)) # # interactive() interactive()
def step(iself, snes, X, F, Y): # X is the current guess for the solution # F is the residual as defined by F(u^k) where we are trying to solve F(u) = 0 # Y is where the step is stored Xorig = X.copy() # The residual is changed in newresidual for convergence testing and # linesearch purposes. The following line resets the residual to whatever # it should be for semismooth Newton step calculation F.axpy(+1.0, self.residualChanges) J = snes.getJacobian()[0] snes.computeJacobian(X, J) # To make the notation more mathematical z = X dz = Y # Make copies of the stored slack variables slack_lb = self.slack_lb.copy() slack_ub = self.slack_ub.copy() # Calculate the active and inactive sets lb_active_dofs = where( slack_lb.array_r - (z.array_r - lb.array_r) > 0)[0].astype('int32') lb_active_is = PETSc.IS().createGeneral(lb_active_dofs, comm=comm) lb_inactive_dofs = where( slack_lb.array_r - (z.array_r - lb.array_r) <= 0)[0].astype('int32') lb_inactive_is = PETSc.IS().createGeneral(lb_inactive_dofs, comm=comm) self.lb_active_is_old = lb_active_is ub_active_dofs = where( slack_ub.array_r - (ub.array_r - z.array_r) > 0)[0].astype('int32') ub_active_is = PETSc.IS().createGeneral(ub_active_dofs, comm=comm) ub_inactive_dofs = where( slack_ub.array_r - (ub.array_r - z.array_r) <= 0)[0].astype('int32') ub_inactive_is = PETSc.IS().createGeneral(ub_inactive_dofs, comm=comm) self.ub_active_is_old = ub_active_is inactive_dofs = array(list( set(lb_inactive_dofs).intersection(set(ub_inactive_dofs))), dtype=int32) inactive_is = PETSc.IS().createGeneral(inactive_dofs, comm=comm) self.inactive_is_old = inactive_is dz_lb_active = dz.getSubVector(lb_active_is) dz_ub_active = dz.getSubVector(ub_active_is) dz_inactive = dz.getSubVector(inactive_is) # Set dz where the lower bound is active. lb_active = lb.getSubVector(lb_active_is) z_lb_active = z.getSubVector(lb_active_is) lb_active.copy( dz_lb_active) # where lower bound is active: dz = lb dz_lb_active.axpy( -1.0, z_lb_active) # dz = lb - z z.restoreSubVector(lb_active_is, z_lb_active) # Set dz where the upper bound is active. ub_active = ub.getSubVector(ub_active_is) z_ub_active = z.getSubVector(ub_active_is) ub_active.copy( dz_ub_active) # where upper bound is active: dz = ub dz_ub_active.axpy( -1.0, z_ub_active) # dz = ub - z z.restoreSubVector(ub_active_is, z_ub_active) # Solve the PDE where the constraints are inactive. M = J M_inact = get_deep_submat(M, inactive_is, inactive_is) M_lb = get_deep_submat(M, inactive_is, lb_active_is) M_ub = get_deep_submat(M, inactive_is, ub_active_is) F_inact = F.getSubVector(inactive_is) rhs = -F_inact.copy() tmp = F_inact.duplicate() M_lb.mult(dz_lb_active, tmp) rhs.axpy(-1.0, tmp) M_ub.mult(dz_ub_active, tmp) rhs.axpy(-1.0, tmp) ksp = PETSc.KSP().create(comm=comm) ksp.setOperators(M_inact) ksp.setType("preonly") ksp.pc.setType("lu") ksp.pc.setFactorSolverType("mumps") ksp.setFromOptions() ksp.setUp() ksp.solve(rhs, dz_inactive) del rhs del M_ub, M_lb, M_inact F.restoreSubVector(inactive_is, F_inact) lb.restoreSubVector(lb_active_is, lb_active) ub.restoreSubVector(ub_active_is, ub_active) dz.restoreSubVector(inactive_is, dz_inactive) # Now update inactive set of the slacks slack_lb_inactive = slack_lb.getSubVector(inactive_is) slack_ub_inactive = slack_ub.getSubVector(inactive_is) slack_lb_inactive.array[:] = 0 slack_ub_inactive.array[:] = 0 slack_lb.restoreSubVector(inactive_is, slack_lb_inactive) slack_ub.restoreSubVector(inactive_is, slack_ub_inactive) # Active set of slacks are updated when calculating the new residual # Store active sets of residual for later use in updating slacks F_lb = F.getSubVector(lb_active_is) self.Flb = F_lb.copy() F.restoreSubVector(lb_active_is, F_lb) F_ub = F.getSubVector(ub_active_is) self.Fub = F_ub.copy() F.restoreSubVector(ub_active_is, F_ub) # Store Hessian used later to update slacks self.M = M.copy() dz.restoreSubVector(ub_active_is, dz_ub_active) dz.restoreSubVector(lb_active_is, dz_lb_active) # dz was only a pointer, so Y is up to date. Y.scale(-1.0) # PETsc has weird conventions.... # Update stored slacks slack_lb.copy(self.slack_lb) slack_ub.copy(self.slack_ub) # Compute resizing due to deflation tau = compute_tau(deflation, problem.u, Y, None) Y.scale(tau) # Store current iterate and step for later convergence testing self.Xold = X.copy() self.Y = Y.copy()
KSPlinearfluids, MatrixLinearFluids = PrecondSetup.FluidLinearSetup( PressureF, MU, mesh) kspFp, Fp = PrecondSetup.FluidNonLinearSetup(PressureF, MU, u_k, mesh) IS = MO.IndexSet(W, 'Blocks') eps = 1.0 # error measure ||u-u_k|| tol = 1.0E-4 # tolerance iter = 0 # iteration counter maxiter = 5 # max no of iterations allowed SolutionTime = 0 outer = 0 # parameters['linear_algebra_backend'] = 'uBLAS' u_is = PETSc.IS().createGeneral(W.sub(0).dofmap().dofs()) p_is = PETSc.IS().createGeneral(W.sub(1).dofmap().dofs()) b_is = PETSc.IS().createGeneral(W.sub(2).dofmap().dofs()) r_is = PETSc.IS().createGeneral(W.sub(3).dofmap().dofs()) NS_is = PETSc.IS().createGeneral(range(VelocityF.dim() + PressureF.dim())) M_is = PETSc.IS().createGeneral( range(VelocityF.dim() + PressureF.dim(), W.dim())) bcu = DirichletBC(W.sub(0), Expression(("0.0", "0.0"), degree=4), boundary) bcp = DirichletBC(W.sub(1), Expression(("0.0"), degree=4), boundary) bcb = DirichletBC(W.sub(2), Expression(("0.0", "0.0"), degree=4), boundary) bcr = DirichletBC(W.sub(3), Expression("0.0", degree=4), boundary) bcs = [bcu, bcb, bcr] OuterTol = 1e-5 InnerTol = 1e-5 NSits = 0 Mits = 0
PP = assemble(prec) bcc.apply(PP) P = CP.Assemble(PP) b = bb.array() zeros = 0*b bb = IO.arrayToVec(b) x = IO.arrayToVec(zeros) ksp = PETSc.KSP() ksp.create(comm=PETSc.COMM_WORLD) # ksp.setTolerances(1e-5) ksp.setType('gmres') pc = ksp.getPC() u_is = PETSc.IS().createGeneral(range(V.dim())) F = A.getSubMatrix(u_is,u_is) KspF = NSsetup.Ksp(F) pc.setType('python') pc.setType(PETSc.PC.Type.PYTHON) if Solver == "LSC": pc.setPythonContext(NSprecond.NSLSC(W,KspF,KspL,QB)) # elif Solver == "PCD": # F = assemble(fp) # F = CP.Assemble(F) # pc.setPythonContext(NSprecond.PCD(W, A, Mass, F, L)) ksp.setOperators(A)
def getSubMatCSRrepresentation(self, start, end): from petsc4py import PETSc ids = range(start, end) isg = PETSc.IS().createGeneral(ids) B = self.A.getSubMatrix(isg) return B.getValuesCSR()
bcb = DirichletBC(W.sub(2), Expression(("0", "0")), boundary) bcr = DirichletBC(W.sub(3), Expression(("0")), boundary) bcs = [bcu, bcb, bcr] eps = 1.0 # error measure ||u-u_k|| tol = 1.0E-5 # tolerance iter = 0 # iteration counter maxiter = 4 # max no of iterations allowed SolutionTime = 0 outer = 0 parameters['linear_algebra_backend'] = 'uBLAS' p = forms.Preconditioner(mesh, W, u_k, b_k, params, IterType) PP, Pb = assemble_system(p, Lns, bcs) NS_is = PETSc.IS().createGeneral(range(Velocity.dim() + Pressure.dim())) M_is = PETSc.IS().createGeneral( range(Velocity.dim() + Pressure.dim(), W.dim())) if IterType == "Full" or IterType == "MD": (pQ) = TrialFunction(Pressure) (qQ) = TestFunction(Pressure) print MU Q = assemble(inner(pQ, qQ) * dx) L = assemble(inner(grad(pQ), grad(qQ)) * dx) n = FacetNormal(mesh) fp = MU * inner(grad(qQ), grad(pQ)) * dx + inner( (u_k[0] * grad(pQ)[0] + u_k[1] * grad(pQ)[1]), qQ) * dx + ( 1 / 2) * div(u_k) * inner(pQ, qQ) * dx - (1 / 2) * ( u_k[0] * n[0] + u_k[1] * n[1]) * inner(pQ, qQ) * ds L = CP.Assemble(L)
assemble(r_f + r_f, tensor=b) for bc in bcs: bc.apply(A, b) Amat = A.mat() parprint("Assembled in {}s".format(time() - tt)) tt = time() ksp = PETSc.KSP().create() ksp.setOperators(Amat, Amat) pc = ksp.getPC() ksp.setOptionsPrefix("fp_") # Set fieldsplit dofs pc.setType('fieldsplit') is_f = PETSc.IS().createGeneral(V.sub(0).dofmap().dofs()) is_p = PETSc.IS().createGeneral(V.sub(1).dofmap().dofs()) pc.setFieldSplitIS((None, is_f)) pc.setFieldSplitIS((None, is_p)) pc.setFromOptions() ksp.setFromOptions() ksp.solve(b.vec(), sol.vector().vec()) parprint("Solved in {} iterations in {}s".format(ksp.getIterationNumber(), time() - tt)) # Weak scaling (100k per core): # -np 1 -N 16: Solves in 1.12s # -np 2 -N 20: Solves in 1.49s # -np 4 -N 25: Solves in 2.61s # -np 6 -N 29: Solves in 3.66s
def testApplyIS(self): is_in = PETSc.IS().createStride(self.lgmap.getSize()) is_out = self.lgmap.apply(is_in)
V = FunctionSpace(mesh, 'CG', 1) u = TrialFunction(V) v = TestFunction(V) # Project boundary conditions M = assemble(inner(u, v)*ds) b = assemble(inner(u_exact, v)*ds) bc = DirichletBC(V, Constant(0), DomainBoundary()) b_dofs = bc.get_boundary_values().keys() # ----------------------------------------------------------------------------- Ab_ = PETSc.Mat() bb_ = PETSc.Vec() # ----------------------------------------------------------------------------- indices = [1, 2, 3] rows = PETSc.IS() rows.createGeneral(indices) A_.getSubMatrix(rows, rows, Ab_) b_.getSubVector(rows, bb_) Ab = PETScMatrix(Ab_) bb = PETScVector(bb_) print Ab.array() print bb.array()
def postprocess(self, inputSetup): """Interpolate a given electric field for a vector of receivers. :param object inputSetup: user input setup. """ # --------------------------------------------------------------- # Initialization # --------------------------------------------------------------- # Start timer Timers()["Postprocessing"].start() Print.master(' Postprocessing solution') # Parameters shortcut (for code legibility) model = inputSetup.model run = inputSetup.run output = inputSetup.output # Ranges over receivers Istart_receivers, Iend_receivers = self.receivers.getOwnershipRange() # Number of receivers total_num_receivers = self.receivers.getSize()[0] local_num_receivers = Iend_receivers - Istart_receivers # Define constants num_nodes_per_element = 4 num_faces_per_element = 4 num_edges_per_face = 3 num_edges_per_element = 6 num_nodes_per_edge = 2 num_dimensions = 3 # Compute number of dofs per element num_dof_in_element = np.int(model.basis_order * (model.basis_order + 2) * (model.basis_order + 3) / 2) # --------------------------------------------------------------- # Get dofs-connectivity for receivers # --------------------------------------------------------------- # Auxiliar arrays dofsIdxRecv = np.zeros((local_num_receivers, num_dof_in_element), dtype=PETSc.IntType) j = 0 for i in np.arange(Istart_receivers, Iend_receivers): # Get dofs for receiver tmp = (self.receivers.getRow(i)[1].real).astype(PETSc.IntType) tmp = tmp[53::] dofsIdxRecv[j, :] = tmp j += 1 # Gather global solution of x to local vector # Sequential vector for gather tasks x_local = createSequentialVector(local_num_receivers * num_dof_in_element, run.cuda, communicator=None) # Build Index set in PETSc format IS_dofs = PETSc.IS().createGeneral(dofsIdxRecv.flatten(), comm=PETSc.COMM_WORLD) # Build gather vector gatherVector = PETSc.Scatter().create(self.x, IS_dofs, x_local, None) # Ghater values gatherVector.scatter(self.x, x_local, PETSc.InsertMode.INSERT_VALUES, PETSc.ScatterMode.FORWARD) # --------------------------------------------------------------- # Allocate parallel arrays for output # --------------------------------------------------------------- receiver_fieldX = createParallelVector(total_num_receivers, run.cuda, communicator=None) receiver_fieldY = createParallelVector(total_num_receivers, run.cuda, communicator=None) receiver_fieldZ = createParallelVector(total_num_receivers, run.cuda, communicator=None) receiver_coordinatesX = createParallelVector(total_num_receivers, run.cuda, communicator=None) receiver_coordinatesY = createParallelVector(total_num_receivers, run.cuda, communicator=None) receiver_coordinatesZ = createParallelVector(total_num_receivers, run.cuda, communicator=None) k = 0 for i in np.arange(Istart_receivers, Iend_receivers): # Get receiver data receiver_data = self.receivers.getRow(i)[1].real # Get indexes of nodes for i nodesEle = receiver_data[0:4].astype(np.int) # Get nodes coordinates for i coordEle = receiver_data[4:16] coordEle = np.reshape(coordEle, (num_nodes_per_element, num_dimensions)) # Get faces indexes for i #facesEle = receiver_data[16:20].astype(np.int) # Get edges indexes for faces in i edgesFace = receiver_data[20:32].astype(np.int) edgesFace = np.reshape(edgesFace, (num_faces_per_element, num_edges_per_face)) # Get indexes of edges for i edgesEle = receiver_data[32:38].astype(np.int) # Get node indexes for edges in i edgesNodesEle = receiver_data[38:50].astype(np.int) edgesNodesEle = np.reshape( edgesNodesEle, (num_edges_per_element, num_nodes_per_edge)) # Get receiver coordinates coordReceiver = receiver_data[50:53] # Get dofs for i #dofsSource = receiver_data[53::].astype(PETSc.IntType) # Compute jacobian for i _, invjacobian = computeJacobian(coordEle) # Compute global orientation for i edge_orientation, face_orientation = computeElementOrientation( edgesEle, nodesEle, edgesNodesEle, edgesFace) # Transform xyz source position to XiEtaZeta coordinates (reference tetrahedral element) XiEtaZeta = tetrahedronXYZToXiEtaZeta(coordEle, coordReceiver) # Compute basis for i basis = computeBasisFunctions(edge_orientation, face_orientation, invjacobian, model.basis_order, XiEtaZeta) # Get element fields local_field = x_local[k * num_dof_in_element:(k * num_dof_in_element) + num_dof_in_element] # Initialize variables Ex = 0. Ey = 0. Ez = 0. # Interpolate electric field for j in np.arange(num_dof_in_element): Rfield = np.real(local_field[j]) # Real part Ifield = np.imag(local_field[j]) # Imaginary part # Exyz[i] = Exyz[i] + real_part*basis + imag_part*basis Ex += Rfield * basis[0, j] + np.sqrt( -1. + 0.j) * Ifield * basis[0, j] Ey += Rfield * basis[1, j] + np.sqrt( -1. + 0.j) * Ifield * basis[1, j] Ez += Rfield * basis[2, j] + np.sqrt( -1. + 0.j) * Ifield * basis[2, j] # Increase counter over local vector (x_local) k += 1 # Set total field components for i receiver_fieldX.setValue(i, Ex, addv=PETSc.InsertMode.INSERT_VALUES) receiver_fieldY.setValue(i, Ey, addv=PETSc.InsertMode.INSERT_VALUES) receiver_fieldZ.setValue(i, Ez, addv=PETSc.InsertMode.INSERT_VALUES) # Set coordinates for i receiver_coordinatesX.setValue(i, coordReceiver[0], addv=PETSc.InsertMode.INSERT_VALUES) receiver_coordinatesY.setValue(i, coordReceiver[1], addv=PETSc.InsertMode.INSERT_VALUES) receiver_coordinatesZ.setValue(i, coordReceiver[2], addv=PETSc.InsertMode.INSERT_VALUES) # Start global assembly receiver_fieldX.assemblyBegin() receiver_fieldY.assemblyBegin() receiver_fieldZ.assemblyBegin() receiver_coordinatesX.assemblyBegin() receiver_coordinatesY.assemblyBegin() receiver_coordinatesZ.assemblyBegin() # End global assembly receiver_fieldX.assemblyEnd() receiver_fieldY.assemblyEnd() receiver_fieldZ.assemblyEnd() receiver_coordinatesX.assemblyEnd() receiver_coordinatesY.assemblyEnd() receiver_coordinatesZ.assemblyEnd() # Write intermediate results out_path = output.directory_scratch + '/fieldsX.dat' writePetscVector(out_path, receiver_fieldX, communicator=None) out_path = output.directory_scratch + '/fieldsY.dat' writePetscVector(out_path, receiver_fieldY, communicator=None) out_path = output.directory_scratch + '/fieldsZ.dat' writePetscVector(out_path, receiver_fieldZ, communicator=None) out_path = output.directory_scratch + '/receiver_coordinatesX.dat' writePetscVector(out_path, receiver_coordinatesX, communicator=None) out_path = output.directory_scratch + '/receiver_coordinatesY.dat' writePetscVector(out_path, receiver_coordinatesY, communicator=None) out_path = output.directory_scratch + '/receiver_coordinatesZ.dat' writePetscVector(out_path, receiver_coordinatesZ, communicator=None) # Write final solution if MPIEnvironment().rank == 0: input_file = output.directory_scratch + '/fieldsX.dat' electric_fieldsX = readPetscVector(input_file, communicator=PETSc.COMM_SELF) input_file = output.directory_scratch + '/fieldsY.dat' electric_fieldsY = readPetscVector(input_file, communicator=PETSc.COMM_SELF) input_file = output.directory_scratch + '/fieldsZ.dat' electric_fieldsZ = readPetscVector(input_file, communicator=PETSc.COMM_SELF) input_file = output.directory_scratch + '/receiver_coordinatesX.dat' recv_coordX = readPetscVector(input_file, communicator=PETSc.COMM_SELF) input_file = output.directory_scratch + '/receiver_coordinatesY.dat' recv_coordY = readPetscVector(input_file, communicator=PETSc.COMM_SELF) input_file = output.directory_scratch + '/receiver_coordinatesZ.dat' recv_coordZ = readPetscVector(input_file, communicator=PETSc.COMM_SELF) # Allocate data_fields = np.zeros((total_num_receivers, 3), dtype=np.complex) data_coordinates = np.zeros((total_num_receivers, 3), dtype=np.float) # Loop over receivers for i in np.arange(total_num_receivers): # Get electric field components data_fields[i, 0] = electric_fieldsX.getValue(i) data_fields[i, 1] = electric_fieldsY.getValue(i) data_fields[i, 2] = electric_fieldsZ.getValue(i) # Get coordinates data_coordinates[i, 0] = recv_coordX.getValue(i).real data_coordinates[i, 1] = recv_coordY.getValue(i).real data_coordinates[i, 2] = recv_coordZ.getValue(i).real # Write final output output_file = output.directory + '/electric_fields.h5' fileID = h5py.File(output_file, 'w') # Create coordinates dataset _ = fileID.create_dataset('electric_fields', data=data_fields) _ = fileID.create_dataset('receiver_coordinates', data=data_coordinates) # Close file fileID.close() # Remove temporal directory shutil.rmtree(output.directory_scratch) # Stop timer Timers()["Postprocessing"].stop()
draw(Ap) # Print on file viewer.createASCII(name='test_viewer.txt') viewer.pushFormat(viewer.Format.ASCII_DENSE) Ap.view(viewer=viewer) """ Mat Object: 1 MPI processes type: seqaij row 0: (0, 0.166667) (1, 0.0416667) (2, 0.0833333) (3, 0.0416667) row 1: (0, 0.0416667) (1, 0.0833333) (2, 0.0416667) row 2: (0, 0.0833333) (1, 0.0416667) (2, 0.166667) (3, 0.0416667) row 3: (0, 0.0416667) (2, 0.0416667) (3, 0.0833333) """ iset = PETSc.IS().createGeneral([0, 1]) # select indicies 0 and 1 iset2 = PETSc.IS().createGeneral([1, 0]) # select indicies 1 and 0 Ap1, = Ap.createSubMatrices(iset, iscols=iset) # Plot on screen (approach 1) viewer.createDraw() Ap1.view(viewer=viewer) # Plot on the screen (approach 2) #draw = PETSc.Viewer.DRAW(Ap1.comm) #draw(Ap1) """ Mat Object: 1 MPI processes type: seqaij row 0: (0, 0.166667) (1, 0.0416667) row 1: (0, 0.0416667) (1, 0.0833333)
# Set near null space for pressure null_vec = A.createVecLeft() offset = V.dofmap.index_map.size_local * V.dofmap.index_map.block_size null_vec.array[offset:] = 1.0 null_vec.normalize() nsp = PETSc.NullSpace().create(vectors=[null_vec]) assert nsp.test(A) A.setNullSpace(nsp) # Build IndexSets for each field (global dof indices for each field) V_map = V.dofmap.index_map Q_map = Q.dofmap.index_map offset_u = V_map.local_range[0] * V_map.block_size + Q_map.local_range[0] offset_p = offset_u + V_map.size_local * V_map.block_size is_u = PETSc.IS().createStride(V_map.size_local * V_map.block_size, offset_u, 1, comm=PETSc.COMM_SELF) is_p = PETSc.IS().createStride(Q_map.size_local, offset_p, 1, comm=PETSc.COMM_SELF) # Create Krylov solver ksp = PETSc.KSP().create(mesh.mpi_comm()) ksp.setOperators(A, P) ksp.setTolerances(rtol=1e-8) ksp.setType("minres") ksp.getPC().setType("fieldsplit") ksp.getPC().setFieldSplitType(PETSc.PC.CompositeType.ADDITIVE) ksp.getPC().setFieldSplitIS(("u", is_u), ("p", is_p))
def __init__(self, pardofs): self.pardofs = pardofs comm = pardofs.comm.mpi4py globnums, nglob = pardofs.EnumerateGlobally() self.iset = psc.IS().createGeneral(indices=globnums, comm=comm)
def setUp(self): v1, v2 = PETSc.Vec().createSeq(0), PETSc.Vec().createSeq(0) i1, i2 = PETSc.IS().createGeneral([]), PETSc.IS().createGeneral([]) self.obj = PETSc.Scatter().createWithData(v1, i1, v2, i2) del v1, v2, i1, i2
def setUp(self): self.idx = self._mk_idx(PETSc.COMM_WORLD) self.iset = PETSc.IS().createGeneral(self.idx, comm=PETSc.COMM_WORLD) self.lgmap = PETSc.LGMap().create(self.iset)
def foo(): m = 5 errL2u = np.zeros((m - 1, 1)) errH1u = np.zeros((m - 1, 1)) errL2p = np.zeros((m - 1, 1)) errL2b = np.zeros((m - 1, 1)) errCurlb = np.zeros((m - 1, 1)) errL2r = np.zeros((m - 1, 1)) errH1r = np.zeros((m - 1, 1)) l2uorder = np.zeros((m - 1, 1)) H1uorder = np.zeros((m - 1, 1)) l2porder = np.zeros((m - 1, 1)) l2border = np.zeros((m - 1, 1)) Curlborder = np.zeros((m - 1, 1)) l2rorder = np.zeros((m - 1, 1)) H1rorder = np.zeros((m - 1, 1)) NN = np.zeros((m - 1, 1)) DoF = np.zeros((m - 1, 1)) Velocitydim = np.zeros((m - 1, 1)) Magneticdim = np.zeros((m - 1, 1)) Pressuredim = np.zeros((m - 1, 1)) Lagrangedim = np.zeros((m - 1, 1)) Wdim = np.zeros((m - 1, 1)) iterations = np.zeros((m - 1, 1)) SolTime = np.zeros((m - 1, 1)) udiv = np.zeros((m - 1, 1)) MU = np.zeros((m - 1, 1)) level = np.zeros((m - 1, 1)) NSave = np.zeros((m - 1, 1)) Mave = np.zeros((m - 1, 1)) TotalTime = np.zeros((m - 1, 1)) nn = 2 dim = 2 ShowResultPlots = 'yes' split = 'Linear' MU[0] = 1e0 for xx in xrange(1, m): print xx level[xx - 1] = xx + 0 nn = 2**(level[xx - 1]) # Create mesh and define function space nn = int(nn) NN[xx - 1] = nn / 2 # parameters["form_compiler"]["quadrature_degree"] = 6 # parameters = CP.ParameterSetup() mesh = UnitCubeMesh(nn, nn, nn) # BoxDomain = mshr.Box(dolfin.Point(0., 0., 0.), dolfin.Point(2., 2., 2.)) - mshr.Box(dolfin.Point(1., 1., 1.), dolfin.Point(2., 2., 2.)) # mesh = mshr.generate_mesh(BoxDomain, nn) order = 2 parameters['reorder_dofs_serial'] = False Velocity = VectorFunctionSpace(mesh, "CG", order) Pressure = FunctionSpace(mesh, "CG", order - 1) Magnetic = FunctionSpace(mesh, "N1curl", order - 1) Lagrange = FunctionSpace(mesh, "CG", order - 1) W = MixedFunctionSpace([Velocity, Pressure, Magnetic, Lagrange]) # W = Velocity*Pressure*Magnetic*Lagrange Velocitydim[xx - 1] = Velocity.dim() Pressuredim[xx - 1] = Pressure.dim() Magneticdim[xx - 1] = Magnetic.dim() Lagrangedim[xx - 1] = Lagrange.dim() Wdim[xx - 1] = W.dim() print "\n\nW: ", Wdim[xx - 1], "Velocity: ", Velocitydim[ xx - 1], "Pressure: ", Pressuredim[xx - 1], "Magnetic: ", Magneticdim[ xx - 1], "Lagrange: ", Lagrangedim[xx - 1], "\n\n" dim = [Velocity.dim(), Pressure.dim(), Magnetic.dim(), Lagrange.dim()] def boundary(x, on_boundary): return on_boundary u0, p0, b0, r0, Laplacian, Advection, gradPres, CurlCurl, gradR, NS_Couple, M_Couple = ExactSol.MHD3D( 4, 1) bcu = DirichletBC(Velocity, u0, boundary) bcb = DirichletBC(Magnetic, b0, boundary) bcr = DirichletBC(Lagrange, r0, boundary) # bc = [u0,p0,b0,r0] bcs = [bcu, bcb, bcr] FSpaces = [Velocity, Pressure, Magnetic, Lagrange] (u, b, p, r) = TrialFunctions(W) (v, c, q, s) = TestFunctions(W) kappa = 1.0 Mu_m = 10.0 MU = 1.0 / 1 IterType = 'Full' Split = "No" Saddle = "No" Stokes = "No" SetupType = 'python-class' F_NS = -MU * Laplacian + Advection + gradPres - kappa * NS_Couple if kappa == 0: F_M = Mu_m * CurlCurl + gradR - kappa * M_Couple else: F_M = Mu_m * kappa * CurlCurl + gradR - kappa * M_Couple params = [kappa, Mu_m, MU] MO.PrintStr("Seting up initial guess matricies", 2, "=", "\n\n", "\n") BCtime = time.time() BC = MHDsetup.BoundaryIndices(mesh) MO.StrTimePrint("BC index function, time: ", time.time() - BCtime) Hiptmairtol = 1e-5 HiptmairMatrices = PrecondSetup.MagneticSetup(Magnetic, Lagrange, b0, r0, Hiptmairtol, params) MO.PrintStr("Setting up MHD initial guess", 5, "+", "\n\n", "\n\n") u_k, p_k, b_k, r_k = common.InitialGuess(FSpaces, [u0, p0, b0, r0], [F_NS, F_M], params, HiptmairMatrices, 1e-10, Neumann=Expression( ("0", "0")), options="New") b_t = TrialFunction(Velocity) c_t = TestFunction(Velocity) ones = Function(Pressure) ones.vector()[:] = (0 * ones.vector().array() + 1) # pConst = - assemble(p_k*dx)/assemble(ones*dx) p_k.vector()[:] += -assemble(p_k * dx) / assemble(ones * dx) x = Iter.u_prev(u_k, p_k, b_k, r_k) KSPlinearfluids, MatrixLinearFluids = PrecondSetup.FluidLinearSetup( Pressure, MU) kspFp, Fp = PrecondSetup.FluidNonLinearSetup(Pressure, MU, u_k) #plot(b_k) ns, maxwell, CoupleTerm, Lmaxwell, Lns = forms.MHD2D( mesh, W, F_M, F_NS, u_k, b_k, params, IterType, "CG", Saddle, Stokes) RHSform = forms.PicardRHS(mesh, W, u_k, p_k, b_k, r_k, params, "CG", Saddle, Stokes) bcu = DirichletBC(W.sub(0), Expression(("0.0", "0.0", "0.0")), boundary) bcb = DirichletBC(W.sub(2), Expression(("0.0", "0.0", "0.0")), boundary) bcr = DirichletBC(W.sub(3), Expression(("0.0")), boundary) bcs = [bcu, bcb, bcr] parameters['linear_algebra_backend'] = 'uBLAS' eps = 1.0 # error measure ||u-u_k|| tol = 1.0E-4 # tolerance iter = 0 # iteration counter maxiter = 10 # max no of iterations allowed SolutionTime = 0 outer = 0 # parameters['linear_algebra_backend'] = 'uBLAS' # FSpaces = [Velocity,Magnetic,Pressure,Lagrange] if IterType == "CD": MO.PrintStr("Setting up PETSc " + SetupType, 2, "=", "\n", "\n") Alin = MHDsetup.Assemble(W, ns, maxwell, CoupleTerm, Lns, Lmaxwell, RHSform, bcs + BC, "Linear", IterType) Fnlin, b = MHDsetup.Assemble(W, ns, maxwell, CoupleTerm, Lns, Lmaxwell, RHSform, bcs + BC, "NonLinear", IterType) A = Fnlin + Alin A, b = MHDsetup.SystemAssemble(FSpaces, A, b, SetupType, IterType) u = b.duplicate() u_is = PETSc.IS().createGeneral(range(Velocity.dim())) NS_is = PETSc.IS().createGeneral(range(Velocity.dim() + Pressure.dim())) M_is = PETSc.IS().createGeneral( range(Velocity.dim() + Pressure.dim(), W.dim())) OuterTol = 1e-5 InnerTol = 1e-5 NSits = 0 Mits = 0 TotalStart = time.time() SolutionTime = 0 while eps > tol and iter < maxiter: iter += 1 MO.PrintStr("Iter " + str(iter), 7, "=", "\n\n", "\n\n") AssembleTime = time.time() if IterType == "CD": MO.StrTimePrint("MHD CD RHS assemble, time: ", time.time() - AssembleTime) b = MHDsetup.Assemble(W, ns, maxwell, CoupleTerm, Lns, Lmaxwell, RHSform, bcs + BC, "CD", IterType) else: MO.PrintStr("Setting up PETSc " + SetupType, 2, "=", "\n", "\n") if Split == "Yes": if iter == 1: Alin = MHDsetup.Assemble(W, ns, maxwell, CoupleTerm, Lns, Lmaxwell, RHSform, bcs + BC, "Linear", IterType) Fnlin, b = MHDsetup.Assemble(W, ns, maxwell, CoupleTerm, Lns, Lmaxwell, RHSform, bcs + BC, "NonLinear", IterType) A = Fnlin + Alin A, b = MHDsetup.SystemAssemble(FSpaces, A, b, SetupType, IterType) u = b.duplicate() else: Fnline, b = MHDsetup.Assemble(W, ns, maxwell, CoupleTerm, Lns, Lmaxwell, RHSform, bcs + BC, "NonLinear", IterType) A = Fnlin + Alin A, b = MHDsetup.SystemAssemble(FSpaces, A, b, SetupType, IterType) else: AA, bb = assemble_system(maxwell + ns + CoupleTerm, (Lmaxwell + Lns) - RHSform, bcs) A, b = CP.Assemble(AA, bb) # if iter == 1: MO.StrTimePrint("MHD total assemble, time: ", time.time() - AssembleTime) u = b.duplicate() kspFp, Fp = PrecondSetup.FluidNonLinearSetup(Pressure, MU, u_k) print "Inititial guess norm: ", u.norm( PETSc.NormType.NORM_INFINITY) #A,Q if IterType == 'Full': n = FacetNormal(mesh) mat = as_matrix([[ b_k[2] * b_k[2] + b[1] * b[1], -b_k[1] * b_k[0], -b_k[0] * b_k[2] ], [ -b_k[1] * b_k[0], b_k[0] * b_k[0] + b_k[2] * b_k[2], -b_k[2] * b_k[1] ], [ -b_k[0] * b_k[2], -b_k[1] * b_k[2], b_k[0] * b_k[0] + b_k[1] * b_k[1] ]]) a = params[2] * inner(grad(b_t), grad(c_t)) * dx( W.mesh()) + inner((grad(b_t) * u_k), c_t) * dx(W.mesh( )) + (1. / 2) * div(u_k) * inner(c_t, b_t) * dx( W.mesh()) - (1. / 2) * inner(u_k, n) * inner( c_t, b_t) * ds(W.mesh()) + kappa / Mu_m * inner( mat * b_t, c_t) * dx(W.mesh()) ShiftedMass = assemble(a) bcu.apply(ShiftedMass) ShiftedMass = CP.Assemble(ShiftedMass) kspF = NSprecondSetup.LSCKSPnonlinear(ShiftedMass) else: F = A.getSubMatrix(u_is, u_is) kspF = NSprecondSetup.LSCKSPnonlinear(F) stime = time.time() u, mits, nsits = S.solve(A, b, u, params, W, 'Directclase', IterType, OuterTol, InnerTol, HiptmairMatrices, Hiptmairtol, KSPlinearfluids, Fp, kspF) Soltime = time.time() - stime MO.StrTimePrint("MHD solve, time: ", Soltime) Mits += mits NSits += nsits SolutionTime += Soltime u1, p1, b1, r1, eps = Iter.PicardToleranceDecouple( u, x, FSpaces, dim, "2", iter) p1.vector()[:] += -assemble(p1 * dx) / assemble(ones * dx) u_k.assign(u1) p_k.assign(p1) b_k.assign(b1) r_k.assign(r1) uOld = np.concatenate((u_k.vector().array(), p_k.vector().array(), b_k.vector().array(), r_k.vector().array()), axis=0) x = IO.arrayToVec(uOld) XX = np.concatenate((u_k.vector().array(), p_k.vector().array(), b_k.vector().array(), r_k.vector().array()), axis=0) SolTime[xx - 1] = SolutionTime / iter NSave[xx - 1] = (float(NSits) / iter) Mave[xx - 1] = (float(Mits) / iter) iterations[xx - 1] = iter TotalTime[xx - 1] = time.time() - TotalStart # dim = [Velocity.dim(), Pressure.dim(), Magnetic.dim(),Lagrange.dim()] # # ExactSolution = [u0,p0,b0,r0] # errL2u[xx-1], errH1u[xx-1], errL2p[xx-1], errL2b[xx-1], errCurlb[xx-1], errL2r[xx-1], errH1r[xx-1] = Iter.Errors(XX,mesh,FSpaces,ExactSolution,order,dim, "DG") # # if xx > 1: # l2uorder[xx-1] = np.abs(np.log2(errL2u[xx-2]/errL2u[xx-1])) # H1uorder[xx-1] = np.abs(np.log2(errH1u[xx-2]/errH1u[xx-1])) # # l2porder[xx-1] = np.abs(np.log2(errL2p[xx-2]/errL2p[xx-1])) # # l2border[xx-1] = np.abs(np.log2(errL2b[xx-2]/errL2b[xx-1])) # Curlborder[xx-1] = np.abs(np.log2(errCurlb[xx-2]/errCurlb[xx-1])) # # l2rorder[xx-1] = np.abs(np.log2(errL2r[xx-2]/errL2r[xx-1])) # H1rorder[xx-1] = np.abs(np.log2(errH1r[xx-2]/errH1r[xx-1])) # # # # # import pandas as pd # # # # LatexTitles = ["l","DoFu","Dofp","V-L2","L2-order","V-H1","H1-order","P-L2","PL2-order"] # LatexValues = np.concatenate((level,Velocitydim,Pressuredim,errL2u,l2uorder,errH1u,H1uorder,errL2p,l2porder), axis=1) # LatexTable = pd.DataFrame(LatexValues, columns = LatexTitles) # pd.set_option('precision',3) # LatexTable = MO.PandasFormat(LatexTable,"V-L2","%2.4e") # LatexTable = MO.PandasFormat(LatexTable,'V-H1',"%2.4e") # LatexTable = MO.PandasFormat(LatexTable,"H1-order","%1.2f") # LatexTable = MO.PandasFormat(LatexTable,'L2-order',"%1.2f") # LatexTable = MO.PandasFormat(LatexTable,"P-L2","%2.4e") # LatexTable = MO.PandasFormat(LatexTable,'PL2-order',"%1.2f") # print LatexTable # # # print "\n\n Magnetic convergence" # MagneticTitles = ["l","B DoF","R DoF","B-L2","L2-order","B-Curl","HCurl-order"] # MagneticValues = np.concatenate((level,Magneticdim,Lagrangedim,errL2b,l2border,errCurlb,Curlborder),axis=1) # MagneticTable= pd.DataFrame(MagneticValues, columns = MagneticTitles) # pd.set_option('precision',3) # MagneticTable = MO.PandasFormat(MagneticTable,"B-Curl","%2.4e") # MagneticTable = MO.PandasFormat(MagneticTable,'B-L2',"%2.4e") # MagneticTable = MO.PandasFormat(MagneticTable,"L2-order","%1.2f") # MagneticTable = MO.PandasFormat(MagneticTable,'HCurl-order',"%1.2f") # print MagneticTable import pandas as pd print "\n\n Iteration table" if IterType == "Full": IterTitles = [ "l", "DoF", "AV solve Time", "Total picard time", "picard iterations", "Av Outer its", "Av Inner its", ] else: IterTitles = [ "l", "DoF", "AV solve Time", "Total picard time", "picard iterations", "Av NS iters", "Av M iters" ] IterValues = np.concatenate( (level, Wdim, SolTime, TotalTime, iterations, Mave, NSave), axis=1) IterTable = pd.DataFrame(IterValues, columns=IterTitles) if IterType == "Full": IterTable = MO.PandasFormat(IterTable, 'Av Outer its', "%2.1f") IterTable = MO.PandasFormat(IterTable, 'Av Inner its', "%2.1f") else: IterTable = MO.PandasFormat(IterTable, 'Av NS iters', "%2.1f") IterTable = MO.PandasFormat(IterTable, 'Av M iters', "%2.1f") print IterTable print " \n Outer Tol: ", OuterTol, "Inner Tol: ", InnerTol tableName = "3d_Fichera_nu=" + str(MU) + "_nu_m=" + str( Mu_m) + "_kappa=" + str(kappa) + ".tex" IterTable.to_latex(tableName)
def solve_solid(W, f1, f2, eta_0, pT_0, p_0, bdries, bcs, parameters, nitsche_penalty): '''Return displacement, percolation velocity, pressure and final time''' print('Solving Biot for %d unknowns' % W.dim()) # NOTE: this is time dependent problem which we solve with # parameters['dt'] for parameters['nsteps'] time steps and to # update time in f1, f2 or the expressions bcs the physical time is # set as parameters['T0'] + dt*(k-th step) mesh = W.mesh() comm = mesh.mpi_comm() needed = preduce(comm, operator.or_, (set(bdries.array()), )) - set((0, )) # Validate elasticity bcs bcs_E = bcs['elasticity'] assert all(k in ('displacement', 'traction', 'nitsche_t') for k in bcs_E) displacement_bcs = bcs_E.get('displacement', ()) traction_bcs = bcs_E.get('traction', ()) nitsche_t_bcs = bcs_E.get('nitsche_t', ()) # Tuple of pairs (tag, boundary value) is expected displacement_tags = set(item[0] for item in displacement_bcs) traction_tags = set(item[0] for item in traction_bcs) nitsche_t_tags = set(item[0] for item in nitsche_t_bcs) tags = (displacement_tags, traction_tags, nitsche_t_tags) for this, that in itertools.combinations(tags, 2): if this and that: assert not this & that assert needed == preduce(comm, operator.or_, tags) # Validate Darcy bcs bcs_D = bcs['darcy'] assert all(k in ('pressure', 'flux') for k in bcs_D) pressure_bcs = bcs_D.get('pressure', ()) flux_bcs = bcs_D.get('flux', ()) # Tuple of pairs (tag, boundary value) is expected pressure_tags = set(item[0] for item in pressure_bcs) flux_tags = set(item[0] for item in flux_bcs) tags = (pressure_tags, flux_tags) for this, that in itertools.combinations(tags, 2): if this and that: assert not this & that assert needed == preduce(comm, operator.or_, tags), (needed, preduce(comm, operator.or_, tags)) # Collect bc values for possible temporal update in the integration bdry_expressions = sum(([item[1] for item in bc] for bc in (displacement_bcs, traction_bcs, pressure_bcs, flux_bcs)), []) # Nitsche is special (tag, (vel_data, stress_data)) [bdry_expressions.extend(val[1]) for val in nitsche_t_bcs] # FEM --- eta, pT, p = TrialFunctions(W) phi, qT, q = TestFunctions(W) assert len(eta.ufl_shape) == 1 and len(pT.ufl_shape) == 0 and len(p.ufl_shape) == 0 # Material parameters kappa, mu, lmbda, alpha, s0 = (parameters[k] for k in ('kappa', 'mu', 'lmbda', 'alpha', 's0')) # For weak form also time step is needed dt = Constant(parameters['dt']) # Previous solutions wh_0 = Function(W) assign(wh_0.sub(0), interpolate(eta_0, W.sub(0).collapse())) assign(wh_0.sub(1), interpolate(pT_0, W.sub(1).collapse())) assign(wh_0.sub(2), interpolate(p_0, W.sub(2).collapse())) eta_0, pT_0, p_0 = split(wh_0) # Standard bit # Elasticity a = (2*mu*inner(sym(grad(eta)), sym(grad(phi)))*dx - inner(pT, div(phi))*dx) L = inner(f1, phi)*dx # Total pressure a += -inner(div(eta), qT)*dx - (1/lmbda)*inner(pT, qT)*dx + (alpha/lmbda)*inner(p, qT)*dx # Darcy a += (alpha/lmbda)*inner(q, pT)*dx - inner((s0+alpha**2/lmbda)*p, q)*dx - inner(kappa*dt*grad(p), grad(q))*dx L += -dt*inner(f2, q)*dx - inner(s0*p_0, q)*dx - inner(alpha*div(eta_0), q)*dx # Handle natural bcs n = FacetNormal(mesh) ds = Measure('ds', domain=mesh, subdomain_data=bdries) # For elasticity for tag, value in traction_bcs: L += inner(value, phi)*ds(tag) # For Darcy for tag, value in flux_bcs: if value.ufl_shape == (): L += dt*inner(value, q)*ds(tag) # Scalar that is -kappa*grad(p).n else: assert len(value.ufl_shape) == 1 # A vector that is -kappa*grad(p) L += dt*inner(dot(value, n), q)*ds(tag) # sigma_B = lambda u, p: 2*mu*sym(grad(u)) - (-lmbda*div(u) + alpha*p)*Identity(len(u)) sigma_B = lambda u, pT: 2*mu*sym(grad(u)) - pT*Identity(len(u)) # Nitsche # We have -sigma.n . phi -> -(sigma.n.n)(phi.n) + -(sigma(eta, p).n.t)(phi.t) # <bdry data> # Symmetry # -(sigma(phi, q).n.t.(eta.t - bdry_data) # and penalize # + gamma/h (phi.t)*(eta.t - bdry_data) # Generalize cross product def wedge(x, y): (n, ) = x.ufl_shape (m, ) = y.ufl_shape assert n == m if n == 2: R = Constant(((0, -1), (1, 0))) return dot(x, dot(R, y)) else: return cross(x, y) hF = CellDiameter(mesh) for tag, (vel_data, stress_data) in nitsche_t_bcs: a += (-inner(wedge(dot(sigma_B(eta, pT), n), n), wedge(phi, n))*ds(tag) -inner(wedge(dot(sigma_B(phi, qT), n), n), wedge(eta, n))*ds(tag) + Constant(nitsche_penalty)/hF*inner(wedge(eta, n), wedge(phi, n))*ds(tag) ) L += ( # This is the velocity part -inner(wedge(dot(sigma_B(phi, qT), n), n), vel_data)*ds(tag) + Constant(nitsche_penalty)/hF*inner(vel_data, wedge(phi, n))*ds(tag) # Not the stress comess from + inner(stress_data, dot(phi, n))*ds(tag) ) # Displacement bcs and flux bcs go on the system bcs_strong = [DirichletBC(W.sub(0), value, bdries, tag) for tag, value in displacement_bcs] bcs_strong.extend([DirichletBC(W.sub(2), value, bdries, tag) for tag, value in pressure_bcs]) # Discrete problem assembler = SystemAssembler(a, L, bcs_strong) A, b = PETScMatrix(), PETScVector() # Assemble once and setup solver for it assembler.assemble(A) if parameters.get('solver', 'direct') == 'direct': solver = PETScLUSolver(A, 'mumps') ksp = solver.ksp() else: # Lee Mardal Winther preconditioner (assuming here that we are # fixing displacement somewhere). Again wishful thinking handling # of Nitsche a_prec = (2*mu*inner(sym(grad(eta)), sym(grad(phi)))*dx # Full H1 here? + (1 + 1/2/mu)*inner(pT, qT)*dx + inner((s0 + alpha**2/lmbda)*p, q)*dx + inner(kappa*dt*grad(p), grad(q))*dx) for tag, (vel_data, stress_data) in nitsche_t_bcs: # NOTE: this has pT, qT but nxn should mean that there is no # contrip to offdiagonal block a_prec += (-inner(wedge(dot(sigma_B(eta, pT), n), n), wedge(phi, n))*ds(tag) -inner(wedge(dot(sigma_B(phi, qT), n), n), wedge(eta, n))*ds(tag) + Constant(nitsche_penalty)/hF*inner(wedge(eta, n), wedge(phi, n))*ds(tag) ) B, b_dummy = PETScMatrix(), PETScVector() assemble_system(a_prec, L, bcs_strong, A_tensor=B, b_tensor=b_dummy) solver = PETScKrylovSolver() ksp = solver.ksp() ksp.setType(PETSc.KSP.Type.MINRES) ksp.setOperators(A.mat(), B.mat()) ksp.setInitialGuessNonzero(True) # For time dep problem V_dofs, QT_dofs, Q_dofs = (W.sub(i).dofmap().dofs() for i in range(3)) pc = ksp.getPC() pc.setType(PETSc.PC.Type.FIELDSPLIT) is_V = PETSc.IS().createGeneral(V_dofs) is_QT = PETSc.IS().createGeneral(QT_dofs) is_Q = PETSc.IS().createGeneral(Q_dofs) pc.setFieldSplitIS(('0', is_V), ('1', is_QT), ('2', is_Q)) pc.setFieldSplitType(PETSc.PC.CompositeType.ADDITIVE) ksp.setUp() # ... all blocks inverted AMG sweeps subksps = pc.getFieldSplitSubKSP() # NOTE: ideally this would be done with multigrid but let's see # how far LU will take us. For amg also consider grad-grad to help # it subksps[0].setType('preonly') subksps[0].getPC().setType('lu') subksps[1].setType('preonly') subksps[1].getPC().setType('hypre') subksps[2].setType('preonly') subksps[2].getPC().setType('hypre') opts = PETSc.Options() # opts.setValue('ksp_monitor_true_residual', None) opts.setValue('ksp_rtol', 1E-14) opts.setValue('ksp_atol', 1E-8) pc.setFromOptions() ksp.setFromOptions() # Temporal integration loop T0 = parameters['T0'] niters, reasons = [], [] for k in range(parameters['nsteps']): # Update source if possible for foo in bdry_expressions + [f1, f2]: hasattr(foo, 't') and setattr(foo, 't', T0) hasattr(foo, 'time') and setattr(foo, 'time', T0) assembler.assemble(b) niters.append(solver.solve(wh_0.vector(), b)) reasons.append(ksp.getConvergedReason()) T0 += dt(0) if k % 10 == 0: print(' Biot at step (%d, %g) |uh|=%g' % (k, T0, wh_0.vector().norm('l2'))) print(' KSP stats MIN/MEAN/MAX (%d|%g|%d) %d' % ( np.min(niters), np.mean(niters), np.max(niters), len(niters) )) for reason, count in Counter(reasons).items(): print(' KSP cvrg reason %s -> %d' % (KSP_CVRG_REASONS[reason], count)) niters.clear() reasons.clear() eta_h, pT_h, p_h = wh_0.split(deepcopy=True) return eta_h, pT_h, p_h, T0
def __init__(self, W): self.W = W self.u_is = PETSc.IS().createGeneral(range(W.sub(0).dim())) self.p_is = PETSc.IS().createGeneral(range(W.sub(0).dim(),W.sub(0).dim()+W.sub(1).dim()))
tol = 1.0E-8 # tolerance iter = 0 # iteration counter maxiter = 10 # max no of iterations allowed parameters = CP.ParameterSetup() outerit = 0 (p) = TrialFunction(Q) (q) = TestFunction(Q) Mass = assemble(inner(p, q) * dx) LL = assemble(inner(grad(p), grad(q)) * dx) Mass = CP.Assemble(Mass) L = CP.Assemble(LL) # u_is = PETSc.IS().createGeneral(range(W.sub(0).dim())) t_is = PETSc.IS().createGeneral(range(W.dim() - 1)) while eps > tol and iter < maxiter: iter += 1 x = Function(W) uu = Function(W) tic() AA, bb = assemble_system(a, L1 - RHSform, bcs) A, b = CP.Assemble(AA, bb) print toc() # A =A.getSubMatrix(t_is,t_is) PP = assemble(prec) # P = as_backend_type(PP).mat() P = CP.Assemble(PP) # Ps = PP.sparray()
bcr = DirichletBC(W.sub(3), Expression(("0.0")), boundary) bcs = [bcu, bcb, bcr] eps = 1.0 # error measure ||u-u_k|| tol = 1.0E-4 # tolerance iter = 0 # iteration counter maxiter = 40 # max no of iterations allowed SolutionTime = 0 outer = 0 if IterType == "CD": AA, bb = assemble_system(maxwell + ns, (Lmaxwell + Lns) - RHSform, bcs) A, b = CP.Assemble(AA, bb) b_is = PETSc.IS().createGeneral( range(Velocity.dim(), Velocity.dim() + Magnetic.dim())) u_is = PETSc.IS().createGeneral(range(Velocity.dim())) NS_is = PETSc.IS().createGeneral(range(Velocity.dim() + Pressure.dim())) M_is = PETSc.IS().createGeneral( range(Velocity.dim() + Pressure.dim(), W.dim())) OuterTol = 1e-5 InnerTol = 1e-3 NSits = 0 Mits = 0 TotalStart = time.time() SolutionTime = 0 while eps > tol and iter < maxiter: iter += 1 MO.PrintStr("Iter " + str(iter), 7, "=", "\n\n", "\n\n") tic()
P1 = FunctionSpace(mesh, "CG", 1) G = as_backend_type( DiscreteOperators.build_gradient(FunctionSpace(mesh, "N1curl", 1), P1)).mat() V1 = FunctionSpace(mesh, "N1curl", 1) constants = [Function(V1) for i in range(3)] for i, c in enumerate(constants): direction = [1.0 if i == j else 0.0 for j in range(3)] c.interpolate(Constant(direction)) pc = ksp.getPC() pc.setType("fieldsplit") pc.setFieldSplitType(0) is0 = PETSc.IS().createGeneral(V.sub(0).dofmap().dofs()) is1 = PETSc.IS().createGeneral(V.sub(1).dofmap().dofs()) pc.setFieldSplitIS(('A_r', is0), ('A_i', is1)) for subksp in pc.getFieldSplitSubKSP(): subksp.setType("cg") subksp.setTolerances(rtol=1.0e-14, atol=1.0e-14, max_it=6) subpc = subksp.getPC() subpc.setType("hypre") subpc.setHYPREType("ams") subpc.setHYPREDiscreteGradient(G) cvecs = [ as_backend_type(constant.vector()).vec() for constant in constants ] subpc.setHYPRESetEdgeConstantVectors(cvecs[0], cvecs[1], cvecs[2])
3637, 3638, 3639, 3640, 3641, 13950, 13951, 13952, 13953, 13954, 13955, 16074, 16075, 16076, 16077, 16078, 16079, 16092, 16093, 16094, 16095, 16096, 16097, 16098, 16099, 16100, 16101, 16102, 16103, 5922, 5923, 5924, 5925, 5926, 5927, 18258, 18259, 18260, 18261, 18262, 18263, 18264, 18265, 18266, 18267, 18268, 18269, 18270, 18271, 18272, 18273, 18274, 18275, 18276, 18277, 18278, 18279, 18280, 18281, 5985, 5986, 5987, 18288, 18289, 18290, 18291, 18292, 18293, 18294, 18295, 18296, 18297, 18298, 18299, 18324, 18325, 18326, 18327, 18328, 18329, 18330, 18331, 10140, 10141, 10142, 10143, 10144, 10145, 18332, 18333, 18334, 18335, 10158, 10159, 10160, 10161, 10162, 10163, 18366, 18367, 18368, 18369, 18370, 18371, 10188, 10189, 10190, 10191, 10192, 10193, 10206, 10207, 10208, 10209, 10210, 10211, 10212, 10213, 10214, 10215, 10216, 10217, 10224, 10225, 10226, 10227, 10228, 10229, 10230, 10231, 10232, 10233, 10234, 10235, 10236, 10237, 10238, 10239 ]] b2 = PETSc.IS() b2.createGeneral(B2[0]) B3 = [[]] b3 = PETSc.IS() b3.createGeneral(B3[0]) B4 = [[]] b4 = PETSc.IS() b4.createGeneral(B4[0]) B5 = [[]] b5 = PETSc.IS() b5.createGeneral(B5[0]) B6 = [[]] b6 = PETSc.IS() b6.createGeneral(B6[0]) Bpt = [b1, b2, b3, b4, b5, b6]
# Set near null space for pressure null_vec = A.createVecLeft() offset = V.dofmap.index_map.size_local * V.dofmap.index_map_bs null_vec.array[offset:] = 1.0 null_vec.normalize() nsp = PETSc.NullSpace().create(vectors=[null_vec]) assert nsp.test(A) A.setNullSpace(nsp) # Build IndexSets for each field (global dof indices for each field) V_map = V.dofmap.index_map Q_map = Q.dofmap.index_map offset_u = V_map.local_range[0] * V.dofmap.index_map_bs + Q_map.local_range[0] offset_p = offset_u + V_map.size_local * V.dofmap.index_map_bs is_u = PETSc.IS().createStride(V_map.size_local * V.dofmap.index_map_bs, offset_u, 1, comm=PETSc.COMM_SELF) is_p = PETSc.IS().createStride(Q_map.size_local, offset_p, 1, comm=PETSc.COMM_SELF) # Create Krylov solver ksp = PETSc.KSP().create(mesh.mpi_comm()) ksp.setOperators(A, P) ksp.setTolerances(rtol=1e-8) ksp.setType("minres") ksp.getPC().setType("fieldsplit") ksp.getPC().setFieldSplitType(PETSc.PC.CompositeType.ADDITIVE) ksp.getPC().setFieldSplitIS( ("u", is_u), ("p", is_p)) # Configure velocity and pressure sub KSPs ksp_u, ksp_p = ksp.getPC().getFieldSplitSubKSP()
def solve_solid(W, f1, f2, eta_0, p_0, bdries, bcs, parameters): '''Return displacement, pressure and final time''' print('Solving Biot for %d unknowns' % W.dim()) # NOTE: this is time dependent problem which we solve with # parameters['dt'] for parameters['nsteps'] time steps and to # update time in f1, f2 or the expressions bcs the physical time is # set as parameters['T0'] + dt*(k-th step) mesh = W.mesh() comm = mesh.mpi_comm() needed = preduce(comm, operator.or_, (set(bdries.array()), )) - set((0, )) # Validate elasticity bcs bcs_E = bcs['elasticity'] assert all(k in ('displacement', 'traction') for k in bcs_E) displacement_bcs = bcs_E.get('displacement', ()) traction_bcs = bcs_E.get('traction', ()) # Tuple of pairs (tag, boundary value) is expected displacement_tags = set(item[0] for item in displacement_bcs) traction_tags = set(item[0] for item in traction_bcs) tags = (displacement_tags, traction_tags) for this, that in itertools.combinations(tags, 2): if this and that: assert not this & that assert needed == preduce(comm, operator.or_, tags), (needed, preduce(comm, operator.or_, tags)) # Validate Darcy bcs bcs_D = bcs['darcy'] assert all(k in ('pressure', 'flux') for k in bcs_D) pressure_bcs = bcs_D.get('pressure', ()) flux_bcs = bcs_D.get('flux', ()) # Tuple of pairs (tag, boundary value) is expected pressure_tags = set(item[0] for item in pressure_bcs) flux_tags = set(item[0] for item in flux_bcs) tags = (pressure_tags, flux_tags) for this, that in itertools.combinations(tags, 2): if this and that: assert not this & that assert needed == preduce(comm, operator.or_, tags), (needed, preduce(comm, operator.or_, tags)) # Collect bc values for possible temporal update in the integration bdry_expressions = sum(([item[1] for item in bc] for bc in (displacement_bcs, traction_bcs, pressure_bcs, flux_bcs)), []) # FEM --- eta, p = TrialFunctions(W) phi, q = TestFunctions(W) assert len(eta.ufl_shape) == 1 and len(p.ufl_shape) == 0 # Material parameters kappa, mu, lmbda, alpha, s0 = (parameters[k] for k in ('kappa', 'mu', 'lmbda', 'alpha', 's0')) # For weak form also time step is needed dt = Constant(parameters['dt']) # Previous solutions wh_0 = Function(W) assign(wh_0.sub(0), interpolate(eta_0, W.sub(0).collapse())) assign(wh_0.sub(1), interpolate(p_0, W.sub(1).collapse())) eta_0, p_0 = split(wh_0) # Elasticity a = (2*mu*inner(sym(grad(eta)), sym(grad(phi)))*dx + inner(lmbda*div(eta), div(phi))*dx - inner(p, alpha*div(phi))*dx) L = inner(f1, phi)*dx # Darcy a += (-alpha*inner(q, div(eta))*dx - inner(s0*p, q)*dx - inner(kappa*dt*grad(p), grad(q))*dx) L += -dt*inner(f2, q)*dx - inner(s0*p_0, q)*dx - inner(alpha*div(eta_0), q)*dx # Handle natural bcs n = FacetNormal(mesh) ds = Measure('ds', domain=mesh, subdomain_data=bdries) # For elasticity for tag, value in traction_bcs: L += inner(value, phi)*ds(tag) # For Darcy for tag, value in flux_bcs: if value.ufl_shape == (): L += dt*inner(value, q)*ds(tag) # Scalar that is -kappa*grad(p).n else: assert len(value.ufl_shape) == 1 # A vector that is -kappa*grad(p) L += dt*inner(dot(value, n), q)*ds(tag) # Displacement bcs and pressure bcs go on the system bcs_strong = [DirichletBC(W.sub(0), value, bdries, tag) for tag, value in displacement_bcs] bcs_strong.extend([DirichletBC(W.sub(1), value, bdries, tag) for tag, value in pressure_bcs]) # Discrete problem assembler = SystemAssembler(a, L, bcs_strong) A, b = PETScMatrix(), PETScVector() # Assemble once and setup solver for it assembler.assemble(A) if parameters.get('solver', 'direct') == 'direct': solver = PETScLUSolver(A, 'mumps') ksp = solver.ksp() else: schur_bit = sqrt(lmbda + 2*mu/len(eta)) # Preconditioner operator following https://arxiv.org/abs/1705.08842 a_prec = (2*mu*inner(sym(grad(eta)), sym(grad(phi)))*dx + inner(lmbda*div(eta), div(phi))*dx + inner(s0*p, q)*dx + inner(kappa*dt*grad(p), grad(q))*dx + (alpha**2/schur_bit**2)*inner(p, q)*dx) B, b_dummy = PETScMatrix(), PETScVector() assemble_system(a_prec, L, bcs_strong, A_tensor=B, b_tensor=b_dummy) solver = PETScKrylovSolver() ksp = solver.ksp() ksp.setType(PETSc.KSP.Type.MINRES) ksp.setOperators(A.mat(), B.mat()) ksp.setInitialGuessNonzero(True) # For time dep problem V_dofs, Q_dofs = (W.sub(i).dofmap().dofs() for i in range(2)) pc = ksp.getPC() pc.setType(PETSc.PC.Type.FIELDSPLIT) is_V = PETSc.IS().createGeneral(V_dofs) is_Q = PETSc.IS().createGeneral(Q_dofs) pc.setFieldSplitIS(('0', is_V), ('1', is_Q)) pc.setFieldSplitType(PETSc.PC.CompositeType.ADDITIVE) ksp.setUp() # ... all blocks inverted AMG sweeps subksps = pc.getFieldSplitSubKSP() subksps[0].setType('preonly') # NOTE: ideally this would be done with multigrid but let's see # how far LU will take us. For amg also consider grad-grad to help # it subksps[0].getPC().setType('lu') subksps[1].setType('preonly') subksps[1].getPC().setType('hypre') opts = PETSc.Options() # opts.setValue('ksp_monitor_true_residual', None) opts.setValue('ksp_rtol', 1E-14) opts.setValue('ksp_atol', 1E-8) pc.setFromOptions() ksp.setFromOptions() # Temporal integration loop T0 = parameters['T0'] niters, reasons = [], [] for k in range(parameters['nsteps']): # Update source if possible for foo in bdry_expressions + [f1, f2]: hasattr(foo, 't') and setattr(foo, 't', T0) hasattr(foo, 'time') and setattr(foo, 'time', T0) assembler.assemble(b) niters.append(solver.solve(wh_0.vector(), b)) reasons.append(ksp.getConvergedReason()) T0 += dt(0) if k % 10 == 0: print(' Biot at step (%d, %g) |uh|=%g' % (k, T0, wh_0.vector().norm('l2'))) print(' KSP stats MIN/MEAN/MAX (%d|%g|%d) %d' % ( np.min(niters), np.mean(niters), np.max(niters), len(niters) )) for reason, count in Counter(reasons).items(): print(' KSP cvrg reason %s -> %d' % (KSP_CVRG_REASONS[reason], count)) niters.clear() reasons.clear() eta_h, p_h = wh_0.split(deepcopy=True) return eta_h, p_h, T0
def solve_stability(self): """ Solve the 2nd-order stability problem """ def global_mask(fun1, fun2, V): # Find the indices where fun1 ~= fun2 at a tolerance diff = fun1.vector() - fun2.vector() diff.abs() diff_glob = PETScVector(mpi_comm_self()) diff.gather(diff_glob, pl.array(range(V.dim()), "intc")) mask = diff_glob < DOLFIN_EPS_LARGE return mask # Locate the elastic part mask = global_mask(self.alpha, self.alpha_prev, self.V_alpha) if pl.all(mask): self.print0("\033[1;36m 2nd stability: elastic phase\033[1;m") self.rq = pl.inf return True else: self._u_alpha_prev.vector()[:] = 0.0 self._u_alpha.vector()[:] = 1.0 assign(self._u_alpha_prev.sub(1), self.alpha_prev) assign(self._u_alpha.sub(1), self.alpha) mask = global_mask(self._u_alpha, self._u_alpha_prev, self._V_u_alpha) self.elas_dofs = set((pl.where(mask == True)[0]).astype(pl.intc)) bc_elas_dofs = self.elas_dofs.union(self.bc_dofs) indices = sorted( set(range(self.ownership[0], self.ownership[1])) - bc_elas_dofs) # Assemble K and M self._K = PETScMatrix() self._M = PETScMatrix() assemble(self._rqP, self._K) assemble(self._rqN, self._M) self._K_mat = self._K.mat() self._M_mat = self._M.mat() # Eliminate the elastic/BC part using PETSc.IS self.IS = PETSc.IS() self.IS.createGeneral(indices) self._K_mat_reduced = self._K_mat.getSubMatrix(self.IS, self.IS) self._K = PETScMatrix(self._K_mat_reduced) self._M_mat_reduced = self._M_mat.getSubMatrix(self.IS, self.IS) self._M = PETScMatrix(self._M_mat_reduced) # Stop if M ~= 0 if self._M.norm("linf") < DOLFIN_EPS_LARGE: self.rq = pl.inf self.print0( "\033[1;36m 2nd stability: Rayleigh quotient: %.3e\033[1;m" % self.rq) return True # Setup the eigenvalue solver self.eigensolver = SLEPcEigenSolver(self._K, self._M) self.set_eigensolver_parameters() # Use last known directions for initial guess assign(self._u_alpha.sub(0), self.V) assign(self._u_alpha.sub(1), self.Beta) _u_alpha_vec = as_backend_type(self._u_alpha.vector()).vec() _u_alpha_vec_reduced = _u_alpha_vec.getSubVector(self.IS) # self.eps.setInitialSpace(_u_alpha_vec_reduced) # Solve the eigenvalue problem self.print0( "\033[1;36m 2nd stability: solving the eigenvalue problem\033[1;m" ) self.eps.solve() r, c, rx, cx = self.eigensolver.get_eigenpair(0) self.print0("\033[1;36m 2nd stability: smallest ev: %.3e\033[1;m" % r) # From reduced vector to full vector self.scatter = PETSc.Scatter() rx_vec = as_backend_type(rx).vec() self.scatter.create(_u_alpha_vec_reduced, None, _u_alpha_vec, self.IS) _u_alpha_vec.zeroEntries() self.scatter.scatter(rx_vec, _u_alpha_vec) _u_alpha_vec.ghostUpdate() # Check the Rayleigh quotient (in theory we should have r == rq) self.rq = assemble(self.rqP) / assemble(self.rqN) if abs(r - self.rq) > DOLFIN_EPS_LARGE: self.print0( "\033[1;36m 2nd stability: Rayleigh quotient: %.3e\033[1;m" % self.rq) # Obtain the perturbation directions to V and Beta assign(self.V, self._u_alpha.sub(0)) assign(self.Beta, self._u_alpha.sub(1)) # Scale V u_mean = self.u.vector().norm("l2") if self.V.vector().norm("l2") > DOLFIN_EPS_LARGE: coeff = u_mean / self.V.vector().norm("l2") self.V.vector()[:] = coeff * self.V.vector() # Scale and project Beta to the admissible space alpha_mean = self.alpha.vector().norm("l2") if self.Beta.vector().norm("l2") > DOLFIN_EPS_LARGE: coeff = alpha_mean / self.Beta.vector().norm("l2") self.Beta.vector()[:] = coeff * self.Beta.vector() self.Beta.vector()[self.Beta.vector() < 0] = 0.0 # Determine if the solution is unique if self.rq > 1: return True
def solve(A,b,u,IS,Fspace,IterType,OuterTol,InnerTol,HiptmairMatrices,KSPlinearfluids,kspF,Fp,MatrixLinearFluids,kspFp): if IterType == "Full": kspOuter = PETSc.KSP().create() kspOuter.setTolerances(OuterTol) kspOuter.setType('fgmres') u_is = PETSc.IS().createGeneral(range(Fspace[0].dim())) p_is = PETSc.IS().createGeneral(range(Fspace[0].dim(),Fspace[0].dim()+Fspace[1].dim())) Bt = A.getSubMatrix(u_is,p_is) reshist = {} def monitor(ksp, its, fgnorm): reshist[its] = fgnorm print "OUTER:", fgnorm kspOuter.setMonitor(monitor) pcOutter = kspOuter.getPC() pcOutter.setType(PETSc.PC.Type.KSP) kspOuter.setOperators(A,A) kspOuter.max_it = 500 kspInner = pcOutter.getKSP() kspInner.max_it = 100 kspInner.max_it = 100 reshist1 = {} def monitor(ksp, its, fgnorm): reshist1[its] = fgnorm print "INNER:", fgnorm # kspInner.setMonitor(monitor) kspInner.setType('gmres') kspInner.setTolerances(InnerTol) pcInner = kspInner.getPC() pcInner.setType(PETSc.PC.Type.PYTHON) pcInner.setPythonContext(MHDstabPrecond.InnerOuterWITHOUT(Fspace,kspF, KSPlinearfluids[0], KSPlinearfluids[1],Fp, HiptmairMatrices[3], HiptmairMatrices[4], HiptmairMatrices[2], HiptmairMatrices[0], HiptmairMatrices[1], HiptmairMatrices[6],1e-6,A)) PP = PETSc.Mat().createPython([A.size[0], A.size[0]]) PP.setType('python') p = PrecondMulti.MultiApply(Fspace,A,HiptmairMatrices[6],MatrixLinearFluids[1],MatrixLinearFluids[0],kspFp, HiptmairMatrices[3]) PP.setPythonContext(p) kspInner.setOperators(PP) tic() scale = b.norm() b = b/scale print b.norm() kspOuter.solve(b, u) u = u*scale print toc() # print s.getvalue() NSits = kspOuter.its del kspOuter Mits = kspInner.its del kspInner # print u.array return u,NSits,Mits NS_is = IS[0] M_is = IS[1] kspNS = PETSc.KSP().create() kspM = PETSc.KSP().create() kspNS.setTolerances(OuterTol) kspNS.setOperators(A.getSubMatrix(NS_is,NS_is)) kspM.setOperators(A.getSubMatrix(M_is,M_is)) del A uNS = u.getSubVector(NS_is) bNS = b.getSubVector(NS_is) kspNS.setType('gmres') pcNS = kspNS.getPC() kspNS.setTolerances(OuterTol) pcNS.setType(PETSc.PC.Type.PYTHON) if IterType == "MD": pcNS.setPythonContext(NSpreconditioner.NSPCD(MixedFunctionSpace([Fspace[0],Fspace[1]]), kspF, KSPlinearfluids[0], KSPlinearfluids[1],Fp)) else: pcNS.setPythonContext(StokesPrecond.MHDApprox(MixedFunctionSpace([Fspace[0],Fspace[1]]), kspF, KSPlinearfluids[1])) scale = bNS.norm() bNS = bNS/scale start_time = time.time() kspNS.solve(bNS, uNS) print ("{:25}").format("NS, time: "), " ==> ",("{:4f}").format(time.time() - start_time),("{:9}").format(" Its: "), ("{:4}").format(kspNS.its), ("{:9}").format(" time: "), ("{:4}").format(time.strftime('%X %x %Z')[0:5]) uNS = scale*uNS NSits = kspNS.its # kspNS.destroy() # for line in reshist.values(): # print line kspM.setFromOptions() kspM.setType(kspM.Type.MINRES) kspM.setTolerances(InnerTol) pcM = kspM.getPC() pcM.setType(PETSc.PC.Type.PYTHON) pcM.setPythonContext(MP.Hiptmair(MixedFunctionSpace([Fspace[2],Fspace[3]]), HiptmairMatrices[3], HiptmairMatrices[4], HiptmairMatrices[2], HiptmairMatrices[0], HiptmairMatrices[1], HiptmairMatrices[6],1e-6)) # x = x*scale uM = u.getSubVector(M_is) bM = b.getSubVector(M_is) scale = bM.norm() bM = bM/scale start_time = time.time() kspM.solve(bM, uM) print ("{:25}").format("Maxwell solve, time: "), " ==> ",("{:4f}").format(time.time() - start_time),("{:9}").format(" Its: "), ("{:4}").format(kspM.its), ("{:9}").format(" time: "), ("{:4}").format(time.strftime('%X %x %Z')[0:5]) uM = uM*scale Mits = kspM.its kspM.destroy() u = IO.arrayToVec(np.concatenate([uNS.array, uM.array])) return u,NSits,Mits
L = MU * (inner(grad(qQ), grad(pQ)) * dx(mesh)) # O = - dot(u_k, n)*pQ('+')*qQ*ds(mesh) - dot(u_k, n)*(pQ('+') - pQ('-'))*qQ('-')*dS(mesh) pp = Function(Q) fp = MU * inner(grad(qQ), grad(pQ)) * dx(mesh) + inner( (u_k[0] * grad(pQ)[0] + u_k[1] * grad(pQ)[1]), qQ) * dx(mesh) + ( 1 / 2) * div(u_k) * inner(pQ, qQ) * dx(mesh) - (1 / 2) * ( u_k[0] * n[0] + u_k[1] * n[1]) * inner(pQ, qQ) * ds(mesh) Laplacian = assemble(L) Laplacian = CP.Assemble(Laplacian) Mass = CP.Assemble(Mass) kspA, kspQ = NSprecondSetup.PCDKSPlinear(Mass, Laplacian) u_is = PETSc.IS().createGeneral(range(W.sub(0).dim())) p_is = PETSc.IS().createGeneral( range(W.sub(0).dim(), W.sub(0).dim() + W.sub(1).dim())) # print L SolutionTime = 0 while eps > tol and iter < maxiter: iter += 1 x = Function(W) uu = Function(W) tic() AA, bb = assemble_system(a, L1 - RHSform, bcs) A, b = CP.Assemble(AA, bb) print toc() # b = b.getSubVector(t_is)
def solver(self, problem, base, params, solver_params, prefix="", vi=None, **kwargs): # base = self.problem.solver(problem, params, solver_params, prefix=prefix, **kwargs) snes = base.snes # u_dvec = as_backend_type(problem.u.vector()) mesh = problem.u.function_space().mesh() comm = mesh.mpi_comm() deflation = problem.deflation is_rho = PETSc.IS().createGeneral( problem.u.function_space().sub(0).dofmap().dofs(), comm=comm) (f, (fenicsresidual, args, kargs)) = snes.getFunction() def newmonitor(snes, it, residual): x = snes.getSolution() # comm = x.function_space().mesh().mpi_comm() rho = x.getSubVector(is_rho) zero = rho.copy() zero.array[:] = 0.0 one = rho.copy() one.array[:] = 1.0 # print("max/min rho before clipping (%s, %s)" %(min(rho.array), max(rho.array))) rho.pointwiseMax(rho, zero) rho.pointwiseMin(rho, one) # print("max/min rho after clipping (%s, %s)" %(min(rho.array), max(rho.array))) x.restoreSubVector(is_rho, rho) # print("max/min x after clipping (%s, %s)" %(min(x.array), max(x.array))) def plus(X, out): out.pointwiseMax(X, zero) def newresidual(snes, X, F): fenicsresidual(snes, X, F) rho = X.getSubVector(is_rho) # print("max/min rho after clipping (%s, %s)" %(min(rho.array), max(rho.array))) lb_dofs = where(rho.array_r <= 0.)[0].astype('int32') is_lb = PETSc.IS().createGeneral(lb_dofs, comm=comm) ub_dofs = where(rho.array_r >= 1.)[0].astype('int32') is_ub = PETSc.IS().createGeneral(ub_dofs, comm=comm) # print("|F|: ", F.norm(PETSc.NormType.NORM_2)) F_lb = F.getSubVector(is_lb) F_ub = F.getSubVector(is_ub) zero = F_lb.duplicate() zero.array[:] = 0.0 F_lb.pointwiseMin(F_lb, zero) # F_lb.pointwiseMax(F_lb, zero) zero = F_ub.duplicate() zero.array[:] = 0.0 F_ub.pointwiseMax(F_ub, zero) # F_ub.pointwiseMin(F_ub, zero) X.restoreSubVector(is_rho, rho) # print("|F_lb|: ", F_lb.norm(PETSc.NormType.NORM_2)) # print("|F_ub|: ", F_ub.norm(PETSc.NormType.NORM_2)) F.restoreSubVector(is_ub, F_ub) F.restoreSubVector(is_lb, F_lb) # print("|F|: ", F.norm(PETSc.NormType.NORM_2)) res = F.norm(PETSc.NormType.NORM_2) # snes.setType("python") # snes.setPythonContext(MySolver()) snes.setFunction(newresidual, f) snes.setMonitor(newmonitor) return base
def foo(): m = 6 mm = 5 errL2u = np.zeros((m - 1, 1)) errH1u = np.zeros((m - 1, 1)) errL2p = np.zeros((m - 1, 1)) errL2b = np.zeros((m - 1, 1)) errCurlb = np.zeros((m - 1, 1)) errL2r = np.zeros((m - 1, 1)) errH1r = np.zeros((m - 1, 1)) l2uorder = np.zeros((m - 1, 1)) H1uorder = np.zeros((m - 1, 1)) l2porder = np.zeros((m - 1, 1)) l2border = np.zeros((m - 1, 1)) Curlborder = np.zeros((m - 1, 1)) l2rorder = np.zeros((m - 1, 1)) H1rorder = np.zeros((m - 1, 1)) NN = np.zeros((m - 1, 1)) DoF = np.zeros((m - 1, 1)) Velocitydim = np.zeros((m - 1, 1)) Magneticdim = np.zeros((m - 1, 1)) Pressuredim = np.zeros((m - 1, 1)) Lagrangedim = np.zeros((m - 1, 1)) Wdim = np.zeros((m - 1, 1)) iterations = np.zeros((m - 1, 3 * (mm - 1))) SolTime = np.zeros((m - 1, 1)) udiv = np.zeros((m - 1, 1)) MU = np.zeros((m - 1, 1)) level = np.zeros((m - 1, 1)) NSave = np.zeros((m - 1, 1)) Mave = np.zeros((m - 1, 1)) TotalTime = np.zeros((m - 1, 1)) KappaSave = np.zeros((mm - 1, 1)) nn = 2 dim = 2 ShowResultPlots = 'yes' split = 'Linear' qq = -1 MU[0] = 1e0 MU = 0.0001 qq = -1 for yy in xrange(1, mm): MU = MU * 10 KappaSave[yy - 1] = MU IterTypes = ['Full', 'MD', 'CD'] for kk in range(len(IterTypes)): qq += 1 for xx in xrange(1, m): print xx level[xx - 1] = xx + 2 nn = 2**(level[xx - 1]) # Create mesh and define function space nn = int(nn) NN[xx - 1] = nn / 2 # parameters["form_compiler"]["quadrature_degree"] = 6 # parameters = CP.ParameterSetup() mesh = UnitSquareMesh(nn, nn) order = 1 parameters['reorder_dofs_serial'] = False Velocity = VectorFunctionSpace(mesh, "CG", order + 1) Pressure = FunctionSpace(mesh, "CG", order) Magnetic = FunctionSpace(mesh, "N1curl", order) Lagrange = FunctionSpace(mesh, "CG", order) W = MixedFunctionSpace( [Velocity, Pressure, Magnetic, Lagrange]) # W = Velocity*Pressure*Magnetic*Lagrange Velocitydim[xx - 1] = Velocity.dim() Pressuredim[xx - 1] = Pressure.dim() Magneticdim[xx - 1] = Magnetic.dim() Lagrangedim[xx - 1] = Lagrange.dim() Wdim[xx - 1] = W.dim() print "\n\nW: ", Wdim[xx - 1], "Velocity: ", Velocitydim[ xx - 1], "Pressure: ", Pressuredim[ xx - 1], "Magnetic: ", Magneticdim[ xx - 1], "Lagrange: ", Lagrangedim[xx - 1], "\n\n" dim = [ Velocity.dim(), Pressure.dim(), Magnetic.dim(), Lagrange.dim() ] def boundary(x, on_boundary): return on_boundary u0, p0, b0, r0, Laplacian, Advection, gradPres, CurlCurl, gradR, NS_Couple, M_Couple = ExactSol.MHD2D( 4, 1) bcu = DirichletBC(W.sub(0), u0, boundary) bcb = DirichletBC(W.sub(2), b0, boundary) bcr = DirichletBC(W.sub(3), r0, boundary) # bc = [u0,p0,b0,r0] bcs = [bcu, bcb, bcr] FSpaces = [Velocity, Pressure, Magnetic, Lagrange] (u, b, p, r) = TrialFunctions(W) (v, c, q, s) = TestFunctions(W) Mu_m = 1e1 kappa = 1 IterType = IterTypes[kk] Split = "No" Saddle = "No" Stokes = "No" F_NS = -MU * Laplacian + Advection + gradPres - kappa * NS_Couple if kappa == 0: F_M = Mu_m * CurlCurl + gradR - kappa * M_Couple else: F_M = Mu_m * kappa * CurlCurl + gradR - kappa * M_Couple params = [kappa, Mu_m, MU] # MO.PrintStr("Preconditioning MHD setup",5,"+","\n\n","\n\n") Hiptmairtol = 1e-5 HiptmairMatrices = PrecondSetup.MagneticSetup( Magnetic, Lagrange, b0, r0, Hiptmairtol, params) MO.PrintStr("Setting up MHD initial guess", 5, "+", "\n\n", "\n\n") u_k, p_k, b_k, r_k = common.InitialGuess(FSpaces, [u0, p0, b0, r0], [F_NS, F_M], params, HiptmairMatrices, 1e-6, Neumann=Expression( ("0", "0")), options="New", FS="DG") #plot(p_k, interactive = True) b_t = TrialFunction(Velocity) c_t = TestFunction(Velocity) #print assemble(inner(b,c)*dx).array().shape #print mat #ShiftedMass = assemble(inner(mat*b,c)*dx) #as_vector([inner(b,c)[0]*b_k[0],inner(b,c)[1]*(-b_k[1])]) ones = Function(Pressure) ones.vector()[:] = (0 * ones.vector().array() + 1) # pConst = - assemble(p_k*dx)/assemble(ones*dx) p_k.vector()[:] += -assemble(p_k * dx) / assemble(ones * dx) x = Iter.u_prev(u_k, p_k, b_k, r_k) KSPlinearfluids, MatrixLinearFluids = PrecondSetup.FluidLinearSetup( Pressure, MU) kspFp, Fp = PrecondSetup.FluidNonLinearSetup(Pressure, MU, u_k) #plot(b_k) ns, maxwell, CoupleTerm, Lmaxwell, Lns = forms.MHD2D( mesh, W, F_M, F_NS, u_k, b_k, params, IterType, "DG", Saddle, Stokes) RHSform = forms.PicardRHS(mesh, W, u_k, p_k, b_k, r_k, params, "DG", Saddle, Stokes) bcu = DirichletBC(Velocity, Expression(("0.0", "0.0")), boundary) bcb = DirichletBC(Magnetic, Expression(("0.0", "0.0")), boundary) bcr = DirichletBC(Lagrange, Expression(("0.0")), boundary) bcs = [bcu, bcb, bcr] parameters['linear_algebra_backend'] = 'uBLAS' SetupType = 'Matrix' BC = MHDsetup.BoundaryIndices(mesh) eps = 1.0 # error measure ||u-u_k|| tol = 1.0E-4 # tolerance iter = 0 # iteration counter maxiter = 20 # max no of iterations allowed SolutionTime = 0 outer = 0 # parameters['linear_algebra_backend'] = 'uBLAS' # FSpaces = [Velocity,Magnetic,Pressure,Lagrange] if IterType == "CD": MO.PrintStr("Setting up PETSc " + SetupType, 2, "=", "\n", "\n") Alin = MHDsetup.Assemble(W, ns, maxwell, CoupleTerm, Lns, Lmaxwell, RHSform, bcs + BC, "Linear", IterType) Fnlin, b = MHDsetup.Assemble(W, ns, maxwell, CoupleTerm, Lns, Lmaxwell, RHSform, bcs + BC, "NonLinear", IterType) A = Fnlin + Alin A, b = MHDsetup.SystemAssemble(FSpaces, A, b, SetupType, IterType) u = b.duplicate() u_is = PETSc.IS().createGeneral(range(Velocity.dim())) NS_is = PETSc.IS().createGeneral( range(Velocity.dim() + Pressure.dim())) M_is = PETSc.IS().createGeneral( range(Velocity.dim() + Pressure.dim(), W.dim())) OuterTol = 1e-5 InnerTol = 1e-5 NSits = 0 Mits = 0 TotalStart = time.time() SolutionTime = 0 while eps > tol and iter < maxiter: iter += 1 MO.PrintStr("Iter " + str(iter), 7, "=", "\n\n", "\n\n") AssembleTime = time.time() if IterType == "CD": MO.StrTimePrint("MHD CD RHS assemble, time: ", time.time() - AssembleTime) b = MHDsetup.Assemble(W, ns, maxwell, CoupleTerm, Lns, Lmaxwell, RHSform, bcs + BC, "CD", IterType) else: MO.PrintStr("Setting up PETSc " + SetupType, 2, "=", "\n", "\n") AA, bb = assemble_system(maxwell + ns + CoupleTerm, (Lmaxwell + Lns) - RHSform, bcs) A, b = CP.Assemble(AA, bb) # if iter == 1: MO.StrTimePrint("MHD total assemble, time: ", time.time() - AssembleTime) kspFp, Fp = PrecondSetup.FluidNonLinearSetup( Pressure, MU, u_k) u = b.duplicate() print "Inititial guess norm: ", u.norm() if u.norm() > 1e50: iter = 10000 break #A,Q kspF = 0 stime = time.time() u, mits, nsits = S.solve(A, b, u, params, W, 'Direct', IterType, OuterTol, InnerTol, HiptmairMatrices, Hiptmairtol, KSPlinearfluids, Fp, kspF) Soltime = time.time() - stime Mits += mits NSits += nsits SolutionTime += Soltime u1, p1, b1, r1, eps = Iter.PicardToleranceDecouple( u, x, FSpaces, dim, "2", iter) p1.vector()[:] += -assemble(p1 * dx) / assemble(ones * dx) u_k.assign(u1) p_k.assign(p1) b_k.assign(b1) r_k.assign(r1) uOld = np.concatenate( (u_k.vector().array(), p_k.vector().array(), b_k.vector().array(), r_k.vector().array()), axis=0) x = IO.arrayToVec(uOld) XX = np.concatenate( (u_k.vector().array(), p_k.vector().array(), b_k.vector().array(), r_k.vector().array()), axis=0) iterations[xx - 1, qq] = iter dim = [ Velocity.dim(), Pressure.dim(), Magnetic.dim(), Lagrange.dim() ] # # ExactSolution = [u0,p0,b0,r0] # errL2u[xx-1], errH1u[xx-1], errL2p[xx-1], errL2b[xx-1], errCurlb[xx-1], errL2r[xx-1], errH1r[xx-1] = Iter.Errors(XX,mesh,FSpaces,ExactSolution,order,dim, "DG") # # if xx > 1: # l2uorder[xx-1] = np.abs(np.log2(errL2u[xx-2]/errL2u[xx-1])) # H1uorder[xx-1] = np.abs(np.log2(errH1u[xx-2]/errH1u[xx-1])) # # l2porder[xx-1] = np.abs(np.log2(errL2p[xx-2]/errL2p[xx-1])) # # l2border[xx-1] = np.abs(np.log2(errL2b[xx-2]/errL2b[xx-1])) # Curlborder[xx-1] = np.abs(np.log2(errCurlb[xx-2]/errCurlb[xx-1])) # # l2rorder[xx-1] = np.abs(np.log2(errL2r[xx-2]/errL2r[xx-1])) # H1rorder[xx-1] = np.abs(np.log2(errH1r[xx-2]/errH1r[xx-1])) # # # # # import pandas as pd # # # # LatexTitles = ["l","DoFu","Dofp","V-L2","L2-order","V-H1","H1-order","P-L2","PL2-order"] # LatexValues = np.concatenate((level,Velocitydim,Pressuredim,errL2u,l2uorder,errH1u,H1uorder,errL2p,l2porder), axis=1) # LatexTable = pd.DataFrame(LatexValues, columns = LatexTitles) # pd.set_option('precision',3) # LatexTable = MO.PandasFormat(LatexTable,"V-L2","%2.4e") # LatexTable = MO.PandasFormat(LatexTable,'V-H1',"%2.4e") # LatexTable = MO.PandasFormat(LatexTable,"H1-order","%1.2f") # LatexTable = MO.PandasFormat(LatexTable,'L2-order',"%1.2f") # LatexTable = MO.PandasFormat(LatexTable,"P-L2","%2.4e") # LatexTable = MO.PandasFormat(LatexTable,'PL2-order',"%1.2f") # print LatexTable # # # print "\n\n Magnetic convergence" # MagneticTitles = ["l","B DoF","R DoF","B-L2","L2-order","B-Curl","HCurl-order"] # MagneticValues = np.concatenate((level,Magneticdim,Lagrangedim,errL2b,l2border,errCurlb,Curlborder),axis=1) # MagneticTable= pd.DataFrame(MagneticValues, columns = MagneticTitles) # pd.set_option('precision',3) # MagneticTable = MO.PandasFormat(MagneticTable,"B-Curl","%2.4e") # MagneticTable = MO.PandasFormat(MagneticTable,'B-L2',"%2.4e") # MagneticTable = MO.PandasFormat(MagneticTable,"L2-order","%1.2f") # MagneticTable = MO.PandasFormat(MagneticTable,'HCurl-order',"%1.2f") # print MagneticTable # import pandas as pd print iterations.shape[1] iter = ["P", "MD", "CD"] IterTitles = ["l", "DoF"] for i in range(iterations.shape[1] / 3): IterTitles += iter print IterTitles IterValues = np.concatenate((level, Wdim, iterations), axis=1) IterTable = pd.DataFrame(IterValues, columns=IterTitles) print IterTable.to_latex() print " \n Outer Tol: ", OuterTol, "Inner Tol: ", InnerTol print KappaSave # # # if (ShowResultPlots == 'yes'): # plot(u_k) # plot(interpolate(u0,Velocity)) # # plot(p_k) # # plot(interpolate(p0,Pressure)) # # plot(b_k) # plot(interpolate(b0,Magnetic)) # # plot(r_k) # plot(interpolate(r0,Lagrange)) # # interactive() interactive()