public Vector solveStateEquation(Vector q) { // 4.Weak form WeakFormLaplace2D weakForm = new WeakFormLaplace2D(); Function fq = new Vector2Function(q); weakForm.setParam(fq, FC.C0, null, null); // Right hand side(RHS): f(x) = -4.0 weakForm.setF(FC.c(-4.0)); // 5.Assembly process AssemblerScalar assembler = new AssemblerScalar(mesh, weakForm); System.out.println("Begin Assemble..."); assembler.assemble(); SparseMatrix stiff = assembler.getStiffnessMatrix(); SparseVector load = assembler.getLoadVector(); // Boundary condition assembler.imposeDirichletCondition(diri); // ???给定一个初始猜测q,边界条件是什么? System.out.println("Assemble done!"); // 6.Solve linear system Solver solver = new Solver(); Vector u_solve = solver.solveCGS(stiff, load); return u_solve; }
public Vector getRealU() { // 4.Weak form WeakFormLaplace2D weakForm = new WeakFormLaplace2D(); plotFunction(mesh, coef_q, "qReal.dat"); weakForm.setParam(coef_q, FC.C0, null, null); // Right hand side(RHS): f(x) = -4.0 weakForm.setF(FC.c(-4.0)); // 5.Assembly process AssemblerScalar assembler = new AssemblerScalar(mesh, weakForm); System.out.println("Begin Assemble..."); assembler.assemble(); SparseMatrix stiff = assembler.getStiffnessMatrix(); SparseVector load = assembler.getLoadVector(); // Boundary condition assembler.imposeDirichletCondition(diri); System.out.println("Assemble done!"); // 6.Solve linear system Solver solver = new Solver(); Vector u = solver.solveCG(stiff, load); System.out.println("u="); for (int i = 1; i <= u.getDim(); i++) System.out.println(String.format("%.3f", u.get(i))); plotVector(mesh, u, "uReal.dat"); return u; }
/** * Adjoint equation L_{u} := (q\nabla{\psi},\nabla{\lambda}) + (u-z,\psi) * * @return */ public SparseVector getResLu(Vector u, Vector lambda, Vector q) { // 4.Weak form WeakFormLaplace2D weakForm = new WeakFormLaplace2D(); Function fq = new Vector2Function(q); weakForm.setParam(fq, FC.C0, null, null); // Right hand side(RHS): f(x) = - (u - z) Function z_u = z.S(new Vector2Function(u)); plotFunction(mesh, z_u, String.format("z_u%02d.dat", this.iterNum)); weakForm.setF(z_u); // 5.Assembly process AssemblerScalar assembler = new AssemblerScalar(mesh, weakForm); System.out.println("Begin Assemble..."); assembler.assemble(); SparseMatrix stiff = assembler.getStiffnessMatrix(); SparseVector load = assembler.getLoadVector(); // Boundary condition assembler.imposeDirichletCondition(FC.C0); System.out.println("Assemble done!"); if (debug) { // 6.Solve linear system Solver solver = new Solver(); Vector lmd_solve = solver.solveCGS(stiff, load); plotVector(mesh, lmd_solve, "lambda_solve.dat"); } // Residual SparseVector res = new SparseVectorHashMap(lambda.getDim()); stiff.mult(lambda, res); res.add(-1.0, load); plotVector(mesh, res, "Res_Lu.dat"); return res; }
/** * State equation L_{\lambda} := (q\nabla{u},\nabla{\phi})-(f,\phi)=0 * * <p>获取状态方程的余量 * * @return */ public SparseVector getResLlmd(Vector u, Vector q) { // 4.Weak form WeakFormLaplace2D weakForm = new WeakFormLaplace2D(); Function fq = new Vector2Function(q); weakForm.setParam(fq, FC.C0, null, null); // Right hand side(RHS): f(x) = -4.0 weakForm.setF(FC.c(-4.0)); // 5.Assembly process AssemblerScalar assembler = new AssemblerScalar(mesh, weakForm); System.out.println("Begin Assemble..."); assembler.assemble(); SparseMatrix stiff = assembler.getStiffnessMatrix(); SparseVector load = assembler.getLoadVector(); // Boundary condition assembler.imposeDirichletCondition(diri); System.out.println("Assemble done!"); if (debug) { // 6.Solve linear system Solver solver = new Solver(); Vector u_solve = solver.solveCGS(stiff, load); plotVector(mesh, u_solve, "u_solve.dat"); } // Residual SparseVector res = new SparseVectorHashMap(u.getDim()); stiff.mult(u, res); res.add(-1.0, load); plotVector(mesh, res, "Res_Llambda.dat"); return res; }
public void run() { // 1.Read in a triangle mesh from an input file with // format ASCII UCD generated by Gridgen MeshReader reader = new MeshReader("triangle.grd"); Mesh mesh = reader.read2DMesh(); // Compute geometry relationship of nodes and elements mesh.computeNodeBelongsToElements(); // 2.Mark border types HashMap<NodeType, Function> mapNTF = new HashMap<NodeType, Function>(); mapNTF.put(NodeType.Dirichlet, null); mesh.markBorderNode(mapNTF); // 3.Use element library to assign degrees of // freedom (DOF) to element ElementList eList = mesh.getElementList(); FELinearTriangle feLT = new FELinearTriangle(); for (int i = 1; i <= eList.size(); i++) feLT.assignTo(eList.at(i)); // 4.Weak form WeakFormLaplace2D weakForm = new WeakFormLaplace2D(); // Right hand side(RHS): f = -2*(x^2+y^2)+36 weakForm.setF(X.M(X).A(Y.M(Y)).M(-2.0).A(36.0)); // 5.Assembly process AssemblerScalar assembler = new AssemblerScalar(mesh, weakForm); assembler.assemble(); Matrix stiff = assembler.getStiffnessMatrix(); Vector load = assembler.getLoadVector(); // Boundary condition assembler.imposeDirichletCondition(C0); // 6.Solve linear system SolverJBLAS solver = new SolverJBLAS(); Vector u = solver.solveDGESV(stiff, load); System.out.println("u="); for (int i = 1; i <= u.getDim(); i++) System.out.println(String.format("%.3f", u.get(i))); // 7.Output results to an Techplot format file MeshWriter writer = new MeshWriter(mesh); writer.writeTechplot("./tutorial/Laplace2D.dat", u); this.mesh = mesh; this.u = u; }
public SparseMatrix getBR() { // 4.Weak form: (dq,\chi) WeakFormLaplace2D weakForm = new WeakFormLaplace2D(); weakForm.setParam(FC.C0, FC.c(beta), null, null); // Right hand side(RHS): f(x) = 0 weakForm.setF(FC.C0); // 5.Assembly process AssemblerScalar assembler = new AssemblerScalar(mesh, weakForm); System.out.println("Begin Assemble..."); assembler.assemble(); SparseMatrix stiff = assembler.getStiffnessMatrix(); // Boundary condition // 边界条件需要在大矩阵中设置 // assembler.imposeDirichletCondition(FC.c0); System.out.println("Assemble done!"); return stiff; }
public SparseMatrix getA(Vector qk) { // 4.Weak form: (\nabla{dl},qk*\nabla{\phi}) WeakFormLaplace2D weakForm = new WeakFormLaplace2D(); Function fqk = new Vector2Function(qk); weakForm.setParam(fqk, FC.C0, null, null); // Right hand side(RHS): f(x) = 0 weakForm.setF(FC.C0); // 5.Assembly process AssemblerScalar assembler = new AssemblerScalar(mesh, weakForm); System.out.println("Begin Assemble..."); assembler.assemble(); SparseMatrix stiff = assembler.getStiffnessMatrix(); // Boundary condition // 边界条件需要在大矩阵中设置 // assembler.imposeDirichletCondition(FC.c0); System.out.println("Assemble done!"); return stiff; }
public static void adaptiveTestTriangle() { MeshReader reader = new MeshReader("patch_triangle.grd"); Mesh mesh = reader.read2DMesh(); mesh.computeNodeBelongsToElements(); mesh.computeNeighborNodes(); mesh.computeGlobalEdge(); mesh.computeNeighborElements(); HashMap<NodeType, Function> mapNTF = new HashMap<NodeType, Function>(); mapNTF.put(NodeType.Dirichlet, null); mesh.markBorderNode(mapNTF); ElementList eList = mesh.getElementList(); ElementList eToRefine = new ElementList(); // 直接指定需要加密的单元编号 eToRefine.add(eList.at(6)); eToRefine.add(eList.at(16)); eToRefine.add(eList.at(3)); eToRefine.add(eList.at(4)); Refiner.refineOnce(mesh, eToRefine); mesh.markBorderNode(mapNTF); // //二次加密 // eToRefine.clear(); // //单元编号的问题该如何处理? // eToRefine.add(eList.at(17)); // //第一步:新增加的结点赋予全局编号,加入mesh对象 // Refiner.refineOnce(mesh, eToRefine); // mesh.markBorderNode(mapNTF); SFLinearLocal2D[] shapeFun = new SFLinearLocal2D[3]; for (int i = 0; i < 3; i++) shapeFun[i] = new SFLinearLocal2D(i + 1); SFLinearLocal2D[] shapeFun2 = new SFLinearLocal2D[3]; for (int i = 0; i < 3; i++) { shapeFun2[i] = new SFLinearLocal2D(i + 1, 0.5); } // Asign degree of freedom to element for (int i = 1; i <= mesh.getElementList().size(); i++) { Element e = mesh.getElementList().at(i); int nDofLocalIndexCounter = 0; for (int j = 1; j <= e.nodes.size(); j++) { // Asign shape function to DOF if (e.nodes.at(j) instanceof NodeRefined) { NodeRefined nRefined = (NodeRefined) e.nodes.at(j); if (nRefined.isHangingNode()) { DOF dof = new DOF( ++nDofLocalIndexCounter, nRefined.constrainNodes.at(1).globalIndex, shapeFun2[j - 1]); e.addNodeDOF(j, dof); DOF dof2 = new DOF( ++nDofLocalIndexCounter, nRefined.constrainNodes.at(2).globalIndex, shapeFun2[j - 1]); e.addNodeDOF(j, dof2); } else { DOF dof = new DOF(++nDofLocalIndexCounter, e.nodes.at(j).globalIndex, shapeFun[j - 1]); e.addNodeDOF(j, dof); } } else { DOF dof = new DOF(++nDofLocalIndexCounter, e.nodes.at(j).globalIndex, shapeFun[j - 1]); e.addNodeDOF(j, dof); } } } // User defined weak form of PDE (including bounder conditions) WeakFormLaplace2D weakForm = new WeakFormLaplace2D(); // -\Delta{u} = f // u(x,y)=0, (x,y)\in\partial{\Omega} // \Omega = [0,10]*[0,10] // u=[(x-5)^2-25]*[(y-5)^2-25] // f=-2*( (x-5)^2 + (y-5)^2 ) + 100 Function fxm5 = new FAxpb("x", 1.0, -5.0); Function fym5 = new FAxpb("y", 1.0, -5.0); weakForm.setF( FC.c(-2.0) .M(FMath.pow(fxm5, new FC(2.0))) .A(FC.c(-2.0).M(FMath.pow(fym5, new FC(2.0)))) .A(FC.c(100.0))); AssemblerScalar assembler = new AssemblerScalar(mesh, weakForm); System.out.println("Begin Assemble..."); assembler.assemble(); Matrix stiff = assembler.getStiffnessMatrix(); Vector load = assembler.getLoadVector(); assembler.imposeDirichletCondition(new FC(0.0)); System.out.println("Assemble done!"); SolverJBLAS solver = new SolverJBLAS(); Vector u = solver.solveDGESV(stiff, load); // hanging node赋值 for (int i = 1; i <= mesh.getElementList().size(); i++) { Element e = mesh.getElementList().at(i); for (int j = 1; j <= e.nodes.size(); j++) { if (e.nodes.at(j) instanceof NodeRefined) { NodeRefined nRefined = (NodeRefined) e.nodes.at(j); if (nRefined.isHangingNode()) { double hnValue = (u.get(nRefined.constrainNodes.at(1).globalIndex) + u.get(nRefined.constrainNodes.at(2).globalIndex)) / 2.0; u.set(nRefined.globalIndex, hnValue); } } } } System.out.println("u="); for (int i = 1; i <= u.getDim(); i++) System.out.println(String.format("%.3f", u.get(i))); MeshWriter writer = new MeshWriter(mesh); writer.writeTechplot("patch_triangle.dat", u); }
public static void beforeRefinement() { // MeshReader reader = new MeshReader("patch_rectangle.grd"); MeshReader reader = new MeshReader("patch_rectangle2.grd"); // MeshReader reader = new MeshReader("patch_rectangle_refine.grd"); Mesh mesh = reader.read2DMesh(); mesh.computeNodeBelongsToElements(); mesh.computeNeighborNodes(); mesh.computeGlobalEdge(); mesh.computeNeighborElements(); HashMap<NodeType, Function> mapNTF = new HashMap<NodeType, Function>(); mapNTF.put(NodeType.Dirichlet, null); mesh.markBorderNode(mapNTF); SFBilinearLocal2D[] shapeFun = new SFBilinearLocal2D[4]; for (int i = 0; i < 4; i++) shapeFun[i] = new SFBilinearLocal2D(i + 1); // Asign degree of freedom to element for (int i = 1; i <= mesh.getElementList().size(); i++) { Element e = mesh.getElementList().at(i); int nDofLocalIndexCounter = 0; for (int j = 1; j <= e.nodes.size(); j++) { // Asign shape function to DOF DOF dof = new DOF(++nDofLocalIndexCounter, e.nodes.at(j).globalIndex, shapeFun[j - 1]); e.addNodeDOF(j, dof); } } // User defined weak form of PDE (including bounder conditions) WeakFormLaplace2D weakForm = new WeakFormLaplace2D(); // -\Delta{u} = f // u(x,y)=0, (x,y)\in\partial{\Omega} // \Omega = [0,10]*[0,10] // u=[(x-5)^2-25]*[(y-5)^2-25] // f=-2*( (x-5)^2 + (y-5)^2 ) + 100 Function fxm5 = new FAxpb("x", 1.0, -5.0); Function fym5 = new FAxpb("y", 1.0, -5.0); weakForm.setF( FC.c(-2.0) .M(FMath.pow(fxm5, new FC(2.0))) .A(FC.c(-2.0).M(FMath.pow(fym5, new FC(2.0)))) .A(FC.c(100.0))); AssemblerScalar assembler = new AssemblerScalar(mesh, weakForm); System.out.println("Begin Assemble..."); assembler.assemble(); Matrix stiff = assembler.getStiffnessMatrix(); Vector load = assembler.getLoadVector(); assembler.imposeDirichletCondition(new FC(0.0)); System.out.println("Assemble done!"); stiff.print(); SolverJBLAS solver = new SolverJBLAS(); Vector u = solver.solveDGESV(stiff, load); System.out.println("u="); for (int i = 1; i <= u.getDim(); i++) System.out.println(String.format("%.3f", u.get(i))); MeshWriter writer = new MeshWriter(mesh); writer.writeTechplot("patch_rectangle_before_refine.dat", u); writer.writeTechplot("patch_rectangle_before_refine_load.dat", load); }
public static void adaptiveTestRectangle() { // MeshReader reader = new MeshReader("patch_rectangle.grd"); MeshReader reader = new MeshReader("patch_rectangle2.grd"); // MeshReader reader = new MeshReader("patch_rectangle_refine.grd"); Mesh mesh = reader.read2DMesh(); HashMap<NodeType, Function> mapNTF = new HashMap<NodeType, Function>(); // 验证边界结点加密后是自由的,而不是hanging node // mapNTF.put(NodeType.Robin, new AbstractFunction("x","y"){ // @Override // public double value(Variable v) { // if(Math.abs(v.get("x"))<0.01) // return 1.0; // else // return -1.0; // } // }); mapNTF.put(NodeType.Dirichlet, null); mesh.computeNodeBelongsToElements(); mesh.computeNeighborNodes(); mesh.markBorderNode(mapNTF); mesh.computeGlobalEdge(); mesh.computeNeighborElements(); ElementList eList = mesh.getElementList(); ElementList eToRefine = new ElementList(); eToRefine.add(eList.at(6)); eToRefine.add(eList.at(7)); eToRefine.add(eList.at(10)); eToRefine.add(eList.at(11)); Refiner.refineOnce(mesh, eToRefine); mesh.markBorderNode(mapNTF); mesh.printMeshInfo(); Tools.plotFunction(mesh, "", "patch_rectangle_test1.dat", FC.C0); // 二次加密 eToRefine.clear(); // 单元编号的问题该如何处理? eToRefine.add(eList.at(17)); eToRefine.add(eList.at(18)); // 第一步:新增加的结点赋予全局编号,加入mesh对象 Refiner.refineOnce(mesh, eToRefine); mesh.markBorderNode(mapNTF); mesh.printMeshInfo(); Tools.plotFunction(mesh, "", "patch_rectangle_test2.dat", FC.C0); SFBilinearLocal2D[] shapeFun = new SFBilinearLocal2D[4]; for (int i = 0; i < 4; i++) shapeFun[i] = new SFBilinearLocal2D(i + 1); SFBilinearLocal2D[] shapeFun2 = new SFBilinearLocal2D[4]; for (int i = 0; i < 4; i++) { shapeFun2[i] = new SFBilinearLocal2D(i + 1, 0.5); } // Asign degree of freedom to element for (int i = 1; i <= mesh.getElementList().size(); i++) { Element e = mesh.getElementList().at(i); int nDofLocalIndexCounter = 0; for (int j = 1; j <= e.nodes.size(); j++) { // Asign shape function to DOF if (e.nodes.at(j) instanceof NodeRefined) { NodeRefined nRefined = (NodeRefined) e.nodes.at(j); if (nRefined.isHangingNode()) { DOF dof = new DOF( ++nDofLocalIndexCounter, nRefined.constrainNodes.at(1).globalIndex, shapeFun2[j - 1]); e.addNodeDOF(j, dof); DOF dof2 = new DOF( ++nDofLocalIndexCounter, nRefined.constrainNodes.at(2).globalIndex, shapeFun2[j - 1]); e.addNodeDOF(j, dof2); } else { DOF dof = new DOF(++nDofLocalIndexCounter, e.nodes.at(j).globalIndex, shapeFun[j - 1]); e.addNodeDOF(j, dof); } } else { DOF dof = new DOF(++nDofLocalIndexCounter, e.nodes.at(j).globalIndex, shapeFun[j - 1]); e.addNodeDOF(j, dof); } } } // User defined weak form of PDE (including bounder conditions) WeakFormLaplace2D weakForm = new WeakFormLaplace2D(); // -\Delta{u} = f // u(x,y)=0, (x,y)\in\partial{\Omega} // \Omega = [0,10]*[0,10] // u=[(x-5)^2-25]*[(y-5)^2-25] // f=-2*( (x-5)^2 + (y-5)^2 ) + 100 Function fxm5 = new FAxpb("x", 1.0, -5.0); Function fym5 = new FAxpb("y", 1.0, -5.0); weakForm.setF( FC.c(-2.0) .M(FMath.pow(fxm5, new FC(2.0))) .A(FC.c(-2.0).M(FMath.pow(fym5, new FC(2.0)))) .A(FC.c(100.0))); AssemblerScalar assembler = new AssemblerScalar(mesh, weakForm); System.out.println("Begin Assemble..."); assembler.assemble(); Matrix stiff = assembler.getStiffnessMatrix(); Vector load = assembler.getLoadVector(); assembler.imposeDirichletCondition(new FC(0.0)); System.out.println("Assemble done!"); stiff.print(); load.print(); SolverJBLAS solver = new SolverJBLAS(); Vector u = solver.solveDGESV(stiff, load); // //hanging node赋值 // for(int i=1;i<=mesh.getElementList().size();i++) { // Element e = mesh.getElementList().at(i); // for(int j=1;j<=e.nodes.size();j++) { // if(e.nodes.at(j) instanceof NodeRefined) { // NodeRefined nRefined = (NodeRefined)e.nodes.at(j); // if(nRefined.isHangingNode()) { // double hnValue = // (u.get(nRefined.constrainNodes.at(1).globalIndex)+ // u.get(nRefined.constrainNodes.at(2).globalIndex))/2.0; // // u.set(nRefined.globalIndex, hnValue); // } // } // } // } System.out.println("u="); for (int i = 1; i <= u.getDim(); i++) System.out.println(String.format("%.3f", u.get(i))); MeshWriter writer = new MeshWriter(mesh); writer.writeTechplot("patch_rectangle.dat", u); Vector res = new SparseVectorHashMap(u.getDim()); stiff.mult(u, res); res.add(-1.0, load); writer.writeTechplot("patch_rectangle_res.dat", res); writer.writeTechplot("patch_rectangle_load.dat", load); connectSells(mesh, load); writer.writeTechplot("patch_rectangle_load_connectSells.dat", load); }