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;
  }
 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);
 }
Esempio n. 3
0
 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);
       }
     }
   }
 }
  /**
   * 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;
  }
Esempio n. 6
0
  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;
  }
  /**
   * Parameter regularization L_{q} := \beta(q-\overline{q},\chi) + (\chi\nabla{u},\nabla{\lambda})
   *
   * @param u
   * @param lambda
   * @param q
   * @return
   */
  public SparseVector getResLq(Vector u, Vector lambda, Vector q) {
    // 4.Weak form
    WeakFormL22D weakForm = new WeakFormL22D();
    weakForm.setParam(FC.C0, FC.C1);
    // Right hand side(RHS): f(x) = -(1.0/\beta)\nabla{u}\cdot\nabla{v}
    Function fu = new Vector2Function(u, mesh, "x", "y");
    Function flmd = new Vector2Function(lambda, mesh, "x", "y");
    Function f = FMath.grad(fu).dot(FMath.grad(flmd));
    plotFunction(mesh, f, String.format("Grad(u)Grad(lmd)%02d.dat", this.iterNum));
    Function f2 = FC.c(-1.0 / beta).M(f).A(qBar);
    plotFunction(mesh, f2, String.format("LqRHS%02d.dat", this.iterNum));
    weakForm.setF(f2);

    // 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.c(8.0));
    System.out.println("Assemble done!");

    if (debug) {
      // 6.Solve linear system
      Solver solver = new Solver();
      Vector q_solve = solver.solveCGS(stiff, load);
      plotVector(mesh, q_solve, "q_solve.dat");
    }

    // Residual
    SparseVector res = new SparseVectorHashMap(q.getDim());
    stiff.mult(q, res);
    res.add(-1.0, load);
    plotVector(mesh, res, "Res_Lq.dat");

    return res;
  }
Esempio n. 8
0
  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);
  }
Esempio n. 9
0
  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);
  }
Esempio n. 10
0
  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);
  }
Esempio n. 11
0
  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));
    }
  }