예제 #1
0
QuadEdgeBasis::QuadEdgeBasis(size_t order){
  // Reference Space //
  refSpace  = new QuadReferenceSpace;
  nRefSpace = getReferenceSpace().getNReferenceSpace();

  const vector<vector<vector<size_t> > >&
    edgeIdx = refSpace->getEdgeNodeIndex();

  const vector<vector<vector<size_t> > >&
    faceIdx = refSpace->getFaceNodeIndex();

  // Set Basis Type //
  this->order = order;

  type = 1;
  dim  = 2;

  nVertex   = 0;
  nEdge     = 4 * (order + 1);
  nFace     = 2 * (order + 1) * order;
  nCell     = 0;
  nFunction = nVertex + nEdge + nFace + nCell;

  // Legendre Polynomial //
  const size_t orderPlus = order + 1;

  Polynomial* legendre    = new Polynomial[orderPlus];
  Polynomial* intLegendre = new Polynomial[orderPlus];

  Legendre::integrated(intLegendre, orderPlus);
  Legendre::legendre(legendre, order);

  // Lagrange & Lifting //
  const Polynomial lagrange[4] =
    {
      Polynomial((Polynomial(1, 0, 0, 0) - Polynomial(1, 1, 0, 0)) *
                 (Polynomial(1, 0, 0, 0) - Polynomial(1, 0, 1, 0))),

      Polynomial((Polynomial(1, 1, 0, 0)) *
                 (Polynomial(1, 0, 0, 0) - Polynomial(1, 0, 1, 0))),

      Polynomial((Polynomial(1, 1, 0, 0)) *
                 (Polynomial(1, 0, 1, 0))),

      Polynomial((Polynomial(1, 0, 0, 0) - Polynomial(1, 1, 0, 0)) *
                 (Polynomial(1, 0, 1, 0)))
    };

  const Polynomial lifting[4] =
    {
      Polynomial((Polynomial(1, 0, 0, 0) - Polynomial(1, 1, 0, 0)) +
                 (Polynomial(1, 0, 0, 0) - Polynomial(1, 0, 1, 0))),

      Polynomial((Polynomial(1, 1, 0, 0)) +
                 (Polynomial(1, 0, 0, 0) - Polynomial(1, 0, 1, 0))),

      Polynomial((Polynomial(1, 1, 0, 0)) +
                 (Polynomial(1, 0, 1, 0))),

      Polynomial((Polynomial(1, 0, 0, 0) - Polynomial(1, 1, 0, 0)) +
                 (Polynomial(1, 0, 1, 0)))
    };

  // Basis //
  basis = new vector<Polynomial>**[nRefSpace];

  for(size_t s = 0; s < nRefSpace; s++)
    basis[s] = new vector<Polynomial>*[nFunction];

  // Edge Based //
  for(size_t s = 0; s < nRefSpace; s++){
    size_t i = 0;

    for(size_t e = 0; e < 4; e++){
      for(size_t l = 0; l < orderPlus; l++){
        // Nedelec
        if(l == 0){
          Polynomial lambda = (lagrange[edgeIdx[s][e][0]] +
                               lagrange[edgeIdx[s][e][1]]) * 0.5;

          basis[s][i] =
            new vector<Polynomial>((lifting[edgeIdx[s][e][1]] -
                                    lifting[edgeIdx[s][e][0]]).gradient());

          basis[s][i]->at(0).mul(lambda);
          basis[s][i]->at(1).mul(lambda);
          basis[s][i]->at(2).mul(lambda);
        }

        // High Order
        else{
          basis[s][i] =
            new vector<Polynomial>
            ((intLegendre[l].compose(lifting[edgeIdx[s][e][1]] -
                                     lifting[edgeIdx[s][e][0]])
              *
              (lagrange[edgeIdx[s][e][0]] +
               lagrange[edgeIdx[s][e][1]])).gradient());
        }

        i++;
      }
    }
  }

  // Face Based //

  // NB: We use (*(*faceIdx[s])[f])[]
  //     where f = 0, because triangles
  //     have only ONE face: the face '0'

  for(size_t s = 0; s < nRefSpace; s++){
    size_t i = nEdge;

    // Type 1
    for(size_t l1 = 1; l1 < orderPlus; l1++){
      for(size_t l2 = 1; l2 < orderPlus; l2++){
        basis[s][i] =
          new vector<Polynomial>
          ((intLegendre[l1].compose(lifting[faceIdx[s][0][0]] -
                                    lifting[faceIdx[s][0][1]])
            *

            intLegendre[l2].compose(lifting[faceIdx[s][0][0]] -
                                    lifting[faceIdx[s][0][3]])).gradient());

        i++;
      }
    }

    // Type 2
    for(size_t l1 = 1; l1 < orderPlus; l1++){
      for(size_t l2 = 1; l2 < orderPlus; l2++){
        Polynomial pOne = lifting[faceIdx[s][0][0]] -
                          lifting[faceIdx[s][0][1]];

        Polynomial pTwo = lifting[faceIdx[s][0][0]] -
                          lifting[faceIdx[s][0][3]];

        Polynomial lOne =    legendre[l1].compose(pOne) *
                          intLegendre[l2].compose(pTwo);

        Polynomial lTwo =    legendre[l2].compose(pTwo) *
                          intLegendre[l1].compose(pOne);

        vector<Polynomial> gradOne = pOne.gradient();
        vector<Polynomial> gradTwo = pTwo.gradient();

        gradOne[0].mul(lOne);
        gradOne[1].mul(lOne);
        gradOne[2].mul(lOne);

        gradTwo[0].mul(lTwo);
        gradTwo[1].mul(lTwo);
        gradTwo[2].mul(lTwo);

        basis[s][i] = new vector<Polynomial>(gradOne);

        basis[s][i]->at(0).sub(gradTwo[0]);
        basis[s][i]->at(1).sub(gradTwo[1]);
        basis[s][i]->at(2).sub(gradTwo[2]);

        i++;
      }
    }

    // Type 3.1
    for(size_t l1 = 1; l1 < orderPlus; l1++){
      Polynomial tmp =
        intLegendre[l1].compose(lifting[faceIdx[s][0][0]] -
                                lifting[faceIdx[s][0][3]]);


      basis[s][i] =
        new vector<Polynomial>((lifting[faceIdx[s][0][0]] -
                                lifting[faceIdx[s][0][1]]).gradient());

      basis[s][i]->at(0).mul(tmp);
      basis[s][i]->at(1).mul(tmp);
      basis[s][i]->at(2).mul(tmp);

      i++;
    }

    // Type 3.2
    for(size_t l1 = 1; l1 < orderPlus; l1++){
      Polynomial tmp =
        intLegendre[l1].compose(lifting[faceIdx[s][0][0]] -
                                lifting[faceIdx[s][0][1]]);


      basis[s][i] =
        new vector<Polynomial>((lifting[faceIdx[s][0][0]] -
                                lifting[faceIdx[s][0][3]]).gradient());

      basis[s][i]->at(0).mul(tmp);
      basis[s][i]->at(1).mul(tmp);
      basis[s][i]->at(2).mul(tmp);

      i++;
    }
  }

  // Mapping to Gmsh Quad //
  // x = (u + 1) / 2
  // y = (v + 1) / 2
  //
  // (x, y) = Zaglmayr Ref Quad
  // (u, v) = Gmsh     Ref Quad

  Polynomial  mapX(Polynomial(0.5, 1, 0, 0) +
                   Polynomial(0.5, 0, 0, 0));

  Polynomial  mapY(Polynomial(0.5, 0, 1, 0) +
                   Polynomial(0.5, 0, 0, 0));

  for(size_t s = 0; s < nRefSpace; s++){
    for(size_t i = 0; i < nFunction; i++){
      vector<Polynomial>* old;
      vector<Polynomial>  nxt(3);

      old    = basis[s][i];
      nxt[0] = (*old)[0].compose(mapX, mapY);
      nxt[1] = (*old)[1].compose(mapX, mapY);
      nxt[2] = (*old)[2].compose(mapX, mapY);

      basis[s][i] = new vector<Polynomial>(nxt);
      delete old;
    }
  }

  // Free Temporary Sapce //
  delete[] legendre;
  delete[] intLegendre;
}
예제 #2
0
TriEdgeBasis::TriEdgeBasis(size_t order){
  // Set Basis Type //
  this->order = order;

  type = TYPE_TRI;
  dim  = 2;

  nVertex   = 0;
  nEdge     = 3 * (order + 1);
  nFace     = ((order - 1) * order + order - 1);
  nCell     = 0;
  nFunction = nVertex + nEdge + nFace + nCell;

  // Reference Space //
  const size_t nOrientation = ReferenceSpaceManager::getNOrientation(type);

  const vector<vector<vector<size_t> > >&
    edgeIdx = ReferenceSpaceManager::getEdgeNodeIndex(type);

  const vector<vector<vector<size_t> > >&
    faceIdx = ReferenceSpaceManager::getFaceNodeIndex(type);

  // Alloc Some Space //
  const int orderPlus  = order + 1;
  const int orderMinus = order - 1;

  Polynomial* legendre    = new Polynomial[orderPlus];
  Polynomial* intLegendre = new Polynomial[orderPlus];

  // Legendre Polynomial //
  Legendre::legendre(legendre, order);
  Legendre::intScaled(intLegendre, orderPlus);

  // Lagrange //
  const Polynomial lagrange[3] =
    {
      Polynomial(Polynomial(1, 0, 0, 0) -
                 Polynomial(1, 1, 0, 0) -
                 Polynomial(1, 0, 1, 0)),

      Polynomial(Polynomial(1, 1, 0, 0)),

      Polynomial(Polynomial(1, 0, 1, 0))
    };

  // One //
  Polynomial one(1, 0, 0, 0);

  // Basis //
  basis = new vector<Polynomial>**[nOrientation];

  for(size_t s = 0; s < nOrientation; s++)
    basis[s] = new vector<Polynomial>*[nFunction];

  // Edge Based //
  for(size_t s = 0; s < nOrientation; s++){
    size_t i = 0;

    for(int e = 0; e < 3; e++){
      for(int l = 0; l < orderPlus; l++){
        // Nedelec
        if(l == 0){
          vector<Polynomial> tmp1 = lagrange[edgeIdx[s][e][1]].gradient();
          vector<Polynomial> tmp2 = lagrange[edgeIdx[s][e][0]].gradient();

          tmp1[0].mul(lagrange[edgeIdx[s][e][0]]);
          tmp1[1].mul(lagrange[edgeIdx[s][e][0]]);
          tmp1[2].mul(lagrange[edgeIdx[s][e][0]]);

          tmp2[0].mul(lagrange[edgeIdx[s][e][1]]);
          tmp2[1].mul(lagrange[edgeIdx[s][e][1]]);
          tmp2[2].mul(lagrange[edgeIdx[s][e][1]]);

          tmp2[0].sub(tmp1[0]);
          tmp2[1].sub(tmp1[1]);
          tmp2[2].sub(tmp1[2]);

          basis[s][i] = new vector<Polynomial>(tmp2);
        }

        // High Order
        else{
          basis[s][i] =
            new vector<Polynomial>
            ((intLegendre[l].compose(lagrange[edgeIdx[s][e][0]] -
                                     lagrange[edgeIdx[s][e][1]]
                                     ,
                                     lagrange[edgeIdx[s][e][1]] +
                                     lagrange[edgeIdx[s][e][0]])).gradient());
        }
        i++;
      }
    }
  }

  // Face Based //

  // NB: We use (*(*faceIdx[s])[f])[]
  //     where f = 0, because triangles
  //     have only ONE face: the face '0'

  for(size_t s = 0; s < nOrientation; s++){
    size_t i = nEdge;

    for(size_t l1 = 1; l1 < order; l1++){
      for(int l2 = 0; l2 + (int)l1 - 1 < orderMinus; l2++){
        // Preliminary Type 1
        Polynomial u =
          intLegendre[l1].compose(lagrange[faceIdx[s][0][1]] -
                                  lagrange[faceIdx[s][0][0]]
                                  ,
                                  lagrange[faceIdx[s][0][0]] +
                                  lagrange[faceIdx[s][0][1]]);
        Polynomial v =
          lagrange[faceIdx[s][0][2]] *
          legendre[l2].compose(lagrange[faceIdx[s][0][2]] * 2 - one);

        // Preliminary Type 2
        vector<Polynomial> gradU = u.gradient();
        vector<Polynomial> gradV = v.gradient();

        vector<Polynomial> vGradU(gradU);
        vGradU[0].mul(v);
        vGradU[1].mul(v);
        vGradU[2].mul(v);

        vector<Polynomial> uGradV(gradV);
        uGradV[0].mul(u);
        uGradV[1].mul(u);
        uGradV[2].mul(u);

        vector<Polynomial> subGradUV(vGradU);
        subGradUV[0].sub(uGradV[0]);
        subGradUV[1].sub(uGradV[1]);
        subGradUV[2].sub(uGradV[2]);

        // Preliminary Type 3
        vector<Polynomial> gradL1 = lagrange[faceIdx[s][0][0]].gradient();
        vector<Polynomial> gradL2 = lagrange[faceIdx[s][0][1]].gradient();

        vector<Polynomial> l2GradL1(gradL1);
        l2GradL1[0].mul(lagrange[faceIdx[s][0][1]]);
        l2GradL1[1].mul(lagrange[faceIdx[s][0][1]]);
        l2GradL1[2].mul(lagrange[faceIdx[s][0][1]]);

        vector<Polynomial> l1GradL2(gradL2);
        l1GradL2[0].mul(lagrange[faceIdx[s][0][0]]);
        l1GradL2[1].mul(lagrange[faceIdx[s][0][0]]);
        l1GradL2[2].mul(lagrange[faceIdx[s][0][0]]);

        vector<Polynomial> subGradL1L2V(l2GradL1);
        subGradL1L2V[0].sub(l1GradL2[0]);
        subGradL1L2V[1].sub(l1GradL2[1]);
        subGradL1L2V[2].sub(l1GradL2[2]);

        subGradL1L2V[0].mul(v);
        subGradL1L2V[1].mul(v);
        subGradL1L2V[2].mul(v);


        // Type 1
        basis[s][i] = new vector<Polynomial>((u * v).gradient());
        i++;

        // Type 2
        basis[s][i] = new vector<Polynomial>(subGradUV);
        i++;

        // Type 3
        if(l1 == 1){
          basis[s][i] = new vector<Polynomial>(subGradL1L2V);
          i++;
        }
      }
    }
  }

  // Clear //
  delete[] legendre;
  delete[] intLegendre;
}