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); } } }
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 ¢er(*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]); } } } } }
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()); } } } } } }
/* ************************************************************************* * 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); } } } } } }