package BoxTools;
/** A BoxedArray
object is a wrapper of a Ti array T [SPACE_DIM d]
,
* which is defined on a box. The template parameter T
should be an immutable
* class (in the future, a value class) or a primitive type in order to make the copy operation
* efficient. Since currently Titanium has little support of programming with type, the current
* implementation can only support T
being either a class or a primitive type,
* but not both. Also since Titanium currently does not support inheritance involving a template
* class, it is impossible for BoxedArray
to extend an interface or abstract class,
* which defines the interface between BoxedArray
and BoxLayoutData
.
* A BoxedArray
can either be global or local, but operations here are only defined
* on local BoxedArray
s.
* @see BoxLayoutData
* @version 2.0
* Modified on Jun 21, 2004. The exchange info is cached at this level.
* on Jul 09, 2004. change of syntax of foreach, see foreachLoopTest.ti.
*
* @author Tong Wen, LBNL
* @since 1.0
*/
template public class BoxedArray{
private static final int SPACE_DIM =Util.SPACE_DIM;
T [SPACE_DIM d] local m_array;
private RectDomain m_domain;
private int m_neighborSize=0;
private boolean [] local m_neighborIsLocal;
private T [1d] local [SPACE_DIM d] m_neighbors;
private RectDomain [] local m_neighborsDomain;
RectDomain box;
//Point point; /*for the foreach loop change*/
//Timer tmrPointer=new Timer();
Timer local tmrCopy=new Timer();
Timer local tmrRestrict=new Timer();
T [SPACE_DIM d] tiArrayB;
T [SPACE_DIM d] local tiArrayBLocal;
public inline BoxedArray(RectDomain a_box){
m_array=new T [a_box];
//foreach (point in box) m_array[point]=new T();
m_domain=a_box;
}
public inline BoxedArray(RectDomain a_box, PrivateRegion local a_region){
m_array=new (a_region)T [a_box];
//foreach (point in box) m_array[point]=new T();
m_domain=a_box;
}
public final inline RectDomain domain(){
return m_domain;
}
public final inline T[SPACE_DIM d] getArray(){
return m_array;
}
public final inline local T[SPACE_DIM d] local getLocalArray(){
return m_array;
}
/**methods for exchange: getting values for the ghost cells from my neighbors. Only called from BoxLayoutData.**/
final inline local void buildNeighborInfoCache(int a_numOfNeighbors){
//if (m_neighborSize==0){
m_neighborSize=a_numOfNeighbors;
m_neighborIsLocal=new boolean [m_neighborSize];
m_neighbors=new T [0:m_neighborSize-1] local [SPACE_DIM d];
m_neighborsDomain=new RectDomain [m_neighborSize];
//}
//else
//Util.printErrMsg("BoxedArray::fillNeighborInfoCache(): the cache has already been build!");
}
final inline local void fillNeighborInfoCache(template BoxedArray a_BA, RectDomain a_RD, int a_idx, boolean a_isLocal){
//if (m_neighborSize>0){
m_neighborIsLocal[a_idx]=a_isLocal;
/*m_neighbors[a_idx]=a_BA.m_array;*/
if (a_isLocal)
m_neighbors[a_idx]=a_BA.m_array;
else
m_neighbors[a_idx]=a_BA.m_array.restrict(a_RD);
m_neighborsDomain[a_idx]=a_RD;
//}
//else
//Util.printErrMsg("BoxedArray::fillNeighborInfoCache(): the cache has not been build yet!");
}
final inline local void exchange(){
tmrCopy.reset();tmrRestrict.reset();
for (int i=0;i local op+=(template BoxedArray local a_BA){
box=m_domain*a_BA.domain();
foreach (point in box) m_array[point]+=a_BA.m_array[point];
return this;
}
public final inline local template BoxedArray local op-=(template BoxedArray local a_BA){
box=m_domain*a_BA.domain();
foreach (point in box) m_array[point]-=a_BA.m_array[point];
return this;
}
public final inline local template BoxedArray local op*=(double a_db){
foreach (point in m_domain) m_array[point]*=(T )a_db;
return this;
}
public final inline local template BoxedArray local op<<=(double a_db){
foreach (point in m_domain) m_array[point]=(T )a_db;
return this;
}
public final inline local template BoxedArray local op<<=(template BoxedArray local a_BA){
box=m_domain*a_BA.domain();
foreach (point in box) m_array[point]=a_BA.m_array[point];
return this;
}
public final inline local double dotProduct(template BoxedArray local a_BA){
double result=0;
box=m_domain*a_BA.m_domain;
foreach (point in box) result+=(m_array[point]*a_BA.m_array[point]);
return result;
}
public final inline local void setByDouble(double a_db, RectDomain a_box){
a_box=a_box*m_domain;
foreach (point in a_box) m_array[point]=(T )a_db;
}
/*final inline local void set(template BoxedArray local a_BA, RectDomain a_box){
foreach (point in a_box) m_array[point]=a_BA.m_array[point];
}*/
public final inline local void setBySum(template BoxedArray local a_BA1, template BoxedArray local a_BA2 ){
box=m_domain*a_BA1.domain()*a_BA2.domain();
foreach (point in box) m_array[point]=a_BA1.m_array[point]+a_BA2.m_array[point];
}
public final inline local void setByRemainder(template BoxedArray local a_BA1, template BoxedArray local a_BA2 ){
box=m_domain*a_BA1.domain()*a_BA2.domain();
foreach (point in box) m_array[point]=a_BA1.m_array[point]-a_BA2.m_array[point];
}
public final inline local T op[](Point point){
return m_array[point];
}
public final inline local double norm(){
double result=0;
foreach (point in m_domain) result+=Math.pow(m_array[point],2);
return Math.sqrt(result);
}
public final inline local void copy(template BoxedArray from_BA, RectDomain from_domain, RectDomain to_domain){
T [SPACE_DIM d] local tiArrayA=m_array.restrict(to_domain);
/*T [SPACE_DIM d] tiArrayB=from_BA.getArray().restrict(from_domain);
tiArrayA.copy(tiArrayB);*/
tiArrayA.copy(from_BA.getArray().restrict(from_domain));
}
public final inline local void copy(template BoxedArray from_BA, RectDomain from_domain){
/*T [SPACE_DIM d] tiArrayB=from_BA.getArray().restrict(from_domain);
m_array.copy(tiArrayB);*/
m_array.copy((from_BA.m_array).restrict(from_domain));
/*
tmrPointer.start();tiArrayB=from_BA.m_array;tmrPointer.stop();Util.countPointer+=tmrPointer.millis();tmrPointer.reset();
tmrRestrict.start();tiArrayB=tiArrayB.restrict(from_domain);tmrRestrict.stop();Util.countRestrict+=tmrRestrict.millis();tmrRestrict.reset();
tmrCopy.start();m_array.copy(tiArrayB);tmrCopy.stop();Util.countTiCopy+=tmrCopy.millis();tmrCopy.reset();
*/
}
public final inline local void copy(template BoxedArray from_BA){
/*T [SPACE_DIM d] tiArrayB=from_BA.getArray();
m_array.copy(tiArrayB);*/
m_array.copy(from_BA.getArray());
}
/** "foreach" loop should be slower than bulk copy. However, this is not the case for current version.
* That is the reason why we distinguish copy and local copy operations here.
*/
public final inline local void localCopy(template BoxedArray local from_BA, RectDomain from_domain, RectDomain to_domain){
//T [SPACE_DIM d] local tiArrayB=from_BA.getLocalArray();
box=from_domain*to_domain;
foreach (point in box) m_array[point]=from_BA.m_array[point];
}
public final inline local void localCopy(template BoxedArray local from_BA, RectDomain from_domain){
//T [SPACE_DIM d] local tiArrayB=from_BA.getLocalArray();
box=from_domain*m_domain; //Exchange Version 1: comment it out if Exchange ghost region cached!.
foreach (point in box) m_array[point]=from_BA.m_array[point]; //Exchange Version 1:
//foreach (point in from_domain) m_array[point]=from_BA.m_array[point];//Exchange Version 2.
//tmrCopy.start();
//T [SPACE_DIM d] local tiArrayB=from_BA.getLocalArray().restrict(from_domain);
//m_array.copy(tiArrayB);
//tmrCopy.stop();Util.addCountCopy(tmrCopy.millis());tmrCopy.reset();
//m_array.copy(from_BA.getArray().restrict(from_domain));
}
public final inline local void localCopy(template BoxedArray local from_BA){
//T [SPACE_DIM d] local tiArrayB=from_BA.getLocalArray();
box=m_domain*from_BA.domain();
foreach (point in box) m_array[point]=from_BA.m_array[point];
//m_array.copy(from_BA.getLocalArray());
}
/*
public final local void setValue(RectDomain a_box, template Function a_function){
foreach (point in a_box) m_array[point]=a_function.value(point);
}
*/
}