void refine(BoxLayout& a_output, const BoxLayout& a_input, int a_refinement)
{
  if (!a_input.isClosed())
    {
      MayDay::Error("input to refine must be called with closed BoxLayout");
    }
  if (a_output.isClosed())
    {
      MayDay::Error("output of refine must be called on open BoxLayout");
    }
  a_output.deepCopy(a_input);

  for (int ivec = 0; ivec < a_output.m_boxes->size(); ivec++)
    {
      (*a_output.m_boxes)[ivec].box.refine(a_refinement);
    }
  a_output.close();
}
Esempio n. 2
0
// -------------------------------------------------------------
void
Mask::buildMask(BaseFab<int>& a_mask, const ProblemDomain& a_dProblem,
                const BoxLayout& a_grids, const BoxLayout* a_fineGridsPtr,
                int a_nRefFine)
{
  // first set entire box to Physical BC
  a_mask.setVal(maskPhysical);

  // now set all of domain interior to coarse
  Box domainInterior(a_mask.box());
  domainInterior &= a_dProblem;
  a_mask.setVal(maskCoarse,domainInterior,0);

  // now loop over this level's boxes and set them to "copy"
  LayoutIterator lit = a_grids.layoutIterator();

  for (lit.reset(); lit.ok(); ++lit)
    {
      Box intersectBox = a_grids.get(lit());
      intersectBox &= a_mask.box();
      if (!intersectBox.isEmpty())
        {
          a_mask.setVal(maskCopy,intersectBox,0);
        }
    }

  // if finer grids exist, set them to "covered"
  if (a_fineGridsPtr != NULL)
    {
      CH_assert (a_nRefFine > 1);

      LayoutIterator litFine = a_fineGridsPtr->layoutIterator();
      for (litFine.reset(); litFine.ok(); ++litFine)
        {
          Box coarsenedBox(a_fineGridsPtr->get(litFine()));
          coarsenedBox.coarsen(a_nRefFine);
          coarsenedBox &= a_mask.box();
          if (!coarsenedBox.isEmpty())
            {
              a_mask.setVal(maskCovered,coarsenedBox,0);
            }
        }
    }
}
Esempio n. 3
0
	/* ECMAScript constructor */
	Handle<Value> BoxLayout::New(const Arguments& args)
	{
		HandleScope scope;

		if (!args.IsConstructCall()) {
			return ThrowException(Exception::TypeError(
				String::New("Use the new operator to create instances of this object."))
			);
		}

		// Creates a new instance object of this type and wraps it.
		BoxLayout* obj = new BoxLayout();
		obj->Wrap(args.This());

		/* Initializing sub-objects */
		Local<Object> ScrollableObject = Scrollable::New(MX_SCROLLABLE(obj->_actor));
		args.Holder()->Set(String::NewSymbol("scroll"), ScrollableObject);

		return scope.Close(args.This());
	}
