FAdaptiveCell.hpp 6.22 KB
Newer Older
1 2
#ifndef FAdaptiveCELL
#define FAdaptiveCELL
3

4
#include "Components/FBasicCell.hpp"
5 6

/**
7
 * This class is a wrapper to work with adaptive kernel
8
 * It contains a pointer to the real computation cell but use it only if
9
 * the cell is adaptive AND has been use for development.
10
 *
11 12 13 14
 * A cell is adaptive if:
 *  - it has more than one child
 *  -  it used for development
 *  -  it is use to store the leaves
15 16 17
 * Else it stores a pointer to the lower adaptive cell.
 */
template <class RealCell, class ContainerClass>
18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
class FAdaptiveCell : public FBasicCell {
	/** The cell used for the computation */
	RealCell* realCell;
	/** To keep track of the cell state */
	bool IamAdaptive;

	/** If not adaptive then we need to know the lower adaptive cell */
	FAdaptiveCell<RealCell, ContainerClass>* subAdaptiveCell;
	/** The lower adaptive cell level */
	int subAdaptiveLevel;

	/** The leaves that have been skiped for the P2M/M2M... */
	FVector<ContainerClass*> subLeaves;
	//
	// Global Index of the cell in the octree (This id is unique)
	long int gID;
34 35

public:
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210
	/** Set has not Adaptive by default */
	FAdaptiveCell() : realCell(nullptr), IamAdaptive(false), subAdaptiveCell(nullptr), subAdaptiveLevel(0),gID(0){
	}

	~FAdaptiveCell(){
		if (realCell) delete realCell;
	}

	void resetToInitialState(){
		subLeaves.clear();
		if(realCell){
			realCell->resetToInitialState();
		}
	}

	////////////////////////////////////////////////////////////////////////////////
	/// Get the real cell
	////////////////////////////////////////////////////////////////////////////////

	/** To say if it is used for development or not */
	void setHaveDevelopment(const bool inHaveDevelopment) {
		if(inHaveDevelopment && !realCell){
			// alloc and init the real cell
			realCell = new RealCell;
			realCell->setMortonIndex(this->getMortonIndex());
			realCell->setCoordinate(this->getCoordinate());
			// clean other information
			subAdaptiveCell  = nullptr;
			subAdaptiveLevel = 0;
			subLeaves.clear();
		}
		else if(!inHaveDevelopment && realCell){
			// clean real cell if needed
			delete realCell;
			realCell = nullptr;
		}
	}

	bool hasDevelopment() const{
		return realCell != nullptr;
	}

	RealCell* getRealCell(){
		return realCell;
	}

	const RealCell* getRealCell() const {
		return realCell;
	}

	////////////////////////////////////////////////////////////////////////////////
	/// Set Adaptive
	////////////////////////////////////////////////////////////////////////////////

	bool isAdaptive() const {
		return IamAdaptive;
	}

	void setAdaptive(const bool inIsAdaptive) {
		IamAdaptive = inIsAdaptive;
	}

	////////////////////////////////////////////////////////////////////////////////
	/// Manage the sub leaves
	////////////////////////////////////////////////////////////////////////////////

	void addSubLeaf(const ContainerClass* aLeaf){
		subLeaves.push(const_cast<ContainerClass*>(aLeaf));
	}

	void addSubLeaf(ContainerClass* aLeaf){
		subLeaves.push(aLeaf);
	}

	void addSubLeaves(const ContainerClass*const* aLeavesToInsert, const int nbLeavesToInsert){
		subLeaves.memocopy(const_cast<ContainerClass*const*>(aLeavesToInsert),nbLeavesToInsert);
	}

	int getNbSubLeaves() const {
		return subLeaves.getSize();
	}

	ContainerClass* const * getSubLeaves() {
		return subLeaves.data();
	}

	const ContainerClass * const * getSubLeaves() const{
		return subLeaves.data();
	}

	ContainerClass* getSubLeaf(const int leafIdx) const{
		return subLeaves[leafIdx];
	}

	////////////////////////////////////////////////////////////////////////////////
	/// Manage the sub cell
	////////////////////////////////////////////////////////////////////////////////

	void setSubAdaptiveCell(FAdaptiveCell<RealCell,ContainerClass>* inSubAdaptiveCell, const int inSubAdaptiveLevel){
		subAdaptiveCell  = inSubAdaptiveCell;
		subAdaptiveLevel = inSubAdaptiveLevel;
	}

	void setSubAdaptiveCell(const FAdaptiveCell<RealCell,ContainerClass>* inSubAdaptiveCell, const int inSubAdaptiveLevel){
		subAdaptiveCell  = const_cast<FAdaptiveCell<RealCell,ContainerClass>*>(inSubAdaptiveCell);
		subAdaptiveLevel = inSubAdaptiveLevel;
	}

	FAdaptiveCell<RealCell,ContainerClass>* getSubAdaptiveCell() {
		return subAdaptiveCell;
	}

	FAdaptiveCell<RealCell,ContainerClass>* getSubAdaptiveCell() const {
		return subAdaptiveCell;
	}

	int getSubAdaptiveLevel() const {
		return subAdaptiveLevel;
	}
	//#ifdef DEBUG_ADAPTIVE
	////////////////////////////////////////////////////////////////////////////////
	/// Manage a global IG DEBUG PURPOSE
	////////////////////////////////////////////////////////////////////////////////
	//! Return the global Id of the cell in the octree
	const long int  getGlobalId(){
		return this->gID ;
	}
	const long int  getGlobalId( ) const{
		return this->gID ;
	}
	//!  Set he global Id of the cell in the octree to id
	void setGlobalId(const long int & id){
		this->gID = id;  ;
	}
	//#endif
	/**
	 * Operator stream FAdaptCell to std::ostream
	 *
	 * @param[in,out] output where to write the adaptive cell
	 * @param[in] inPosition the cell to write out
	 * @return the output for multiple << operators
	 */
	template <class StreamClass>
	friend StreamClass& operator<<(StreamClass& output, const FAdaptiveCell<RealCell,  ContainerClass>&  cell){
		output << "(  Cell Id " << cell.getGlobalId()  << " Adaptive  " <<  std::boolalpha << cell.isAdaptive()
								<< "  sminM " << " cell.isSminMCriteria() "<< " "<< cell.getNbSubLeaves()  ;
		if(cell.getNbSubLeaves() >0){
			output << " LF = { " ;
			for (int i=0; i	 <cell.getNbSubLeaves()  ; ++i){
				output <<cell.getSubLeaf(i)->getNbParticles() << " ";
			}
			output << "}" ;
		}
		//		output <<" CA={ ";
		//		const FVector<FExtACell>  * v =cell.getadaptiveChild() ;
		//		if (cell.sizeofadaptiveChild()> 0 ){
		//			for (int i=0; i < v->getSize() ; ++i){
		//				output << v->operator [](i).cell->getGlobalId() << " ";
		//			}
		//		}
		//		output << "} " ;
		//		if(cell.getadaptiveFather().cell){
		//			output << " FA={" << (cell.getadaptiveFather()).cell->getGlobalId() << "} " ;
		//		}
		//		else
		//		{
		//			output <<  "   FA={} " ;
		//		}
		if(cell.hasDevelopment()){
			output <<*(cell.getRealCell()) ;
		}
		//	output << std::endl << "    Multipoles " << *(cell.getRealCell()) << std::endl;
		output << " )"	<<std::endl;
		return output;  // for multiple << operators.
	}
211 212 213
};

#endif