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 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); }