public SparseMatrix getC(Vector uk) {
    // 4.Weak form: (\nabla{\phi},dq\nabla{uk})
    WeakFormGCM weakForm = new WeakFormGCM();

    Function fuk = new Vector2Function(uk, mesh, "x", "y");
    Function u_x = fuk._d("x");
    Function u_y = fuk._d("y");
    plotFunction(mesh, u_x, "u_x.dat");
    plotFunction(mesh, u_y, "u_y.dat");
    weakForm.setParam(FC.C0, FC.C0, u_x, u_y);
    // 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;
  }
 @Override
 public double integrate(Element e, Function fun) {
   if (fun == null) return 0.0;
   if (e.dim() == 2) {
     if (e.vertices().size() == 3) {
       // 三角形单元
       return FOIntegrate.intOnTriangleRefElement(fun.M(e.getJacobin()), 2);
     } else if (e.vertices().size() == 4) {
       // 四边形单元
       return FOIntegrate.intOnRectangleRefElement(
           fun.M(e.getJacobin()), 5 // TODO
           );
     }
   } else if (e.dim() == 3) {
     if (e.vertices().size() == 4) {
       // 四面体单元
       return FOIntegrate.intOnTetrahedraRefElement(fun.M(e.getJacobin()), 2);
     } else if (e.vertices().size() == 8) {
       // 六面体单元
       return FOIntegrate.intOnHexahedraRefElement(fun.M(e.getJacobin()), 2);
     }
   } else if (e.dim() == 1) {
     // 一维单元
     return FOIntegrate.intOnLinearRefElement(fun.M(e.getJacobin()), 5);
   } else {
     throw new FutureyeException("Can NOT integrate on e" + e.vertices());
   }
   throw new FutureyeException("Error");
 }
  /**
   * 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;
  }
 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 Vector solveAdjointEquation(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) = - (u - z)
    weakForm.setF(z.S(new Vector2Function(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!");

    // 6.Solve linear system
    Solver solver = new Solver();
    Vector lmd_solve = solver.solveCGS(stiff, load);

    return lmd_solve;
  }