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 void readMesh() { MeshReader reader = new MeshReader("lagrangian.grd"); mesh = reader.read2DMesh(); mesh.computeNodeBelongsToElements(); // 2.Mark border types HashMap<NodeType, Function> mapNTF = new HashMap<NodeType, Function>(); mapNTF.put(NodeType.Dirichlet, null); mesh.markBorderNode(mapNTF); ElementList eList = mesh.getElementList(); // for(int i=1;i<=eList.size();i++) { // System.out.println(eList.at(i)); // } // 3.Use element library to assign degrees of // freedom (DOF) to element FELinearTriangle feLT = new FELinearTriangle(); for (int i = 1; i <= eList.size(); i++) feLT.assignTo(eList.at(i)); }
public void imposeDirichletCondition(SparseBlockMatrix BM, SparseBlockVector BV, Function diri) { ElementList eList = mesh.getElementList(); int nNode = mesh.getNodeList().size(); for (int i = 1; i <= eList.size(); i++) { Element e = eList.at(i); DOFList DOFs = e.getAllDOFList(DOFOrder.NEFV); for (int j = 1; j <= DOFs.size(); j++) { DOF dof = DOFs.at(j); GeoEntity ge = dof.getOwner(); if (ge instanceof Node) { Node n = (Node) ge; if (n.getNodeType() == NodeType.Dirichlet) { Variable v = Variable.createFrom(diri, n, 0); setDirichlet(BM, BV, dof.getGlobalIndex(), diri.value(v)); setDirichlet(BM, BV, nNode + dof.getGlobalIndex(), diri.value(v)); setDirichlet(BM, BV, nNode * 2 + dof.getGlobalIndex(), diri.value(v)); } } } } }
public static void plotFunction(Mesh mesh, Function fun, String fileName) { NodeList list = mesh.getNodeList(); int nNode = list.size(); Variable var = new Variable(); Vector v = new SparseVectorHashMap(nNode); for (int i = 1; i <= nNode; i++) { Node node = list.at(i); var.setIndex(node.globalIndex); var.set("x", node.coord(1)); var.set("y", node.coord(2)); v.set(i, fun.value(var)); } plotVector(mesh, v, fileName); }
public static void connectSells(Mesh mesh, Vector v) { NodeList nodes = mesh.getNodeList(); for (int i = 1; i <= nodes.size(); i++) { Node node = nodes.at(i); if (node instanceof NodeRefined) { NodeRefined nRefined = (NodeRefined) node; if (nRefined.isHangingNode()) { v.set( node.globalIndex, v.get(nRefined.constrainNodes.at(1).globalIndex) * 0.5 + v.get(nRefined.constrainNodes.at(2).globalIndex) * 0.5); } } } }
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); }
public void gaussNewtonIterate() { // 初值 NodeList nodes = mesh.getNodeList(); // 初始q=q0 Vector q0 = new SparseVectorHashMap(nodes.size()); Vector q00 = new SparseVectorHashMap(nodes.size()); for (int i = 1; i <= nodes.size(); i++) { Node node = nodes.at(i); if (node.getNodeType() == NodeType.Dirichlet) q0.set(i, this.coef_q.value(Variable.createFrom(coef_q, node, 0))); else { // q0.set(i,this.coef_q.value(Variable.createFrom(coef_q, node, 0))+1.0+Math.random()*0.9); // q0.set(i,1.0+Math.random()*0.9); double x = node.coord(1); double y = node.coord(2); if (Math.sqrt((x) * (x) + (y) * (y)) < 0.5) { q0.set(i, 3.0); // =1的圆位置偏移 // if(Math.sqrt((x-0.3)*(x-0.3)+(y)*(y))<0.5) { // q0.set(i,1.0); } else { q0.set(i, 8.0); } } q00.set( i, this.coef_q.value(Variable.createFrom(coef_q, node, 0)) + 1.0 + Math.random() * 0.9); } plotVector(mesh, q0, "q0.dat"); plotVector(mesh, q00, "q00.dat"); // 初始u=u0, lambda=lambda0,从q00计算而来 Vector u0 = this.solveStateEquation(q0); // q00 plotVector(mesh, u0, "u0.dat"); Vector lambda0 = this.solveAdjointEquation(u0, q0); // q00 plotVector(mesh, lambda0, "lambda0.dat"); // 强制u0=0,lambda0=0 // q0 = new SparseVectorHashMap(nodes.size(),1.0); // u0 = new SparseVectorHashMap(nodes.size(),0.0); // lambda0 = new SparseVectorHashMap(nodes.size(),0.0); SparseBlockVector f = new SparseBlockVector(3); // 迭代求解 for (int iter = 0; iter < 50; iter++) { iterNum = iter; SparseBlockMatrix BM = this.getSearchDirectionMatrix(u0, q0); f.setBlock(1, this.getResLu(u0, lambda0, q0).scale(-1.0)); f.setBlock(2, this.getResLlmd(u0, q0).scale(-1.0)); // bugfix lambda0->q0 f.setBlock(3, this.getResLq(u0, lambda0, q0).scale(-1.0)); // 设置边界条件并求解 // 需要交换矩阵BM的第1, 2列,然后设置边界条件,这样使得矩阵A, A'可逆 // BlockMatrix newBM = this.changeBlockColumn(BM, 1, 2); // this.imposeDirichletCondition(newBM, f, FC.c0); // SchurComplementLagrangianSolver solver = // new SchurComplementLagrangianSolver(BM, f,mesh); // BlockVector x = solver.solve(); this.imposeDirichletCondition(BM, f, FC.C0); SolverJBLAS sol = new SolverJBLAS(); SparseBlockVector x = sol.solveDGESV(BM, f); plotVector(mesh, x.getBlock(1), String.format("delta_u%02d.dat", iter)); plotVector(mesh, x.getBlock(2), String.format("delta_lambda%02d.dat", iter)); plotVector(mesh, x.getBlock(3), String.format("delta_q%02d.dat", iter)); // 待定,与beta选取有关 // double stepLength = 0.01; // double stepLength = 0.3; // double stepLength = 0.00005; double stepLength = 0.0001; u0.add(stepLength, x.getBlock(1)); lambda0.add(stepLength, x.getBlock(2)); q0.add(stepLength, x.getBlock(3)); plotVector(mesh, u0, String.format("rlt_u%02d.dat", iter)); plotVector(mesh, lambda0, String.format("rlt_lambda%02d.dat", iter)); plotVector(mesh, q0, String.format("rlt_q%02d.dat", iter)); } }
@Override public int getDOFNumOnMesh(Mesh mesh, int vsfDim) { return mesh.getNodeList().size(); }