void CleverNodeInjection<TYPE>::coarsen(
    SAMRAI::hier::Patch& coarse,
    const SAMRAI::hier::Patch& fine,
    const int dst_component,
    const int src_component,
    const SAMRAI::hier::Box& coarse_box,
    const SAMRAI::hier::IntVector& ratio) const
{
  boost::shared_ptr<CleverNodeData<TYPE> > fine_data(
      SHARED_PTR_CAST(CleverNodeData<TYPE> ,
        fine.getPatchData(src_component)));

  boost::shared_ptr<CleverNodeData<TYPE> > coarse_data(
      SHARED_PTR_CAST(CleverNodeData<TYPE> ,
        coarse.getPatchData(dst_component)));

  const SAMRAI::hier::Box coarse_ghost_box =
    SAMRAI::pdat::NodeGeometry::toNodeBox(coarse_data->getGhostBox());
  const SAMRAI::hier::Box fine_ghost_box = 
    SAMRAI::pdat::NodeGeometry::toNodeBox(fine_data->getGhostBox());

   const hier::Index filo = fine_data->getGhostBox().lower();
   const hier::Index fihi = fine_data->getGhostBox().upper();
   const hier::Index cilo = coarse_data->getGhostBox().lower();
   const hier::Index cihi = coarse_data->getGhostBox().upper();

   const hier::Index ifirstc = coarse_box.lower();
   const hier::Index ilastc = coarse_box.upper();

  for(int depth = 0; depth < coarse_data->getDepth(); depth++) {
    if (fine.getDim() == SAMRAI::tbox::Dimension(2)) {
         F90_FUNC(conavgclevernodedoub2d, CONAVGCLEVERNODEDOUB2D)
           (ifirstc(0), ifirstc(1), ilastc(0), ilastc(1),
            filo(0), filo(1), fihi(0), fihi(1),
            cilo(0), cilo(1), cihi(0), cihi(1),
            &ratio[0],
            fine_data->getPointer(depth),
            coarse_data->getPointer(depth));
    } else {
      TBOX_ERROR("CleverNodeInjection error...\n"
          << "dim != 2 not supported." << std::endl);
    }
  }
}
Exemple #2
0
void Stokes::FACOps::residual_3D
(SAMRAI::pdat::CellData<double> &p,
 SAMRAI::pdat::SideData<double> &v,
 SAMRAI::pdat::CellData<double> &cell_viscosity,
 SAMRAI::pdat::CellData<double> &p_rhs,
 SAMRAI::pdat::SideData<double> &v_rhs,
 SAMRAI::pdat::CellData<double> &p_resid,
 SAMRAI::pdat::SideData<double> &v_resid,
 SAMRAI::hier::Patch &patch,
 const SAMRAI::hier::Box &pbox,
 const SAMRAI::geom::CartesianPatchGeometry &geom)
{
  boost::shared_ptr<SAMRAI::pdat::EdgeData<double> > edge_viscosity_ptr = 
    boost::dynamic_pointer_cast<SAMRAI::pdat::EdgeData<double> >
    (patch.getPatchData(edge_viscosity_id));
  SAMRAI::pdat::EdgeData<double> &edge_viscosity(*edge_viscosity_ptr);

  const double *Dx = geom.getDx();
  const SAMRAI::hier::Index ip(1,0,0), jp(0,1,0), kp(0,0,1);
  const SAMRAI::hier::Index pp[]={ip,jp,kp};

  SAMRAI::pdat::CellIterator cend(SAMRAI::pdat::CellGeometry::end(pbox));
  for(SAMRAI::pdat::CellIterator ci(SAMRAI::pdat::CellGeometry::begin(pbox));
      ci!=cend; ++ci)
    {
      const SAMRAI::pdat::CellIndex &center(*ci);
      SAMRAI::pdat::CellIndex up(center), down(center), right(center),
        left(center), front(center), back(center);

      ++right[0];
      --left[0];
      ++up[1];
      --down[1];
      ++front[2];
      --back[2];

      /* p */
      if(center[0]!=pbox.upper(0) && center[1]!=pbox.upper(1)
         && center[2]!=pbox.upper(2))
        {
          const SAMRAI::pdat::SideIndex
            x(center,0,SAMRAI::pdat::SideIndex::Lower),
            y(center,1,SAMRAI::pdat::SideIndex::Lower),
            z(center,2,SAMRAI::pdat::SideIndex::Lower);

          double dvx_dx=(v(x+ip) - v(x))/Dx[0];
          double dvy_dy=(v(y+jp) - v(y))/Dx[1];
          double dvz_dz=(v(z+kp) - v(z))/Dx[2];
          p_resid(center)=p_rhs(center) - dvx_dx - dvy_dy - dvz_dz;
        }

      for(Gamra::Dir ix=0;ix<3;++ix)
        {
          const Gamra::Dir iy(ix.next(3));
          const Gamra::Dir iz(iy.next(3));
          const SAMRAI::pdat::SideIndex
            x(center,ix,SAMRAI::pdat::SideIndex::Lower),
            y(center,iy,SAMRAI::pdat::SideIndex::Lower),
            z(center,iz,SAMRAI::pdat::SideIndex::Lower);
          const SAMRAI::pdat::EdgeIndex
            edge_y(center,iy,SAMRAI::pdat::EdgeIndex::LowerLeft),
            edge_z(center,iz,SAMRAI::pdat::EdgeIndex::LowerLeft);

          if(center[iy]!=pbox.upper(iy) && center[iz]!=pbox.upper(iz))
            {
              if((center[ix]==pbox.lower(ix) && v(x-pp[ix])==boundary_value)
                 || (center[ix]==pbox.upper(ix) && v(x+pp[ix])==boundary_value))
                {
                  v_resid(x)=0;
                }
              else
                {
                  v_resid(x)=v_rhs(x)
                    - v_operator_3D(v,p,cell_viscosity,edge_viscosity,
                                    center,edge_y,edge_z,x,y,z,
                                    pp[ix],pp[iy],pp[iz],Dx[ix],Dx[iy],Dx[iz]);
                }
            }
        }          
    }
}
Exemple #3
0
void Elastic::Boundary_Conditions::set_dirichlet
(SAMRAI::pdat::SideData<double> &v,
 const boost::shared_ptr<SAMRAI::pdat::SideData<double> > &dv_mixed_ptr,
 const SAMRAI::hier::Index unit[],
 const Gamra::Dir &dim,
 const SAMRAI::hier::Box &pbox,
 const SAMRAI::hier::Box &gbox,
 const boost::shared_ptr<SAMRAI::geom::CartesianPatchGeometry> geom,
 const double *dx,
 const bool &homogeneous) const
{
  for(Gamra::Dir ix=0; ix<dim; ++ix)
    {
      double offset[]={0.5,0.5,0.5};
      offset[ix]=0;

      for(Gamra::Dir iy=ix.next(dim); iy!=ix; iy=iy.next(dim))
        {
          const Gamra::Dir ix_iy(index_map(ix,iy,dim));

          SAMRAI::hier::Box x_box(gbox);
          x_box.setLower(ix,(geom->getTouchesRegularBoundary(ix,0)
                             && is_dirichlet[ix][ix][0]) ?
                         pbox.lower(ix)+1 : pbox.lower(ix));
          x_box.setUpper(ix,(geom->getTouchesRegularBoundary(ix,1)
                             && is_dirichlet[ix][ix][1]) ?
                         pbox.upper(ix)-1 : pbox.upper(ix));

          if(geom->getTouchesRegularBoundary(iy,0) && is_dirichlet[ix][iy][0])
            {
              SAMRAI::hier::Box y_box(x_box);
              y_box.setUpper(iy,y_box.lower(iy));

              SAMRAI::pdat::SideIterator
                end(SAMRAI::pdat::SideGeometry::end(y_box,ix));
              for(SAMRAI::pdat::SideIterator
                    si(SAMRAI::pdat::SideGeometry::begin(y_box,ix));
                  si!=end; ++si)
                {
                  const SAMRAI::pdat::SideIndex &x(*si);
                  v(x)=-v(x+unit[iy]);
                  if(!homogeneous)
                    {
                      std::vector<double> coord(dim);
                      coord[iy]=geom->getXLower()[iy];
                      for(int d=(iy+1)%dim;d!=iy;d=(d+1)%dim)
                        coord[d]=geom->getXLower()[d]
                          + dx[d]*(x[d]-pbox.lower()[d]+offset[d]);
                      if(have_faults())
                        v(x)+= -(*dv_mixed_ptr)(x+unit[iy],ix_iy+1);
                      v(x)+=2*expression[ix][iy][0].eval(coord.data());
                    }
                }
            }
          if(geom->getTouchesRegularBoundary(iy,1) && is_dirichlet[ix][iy][1])
            {
              SAMRAI::hier::Box y_box(x_box);
              y_box.setLower(iy,y_box.upper(iy));

              SAMRAI::pdat::SideIterator
                end(SAMRAI::pdat::SideGeometry::end(y_box,ix));
              for(SAMRAI::pdat::SideIterator
                    si(SAMRAI::pdat::SideGeometry::begin(y_box,ix));
                  si!=end; ++si)
                {
                  const SAMRAI::pdat::SideIndex &x(*si);
                  v(x)=-v(x-unit[iy]);
                  if(!homogeneous)
                    {
                      std::vector<double> coord(dim);
                      coord[iy]=geom->getXUpper()[iy];
                      for(int d=(iy+1)%dim;d!=iy;d=(d+1)%dim)
                        coord[d]=geom->getXLower()[d]
                          + dx[d]*(x[d]-pbox.lower()[d]+offset[d]);
                      if(have_faults())
                        v(x)+= -(*dv_mixed_ptr)(x-unit[iy],ix_iy);
                      v(x)+=2*expression[ix][iy][1].eval(coord.data());
                    }
                }
            }
        }
      
      SAMRAI::hier::Box box(gbox);

      if(geom->getTouchesRegularBoundary(ix,0) && is_dirichlet[ix][ix][0])
        {
          SAMRAI::hier::Box x_box(box);
          x_box.setUpper(ix,x_box.lower(ix));

          SAMRAI::pdat::SideIterator
            end(SAMRAI::pdat::SideGeometry::end(x_box,ix));
          for(SAMRAI::pdat::SideIterator
                si(SAMRAI::pdat::SideGeometry::begin(x_box,ix)); si!=end; ++si)
            {
              const SAMRAI::pdat::SideIndex &x(*si);
              if(x[ix]<pbox.lower(ix))
                v(x)=boundary_value;
              else
                {
                  if(homogeneous)
                    {
                      v(x)=0;
                    }
                  else
                    {
                      std::vector<double> coord(dim);
                      for(int d=0;d<dim;++d)
                        coord[d]=geom->getXLower()[d]
                          + dx[d]*(x[d]-pbox.lower()[d]+offset[d]);
                      v(x)=expression[ix][ix][0].eval(coord.data());
                    }
                }
            }
        }
      if(geom->getTouchesRegularBoundary(ix,1) && is_dirichlet[ix][ix][1])
        {
          SAMRAI::hier::Box x_box(box);
          x_box.setLower(ix,x_box.upper(ix));

          SAMRAI::pdat::SideIterator
            end(SAMRAI::pdat::SideGeometry::end(x_box,ix));
          for(SAMRAI::pdat::SideIterator
                si(SAMRAI::pdat::SideGeometry::begin(x_box,ix)); si!=end; ++si)
            {
              const SAMRAI::pdat::SideIndex &x(*si);
              if(x[ix]>pbox.upper(ix)+1)
                v(x)=boundary_value;
              else
                {
                  if(homogeneous)
                    {
                      v(x)=0;
                    }
                  else
                    {
                      std::vector<double> coord(dim);
                      for(int d=0;d<dim;++d)
                        coord[d]=geom->getXLower()[d]
                          + dx[d]*(x[d]-pbox.lower()[d]+offset[d]);
                      v(x)=expression[ix][ix][1].eval(coord.data());
                    }
                }
            }
        }
    }    
}
Exemple #4
0
/*
*************************************************************************
* Set up the initial guess and problem parameters                       *
* and solve the Stokes problem.  We explicitly initialize and          *
* deallocate the solver state in this example.                          *
*************************************************************************
*/
bool Stokes::FAC::solve()
{

  if (!d_hierarchy) {
    TBOX_ERROR(d_object_name
               << "Cannot solve using an uninitialized object.\n");
  }

  int ln;
  /*
   * Fill in the initial guess.
   */
  for (ln = 0; ln <= d_hierarchy->getFinestLevelNumber(); ++ln) {
    boost::shared_ptr<SAMRAI::hier::PatchLevel> level = d_hierarchy->getPatchLevel(ln);
    SAMRAI::hier::PatchLevel::Iterator ip(level->begin());
    SAMRAI::hier::PatchLevel::Iterator iend(level->end());
    for ( ; ip!=iend; ++ip) {
      boost::shared_ptr<SAMRAI::hier::Patch> patch = *ip;
      boost::shared_ptr<SAMRAI::pdat::CellData<double> > p =
        boost::dynamic_pointer_cast<SAMRAI::pdat::CellData<double> >
        (patch->getPatchData(p_id));

      boost::shared_ptr<SAMRAI::geom::CartesianPatchGeometry> geom =
        boost::dynamic_pointer_cast<SAMRAI::geom::CartesianPatchGeometry>
        (patch->getPatchGeometry());

      if(p_initial.empty())
        {
          p->fill(0.0);
        }
      else
        {
          const int dim=d_dim.getValue();
          const double *dx=geom->getDx();
          std::vector<double> xyz(dim);
          std::vector<double> dx_p(dim);
          for(int d=0;d<dim;++d)
            dx_p[d]=(p_initial_xyz_max[d]
                     - p_initial_xyz_min[d])/(p_initial_ijk[d]-1);
          std::vector<int> di(dim);
          di[0]=1;
          for(int d=1;d<dim;++d)
            di[d]=di[d-1]*p_initial_ijk[d-1];

          SAMRAI::hier::Box pbox = p->getBox();
          SAMRAI::pdat::CellIterator
            cend(SAMRAI::pdat::CellGeometry::end(p->getGhostBox()));
          for(SAMRAI::pdat::CellIterator
                ci(SAMRAI::pdat::CellGeometry::begin(p->getGhostBox()));
              ci!=cend; ++ci)
            {
              const SAMRAI::pdat::CellIndex &c(*ci);
              std::vector<double> xyz(dim);
              /* VLA's not allowed by clang */
              double weight[3][2];
              for(int d=0;d<dim;++d)
                xyz[d]=geom->getXLower()[d]
                  + dx[d]*(c[d]-pbox.lower()[d] + 0.5);

              int ijk(0);
              std::vector<int> ddi(dim);
              for(int d=0;d<dim;++d)
                {
                  int i=static_cast<int>(xyz[d]*(p_initial_ijk[d]-1)
                                         /(p_initial_xyz_max[d]
                                           - p_initial_xyz_min[d]));
                  i=std::max(0,std::min(p_initial_ijk[d]-1,i));
                  ijk+=i*di[d];

                  if(i==p_initial_ijk[d]-1)
                    {
                      weight[d][0]=1;
                      weight[d][1]=0;
                      ddi[d]=0;
                    }
                  else
                    {
                      weight[d][1]=
                        (xyz[d]-(i*dx_p[d] + p_initial_xyz_min[d]))/dx_p[d];
                      weight[d][0]=1-weight[d][1];
                      ddi[d]=di[d];
                    }
                }

              if(dim==2)
                {
                  (*p)(c)=p_initial[ijk]*weight[0][0]*weight[1][0]
                    + p_initial[ijk+ddi[0]]*weight[0][1]*weight[1][0]
                    + p_initial[ijk+ddi[1]]*weight[0][0]*weight[1][1]
                    + p_initial[ijk+ddi[0]+ddi[1]]*weight[0][1]*weight[1][1];
                }
              else
                {
                  (*p)(c)=p_initial[ijk]*weight[0][0]*weight[1][0]*weight[2][0]
                    + p_initial[ijk+ddi[0]]*weight[0][1]*weight[1][0]*weight[2][0]
                    + p_initial[ijk+ddi[1]]*weight[0][0]*weight[1][1]*weight[2][0]
                    + p_initial[ijk+ddi[0]+ddi[1]]*weight[0][1]*weight[1][1]*weight[2][0]
                    
                    + p_initial[ijk+ddi[2]]*weight[0][0]*weight[1][0]*weight[2][1]
                    + p_initial[ijk+ddi[0]+ddi[2]]*weight[0][1]*weight[1][0]*weight[2][1]
                    + p_initial[ijk+ddi[1]+ddi[2]]*weight[0][0]*weight[1][1]*weight[2][1]
                    + p_initial[ijk+ddi[0]+ddi[1]+ddi[2]]*weight[0][1]*weight[1][1]*weight[2][1];
                }
            }
        }

      boost::shared_ptr<SAMRAI::pdat::SideData<double> > v =
        boost::dynamic_pointer_cast<SAMRAI::pdat::SideData<double> >
        (patch->getPatchData(v_id));
      v->fill(0.0);
    }
    d_stokes_fac_solver.set_boundaries(p_id,v_id,level,false);
  }

  fix_viscosity();

  d_stokes_fac_solver.initializeSolverState
    (p_id,cell_viscosity_id,edge_viscosity_id,dp_id,p_rhs_id,v_id,v_rhs_id,
     d_hierarchy,0,d_hierarchy->getFinestLevelNumber());

  SAMRAI::tbox::plog << "solving..." << std::endl;
  int solver_ret;
  solver_ret = d_stokes_fac_solver.solveSystem(p_id,p_rhs_id,v_id,v_rhs_id);

  double avg_factor, final_factor;
  d_stokes_fac_solver.getConvergenceFactors(avg_factor, final_factor);
  SAMRAI::tbox::plog << "\t" << (solver_ret ? "" : "NOT ") << "converged " << "\n"
             << "	iterations: "
             << d_stokes_fac_solver.getNumberOfIterations() << "\n"
             << "	residual: "<< d_stokes_fac_solver.getResidualNorm()
             << "\n"
             << "	average convergence: "<< avg_factor << "\n"
             << "	final convergence: "<< final_factor << "\n"
             << std::flush;

  d_stokes_fac_solver.deallocateSolverState();

  return solver_ret;
}
void Elastic::Boundary_Conditions::set_embedded_boundary
(const SAMRAI::hier::Patch& patch, const int &level_set_id,
 const int &dv_mixed_id)
{
  boost::shared_ptr<SAMRAI::pdat::SideData<double> > level_set_ptr=
    boost::dynamic_pointer_cast<SAMRAI::pdat::SideData<double> >
    (patch.getPatchData(level_set_id));
  SAMRAI::pdat::SideData<double> &level_set(*level_set_ptr);

  boost::shared_ptr<SAMRAI::pdat::SideData<double> > dv_mixed_ptr;
  if(dv_mixed_id!=invalid_id)
    dv_mixed_ptr=boost::dynamic_pointer_cast
      <SAMRAI::pdat::SideData<double> >(patch.getPatchData(dv_mixed_id));

  const SAMRAI::tbox::Dimension dimension(patch.getDim());
  const Gamra::Dir dim(dimension.getValue());

  const SAMRAI::hier::Box gbox=level_set.getGhostBox();
  const SAMRAI::hier::Box box=level_set.getBox();

  boost::shared_ptr<SAMRAI::geom::CartesianPatchGeometry> geom =
    boost::dynamic_pointer_cast<SAMRAI::geom::CartesianPatchGeometry>
    (patch.getPatchGeometry());

  /* Corners are not synced, so we set the level set to a generic
   * negative value and dv_mixed to zero.  Setting dv_mixed to zero
   * implies that we do not care about faults that intersect that
   * corner (nor should we). */
  for(Gamra::Dir ix=0; ix<dim; ++ix)
    {
      const Gamra::Dir iy(ix.next(dim));
      const Gamra::Dir iz(iy.next(dim));

      std::vector<std::vector<int> > corners(dim);
      corners[ix].push_back(box.lower(ix));
      corners[ix].push_back(box.upper(ix)+1);

      if(geom->getTouchesRegularBoundary(iy,0))
        corners[iy].push_back(gbox.lower(iy));
      if(geom->getTouchesRegularBoundary(iy,1))
        corners[iy].push_back(gbox.upper(iy));

      if(dim==3)
        {
          if(geom->getTouchesRegularBoundary(iz,0))
            corners[iz].push_back(gbox.lower(iz));
          if(geom->getTouchesRegularBoundary(iz,1))
            corners[iz].push_back(gbox.upper(iz));
        }

      SAMRAI::pdat::SideIndex x(SAMRAI::hier::Index(dimension),ix,
                                SAMRAI::pdat::SideIndex::Lower);
      for(std::vector<int>::iterator i=corners[ix].begin();
          i!=corners[ix].end(); ++i)
        {
          x[ix]=*i;
          if(dim==2)
            {
              for(std::vector<int>::iterator j=corners[iy].begin();
                  j!=corners[iy].end();++j)
                {
                  x[iy]=*j;
                  set_embedded_values(x,dim,level_set,dv_mixed_ptr);
                }
            }
          else
            {
              for(std::vector<int>::iterator j=corners[iy].begin();
                  j!=corners[iy].end();++j)
                for(int kk=gbox.lower(iz); kk<=gbox.upper(iz); ++kk)
                  {
                    x[iy]=*j;
                    x[iz]=kk;
                    set_embedded_values(x,dim,level_set,dv_mixed_ptr);
                  }
              for(std::vector<int>::iterator k=corners[iz].begin();
                  k!=corners[iz].end();++k)
                {
                  for(int jj=gbox.lower(iy); jj<=gbox.upper(iy); ++jj)
                    {
                      x[iy]=jj;
                      x[iz]=*k;
                      set_embedded_values(x,dim,level_set,dv_mixed_ptr);
                    }
                }
            }
        }
    }
}