예제 #1
0
// ============================================================================
void GetNeighboursCartesian3d(const int i,
                              const int nx, const int ny, const int nz,
                              int& left, int& right, int& lower, int& upper,
                              int& below, int& above)
{
  int ixy, iz;
  ixy = i % (nx * ny);

  iz = (i - ixy) / (nx * ny);

  if (iz == 0)      below = -1;
  else              below = i - nx * ny;
  if (iz == nz - 1) above = -1;
  else              above = i + nx * ny;

  GetNeighboursCartesian2d(ixy, nx, ny, left, right, lower, upper);

  if (left  != -1) left  += iz * (nx * ny);
  if (right != -1) right += iz * (nx * ny);
  if (lower != -1) lower += iz * (nx * ny);
  if (upper != -1) upper += iz * (nx * ny);
}
    std::pair< Teuchos::RCP<Matrix>, Teuchos::RCP<Matrix> >
    Cross2D_Helmholtz_Pair(const Teuchos::RCP<const Map> & map,
                           const GlobalOrdinal nx,      const GlobalOrdinal ny,
                           const double h,              const double delta,
                           const int PMLgridptsx_left,  const int PMLgridptsx_right,
                           const int PMLgridptsy_left,  const int PMLgridptsy_right,
                           const double omega,          const Scalar shift,
			   const int model) {

      Teuchos::RCP<Matrix> ktx = MatrixTraits<Map,Matrix>::Build(map, 5);
      Teuchos::RCP<Matrix> mtx = MatrixTraits<Map,Matrix>::Build(map, 1);
      LocalOrdinal NumMyElements = map->getNodeNumElements();
      Teuchos::ArrayView<const GlobalOrdinal> MyGlobalElements = map->getNodeElementList();
      GlobalOrdinal left, right, lower, upper, center;
      LocalOrdinal nnz=5;
      std::vector<Scalar> Values(nnz);
      std::vector<GlobalOrdinal> Indices(nnz);
      VelocityModel<Scalar,LocalOrdinal,GlobalOrdinal> velocitymodel(2,model);

      double LBx, RBx, LBy, RBy, Dx, Dy;
      Scalar sx_left, sx_center, sx_right;
      Scalar sy_left, sy_center, sy_right;
      Scalar c;
      // Calculate some parameters
      Dx = ((double) nx-1)*h;
      Dy = ((double) ny-1)*h;
      LBx = ((double) PMLgridptsx_left)*h;
      RBx = Dx-((double) PMLgridptsx_right)*h;
      LBy = ((double) PMLgridptsy_left)*h;
      RBy = Dy-((double) PMLgridptsy_right)*h;

      for (LocalOrdinal i = 0; i < NumMyElements; ++i)  {

	// calculate PML functions
        size_t numEntries = 0;
        center = MyGlobalElements[i];
        GetNeighboursCartesian2d(center, nx, ny, left, right, lower, upper);
        GetPMLvalues(center, nx, ny, h, delta,
                     Dx, Dy, LBx, RBx, LBy, RBy,
                     sx_left, sx_center, sx_right,
                     sy_left, sy_center, sy_right);
	// get velocity
	GlobalOrdinal ix, iy;
	ix = i % nx;
	iy = (i - ix) / nx;
	double xcoord, ycoord;
	xcoord=((double) ix)*h;
	ycoord=((double) iy)*h;
	c = velocitymodel.getVelocity(xcoord,ycoord,0.0);

        if (left != -1) {
          Indices[numEntries] = left;
          Values [numEntries] = -(sy_center/sx_center + sy_center/sx_left)/2.0;
          numEntries++;
        }
        if (right != -1) {
          Indices[numEntries] = right;
          Values [numEntries] = -(sy_center/sx_center + sy_center/sx_right)/2.0;
          numEntries++;
        }
        if (lower != -1) {
          Indices[numEntries] = lower;
          Values [numEntries] = -(sx_center/sy_center + sx_center/sy_left)/2.0;
          numEntries++;
        }
        if (upper != -1) {
          Indices[numEntries] = upper;
          Values [numEntries] = -(sx_center/sy_center + sx_center/sy_right)/2.0;
          numEntries++;
        }

        // diagonal
        Scalar z = (Scalar) 0.0;
        for (size_t j = 0; j < numEntries; j++)
          z -= Values[j];

        Indices[numEntries] = center;
        Values [numEntries] = z;
        numEntries++;

        Teuchos::ArrayView<GlobalOrdinal> iv(&Indices[0], numEntries);
        Teuchos::ArrayView<Scalar>        av(&Values[0],  numEntries);
        ktx->insertGlobalValues(center, iv, av);
        mtx->insertGlobalValues(center,
                                Teuchos::tuple<GlobalOrdinal>(center),
                                Teuchos::tuple<Scalar>(h*h*sx_center*sy_center/(c*c)) );

      }

      ktx->fillComplete();
      mtx->fillComplete();
      std::pair< Teuchos::RCP<Matrix>, Teuchos::RCP<Matrix> > system;
      system=std::make_pair(ktx,mtx);
      return system;

    } //Cross2D_Helmholtz