Example #1
0
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);
      }

   }

}