GradientBasis::GradientBasis(int tag, int order)
{
  const int type = ElementType::ParentTypeFromTag(tag);

  fullMatrix<double> samplingPoints;

  switch (type) {
    case TYPE_PNT :
      samplingPoints = gmshGeneratePointsLine(0);
      break;
    case TYPE_LIN :
      samplingPoints = gmshGeneratePointsLine(order);
      break;
    case TYPE_TRI :
      samplingPoints = gmshGeneratePointsTriangle(order,false);
      break;
    case TYPE_QUA :
      samplingPoints = gmshGeneratePointsQuadrangle(order,false);
      break;
    case TYPE_TET :
      samplingPoints = gmshGeneratePointsTetrahedron(order,false);
      break;
    case TYPE_PRI :
      samplingPoints = gmshGeneratePointsPrism(order,false);
      break;
    case TYPE_HEX :
      samplingPoints = gmshGeneratePointsHexahedron(order,false);
      break;
    case TYPE_PYR :
      samplingPoints = gmshGeneratePointsPyramidGeneral(false, order+2, order);
      break;
    default :
      Msg::Error("Unknown Jacobian function space for element tag %d", tag);
      return;
  }
  const int numSampPnts = samplingPoints.size1();

  // Store shape function gradients of mapping at Jacobian nodes
  fullMatrix<double> allDPsi;
  const nodalBasis *mapBasis = BasisFactory::getNodalBasis(tag);
  mapBasis->df(samplingPoints, allDPsi);
  const int numMapNodes = allDPsi.size1();

  gradShapeMatX.resize(numSampPnts, numMapNodes);
  gradShapeMatY.resize(numSampPnts, numMapNodes);
  gradShapeMatZ.resize(numSampPnts, numMapNodes);
  for (int i=0; i<numSampPnts; i++) {
    for (int j=0; j<numMapNodes; j++) {
      gradShapeMatX(i, j) = allDPsi(j, 3*i);
      gradShapeMatY(i, j) = allDPsi(j, 3*i+1);
      gradShapeMatZ(i, j) = allDPsi(j, 3*i+2);
    }
  }
}
Exemple #2
0
void bezierBasis::_construct(int parentType, int p)
{
  order = p;
  fullMatrix<double> exponents;
  std::vector< fullMatrix<double> > subPoints;

  if (parentType == TYPE_PYR) {
    dim = 3;
    numLagCoeff = 8;
    exponents = JacobianBasis::generateJacMonomialsPyramid(order);
    subPoints = generateSubPointsPyr(order);

    numDivisions = static_cast<int>(subPoints.size());

    fullMatrix<double> bezierPoints = exponents;
    bezierPoints.scale(1. / (order + 2));

    matrixBez2Lag = generateBez2LagMatrixPyramid(exponents, bezierPoints, order);
    matrixBez2Lag.invert(matrixLag2Bez);
    subDivisor = generateSubDivisorPyramid(exponents, subPoints, matrixLag2Bez, order);
    return;
  }

  int dimSimplex;
  switch (parentType) {
    case TYPE_PNT :
      dim = 0;
      numLagCoeff = 1;
      dimSimplex = 0;
      exponents = gmshGenerateMonomialsLine(0);
      subPoints.push_back(gmshGeneratePointsLine(0));
      break;
    case TYPE_LIN : {
      dim = 1;
      numLagCoeff = 2;
      dimSimplex = 0;
      exponents = gmshGenerateMonomialsLine(order);
      subPoints = generateSubPointsLine(order);
      break;
    }
    case TYPE_TRI : {
      dim = 2;
      numLagCoeff = 3;
      dimSimplex = 2;
      exponents = gmshGenerateMonomialsTriangle(order);
      subPoints = generateSubPointsTriangle(order);
      break;
    }
    case TYPE_QUA : {
      dim = 2;
      numLagCoeff = 4;
      dimSimplex = 0;
      exponents = gmshGenerateMonomialsQuadrangle(order);
      subPoints = generateSubPointsQuad(order);
      break;
    }
    case TYPE_TET : {
      dim = 3;
      numLagCoeff = 4;
      dimSimplex = 3;
      exponents = gmshGenerateMonomialsTetrahedron(order);
      subPoints = generateSubPointsTetrahedron(order);
      break;
    }
    case TYPE_PRI : {
      dim = 3;
      numLagCoeff = 6;
      dimSimplex = 2;
      exponents = gmshGenerateMonomialsPrism(order);
      subPoints = generateSubPointsPrism(order);
      break;
    }
    case TYPE_HEX : {
      dim = 3;
      numLagCoeff = 8;
      dimSimplex = 0;
      exponents = gmshGenerateMonomialsHexahedron(order);
      subPoints = generateSubPointsHex(order);
      break;
    }
    default : {
      Msg::Error("Unknown function space of parentType %d : "
          "reverting to TET_1", parentType);
      dim = 3;
      order = 0;
      numLagCoeff = 4;
      dimSimplex = 3;
      exponents = gmshGenerateMonomialsTetrahedron(order);
      subPoints = generateSubPointsTetrahedron(order);
      break;
    }
  }
  numDivisions = static_cast<int>(subPoints.size());

  fullMatrix<double> bezierPoints = exponents;
  bezierPoints.scale(1./order);

  matrixBez2Lag = generateBez2LagMatrix(exponents, bezierPoints, order, dimSimplex);
  matrixBez2Lag.invert(matrixLag2Bez);
  subDivisor = generateSubDivisor(exponents, subPoints, matrixLag2Bez, order, dimSimplex);
}
JacobianBasis::JacobianBasis(int tag, int jacOrder) :
    _bezier(NULL), _tag(tag), _dim(ElementType::DimensionFromTag(tag)),
    _jacOrder(jacOrder >= 0 ? jacOrder : jacobianOrder(tag))
{
  const int parentType = ElementType::ParentTypeFromTag(tag);
  const int primJacobianOrder = jacobianOrder(parentType, 1);

  fullMatrix<double> lagPoints;                                  // Sampling points

  switch (parentType) {
    case TYPE_PNT :
      lagPoints = gmshGeneratePointsLine(0);
      break;
    case TYPE_LIN :
      lagPoints = gmshGeneratePointsLine(_jacOrder);
      break;
    case TYPE_TRI :
      lagPoints = gmshGeneratePointsTriangle(_jacOrder,false);
      break;
    case TYPE_QUA :
      lagPoints = gmshGeneratePointsQuadrangle(_jacOrder,false);
      break;
    case TYPE_TET :
      lagPoints = gmshGeneratePointsTetrahedron(_jacOrder,false);
      break;
    case TYPE_PRI :
      lagPoints = gmshGeneratePointsPrism(_jacOrder,false);
      break;
    case TYPE_HEX :
      lagPoints = gmshGeneratePointsHexahedron(_jacOrder,false);
      break;
    case TYPE_PYR :
      lagPoints = gmshGeneratePointsPyramidGeneral(false, _jacOrder+2, _jacOrder);
      break;
    default :
      Msg::Error("Unknown Jacobian function space for element tag %d", tag);
      return;
  }
  numJacNodes = lagPoints.size1();

  // Store shape function gradients of mapping at Jacobian nodes
  _gradBasis = BasisFactory::getGradientBasis(tag, _jacOrder);

  // Compute matrix for lifting from primary Jacobian basis to Jacobian basis
  int primJacType = ElementType::getTag(parentType, primJacobianOrder, false);
  const nodalBasis *primJacBasis = BasisFactory::getNodalBasis(primJacType);
  numPrimJacNodes = primJacBasis->getNumShapeFunctions();

  matrixPrimJac2Jac.resize(numJacNodes,numPrimJacNodes);
  primJacBasis->f(lagPoints, matrixPrimJac2Jac);

  // Compute shape function gradients of primary mapping at barycenter,
  // in order to compute normal to straight element
  const int primMapType = ElementType::getTag(parentType, 1, false);
  const nodalBasis *primMapBasis = BasisFactory::getNodalBasis(primMapType);
  numPrimMapNodes = primMapBasis->getNumShapeFunctions();

  double xBar = 0., yBar = 0., zBar = 0.;
  double barycenter[3] = {0., 0., 0.};
  for (int i = 0; i < numPrimMapNodes; i++) {
    for (int j = 0; j < primMapBasis->points.size2(); ++j) {
      barycenter[j] += primMapBasis->points(i, j);
    }
  }
  barycenter[0] /= numPrimMapNodes;
  barycenter[1] /= numPrimMapNodes;
  barycenter[2] /= numPrimMapNodes;

  double (*barDPsi)[3] = new double[numPrimMapNodes][3];
  primMapBasis->df(xBar, yBar, zBar, barDPsi);

  primGradShapeBarycenterX.resize(numPrimMapNodes);
  primGradShapeBarycenterY.resize(numPrimMapNodes);
  primGradShapeBarycenterZ.resize(numPrimMapNodes);
  for (int j=0; j<numPrimMapNodes; j++) {
    primGradShapeBarycenterX(j) = barDPsi[j][0];
    primGradShapeBarycenterY(j) = barDPsi[j][1];
    primGradShapeBarycenterZ(j) = barDPsi[j][2];
  }

  delete[] barDPsi;

  // Compute "fast" Jacobian evaluation matrices (at 1st order nodes + barycenter)
  numJacNodesFast = numPrimMapNodes+1;
  fullMatrix<double> lagPointsFast(numJacNodesFast,3);                                  // Sampling points
  lagPointsFast.copy(primMapBasis->points,0,numPrimMapNodes,
                     0,primMapBasis->points.size2(),0,0);                               // 1st order nodes
  lagPointsFast(numPrimMapNodes,0) = barycenter[0];                                     // Last point = barycenter
  lagPointsFast(numPrimMapNodes,1) = barycenter[1];
  lagPointsFast(numPrimMapNodes,2) = barycenter[2];

  fullMatrix<double> allDPsiFast;
  const nodalBasis *mapBasis = BasisFactory::getNodalBasis(tag);
  mapBasis->df(lagPointsFast, allDPsiFast);
  numMapNodes = mapBasis->getNumShapeFunctions();

  gradShapeMatXFast.resize(numJacNodesFast, numMapNodes);
  gradShapeMatYFast.resize(numJacNodesFast, numMapNodes);
  gradShapeMatZFast.resize(numJacNodesFast, numMapNodes);
  for (int i=0; i<numJacNodesFast; i++) {
    for (int j=0; j<numMapNodes; j++) {
      gradShapeMatXFast(i, j) = allDPsiFast(j, 3*i);
      gradShapeMatYFast(i, j) = allDPsiFast(j, 3*i+1);
      gradShapeMatZFast(i, j) = allDPsiFast(j, 3*i+2);
    }
  }
}