Esempio n. 4
0
File: copyTest.cpp Progetto: 8l/rose
void testlap(LevelData<double >& a_phi, double a_dx,char* a_str)
{
  double coef = 1./(a_dx*a_dx);
  Stencil<double> Laplacian(make_pair(getZeros(),-DIM*2*coef));
  BoxLayout bl = a_phi.getBoxLayout();
  
  for (int dir = 0; dir < DIM ; dir++)
    {
      Point edir = getUnitv(dir);
      Stencil<double> plus(make_pair(Shift(edir),coef));
      Stencil<double> minus(make_pair(Shift(edir*(-1)),coef));
      Laplacian = Laplacian + minus + plus;
    }
  
  a_phi.exchange();
  RectMDArray<double> LPhi00(bl.getDomain());
  for (BLIterator blit(bl); blit != blit.end(); ++blit)
    {
      LPhi00 |= Laplacian(a_phi[*blit],bl[*blit]);
    }
   MDWrite(a_str,LPhi00);
};
void
coarsen(BoxLayout& a_output, const BoxLayout& a_input, int a_refinement)
{
   if (!a_input.isClosed())
    {
      MayDay::Error("input to coarsen must be called with closed BoxLayout");
    }
  if (a_output.isClosed())
    {
      MayDay::Error("output of coarsen must be called on open BoxLayout");
    }
  //a_output.deepCopy(a_input);
  a_output.m_boxes      = RefCountedPtr<Vector<Entry> >(new Vector<Entry>(*(a_input.m_boxes)));
  a_output.m_layout     = a_input.m_layout;
#ifdef CH_MPI
  a_output.m_dataIndex  = a_input.m_dataIndex;
#endif

  for (int ivec = 0; ivec < a_output.m_boxes->size(); ivec++)
    {
      (*a_output.m_boxes)[ivec].box.coarsen(a_refinement);
    }
  a_output.close();
}
//checks equality of the vector of boxes inside m_boxes
bool BoxLayout::sameBoxes(const BoxLayout& a_layout) const
{
  bool retval;
  if (size() == a_layout.size())
    {
      retval = true;

      for (int iBox = 0; iBox < size(); ++iBox)
        {
          //RefCountedPtr<Vector<Entry> > m_boxes;
          if ((*m_boxes)[iBox].box != (*a_layout.m_boxes)[iBox].box)
            {
              retval = false;
            }
        }
    }
  else
    {
      retval = false;
    }
  return retval;
}
Esempio n. 7
0
void ReductionCopier::define(const BoxLayout& a_level,
                             const BoxLayout& a_dest,
                             const ProblemDomain& a_domain,
                             const IntVect& a_ghost,
                             const Vector<int>& a_transverseDir,
                             bool  a_exchange)
{
#ifdef MULTIDIM_TIMER
  CH_TIME("ReductionCopier::define")
#endif
  m_isDefined = true;
  m_transverseDir = a_transverseDir;

  CH_assert(a_level.isClosed());
  CH_assert(a_dest.isClosed());
  //  CH_assert(a_level.checkPeriodic(a_domain));

  clear();
  buffersAllocated = false;
  //bool self = a_dest == a_level;
  const BoxLayout&         level= a_level;
  const BoxLayout&         dest = a_dest;

  // note that while much of the implementation for the
  // periodic case remains in this function (as copied, more
  // or less, from the original Copier), at least at the moment
  // periodic support is "turned off" for the ReductionCopier
  // because it's not entirely clear it will do the right thing
  // for this case.  I've left the vast majority of the
  // periodic implementation in place, however, in case we
  // change our minds... (DFM 3/10/09)

  // set up vector of dataIndexes to keep track of which
  // "to" boxes are not completely contained within the primary
  // domain.  these boxes are then candidates for filling by
  // periodic images of the "from" data.
  Vector<DataIndex> periodicallyFilledToVect;

  // in order to cull which "from" data may be needed to
  // fill the "to" data, keep track of the radius around the
  // primary domain in which all these cells lie.
  // do this by incrementally growing the domain box and
  // keeping track of what this radius is.
  // just to make things simpler, start off with a radius of one
  Box grownDomainCheckBox = a_domain.domainBox();
  grownDomainCheckBox.grow(1);
  int periodicCheckRadius = 1;

  // since valid regions of the "from" DBL may also be outside
  // the primary domain, need to keep track of whether any of these
  // need to be checked separately.
  Vector<DataIndex> periodicFromVect;
  // use same domain trick here as well
  Box grownFromDomainCheckBox = a_domain.domainBox();
  int periodicFromCheckRadius = 1;

  Box domainBox(a_domain.domainBox());
  // grab index extents of domain in transverse direction
  Vector<int> transverseLo(m_transverseDir.size());
  Vector<int> transverseHi(m_transverseDir.size());

  for (int n=0; n<m_transverseDir.size(); n++)
    {
      // grab index extents of domain in transverse direction
      transverseLo[n] = domainBox.smallEnd(m_transverseDir[n]);
      transverseHi[n] = domainBox.bigEnd(m_transverseDir[n]);
    }

  bool isPeriodic = false;
  // I think the right thing here is that the ReductionCopier
  // completely ignores periodicity
  //if (!domainBox.isEmpty())
  //isPeriodic = a_domain.isPeriodic();

  // (dfm -- 9/13/05) as currently written, the Copier won't correctly
  // handle periodic cases where the number of ghost cells is greater
  // than the width of the domain.  We _should_ do multiple wraparounds,
  // but we don't. So, put in this assertion. We can revisit this if it
  // becomes an issue
  if (isPeriodic)
    {
      for (int dir=0; dir<SpaceDim; dir++)
        {
          if (a_domain.isPeriodic(dir))
            {
              CH_assert (a_ghost[dir] <= domainBox.size(dir));
            }
        }
    }

  unsigned int myprocID = procID();

  // The following 4 for loops are the result of a performance optimization.
  // When increasing the size of the problem, we found that the code was
  // looping over every destination box for every source box which was N1*N2
  // loop iterations (essentially an N-squared approach).
  // The following code attempts to simply reduce N1 and N2 by first separating
  // the boxes (or LayoutIndexes to boxes) that reside on the current processor.
  // Then the loop to determine which boxes of the first list intersect with
  // which boxes of the second list can be done in N1' * N2' iterations,
  // where N1' is the reduced N1 and N2' is the reduced N2.
  // We have to break up the assigning of MotionItems into two separate
  // loops and be careful about the local copies.  These 4 loops are
  // significantly faster than the original for loop -- _especially_
  // for large problems.  (ndk)

#ifdef CH_MPI  // don't need to do this in serial
  // make a vector of boxes (or LayoutIndexes to boxes) from destination layout
  // that are known to reside on this processor.
  vector<DataIndex> vectorDestDI;
  vector<DataIndex> vectorDestOnProcDI;
  for (LayoutIterator to(a_dest.layoutIterator()); to.ok(); ++to)
  {
    vectorDestDI.push_back(DataIndex(to()));
    if (myprocID == dest.procID(to()))
    {
      vectorDestOnProcDI.push_back(DataIndex(to()));
    }
  }

  // make a vector of boxes (or LayoutIndexes to boxes) from "level"/src layout
  // that are known to reside on this processor.
  vector<DataIndex> vectorLevelDI;
  vector<DataIndex> vectorLevelOnProcDI;
  for (LayoutIterator from(a_level.layoutIterator()); from.ok(); ++from)
  {
    vectorLevelDI.push_back(DataIndex(from()));
    if (myprocID == level.procID(from()))
    {
      vectorLevelOnProcDI.push_back(DataIndex(from()));
    }
  }
#else
  // in serial, it's not very interesting as it's all of them.
  vector<DataIndex> vectorDestOnProcDI;
  vector<DataIndex> vectorLevelDI;
  for (LayoutIterator to(a_dest.layoutIterator()); to.ok(); ++to)
  {
    vectorDestOnProcDI.push_back(DataIndex(to()));
  }
  for (LayoutIterator from(a_level.layoutIterator()); from.ok(); ++from)
  {
    vectorLevelDI.push_back(DataIndex(from()));
  }
#endif

  // loop over all dest/to DI's on my processor
  for (vector<DataIndex>::iterator vdi=vectorDestOnProcDI.begin();
      vdi != vectorDestOnProcDI.end(); ++vdi)
  {

    // at this point, i know myprocID == toProcID
    const DataIndex todi(*vdi);
    Box ghost(dest[todi]);

    // don't do anything if ghost is entirely outside domain
    // may need to revisit this in the periodic case
    if (a_domain.intersects(ghost))
      {
        
        // this is somewhat different from the "normal" Copier. We only want
        // to look at ghost cells if they're outside the domain.
        // note that we don't want to do this for domain ghost cells in the
        // transverse (spreading) directions.
        for (int dir=0; dir<SpaceDim; dir++)
          {
            bool isTransverseDir = false;
            for (int n=0; n<m_transverseDir.size(); n++)
              {
                if (dir == m_transverseDir[n]) isTransverseDir = true;
              }
            // only need to do this if we specify a ghost radius
            if (!isTransverseDir && a_ghost[dir] != 0)
              {
                if (ghost.bigEnd(dir) == domainBox.bigEnd(dir))
                  {
                    ghost.growHi(dir, a_ghost[dir]);
                  }
                
                if (ghost.smallEnd(dir) == domainBox.smallEnd(dir))
                  {
                    ghost.growLo(dir, a_ghost[dir]);
                  }
              }
          }
        
        Box destBox(ghost);
        
        // for this Copier, we want to grow the "dest" region to cover the
        // entire domain in the transverse direction. In that way, we
        // will be able to catch all of the source data regions which
        // project onto the dest boxes
        // do this for all transverse directions
        for (int n=0; n<m_transverseDir.size(); n++)
          {
            ghost.setSmall(m_transverseDir[n], transverseLo[n]);
            ghost.setBig(m_transverseDir[n], transverseHi[n]);
          }
        
        // then for each level/from DI, see if they intersect
        for (vector<DataIndex>::iterator vli = vectorLevelDI.begin();
             vli != vectorLevelDI.end(); ++vli)
          {
            const DataIndex fromdi(*vli);
            const unsigned int fromProcID = level.procID(fromdi);
            Box fromBox(level[fromdi]);
            
            // also grow the fromBox if it's near the domain boundary and
            // if there are ghost cells specified.
            for (int dir=0; dir<SpaceDim; dir++)
              {
                bool isTransverseDir = false;
                for (int n=0; n<m_transverseDir.size(); n++)
                  {
                    if (dir == m_transverseDir[n]) isTransverseDir = true;
                  }
                // only need to do this if we specify a ghost radius
                // and if it's not a transverseDir
                if (!isTransverseDir && a_ghost[dir] != 0)
                  {
                    if (fromBox.bigEnd(dir) == domainBox.bigEnd(dir))
                      {
                        fromBox.growHi(dir, a_ghost[dir]);
                      }
                    
                    if (fromBox.smallEnd(dir) == domainBox.smallEnd(dir))
                      {
                        fromBox.growLo(dir, a_ghost[dir]);
                      }
                  }
              }
            
            if (fromBox.bigEnd(0) < ghost.smallEnd(0))
              {
                //can skip rest cuz we haven't gotten to something interesting
                continue;
              }
          
            if (ghost.intersectsNotEmpty(fromBox)) 
              {
                Box box(ghost); // ??
                box&=fromBox;   // ??
                // to get correct toBox, stretch box in the transverse direction
                // then intersect with the destBox to get the appropriate part
                // of the destbox
                Box toBox(box);
                // do this for all transverse directions
                for (int n=0; n<m_transverseDir.size(); n++)
                  {
                    toBox.setSmall(m_transverseDir[n], transverseLo[n]);
                    toBox.setBig(m_transverseDir[n], transverseHi[n]);
                  }
                toBox &= destBox;
                
                MotionItem* item = new (s_motionItemPool.getPtr())
                  MotionItem(fromdi, todi, box, toBox);
                if (item == NULL)
                  {
                    MayDay::Error("Out of Memory in copier::define");
                  }
                if (fromProcID == myprocID)
                  {
                    // local move
                    if (a_exchange && fromdi == todi)
                      s_motionItemPool.returnPtr(item);
                    else
                      m_localMotionPlan.push_back(item);
                  }
                else
                  {
                    item->procID = fromProcID;
                    m_toMotionPlan.push_back(item);
                  }
              }
            if (fromBox.smallEnd(0) > ghost.bigEnd(0))
              {
                //can break out of loop, since we know that the smallEnd
                // of all the remaining boxes are lexigraphically beyond this ghosted box.
                break;
              }
            
          }      
      } // end if ghost intersects domain
  }       
  
  // Don't need to worry about this in serial as we already
  // took care of the local copy motion items just above.  skip this.
#ifdef CH_MPI
  // loop over all dest/to DI's
  for (vector<DataIndex>::iterator vdi=vectorDestDI.begin();
      vdi != vectorDestDI.end(); ++vdi)
  {

    const DataIndex todi(*vdi);
    Box ghost(dest[todi]);

    // don't do anything if ghost is outside domain
    if (a_domain.intersects(ghost) )
      {
        // this is somewhat different from the "normal" Copier. We only want
        // to look at ghost cells if they're outside the domain.
        // note that we don't want to do this for domain ghost cells in the
        // transverse (spreading) directions.
        for (int dir=0; dir<SpaceDim; dir++)
          {
            bool isTransverseDir = false;
            for (int n=0; n<m_transverseDir.size(); n++)
              {
                if (dir == m_transverseDir[n]) isTransverseDir = true;
              }
            // only need to do this if we specify a ghost radius
            if (!isTransverseDir && a_ghost[dir] != 0)
              {
                if (ghost.bigEnd(dir) == domainBox.bigEnd(dir))
                  {
                    ghost.growHi(dir, a_ghost[dir]);
                  }
                
                if (ghost.smallEnd(dir) == domainBox.smallEnd(dir))
                  {
                    ghost.growLo(dir, a_ghost[dir]);
                  }
              }
          }
        
        Box destBox(ghost);
        
        // for this Copier, we want to grow the "dest" region to cover the
        // entire domain in the transverse direction. In that way, we
        // will be able to catch all of the source data regions which
        // project onto the dest boxes
        // do this for all transverse directions
        for (int n=0; n<m_transverseDir.size(); n++)
          {
            ghost.setSmall(m_transverseDir[n], transverseLo[n]);
            ghost.setBig(m_transverseDir[n], transverseHi[n]);
          }
        
        const unsigned int toProcID = dest.procID(todi);
        
        // then for each level/from DI on this processor, see if they intersect
        for (vector<DataIndex>::iterator vli = vectorLevelOnProcDI.begin();
             vli != vectorLevelOnProcDI.end(); ++vli)
          {
            // at this point, i know myprocID == fromProcID
            
            const DataIndex fromdi(*vli);
            Box fromBox(level[fromdi]);
            
            // also grow the fromBox if it's near the domain boundary and
            // if there are ghost cells specified.
            for (int dir=0; dir<SpaceDim; dir++)
              {
                bool isTransverseDir = false;
                for (int n=0; n<m_transverseDir.size(); n++)
                  {
                    if (dir == m_transverseDir[n]) isTransverseDir = true;
                  }
                // only need to do this if we specify a ghost radius
                // and if it's not a transverseDir
                if (!isTransverseDir && a_ghost[dir] != 0)
                  {
                    if (fromBox.bigEnd(dir) == domainBox.bigEnd(dir))
                      {
                        fromBox.growHi(dir, a_ghost[dir]);
                      }
                    
                    if (fromBox.smallEnd(dir) == domainBox.smallEnd(dir))
                      {
                        fromBox.growLo(dir, a_ghost[dir]);
                      }
                  }
              }
            
            if (fromBox.bigEnd(0) < ghost.smallEnd(0))
              {
                //can skip rest cuz we haven't gotten to something interesting
                continue;
              }
            
            if (ghost.intersectsNotEmpty(fromBox))
              {
                Box box(ghost); // ??
                box&=fromBox;   // ??
                
                // to get correct toBox, stretch box in the transverse direction
                // then intersect with the destBox to get the appropriate part
                // of the destbox
                // do this for each transverse direction
                Box toBox(box);
                for (int n=0; n<m_transverseDir.size(); n++)
                  {
                    toBox.setSmall(m_transverseDir[n], transverseLo[n]);
                    toBox.setBig(m_transverseDir[n], transverseHi[n]);
                  }
                toBox &= destBox;
                
                if (toProcID == myprocID)
                  {
                    // local move
                    // don't push back here!  or you will get two.
                    //     we already did it above...
                    //m_localMotionPlan.push_back(item);
                  }
                else
                  {
                    MotionItem* item = new (s_motionItemPool.getPtr())
                      MotionItem(fromdi, todi, box, toBox);
                    if (item == NULL)
                      {
                        MayDay::Error("Out of Memory in copier::define");
                      }
                    
                    item->procID = toProcID;
                    m_fromMotionPlan.push_back(item);
                  }
              }
            if (fromBox.smallEnd(0) > ghost.bigEnd(0))
              {
                //can break out of loop, since we know that the smallEnd
                // of all the remaining boxes are lexigraphically beyond this ghosted box.
                break;
              }
          }
      } // end if ghost intersects domain
  }
#endif
  
  // put periodic intersection checking in here for "to" boxes
  if (isPeriodic)
  {
    for (LayoutIterator to(a_dest.layoutIterator()); to.ok(); ++to)
    {

      Box ghost(dest[to()]);

      // don't do anything if ghost doesn't intersect domain
      if (a_domain.intersects(ghost) ) 
        {
          
          // this is somewhat different from the "normal" Copier. We only want
          // to look at ghost cells if they're outside the domain.
          // note that we don't want to do this for domain ghost cells in the
          // transverse (spreading) directions.
          for (int dir=0; dir<SpaceDim; dir++)
            {
              bool isTransverseDir = false;
              for (int n=0; n<m_transverseDir.size(); n++)
                {
                  if (dir == m_transverseDir[n]) isTransverseDir = true;
                }
              // only need to do this if we specify a ghost radius
              if (!isTransverseDir && a_ghost[dir] != 0)
                {
                  if (ghost.bigEnd(dir) == domainBox.bigEnd(dir))
                    {
                      ghost.growHi(dir, a_ghost[dir]);
                    }
                  
                  if (ghost.smallEnd(dir) == domainBox.smallEnd(dir))
                    {
                      ghost.growLo(dir, a_ghost[dir]);
                    }
                }
            }
          
          Box destBox(ghost);
          
          // for this Copier, we want to grow the "dest" region to cover the
          // entire domain in the transverse direction. In that way, we
          // will be able to catch all of the source data regions which
          // project onto the dest boxes
          // do this for each transverse directions
          for (int n=0; n<m_transverseDir.size(); n++)
            {
              ghost.setSmall(m_transverseDir[n], transverseLo[n]);
              ghost.setBig(m_transverseDir[n], transverseHi[n]);
            }
          
          //unsigned int toProcID = dest.procID(to());  // unused variable
          
          // only do this if ghost box hangs over domain edge
          if (!domainBox.contains(ghost))
            {
              // add the dataIndex for this box to the list
              // of boxes which we need to come back to
              periodicallyFilledToVect.push_back(DataIndex(to()));
              // now check to see if we need to grow the
              // periodic check radius
              if (!grownDomainCheckBox.contains(ghost))
                {
                  // grow the domainCheckBox until it contains ghost
                  while (!grownDomainCheckBox.contains(ghost))
                    {
                      grownDomainCheckBox.grow(1);
                      periodicCheckRadius++;
                    }
                } // end if we need to grow radius around domain
              
            } //end if ghost box is not contained in domain
        } // end if original ghost box didn't intersect domain
    }// end if periodic
  } 
  
  // Here ends the so-called N-squared optimizations.  the rest is unchanged. (ndk)
  
  // now do periodic checking, if necessary
  if (isPeriodic)
    {
      // the only "from" boxes we will need to check
      // will be those within periodicCheckRadius of the
      // domain boundary. so, create a box to screen out
      // those which we will need to check.
      Box shrunkDomainBox = a_domain.domainBox();
      shrunkDomainBox.grow(-periodicCheckRadius);
      
      ShiftIterator shiftIt = a_domain.shiftIterator();
      IntVect shiftMult(domainBox.size());
      
      // now loop over "from" boxes
      for (LayoutIterator from(a_level.layoutIterator()); from.ok(); ++from)
        {
          // first check to see whether we need to look at this box
          const Box& fromBox = level[from()];
          
          if (!shrunkDomainBox.contains(fromBox))
            {
              unsigned int fromProcID = level.procID(from());
              
              // check to see if fromBox is contained in domain,
              // if not, add it to the list of fromBoxes we need to
              // go back and check separately to see if it will
              // fill one of the "to" boxes
              if (!domainBox.contains(fromBox))
                {
                  periodicFromVect.push_back(DataIndex(from()));
                  
                  if (!grownFromDomainCheckBox.contains(fromBox))
                    {
                      while (!grownFromDomainCheckBox.contains(fromBox))
                          {
                            grownFromDomainCheckBox.grow(1);
                            periodicFromCheckRadius++;
                          }
                    } // end if we need to grow domain check box
                } // end if fromBox is outside domain
              
              // now loop over those "to" boxes which were not contained
              // in the domain
              for (int toRef=0; toRef<periodicallyFilledToVect.size(); toRef++)
                {
                  DataIndex toIndex = periodicallyFilledToVect[toRef];
                    unsigned int toProcID = dest.procID(toIndex);
                    
                    // don't worry about anything that doesn't involve this proc
                    if (toProcID != myprocID && fromProcID != myprocID)
                      {
                        // do nothing
                      }
                    else
                      {
                        Box ghost(dest[toIndex]);
                        
                        // don't do anything if ghost doesn't intersect domain
                        if (a_domain.intersects(ghost))
                          {
                            
                            // this is somewhat different from the "normal" Copier.
                            // We only want
                            // to look at ghost cells if they're outside the domain.
                            // note that we don't want to do this for domain ghost
                            // cells in the transverse (spreading) directions.
                            for (int dir=0; dir<SpaceDim; dir++)
                              {
                                bool isTransverseDir = false;
                                for (int n=0; n<m_transverseDir.size(); n++)
                                  {
                                    if (dir == m_transverseDir[n]) isTransverseDir = true;
                                  }
                                // only need to do this if we specify a ghost radius
                                if (!isTransverseDir && a_ghost[dir] != 0)
                                  {
                                    if (ghost.bigEnd(dir) == domainBox.bigEnd(dir))
                                      {
                                        ghost.growHi(dir, a_ghost[dir]);
                                      }
                                    
                                    if (ghost.smallEnd(dir) == domainBox.smallEnd(dir))
                                      {
                                        ghost.growLo(dir, a_ghost[dir]);
                                      }
                                  }
                              }
                            
                            Box destBox(ghost);
                            
                            // for this Copier, we want to grow the "dest"
                            // region to cover the entire domain in the transverse
                            // direction. In that way, we will be able to catch all
                            // of the source data regions which project onto the
                            // dest boxes
                            // do this for each transverse direction
                            for (int n=0; n<m_transverseDir.size(); n++)
                              {
                                ghost.setSmall(m_transverseDir[n], transverseLo[n]);
                                ghost.setBig(m_transverseDir[n], transverseHi[n]);
                              }
                            
                            // now need to loop over shift vectors and look at images
                            for (shiftIt.begin(); shiftIt.ok(); ++shiftIt)
                              {
                                IntVect shiftVect(shiftIt()*shiftMult);
                                ghost.shift(shiftVect);
                                if (ghost.intersectsNotEmpty(fromBox)) // rarely happens
                                  {
                                    Box intersectBox(ghost);
                                    intersectBox &= fromBox;
                                    Box toBox(intersectBox);
                                    toBox.shift(-shiftVect);
                                    toBox &= destBox;
                                    MotionItem* item = new (s_motionItemPool.getPtr())
                                      MotionItem(DataIndex(from()), DataIndex(toIndex),
                                                 intersectBox, toBox);
                                    if (item == NULL)
                                      {
                                        MayDay::Error("Out of Memory in copier::define");
                                      }
                                    if (toProcID == fromProcID) // local move
                                      m_localMotionPlan.push_back(item);
                                    else if (fromProcID == myprocID)
                                      {
                                        item->procID = toProcID;
                                        m_fromMotionPlan.push_back(item);
                                      }
                                    else
                                      {
                                        item->procID = fromProcID;
                                        m_toMotionPlan.push_back(item);
                                      }
                                    
                                  } // end if shifted box intersects
                                
                                ghost.shift(-shiftVect);
                              } // end loop over shift vectors
                          } // end if original "ghost" intersected domain
                      }  // end if either from box or to box are on this proc
                } // end loop over destination boxes
            } // end if source box is close to domain boundary
        } // end loop over destination boxes
      
      // now go back through the "from" boxes which were outside
      // the domain and see if they intersect any toBoxes
      if (periodicFromVect.size() != 0)
        {
          // the only "to" boxes we will need to check
          // will be those within periodicCheckRadius of the
          // domain boundary. so, create a box to screen out
          // those which we will need to check.
          shrunkDomainBox = a_domain.domainBox();
          shrunkDomainBox.grow(-periodicFromCheckRadius);

          // now loop over the "to" boxes
          for (LayoutIterator to(a_dest.layoutIterator()); to.ok(); ++to)
            {
              // first check to see whether we need to look at this box
              Box ghost(dest[to()]);
              
              // don't do anything if "ghost" doesn't interesect domain
              if (a_domain.intersects(ghost))
                {
                  // this is somewhat different from the "normal" Copier.
                  // We only want
                  // to look at ghost cells if they're outside the domain.
                  // note that we don't want to do this for domain ghost cells
                  // in the transverse (spreading) directions.
                  for (int dir=0; dir<SpaceDim; dir++)
                    {
                      bool isTransverseDir = false;
                      for (int n=0; n<m_transverseDir.size(); n++)
                        {
                          if (dir == m_transverseDir[n]) isTransverseDir = true;
                        }
                      // only need to do this if we specify a ghost radius
                      if (!isTransverseDir && a_ghost[dir] != 0)
                        {
                          if (ghost.bigEnd(dir) == domainBox.bigEnd(dir))
                            {
                              ghost.growHi(dir, a_ghost[dir]);
                            }
                          
                          if (ghost.smallEnd(dir) == domainBox.smallEnd(dir))
                            {
                              ghost.growLo(dir, a_ghost[dir]);
                            }
                        }
                    }
                  Box destBox(ghost);
                  
                  // for this Copier, we want to grow the "dest" region to
                  // cover the entire domain in the transverse direction.
                  // In that way, we will be able to catch all of the source
                  // data regions which project onto the dest boxes
                  // do this for each transverse direction
                  for (int n=0; n<m_transverseDir.size(); n++)
                    {
                      ghost.setSmall(m_transverseDir[n], transverseLo[n]);
                      ghost.setBig(m_transverseDir[n], transverseHi[n]);
                    }
                  
                  if (!shrunkDomainBox.contains(ghost))
                    {
                      unsigned int toProcID = a_dest.procID(to());
                      
                      // now loop over those "from" boxes which are not
                      // contained by the domain
                      for (int fromRef = 0; fromRef<periodicFromVect.size(); fromRef++)
                        {
                          DataIndex fromIndex = periodicFromVect[fromRef];
                          const Box& fromBox = level[fromIndex];
                          unsigned int fromProcID = level.procID(fromIndex);
                          
                          // don't worry about anything which doesn't involve
                          // this proc
                          if (toProcID != myprocID && fromProcID != myprocID)
                            {
                              // do nothing
                            }
                          else
                            {
                              // now need to loop over shift vectors and look at images
                              for (shiftIt.begin(); shiftIt.ok(); ++shiftIt)
                                {
                                  IntVect shiftVect(shiftIt()*shiftMult);
                                  ghost.shift(shiftVect);
                                  if (ghost.intersectsNotEmpty(fromBox))
                                    {
                                      Box intersectBox(ghost);
                                      intersectBox &= fromBox;
                                      Box toBox(intersectBox);
                                      toBox.shift(-shiftVect);
                                      toBox &= destBox;
                                      
                                      MotionItem* item = new (s_motionItemPool.getPtr())
                                        MotionItem(DataIndex(fromIndex), DataIndex(to()),
                                                   intersectBox, toBox);
                                      if (item == NULL)
                                        {
                                          MayDay::Error("Out of Memory in copier::define");
                                        }
                                      if (toProcID == fromProcID) // local move
                                        m_localMotionPlan.push_back(item);
                                      else if (fromProcID == myprocID)
                                        {
                                          item->procID = toProcID;
                                          m_fromMotionPlan.push_back(item);
                                        }
                                      else
                                        {
                                          item->procID = fromProcID;
                                          m_toMotionPlan.push_back(item);
                                        }
                                      
                                    } // end if shifted box intersects
                                  
                                  ghost.shift(-shiftVect);
                                } // end loop over shift vectors
                            } // end if either from box or to box are on this proc
                        } // end loop over "from" boxes
                    } // end if destination box is close to domain boundary
                } // end if original "ghost" intersects domain
            } // end loop over destination boxes
        } // end if any of the "From" boxes were outside the domain

    } // end if we need to do anything for periodicity
}
Esempio n. 8
0
Real DotProduct(const BoxLayoutData<FArrayBox>& a_dataOne,
                const BoxLayoutData<FArrayBox>& a_dataTwo,
                const BoxLayout&                a_dblIn,
                const Interval&                 a_comps)
{
  Vector<Real> rhodot;
  rhodot.reserve(10);
  const int startcomp = a_comps.begin();
  const int endcomp = a_comps.end();
  //calculate the single-processor dot product
  DataIterator dit = a_dataOne.dataIterator();

  for (dit.reset(); dit.ok(); ++dit)
  {
    Box fabbox = a_dblIn.get(dit());
    const FArrayBox& onefab = a_dataOne[dit()];
    const FArrayBox& twofab = a_dataTwo[dit()];
    CH_assert(onefab.box().contains(fabbox));
    CH_assert(twofab.box().contains(fabbox));

    Real dotgrid = 0;
    FORT_DOTPRODUCT(CHF_REAL(dotgrid),
                    CHF_CONST_FRA(onefab),
                    CHF_CONST_FRA(twofab),
                    CHF_BOX(fabbox),
                    CHF_CONST_INT(startcomp),
                    CHF_CONST_INT(endcomp));

    rhodot.push_back(dotgrid);
  }

  // now for the multi-processor fandango

  //gather all the rhodots onto a vector and add them up
  int baseProc = 0;
  Vector<Vector<Real> >dotVec;
  gather(dotVec, rhodot, baseProc);

  Real rhodotTot = 0.0;
  if (procID() == baseProc)
  {
    CH_assert(dotVec.size() == numProc());

    rhodot.resize(a_dblIn.size());

    int index = 0;
    for (int p = 0; p < dotVec.size(); p++)
    {
      Vector<Real>& v = dotVec[p];
      for (int i = 0; i < v.size(); i++, index++)
      {
        rhodot[index] = v[i];
      }
    }

    rhodot.sort();

    for (int ivec = 0; ivec < rhodot.size(); ivec++)
    {
      rhodotTot += rhodot[ivec];
    }
  }

  //broadcast the sum to all processors.
  broadcast(rhodotTot, baseProc);

  //return the total
  return rhodotTot;
}
Esempio n. 9
0
void getError(LevelData<double, 1> & a_error,
              double               & a_maxError,
              const double         & a_dx)
{
  int rank, nprocs;
  MPI_Comm_rank (MPI_COMM_WORLD, &rank);
  MPI_Comm_size (MPI_COMM_WORLD, &nprocs);
  std::cout << "I am rank " << rank << " of " <<  nprocs << " processes" <<  std::endl;

  BoxLayout* layout = new BoxLayout();
  int npatches;
  int nPatchPerProc, iStartIdx, iEndIdx;
  int patchID = -1;
  double local_maxError = 0;

  LevelData<double, 1> *phi;
  LevelData<double, 1> *lphcalc;
  LevelData<double, 1> *lphexac;

  if(rank == 0)
  {
    *layout = a_error.getBoxLayout();
    npatches = layout->size();
    phi = new LevelData<double, 1>(*layout, s_nghost);
    lphcalc = new LevelData<double, 1>(*layout, 0);
    lphexac = new LevelData<double, 1>(*layout, 0);
    //  cout << "initializing phi to sum_dir(sin 2*pi*xdir)" << endl;
    initialize(*phi,*lphexac, a_dx);
    //set ghost cells of phi
    phi->exchange();
  }
  if(nprocs > 1)
    MPI_Bcast( &npatches, 1, MPI_INT, 0, MPI_COMM_WORLD);
  MPI_Barrier(MPI_COMM_WORLD);

  if(npatches == 1)
   nPatchPerProc = 1;
  else
    nPatchPerProc = npatches/nprocs;
  iStartIdx = rank * nPatchPerProc;
  iEndIdx = (npatches < (rank+1)*nPatchPerProc) ? npatches-1 : ((rank+1)*nPatchPerProc-1);
  nPatchPerProc = iEndIdx - iStartIdx + 1; 
  std::cout << "I am rank " << rank << " working from " <<  iStartIdx << " to " << iEndIdx <<  std::endl;

// barrier to sync halo exchange

 

  if(rank == 0)
  {
    Box bxdst, bxsrc;
    MPI_Request reqs[5];
    MPI_Status status[5];
    int iwait = 0;
    for(BLIterator blit(*layout); blit != blit.end(); ++blit)
    {
      //bxdst= (*layout)[*blit];
      patchID++;
      bool mypatch = patchID >= iStartIdx && patchID <=iEndIdx;
      RectMDArray<double>& phiex =     (*phi)[patchID];
      RectMDArray<double>& lphca = (*lphcalc)[patchID];
      RectMDArray<double>& lphex = (*lphexac)[patchID];
      RectMDArray<double>& error = a_error[patchID];
      bxsrc = phiex . getBox();
      bxdst = lphca . getBox();
      lphca.setVal(0.);
      if(mypatch)
      {
cout << "Rank 0 is working on patch " << patchID << endl;
        double tmp;
        tmp = doWork(bxdst, phiex, lphca, lphex, error, a_dx);
        local_maxError = (local_maxError > tmp) ? local_maxError : tmp; 
      }
      else
      {
        int dest = patchID / nPatchPerProc;
//        MPI_Isend(&phiex, sizeof(RectMDArray<double>),MPI_CHAR, dest, 0, MPI_COMM_WORLD,&reqs[0]);
//cout << "master send out patch " <<  patchID<< " sourceDataPointer with size " << phiex.getBox().sizeOf() << endl;
//        MPI_Isend(&lphca, sizeof(RectMDArray<double>),MPI_CHAR, dest, 1, MPI_COMM_WORLD,&reqs[1]);
//cout << "master send out patch " <<  patchID<< " destinationDataPointer with size " << lphca.getBox().sizeOf() << endl;
        MPI_Isend(&bxsrc, sizeof(Box),MPI_CHAR, dest, 4, MPI_COMM_WORLD,&reqs[0]);
cout << "master send out patch " <<  patchID<< " bxdst Box with size " << sizeof(Box)<< endl;
        MPI_Isend(&bxdst, sizeof(Box),MPI_CHAR, dest, 4, MPI_COMM_WORLD,&reqs[1]);
cout << "master send out patch " <<  patchID<< " bxdst Box with size " << sizeof(Box)<< endl;
        double *sourceDataPointer = phiex . getPointer();
        double *destinationDataPointer = lphca . getPointer();
        MPI_Isend(sourceDataPointer, phiex.getBox().sizeOf(),MPI_DOUBLE, dest, 2, MPI_COMM_WORLD,&reqs[2]);
        MPI_Isend(destinationDataPointer, lphca.getBox().sizeOf(),MPI_DOUBLE, dest, 3, MPI_COMM_WORLD,&reqs[3]);
        iwait++;
        MPI_Waitall(4,reqs,status);
cout << "Rank 0 is sending patch " << patchID << " to rank " << dest << endl;

      }
    }
  }
  else
  {
    if(npatches == 1)
     nPatchPerProc = 0;
    else
      nPatchPerProc = npatches/nprocs;
    int src = 0;
    if(nPatchPerProc > 0)
    {
//      MPI_Request reqs[5];
      MPI_Status status[5];
      Box bxdst, bxsrc;
      RectMDArray<double>* phiex = new RectMDArray<double>();
      RectMDArray<double>* lphca = new RectMDArray<double>();
      RectMDArray<double>* lphex = new RectMDArray<double>();
      RectMDArray<double>* error = new RectMDArray<double>();
      int idx;
      for(idx = 0; idx < nPatchPerProc; idx++)      
      {
//        Box bxdst=((const BoxLayout&) layout)[*blit];
        patchID++;
//        MPI_Recv(phiex, sizeof(RectMDArray<double>), MPI_CHAR, src, 0, MPI_COMM_WORLD, &status[0]);
//        MPI_Recv(lphca, sizeof(RectMDArray<double>), MPI_CHAR, src, 1, MPI_COMM_WORLD, &status[1]);
//        double *sourceDataPointer = (double*) malloc(sizeof(double)*phiex->getBox().sizeOf());
        MPI_Recv(&bxsrc, sizeof(Box), MPI_CHAR, src, 4, MPI_COMM_WORLD, &status[0]);
cout << "Rank " << rank << " receive patch " << idx << " bxdst with size " << sizeof(Box)<< endl;
        MPI_Recv(&bxdst, sizeof(Box), MPI_CHAR, src, 4, MPI_COMM_WORLD, &status[1]);
cout << "Rank " << rank << " receive patch " << idx << " bxdst with size " << sizeof(Box)<< endl;
        phiex->define(bxsrc);
        lphca->define(bxdst);
        lphex->define(bxdst);
        error->define(bxdst);
        MPI_Recv(phiex -> getPointer(), phiex->getBox().sizeOf(), MPI_DOUBLE, src, 2, MPI_COMM_WORLD, &status[2]);
cout << "Rank " << rank << " receive patch " << idx << " sourceDataPointer with size " << phiex->getBox().sizeOf() << endl;
//        double *destinationDataPointer = (double*) malloc(sizeof(double)*lphca->getBox().sizeOf());
        MPI_Recv(lphca -> getPointer(), lphca->getBox().sizeOf(), MPI_DOUBLE, src, 3, MPI_COMM_WORLD, &status[3]);
cout << "Rank " << rank << " receive patch " << idx << " destinationDataPointer with size " << lphca->getBox().sizeOf() << endl;
cout << "Rank " << rank << " is working on patch " << npatches << endl;
        double tmp;
        tmp = doWork(bxdst,  *phiex, *lphca, *lphex, *error, a_dx);
        local_maxError = (local_maxError > tmp) ? local_maxError : tmp; 
      }
    }
  }
  MPI_Allreduce(&local_maxError, &a_maxError, 1, MPI_DOUBLE, MPI_MAX, MPI_COMM_WORLD);
  if(rank == 0)
   cout << "max Error is: " << a_maxError << endl;
}