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 testSFLinearLocal2D() { NodeList nodes = new NodeList(); nodes.add(new Node(1, 0.0, 0.0)); nodes.add(new Node(2, 0.2, 0.0)); nodes.add(new Node(3, 0.0, 0.2)); Element e = new Element(nodes); System.out.println("Test coordinate transform and Jacbian on element " + e); CoordinateTransform trans = new CoordinateTransform(2); trans.transformLinear2D(e); trans.computeJacobianMatrix(); trans.computeJacobian2D(); MathFunc jac = trans.getJacobian(); Variable v = new Variable(); v.set("r", 0); v.set("s", 0); check(jac.toString(), jac.apply(v), 0.04); ScalarShapeFunction[] shapeFun = new ScalarShapeFunction[3]; shapeFun[0] = new SFLinearLocal2DRS(1); shapeFun[1] = new SFLinearLocal2DRS(2); shapeFun[2] = new SFLinearLocal2DRS(3); System.out.println("Test the derivatives of shape function SFLinearLocal2DRS:"); double[] rlt = new double[] {-5, -5, 5, 0, 0, 5}; int j = 0; for (int i = 0; i < 3; i++) { System.out.println(shapeFun[i]); shapeFun[i].assignElement(e); MathFunc SFdx = shapeFun[i].diff("x"); MathFunc SFdy = shapeFun[i].diff("y"); check("shapeFun[" + i + "].diff(\"x\")", SFdx.apply(), rlt[j++]); check("shapeFun[" + i + "].diff(\"y\")", SFdy.apply(), rlt[j++]); } System.out.println("Test the derivatives of shape function SFLinearLocal2D:"); shapeFun[0] = new SFLinearLocal2D(1); shapeFun[1] = new SFLinearLocal2D(2); shapeFun[2] = new SFLinearLocal2D(3); j = 0; for (int i = 0; i < 3; i++) { System.out.println(shapeFun[i]); shapeFun[i].assignElement(e); MathFunc SFdx = shapeFun[i].diff("x"); MathFunc SFdy = shapeFun[i].diff("y"); check("shapeFun[" + i + "].diff(\"x\")=" + SFdy, SFdx.apply(v), rlt[j++]); check("shapeFun[" + i + "].diff(\"y\")=" + SFdy, SFdy.apply(v), rlt[j++]); } }
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 testSFBilinearLocal2D() { NodeList nodes = new NodeList(); nodes.add(new Node(1, -2.0, -2.0)); nodes.add(new Node(2, 2.0, -2.0)); nodes.add(new Node(3, 2.0, 2.0)); nodes.add(new Node(4, -2.0, 2.0)); Element e = new Element(nodes); System.out.println("Test coordinate transform and Jacbian on element " + e); CoordinateTransform trans = new CoordinateTransform(2); trans.transformLinear2D(e); trans.computeJacobianMatrix(); trans.computeJacobian2D(); MathFunc jac = trans.getJacobian(); Variable v = new Variable(); v.set("r", 0); v.set("s", 0); check(jac.toString(), jac.apply(v), 4.0); ScalarShapeFunction[] shapeFun = new ScalarShapeFunction[4]; shapeFun[0] = new SFBilinearLocal2D(1); shapeFun[1] = new SFBilinearLocal2D(2); shapeFun[2] = new SFBilinearLocal2D(3); shapeFun[3] = new SFBilinearLocal2D(4); System.out.println("Test the evaluation of SFBilinearLocal2D:"); double[] args = new double[] {0.1, 0.1}; Variable v0 = new Variable(); v0.set("r", args[0]); v0.set("s", args[1]); System.out.println(shapeFun[0]); check(shapeFun[0].toString(), shapeFun[0].apply(v0), 0.2025); check(shapeFun[0].toString(), shapeFun[0].apply(args), 0.2025); check(shapeFun[0].toString(), shapeFun[0].compile().apply(args), 0.2025); System.out.println("Test the derivatives of shape function SFBilinearLocal2D:"); e.updateJacobin(); double[] rlt = new double[] {-0.125, -0.125, 0.125, -0.125, 0.125, 0.125, -0.125, 0.125}; int j = 0; for (int i = 0; i < 4; i++) { System.out.println(shapeFun[i]); shapeFun[i].assignElement(e); MathFunc SFdx = shapeFun[i].diff("x"); MathFunc SFdy = shapeFun[i].diff("y"); check("shapeFun[" + i + "].diff(\"x\")=" + SFdy, SFdx.apply(v), rlt[j++]); check("shapeFun[" + i + "].diff(\"y\")=" + SFdy, SFdy.apply(v), rlt[j++]); } }
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)); } }