@Override
    public double apply(Variable v) {
      double r = v.get(VN.r);
      double s = v.get(VN.s);
      double t = v.get(VN.t);

      return (vt[funIndex][0] * r + 1.0)
          * (vt[funIndex][1] * s + 1.0)
          * (vt[funIndex][2] * t + 1.0)
          / 8.0;
    }
 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++]);
    }
  }
    @Override
    public double apply(Variable v) {
      double r = v.get(VN.r);
      double s = v.get(VN.s);
      double t = v.get(VN.t);

      double cr = vt[funIndex][0];
      double cs = vt[funIndex][1];
      double ct = vt[funIndex][2];

      if ("r".equals(var)) return cr * (cs * s + 1.0) * (ct * t + 1.0) / 8.0;
      else if ("s".equals(var)) return (cr * r + 1.0) * cs * (ct * t + 1.0) / 8.0;
      else if ("t".equals(var)) return (cr * r + 1.0) * (cs * s + 1.0) * ct / 8.0;
      else throw new FutureyeException("");
    }
  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++]);
    }
  }
 @Override
 public double value(Variable v) {
   double x = v.get("x");
   double y = v.get("y");
   if (Math.sqrt(x * x + y * y) < 0.5) return 1.0;
   else return 8.0;
 }
 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));
         }
       }
     }
   }
 }
 @Override
 public double value(Variable v) {
   double x = v.get("x");
   double y = v.get("y");
   return (x * x + y * y) / 8.0 + 7.0 / 32.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));
    }
  }
Esempio n. 10
0
 @Override
 public double apply(Variable v) {
   return v.get(varNames[funIndex]);
 }