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 BoxedArrays. * @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); } */ }