// ============================================================================ 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