Exemplo n.º 1
0
int fluxRegTest()
{
#ifdef CH_USE_HDF5
  writeLevel(NULL);
#endif
  int retflag = 0;

  int nref;
  Vector<Box> fineboxes;
  Vector<Box> coarboxes;
  Box domf, domc;

  //set coarse and fine grid boxes
  setDefaults(nref, coarboxes,  fineboxes, domc, domf);

  {
    // first do nonperiodic test

    Interval interv(0,0);

    //set up coarse and fine grids
    DisjointBoxLayout dblFineCell,dblCoarCell;
    Vector<int> procAssignCoar(coarboxes.size(), 0);
    Vector<int> procAssignFine(fineboxes.size(), 0);
    LoadBalance(procAssignCoar, coarboxes);
    LoadBalance(procAssignFine, fineboxes);

    dblCoarCell.define(coarboxes, procAssignCoar);
    dblFineCell.define(fineboxes, procAssignFine);

    dblCoarCell.close();
    dblFineCell.close();

    LevelData<FArrayBox> coarData(dblCoarCell, 1);
    LevelData<FArrayBox> fineData(dblFineCell, 1);

    DataIterator coarIt = coarData.dataIterator();
    DataIterator fineIt = fineData.dataIterator();

    LevelFluxRegister fluxReg(dblFineCell,
                              dblCoarCell,
                              domf, nref,
                              1);

    //set data and flux registers to zero
    for (coarIt.reset(); coarIt.ok(); ++coarIt)
      coarData[coarIt()].setVal(0.);

    fluxReg.setToZero();

    //increment and decrement
    //flux registers with equal size fluxes
    Real scale = 1.0;
    Real fluxVal = 4.77;
    for (coarIt.reset(); coarIt.ok(); ++coarIt)
      {
        const Box&  cellBoxCoar = dblCoarCell.get(coarIt());
        for (int idir = 0; idir < SpaceDim; idir++)
          {
            Box edgeBoxCoar = surroundingNodes(cellBoxCoar, idir);
            FArrayBox edgeFlux(edgeBoxCoar,1);
            edgeFlux.setVal(fluxVal);
            DataIndex dataIndGlo = coarIt();
            fluxReg.incrementCoarse(edgeFlux, scale,
                                    dataIndGlo, interv, interv, idir);
          }
      }

    for (fineIt.reset(); fineIt.ok(); ++fineIt)
      {
        const Box&  cellBoxFine = dblFineCell.get(fineIt());
        for (int idir = 0; idir < SpaceDim; idir++)
          {
            Box edgeBoxFine = surroundingNodes(cellBoxFine, idir);
            FArrayBox edgeFlux(edgeBoxFine,1);
            edgeFlux.setVal(fluxVal);
            SideIterator sit;
            DataIndex dataIndGlo = fineIt();
            for (sit.reset(); sit.ok(); ++sit)
              {
                fluxReg.incrementFine(edgeFlux, scale,
                                      dataIndGlo,  interv, interv, idir, sit());
              }
          }
      }

    //reflux what ought to be zero into zero and the result should be zero
    fluxReg.reflux(coarData, scale);

    DataIterator datIt = coarData.dataIterator();
    for (datIt.reset(); datIt.ok(); ++datIt)
      {
        const FArrayBox& data = coarData[datIt()];
        Real rmax = Abs(data.max());
        Real rmin = Abs(data.min());
        if ((rmax > 1.0e-10)||(rmin > 1.0e-10))
          {
            pout() << indent << pgmname
                 << ": fluxRegister failed the nonperiodic conservation test = " << endl;
            retflag = 1;
          }
      }
  }
  // end non-periodic test

  // now do the same thing all over again, this time with a periodic domain
  {
    ProblemDomain coarseDomain(domc);
    ProblemDomain fineDomain(domf);
    for (int dir=0; dir<SpaceDim; dir++)
      {
        coarseDomain.setPeriodic(dir, true);
        fineDomain.setPeriodic(dir, true);
      }

    Interval interv(0,0);

    //set up coarse and fine grids
    DisjointBoxLayout dblFineCell,dblCoarCell;
    Vector<int> procAssignCoar(coarboxes.size(), 0);
    Vector<int> procAssignFine(fineboxes.size(), 0);
    LoadBalance(procAssignCoar, coarboxes);
    LoadBalance(procAssignFine, fineboxes);

    dblCoarCell.define(coarboxes, procAssignCoar, coarseDomain);
    dblFineCell.define(fineboxes, procAssignFine, fineDomain);

    dblCoarCell.close();
    dblFineCell.close();

    LevelData<FArrayBox> coarData(dblCoarCell, 1);
    LevelData<FArrayBox> fineData(dblFineCell, 1);

    DataIterator coarIt = coarData.dataIterator();
    DataIterator fineIt = fineData.dataIterator();

    LevelFluxRegister fluxReg(dblFineCell,
                              dblCoarCell,
                              fineDomain, nref,
                              1);

    //set data and flux registers to zero
    for (coarIt.reset(); coarIt.ok(); ++coarIt)
      coarData[coarIt()].setVal(0.);

    fluxReg.setToZero();

    //increment and decrement
    //flux registers with equal size fluxes
    Real scale = 1.0;
    Real fluxVal = 4.77;
    for (coarIt.reset(); coarIt.ok(); ++coarIt)
      {
        const Box&  cellBoxCoar = dblCoarCell.get(coarIt());
        for (int idir = 0; idir < SpaceDim; idir++)
          {
            Box edgeBoxCoar = surroundingNodes(cellBoxCoar, idir);
            FArrayBox edgeFlux(edgeBoxCoar,1);
            edgeFlux.setVal(fluxVal);
            DataIndex dataIndGlo = coarIt();
            fluxReg.incrementCoarse(edgeFlux, scale,
                                    dataIndGlo, interv, interv, idir);
          }
      }

    for (fineIt.reset(); fineIt.ok(); ++fineIt)
      {
        const Box&  cellBoxFine = dblFineCell.get(fineIt());
        for (int idir = 0; idir < SpaceDim; idir++)
          {
            Box edgeBoxFine = surroundingNodes(cellBoxFine, idir);
            FArrayBox edgeFlux(edgeBoxFine,1);
            edgeFlux.setVal(fluxVal);
            SideIterator sit;
            DataIndex dataIndGlo = fineIt();
            for (sit.reset(); sit.ok(); ++sit)
              {
                fluxReg.incrementFine(edgeFlux, scale,
                                      dataIndGlo,  interv, interv, idir, sit());
              }
          }
      }

    //reflux what ought to be zero into zero and the result should be zero
    fluxReg.reflux(coarData, scale);

    DataIterator datIt = coarData.dataIterator();
    for (datIt.reset(); datIt.ok(); ++datIt)
      {
        const FArrayBox& data = coarData[datIt()];
        Real rmax = Abs(data.max());
        Real rmin = Abs(data.min());
        if ((rmax > 1.0e-10)||(rmin > 1.0e-10))
          {
            pout() << indent << pgmname
                 << ": fluxRegister failed the periodic conservation test " << endl;
            retflag += 2;
          }
      }
  } // end periodic test

  return retflag;
}
Exemplo n.º 2
0
void MultiGridManagement2D::coarsen(plint fineLevel, Box2D coarseDomain){
    // The coarsest multi-block, at level 0, cannot be further coarsened.
    PLB_PRECONDITION( fineLevel>=1 && fineLevel<(plint)bulks.size() );
    plint coarseLevel = fineLevel-1;

    // First, trim the domain coarseDomain in case it exceeds the extent of the
    //   multi-block, and determine whether coarseDomain touches one of the boundaries
    //   of the multi-block. This information is needed, because the coarse domain
    //   fully replaces the fine domain on boundaries of the multi-block, and there
    //   is therefore no need to create a coarse-fine coupling.
    bool touchLeft=false, touchRight=false, touchBottom=false, touchTop=false;
    trimDomain(coarseLevel, coarseDomain, touchLeft, touchRight, touchBottom, touchTop);

    // Convert the coarse domain to fine units.
    Box2D fineDomain(coarseDomain.multiply(2));
    // The reduced fine domain is the one which is going to be excluded from
    //   the original fine lattice.
    Box2D intermediateFineDomain(fineDomain.enlarge(-1));
    // The extended coarse domain it the one which is going to be added
    //   to the original coarse lattice.
    Box2D extendedCoarseDomain(coarseDomain.enlarge(1));
    
    // If the domain in question touches a boundary of the multi-block,
    //   both the reduced fine domain and the extended coarse domain are
    //   identified with the boundary location.
    if (touchLeft) {
        intermediateFineDomain.x0 -= 1;
        extendedCoarseDomain.x0   += 1;
    }
    if (touchRight) {
        intermediateFineDomain.x1 += 1;
        extendedCoarseDomain.x1   -= 1;
    }
    if (touchBottom) {
        intermediateFineDomain.y0 -= 1;
        extendedCoarseDomain.y0   += 1;
    }
    if (touchTop) {
        intermediateFineDomain.y1 += 1;
        extendedCoarseDomain.y1   -= 1;
    }

    // Extract reduced fine domain from the original fine multi-block.
    std::vector<Box2D> exceptedBlocks;
    for (pluint iBlock=0; iBlock<bulks[fineLevel].size(); ++iBlock) {
        except(bulks[fineLevel][iBlock], intermediateFineDomain, exceptedBlocks);
    }
    exceptedBlocks.swap(bulks[fineLevel]);

    // Add extended coarse domain to the original coarse multi-block.
    bulks[coarseLevel].push_back(extendedCoarseDomain);
    
    // Define coupling interfaces for all four sides of the refined domain, unless they
    //   touch a boundary of the multi-block.
    if (!touchLeft) {
        coarseGridInterfaces[coarseLevel].push_back( Box2D( extendedCoarseDomain.x0, extendedCoarseDomain.x0,
                                                            extendedCoarseDomain.y0, extendedCoarseDomain.y1 ) );
        fineGridInterfaces[fineLevel].push_back( Box2D( coarseDomain.x0, coarseDomain.x0, 
                                                        coarseDomain.y0, coarseDomain.y1 ) );
                                                        
        // it is a left border in the coarse case
        coarseInterfaceOrientations[coarseLevel].push_back(Array<plint,2>(0,-1));
        // it is an right border in the fine case
        fineInterfaceOrientations[fineLevel].push_back(Array<plint,2>(0,1));
    }
    if (!touchRight) {
        coarseGridInterfaces[coarseLevel].push_back( Box2D( extendedCoarseDomain.x1, extendedCoarseDomain.x1,
                                                            extendedCoarseDomain.y0, extendedCoarseDomain.y1 ) );
        fineGridInterfaces[fineLevel].push_back( Box2D( coarseDomain.x1, coarseDomain.x1, 
                                                        coarseDomain.y0, coarseDomain.y1 ) );
                                                        
        // it is a right border in the coarse case
        coarseInterfaceOrientations[coarseLevel].push_back(Array<plint,2>(0,1));
        // it is a left border in the fine case
        fineInterfaceOrientations[fineLevel].push_back(Array<plint,2>(0,-1));
    }
    if (!touchBottom) {
        coarseGridInterfaces[coarseLevel].push_back( Box2D( extendedCoarseDomain.x0, extendedCoarseDomain.x1,
                                                            extendedCoarseDomain.y0, extendedCoarseDomain.y0 ) );
        fineGridInterfaces[fineLevel].push_back( Box2D( coarseDomain.x0, coarseDomain.x1, 
                                                        coarseDomain.y0, coarseDomain.y0 ) );
                                                        
        // it is a bottom border in the coarse case
        coarseInterfaceOrientations[coarseLevel].push_back(Array<plint,2>(1,-1)); //TODO check this!!!
        // it is a top border in the fine case
        fineInterfaceOrientations[fineLevel].push_back(Array<plint,2>(1,1));        
    }
    if (!touchTop) {
        coarseGridInterfaces[coarseLevel].push_back( Box2D( extendedCoarseDomain.x0, extendedCoarseDomain.x1,
                                                            extendedCoarseDomain.y1, extendedCoarseDomain.y1 ) );
        fineGridInterfaces[fineLevel].push_back( Box2D( coarseDomain.x0, coarseDomain.x1, 
                                                        coarseDomain.y1, coarseDomain.y1 ) );
                                                        
        // it is a top border in the coarse case
        coarseInterfaceOrientations[coarseLevel].push_back(Array<plint,2>(1,1));
        // it is an bottom border in the fine case
        fineInterfaceOrientations[fineLevel].push_back(Array<plint,2>(1,-1));
    }
}