//------------------------------------------------------------
// $Id: volumeSet.h,v 1.1.1.1 1999/11/25 06:26:10 yamauchi Exp $
//------------------------------------------------------------
// 	volume set (objectSetClass から) 
//	(M\pi)^2 
//
//	volume を PE で保持する際に利用するクラス。
//	引数に空間(大域的な空間ではない。このクラスの管理する大きさの
//	配列の index。このクラスは PE のトポロジなどは知らない) の 
//	index を与えるとその空間に属する物体の配列が得られる
// 	実装は空間と速度のトレードオフで変化する予定
//	まずは1次元の配列による
//	objectSet と似ているので template 化を考えるべきだったか? 
//	1998/2/9
//	Copyright (C) 1996--1998 YAMAUCHI Hitoshi 山内 斉
//------------------------------------------------------------
#ifndef _volumeSet_h
#define _volumeSet_h 1

#include "SLList.h"
// #include "mpi2.h"
#include "volume.h"
#include "mpi2exit.h"

class VolumeSetClass {
protected:
    IntVec3 	mLocalSpcNum;	// この volume セットが担当する空間の数
    // 				// 全空間分割数の (1 / PE 数)
    SLList < VolumeClass * > *mpVolList; // volume へのポインタのリストの配列
    
protected:
    void delElems(void)
    {
	if(this->mpVolList != NULL)
	{
	    delete [] this->mpVolList;	    
	}
	this->mpVolList = NULL;	    	
	this->mLocalSpcNum = IllegalPEID;	// set(-2, -2, -2);	
    }
    YorN localIdxOK(const IntVec3& localIdx) const
    {
	if((0 <= localIdx.get(IntVec3::X)) &&
	   (0 <= localIdx.get(IntVec3::Y)) &&
	   (0 <= localIdx.get(IntVec3::Z)) &&
	   (localIdx.get(IntVec3::X) < this->mLocalSpcNum.get(IntVec3::X)) &&
	   (localIdx.get(IntVec3::Y) < this->mLocalSpcNum.get(IntVec3::Y)) &&
	   (localIdx.get(IntVec3::Z) < this->mLocalSpcNum.get(IntVec3::Z)))
	{
	    return(YES);
	}else
	{
	    cout << "Error! :: VolumeSetClass::idxOK idx = " << localIdx << 
		", total space num = " << this->mLocalSpcNum << endl;
	    abort();
	    commMpi2_exit(1);
	    return(NO);
	}
    }
    int  getLocalIdxFromLocalXYZ(int x, int y, int z) const
    {
	return(z * this->mLocalSpcNum.get(IntVec3::Y) * 
	       this->mLocalSpcNum.get(IntVec3::X) +
	       y * this->mLocalSpcNum.get(IntVec3::X) +
	       x);
    }
public:
    VolumeSetClass(void) : mpVolList(NULL) {}
    ~VolumeSetClass(void){ this->delElems();	}
    void init(const IntVec3& aLocalTotalSpcNum);
    void add(const IntVec3& a3dIdx, VolumeClass* pVol);
    SLList < VolumeClass * > *getList(const IntVec3& a3dIdx);
    SLList < VolumeClass * > *getListAs1DimArray(int innerIndex); // 全調査用
    void getAllElementAsList(SLList < VolumeClass * > * pRetList);
    IntVec3 getTotalLocalSpaceIntVec3(void)const{ return(this->mLocalSpcNum); }
    int getTotalLocalSpaceNum(void) const;
    void print(void);
    
};


#endif				// #ifdef _volumeSet_h
