package AMRTools;
import BoxTools.Util;
import BoxTools.BoxLayout;
import BoxTools.BoxLayoutData;
import BoxTools.LayoutIterator;
import BoxTools.DataIterator;
import BoxTools.BoxedArray;
import BoxTools.DataIndex;
import BoxTools.List;
/**
* A LevelFluxRegister object contains the difference at the coarse-fine interface
* between the coarse gradients computed using the ordinary method and the ones computed by
* averaging the fine gradients. The goal is to use this difference to modify Laplacian in order
* maintain the conservation form. Please refer to the Chombo design document for the details.
* Along each orientation, there is one BoxLayoutData storing gradients at the
* coarse-fine interface which are computed using the finite difference method. The updating
* mapping from the gradients at the coarse level to this BoxLayoutData (register)
* is cached. This information is used to update this register quickly. Also, there is another
* another BoxLayoutData storing gradients at the coarse-fine interface which are
* computed by averaging the gradients at the fine level. The updating mapping from the fine
* level data to this register is also cached. Another info cached is the updating mapping from
* the registers to the coarse level data, which is used to modify the Laplacian at the coarse
* level.
* An interesting question to answer during the implement ion is whether a local write plus a
* global read is faster than a global write plus a local read. The guess from the Tatinium group
* is that the first choice is usually faster than the second. We need to verify this. Currently
* we have implementations using both the two strategies.
*
Usage: must be declared local.
* @see BoxTools.BoxLayout, BoxTools.BoxLayoutData, BoxTools.LayoutIterator, BoxTools.BoxedArray
* and BoxTools.DataIndex.
* @see Chombo Specification
* @version 1.1
* Modified on Jul 09, 2004. change of syntax of foreach, see BoxTools/foreachLoopTest.ti.
* @author Tong Wen, LBNL
* @since 1.0
*/
template public class LevelFluxRegister{
private final static int highBoundary=Util.HIGH_SIDE;
private final static int lowBoundary=Util.LOW_SIDE;
private final static int SPACE_DIM=Util.SPACE_DIM;
private final static int SORT_DIM=Util.SORT_DIM;
private BoxLayout local single m_coarseBL;
private BoxLayout local single m_fineBL;
private BoxLayout local single m_fineBL_c;
private RectDomain single m_probDomain; //no use here?
private int single m_refRatio;
//private double single m_dxc;
private GridSpacing local m_DXc;
//private int single m_nComp;
private boolean single m_defined=false;
private int m_numFaceCells;
private Point [] local [] local m_disps;
LayoutIterator local m_coarseLItr, m_fineLItr;
DataIndex local [] local [] local m_FCAdjInfo;
template BoxLayoutData > local [] local m_fluxRegister_c;
template BoxLayoutData > local [] local m_fluxRegister_f;
Domain [] local [] local m_registerDomain;
DataIndex local [] local [] local [] local m_updateIdxes_f;
DataIndex local [] local [] local [] local m_updateIdxes_c;
DataIndex local [] local [] local [] local m_refluxIdxes_f;
LevelFluxRegister(){
m_fluxRegister_c=
new template BoxLayoutData > local [2*SPACE_DIM] local;
m_fluxRegister_f=
new template BoxLayoutData > local [2*SPACE_DIM] local;
m_updateIdxes_f=
new DataIndex local [2*SPACE_DIM] local [] local [] local;
m_updateIdxes_c=
new DataIndex local [2*SPACE_DIM] local [] local [] local;
m_refluxIdxes_f=
new DataIndex local [2*SPACE_DIM] local [] local [] local;
m_registerDomain=
new Domain [2*SPACE_DIM] local [] local;
}
public LevelFluxRegister(BoxLayout local single a_coarseBL, BoxLayout local single a_fineBL, int single a_refRatio, GridSpacing local a_DXc, RectDomain single a_PDomain){
this();
define(a_coarseBL,a_fineBL, a_refRatio,a_DXc, a_PDomain);
}
public LevelFluxRegister(BoxLayout local single a_coarseBL, BoxLayout local single a_fineBL, int single a_refRatio, double single a_dxc, RectDomain single a_PDomain){
this();
GridSpacing local a_DXc=new GridSpacing(a_dxc);
define(a_coarseBL,a_fineBL, a_refRatio,a_DXc, a_PDomain);
}
final local void define(BoxLayout local single a_coarseBL, BoxLayout local single a_fineBL, int single a_refRatio, GridSpacing local a_DXc, RectDomain single a_PDomain){
if (!(a_coarseBL.isDisjointed() && a_fineBL.isDisjointed())){
Util.printErrMsg("LevelFluxRegister::define( ,..., ): Boxes must be disjointed!");
return;
}
int i,j;
int single k, dir, side, orient;
int [] local otherDirs=new int [SPACE_DIM-1];
for (i=1,m_numFaceCells=1;i [2*SPACE_DIM] local [m_numFaceCells] local;
for (k=0;k<2*SPACE_DIM;k++){
orient=k+1;
dir=(orient+1)/2;
for (j=0, i=1;i<=SPACE_DIM;i++)
if (i!=dir) {otherDirs[j]=i; j++;}
switch (SPACE_DIM) {
case 1:
m_disps[k][0]=Point.all(0);
break;
case 2:
for (i=0;i.direction(otherDirs[0],i);
break;
case 3:
int l=0;
for (i=0;i.direction(otherDirs[0],i)+
Point.direction(otherDirs[1],j);
l++;
}
}
}
m_coarseBL=a_coarseBL;
m_fineBL=a_fineBL;
m_refRatio=a_refRatio;
m_DXc=a_DXc;
m_probDomain=a_PDomain;
m_fineBL_c=m_fineBL.coarsen(a_refRatio);
m_coarseLItr=new LayoutIterator(a_coarseBL);
m_fineLItr=new LayoutIterator(m_fineBL_c);
PrivateRegion local region=new PrivateRegion();
Region dr2;
int coarseSize=a_coarseBL.size();
int fineSize=a_fineBL.size();
m_FCAdjInfo=new DataIndex local [fineSize] local [] local;
template List local [] local temp_indexes=
new (region) template List local [fineSize] local;
RectDomain single [] local single boxes;
int single [] local single procIDs_c;
int single [] local single procIDs_f;
for (i=0;i();
boolean sorted=a_coarseBL.isSorted();
RectDomain box, box_f,box_c;
Domain boxCut, registerDomain;
DataIndex local DIdx, DIdx_c, DIdx_f;
int buffSize=0;
m_fineLItr.Reset();
for (i=0;i [] local buff_boxes=new (region) RectDomain [buffSize];
Domain [] local buff_domains=new (region) Domain [buffSize];
int [] local buff_procIDs_c=new (region) int [buffSize];
int [] local buff_procIDs_f=new (region) int [buffSize];
int [] local buff_intIdxes_c=new (region) int [buffSize];
int [] local buff_intIdxes_f=new (region) int [buffSize];
template List local [] local buff_updateIdxes_c=
new (region) template List local [coarseSize] local;
template List local [] local buff_updateIdxes_f=
new (region) template List local [fineSize] local;
template List local [] local buff_refluxIdxes_f=
new (region) template List local [coarseSize] local;
for (i=0;i();
buff_refluxIdxes_f[i]=new (region) template List();
}
for (i=0;i();
int single l,m,n, high_low,plus_minus,d;
BoxLayout local single boundary;
DataIndex local [] local neighborIdxes;
int registerSize;
BoxLayout local single temp_BL_c, temp_BL_f;
LayoutIterator local temp_LItr;
for (k=0;k<2*SPACE_DIM;k++){
orient=k+1;
d=(orient+1)/2;
high_low=(orient+1)%2;
temp_BL_c=new BoxLayout();
temp_BL_f=new BoxLayout();
m_updateIdxes_f[k]=
new DataIndex local [fineSize] local [] local;
m_updateIdxes_c[k]=
new DataIndex local [coarseSize] local [] local;
m_refluxIdxes_f[k]=
new DataIndex local [coarseSize] local [] local;
if (high_low==highBoundary){
plus_minus=-1;
boundary=m_fineBL_c.highBoundary(d,1,false);
}
else{
plus_minus=1;
boundary=m_fineBL_c.lowBoundary(d,1,false);
}
m_fineLItr.Reset();registerSize=0;
for (m=0;m<(int single)fineSize;m++){
DIdx_f=m_fineLItr.GetDataIndex();
box=boundary[DIdx_f];boxCut=box;
neighborIdxes=m_fineBL.getNeighborIdxes(DIdx_f);
/*dr2 = Domain.setRegion(region);*/
PrivateRegion local pr = new PrivateRegion(); //the faster version
dr2 = Domain.setRegion(pr); //the faster version
for (l=0;l<(int single)neighborIdxes.length;l++)
boxCut=boxCut-m_fineBL_c[neighborIdxes[l]];
Domain.setRegion(dr2);
//if ((boolean single)!boxCut.isNull()) //RD.isNull() is deprecated
if ((boolean single)!boxCut.isEmpty())
for (n=0;n<(int single)m_FCAdjInfo[m].length;n++){
DIdx_c=m_FCAdjInfo[m][n];
box_c=m_coarseBL[DIdx_c];
registerDomain=boxCut*box_c;
//box=box*box_c;
//if ((boolean single)!registerDomain.isNull()){ //RD.isNull() is deprecated
if ((boolean single)!registerDomain.isEmpty()){
buff_boxes[registerSize]=box*box_c;
buff_domains[registerSize]=registerDomain;
buff_procIDs_c[registerSize]=DIdx_c.procID();
buff_procIDs_f[registerSize]=DIdx_f.procID();
buff_intIdxes_c[registerSize]=DIdx_c.index();
buff_intIdxes_f[registerSize]=DIdx_f.index();
registerSize++;
}
}
m_fineLItr.Advance();
try {
pr.delete();
} catch (RegionInUse e) {} //the faster version
}
boxes=new (region) RectDomain single [(int single)registerSize] local single;
procIDs_c=new (region) int single [(int single)registerSize] local single;
procIDs_f=new (region) int single [(int single)registerSize] local single;
m_registerDomain[k]=new Domain [registerSize] local;
for (l=0;l<(int single)registerSize;l++){
m_registerDomain[k][l]=buff_domains[l];
boxes[l]=(RectDomain single) buff_boxes[l];
procIDs_c[l]=(int single) buff_procIDs_c[l];
procIDs_f[l]=(int single) buff_procIDs_f[l];
//System.out.print(" {"+boxes[l].toString()+", "+procIDs_c[l]+", "+procIDs_f[l]+"} ");
}
//System.out.print("\n");System.out.flush();
temp_BL_c.define(boxes, procIDs_c, false);
temp_BL_f.define(boxes, procIDs_f, false);
m_fluxRegister_c[k]=new template BoxLayoutData >(temp_BL_c,0);
m_fluxRegister_f[k]=new template BoxLayoutData >(temp_BL_f,0);
temp_LItr=new (region) LayoutIterator(temp_BL_c);
for (i=0;i local a_coarseFlux, DataIndex local a_coarsePatchIndex, double single a_scale, int a_dir, int a_side){
if (isUpdateValid((BoxLayout single) m_coarseBL.getRoot(), (BoxLayout single) a_coarsePatchIndex.root(), a_dir, a_side)){
int i,j,k;
if (a_side==0) k=(a_dir-1)*2+1; else k=(a_dir-1)*2;
RectDomain box;
T [SPACE_DIM d] local tiArray, tiArray_reg;
//Point point; /* for change in the syntax of foreach */
DataIndex local [] local registerIdxes=m_updateIdxes_c[k][a_coarsePatchIndex.index()];
tiArray=a_coarseFlux.getLocalArray();
for (i=0;i local a_fineFlux, DataIndex local a_finePatchIndex, double single a_scale, int a_dir, int a_side){
if (isUpdateValid((BoxLayout single) m_fineBL.getRoot(), (BoxLayout single) a_finePatchIndex.root(), a_dir, a_side)){
int i,j,k;
k=(a_dir-1)*2+a_side;
RectDomain box;
T [SPACE_DIM d] local tiArray_reg, tiArray_f;
template BoxedArray local boxedArray;
//Point point, point_f; /* for change in the syntax of foreach */
Point point_f;
tiArray_f=a_fineFlux.getLocalArray();
DataIndex local [] local registerIdxes=m_updateIdxes_f[k][a_finePatchIndex.index()];
T tempT;
/* on Sep 16, 2004
for (i=0;i.direction(a_dir,1))*m_refRatio;
else
point_f=point*m_refRatio-Point.direction(a_dir,1);
tempT=tiArray_f[point_f+m_disps[k][0]];
for (j=1;j.direction(a_dir,1))*m_refRatio;
tempT=tiArray_f[point_f+m_disps[k][0]];
for (j=1;j.direction(a_dir,1);
tempT=tiArray_f[point_f+m_disps[k][0]];
for (j=1;j > local a_uCoarse){
Ti.barrier();
if (m_defined){
DataIterator local DItr=new DataIterator(a_uCoarse.boxLayout());
int i,j,k, high_low,plus_minus;
DataIndex local [] local registerIdxes;
DataIndex local DIdx;
T [SPACE_DIM d] local tiArray, tiArray_loc;
T [SPACE_DIM d] tiArray_glb;
RectDomain box;
//Point point;
while (!DItr.isEnded()){
DIdx=DItr.access();
tiArray=a_uCoarse[DIdx].getLocalArray();
for (k=0;k > local a_uCoarse, boolean a_defluxON){
Ti.barrier();
if (m_defined){
PrivateRegion local region=new PrivateRegion();
DataIterator local DItr=new DataIterator(a_uCoarse.boxLayout());
int i,j,k, high_low,plus_minus;
double dxc;
DataIndex local [] local registerIdxes_c, registerIdxes_f;
DataIndex local DIdx;
T [SPACE_DIM d] local tiArray, tiArray_loc_c, tiArray_loc_f;
T [SPACE_DIM d] tiArray_glb;
RectDomain box;
//Point point; /* for change in the syntax of foreach */
while (!DItr.isEnded()){
DIdx=DItr.access();
tiArray=a_uCoarse[DIdx].getLocalArray();
for (k=0;k > local a_uCoarse){
reflux(a_uCoarse, false);
}
public final local void deflux(template BoxLayoutData > local a_uCoarse){
reflux(a_uCoarse, true);
}
final local boolean single isUpdateValid(BoxLayout single a_myLayout, BoxLayout single a_dataIndexLayout, int single a_dir, int single a_side){
if (!m_defined){
Util.printErrMsg("LevelFluxRegister::isUpdateValid( , ... , ): the flux register is undefined!");
return false;
}
if (a_myLayout!=a_dataIndexLayout) {
Util.printErrMsg("LevelFluxRegister::isUpdateValid( , ... , ): invalid DataIndex!");
return false;
}
if (a_dir>SPACE_DIM || a_dir<1){
Util.printErrMsg("LevelFluxRegister::isUpdateValid( , ... , ): invalid direction!");
return false;
}
if (a_side!=lowBoundary && a_side!=highBoundary){
Util.printErrMsg("LevelFluxRegister::isUpdateValid( , ... , ): invalid side!");
return false;
}
return true;
}
public local void myprint(){
DataIterator local DItr;
DataIndex local DIdx;
RectDomain box;
BoxLayout local BL;
int i,j,k;
//Point point; /* for change in the syntax of foreach */
T [SPACE_DIM d] local TiArray;
for (i=0;i<2*SPACE_DIM;i++){
BL=m_fluxRegister_c[i].boxLayout();
DItr=new DataIterator(BL);
System.out.println("Boxes on Proc "+Ti.thisProc()+" along orientation "+(i+1));
System.out.println("register for coarse-level data:");
while(!DItr.isEnded()){
DIdx=DItr.access();
box=BL.getBox(DIdx);
System.out.println(" "+box.toString()+" :");
TiArray=m_fluxRegister_c[i][DIdx].getLocalArray();
foreach (point in TiArray.domain()) System.out.print(" "+point.toString()+": "+TiArray[point]);
System.out.print("\n");System.out.flush();
DItr.advance();
}
BL=m_fluxRegister_f[i].boxLayout();
DItr=new DataIterator(BL);
System.out.println("register for fine-level data:");
while(!DItr.isEnded()){
DIdx=DItr.access();
box=BL.getBox(DIdx);
System.out.println(" "+box.toString()+" :");
TiArray=m_fluxRegister_f[i][DIdx].getLocalArray();
foreach (point in TiArray.domain()) System.out.print(" "+point.toString()+": "+TiArray[point]);
System.out.print("\n");System.out.flush();
DItr.advance();
}
//System.out.print("\n");System.out.flush();
/*for (j=0;j