void MblkGeometry::buildSShellGridOnPatch( const hier::Patch& patch, const hier::Box& domain, const int xyz_id, const int level_number, const int block_number) { bool xyz_allocated = patch.checkAllocated(xyz_id); if (!xyz_allocated) { TBOX_ERROR("xyz data not allocated" << std::endl); //patch.allocatePatchData(xyz_id); } boost::shared_ptr<pdat::NodeData<double> > xyz( BOOST_CAST<pdat::NodeData<double>, hier::PatchData>( patch.getPatchData(xyz_id))); TBOX_ASSERT(xyz); if (d_dim == tbox::Dimension(3)) { const hier::Index ifirst = patch.getBox().lower(); const hier::Index ilast = patch.getBox().upper(); hier::IntVector nghost_cells = xyz->getGhostCellWidth(); //int imin = ifirst(0); //int imax = ilast(0) + 1; //int jmin = ifirst(1); //int jmax = ilast(1) + 1; //int kmin = ifirst(2); //int kmax = ilast(2) + 1; //int nx = imax - imin + 1; //int ny = jmax - jmin + 1; //int nxny = nx*ny; int nd_imin = ifirst(0) - nghost_cells(0); int nd_imax = ilast(0) + 1 + nghost_cells(0); int nd_jmin = ifirst(1) - nghost_cells(1); int nd_jmax = ilast(1) + 1 + nghost_cells(1); int nd_kmin = ifirst(2) - nghost_cells(2); int nd_kmax = ilast(2) + 1 + nghost_cells(2); int nd_nx = nd_imax - nd_imin + 1; int nd_ny = nd_jmax - nd_jmin + 1; int nd_nxny = nd_nx * nd_ny; double* x = xyz->getPointer(0); double* y = xyz->getPointer(1); double* z = xyz->getPointer(2); bool found = false; int nrad = (domain.upper(0) - domain.lower(0) + 1); int nth = (domain.upper(1) - domain.lower(1) + 1); int nphi = (domain.upper(2) - domain.lower(2) + 1); /* * If its a solid shell, its a single block and dx = dr, dth, dphi */ if (d_sshell_type == "SOLID") { d_dx[level_number][block_number][0] = (d_sshell_rmax - d_sshell_rmin) / (double)nrad; d_dx[level_number][block_number][1] = 2.0 * tbox::MathUtilities<double>::Abs(d_sangle_thmin) / (double)nth; d_dx[level_number][block_number][2] = 2.0 * tbox::MathUtilities<double>::Abs(d_sangle_thmin) / (double)nphi; // // step in a radial direction in x and set y and z appropriately // for a solid angle we go -th to th and -phi to phi // for (int k = nd_kmin; k <= nd_kmax; ++k) { for (int j = nd_jmin; j <= nd_jmax; ++j) { double theta = d_sangle_thmin + j * d_dx[level_number][block_number][1]; // dx used for dth double phi = d_sangle_thmin + k * d_dx[level_number][block_number][2]; double xface = cos(theta) * cos(phi); double yface = sin(theta) * cos(phi); double zface = sin(phi); for (int i = nd_imin; i <= nd_imax; ++i) { int ind = POLY3(i, j, k, nd_imin, nd_jmin, nd_kmin, nd_nx, nd_nxny); double r = d_sshell_rmin + d_dx[level_number][block_number][0] * (i); double xx = r * xface; double yy = r * yface; double zz = r * zface; x[ind] = xx; y[ind] = yy; z[ind] = zz; } } } found = true; } /* * If its an octant problem, then its got multiple (three) blocks */ if (d_sshell_type == "OCTANT") { double drad = (d_sshell_rmax - d_sshell_rmin) / nrad; // // as in the solid angle we go along a radial direction in // x setting y and z appropriately, but here we have logic for // the block we are in. This is contained in the dispOctant.m // matlab code. // for (int k = nd_kmin; k <= nd_kmax; ++k) { for (int j = nd_jmin; j <= nd_jmax; ++j) { // // compute the position on the unit sphere for our radial line // double xface, yface, zface; computeUnitSphereOctant(block_number, nth, j, k, &xface, &yface, &zface); for (int i = nd_imin; i <= nd_imax; ++i) { int ind = POLY3(i, j, k, nd_imin, nd_jmin, nd_kmin, nd_nx, nd_nxny); double r = d_sshell_rmin + drad * (i); double xx = r * xface; double yy = r * yface; double zz = r * zface; x[ind] = xx; y[ind] = yy; z[ind] = zz; } } } found = true; } if (!found) { TBOX_ERROR( d_object_name << ": " << "spherical shell nodal positions for " << d_sshell_type << " not found" << std::endl); } } }