Commit 61aa139a authored by COULAUD Olivier's avatar COULAUD Olivier

Add a template of the adaptive algorithm

parent 477d550c
// ===================================================================================
// Copyright ScalFmm 2011 INRIA, Olivier Coulaud, Berenger Bramas
// olivier.coulaud@inria.fr, berenger.bramas@inria.fr
// This software is a computer program whose purpose is to compute the FMM.
//
// This software is governed by the CeCILL-C and LGPL licenses and
// abiding by the rules of distribution of free software.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public and CeCILL-C Licenses for more details.
// "http://www.cecill.info".
// "http://www.gnu.org/licenses".
// ===================================================================================
#ifndef FADAPTCELL_HPP
#define FADAPTCELL_HPP
#include <cstddef>
#include <vector>
//
#include "Components/FBasicCell.hpp"
#include "Containers/FVector.hpp"
/**
* @author Olivier Coulaud (Olivier.Coulaud@inria.fr)
* @class FAdaptCell*
* @brief This class defines adaptive cell.
*
* ToDO
*
*/
//class FAdaptCell;
template <class CellClass, class LeafClass>
class FAdaptCell : public FBasicCell {
public:
struct FExtACell {
FAdaptCell<CellClass, LeafClass> * cell ;
int level ; //< Level in the octree of cell
FExtACell() { cell=nullptr ; level =-1 ; } ;
};
protected:
// Global Index of the cell in the octree (This id is unique)
long int gID;
//! Number of particles inside the cell
int nbP ;
//! iAdaptive cell True, false
bool adaptive ;
bool sminMCriteria;
//
// Lists
//
FExtACell adaptiveParent ; //< adaptive Parent of the cell
FVector<FExtACell> adaptiveChild ; //< list of adaptive child of the cell
FVector<LeafClass*> leaves ; //< list of leaf child of the cell
//
//
CellClass * trueFMMCell ; //<a pointer on the cell that contains Multipole and local values
public:
FAdaptCell(): gID(-1), nbP(0), adaptive(false),trueFMMCell(nullptr) {
}
/** Default destructor */
virtual ~FAdaptCell(){
}
//! add nbPart in cell
void addPart(const int n){
this->nbP += n ;
}
//! Return the number of particles inside the cell
const int getnbPart() const{
return this->nbP ;
}
//!return true if the sminM criteria is satisfied
bool isSminMCriteria (){
return this->sminMCriteria;
}
//!return true if the sminM criteria is satisfied
bool isSminMCriteria () const{
return this->sminMCriteria;
}
//! Set if the cell is adaptive or not
void setSminMCriteria(const bool bb=true){
this->sminMCriteria=bb ;
}
//! 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; ;
}
//! Set if the cell is adaptive or not
void setCelladaptive(const bool bb=true){
this->adaptive = bb;
}
//!return true if the cell is adaptive
const bool isadaptive() const{
return this->adaptive;
}
//
//! Add the adaptive parent of the cell
void addadaptiveParent( const FExtACell &ac) {
this->adaptiveParent.cell = ac.cell ;
this->adaptiveParent.level = ac.level ;
// std::cout << " addadaptiveParent " << *(this) <<std::endl;
}
//
//! Add the adaptive child of the cell
void addadaptiveParent( FAdaptCell<CellClass, LeafClass> * cell ,const int idxLevel) {
this->adaptiveParent.cell = cell ; this->adaptiveParent.level = idxLevel ;
}
FExtACell getadaptiveFather() {
return this->adaptiveParent ;
}
FExtACell getadaptiveFather() const {
return this->adaptiveParent ;
}
//
//! Add the adaptive child of the cell
void addadaptiveChild( FAdaptCell<CellClass, LeafClass> * cell ,const int idxLevel) {
FExtACell AC ;
AC.cell = cell ; AC.level = idxLevel ;
this->adaptiveChild.push(AC);
}
//
//! Add the adaptive child of the cell
void addadaptiveChild( const FExtACell &AC){
this->adaptiveChild.push(AC) ;
}
int sizeofadaptiveChild() const{
return this->adaptiveChild.getSize();
}
FVector<FExtACell>* getadaptiveChild(){
return &this->adaptiveChild;
}
const FVector<FExtACell>* getadaptiveChild() const{
return &this->adaptiveChild;
}
FExtACell* getAdaptiveChild(const int i) {
return &this->adaptiveChild[0];
}
//
//! Add the adaptive child of the cell
void addLeafptr( LeafClass * leaf) {
this->leaves.push(leaf) ;
}
//! Return the number of leaves
int getLeavesSize() const{
return this->leaves.getSize();
}
//! Return the number of leaves
LeafClass* getLeaf(const int i ) {
return this->leaves[i];
}
//! Return the number of leaves
LeafClass* getLeaf(const int i ) const {
return this->leaves[i];
}
/** Make it like the beginning */
void resetToInitialState(){
//this->dataDown = 0;
//this->dataUp = 0;
this->nbP = 0 ;
}
/////////////////////////////////////////////////
/** Save the current cell in a buffer */
template <class BufferWriterClass>
void save(BufferWriterClass& buffer) const{
FBasicCell::save(buffer);
//buffer << dataDown << dataUp << nbP;
}
/** Restore the current cell from a buffer */
template <class BufferReaderClass>
void restore(BufferReaderClass& buffer){
FBasicCell::restore(buffer);
// buffer >> dataDown >> dataUp >> nbP;
}
/////////////////////////////////////////////////
/** Serialize only up data in a buffer */
template <class BufferWriterClass>
void serializeUp(BufferWriterClass& buffer) const {
//buffer << this->dataUp;
}
/** Deserialize only up data in a buffer */
template <class BufferReaderClass>
void deserializeUp(BufferReaderClass& buffer){
//buffer >> this->dataUp;
}
/** Serialize only down data in a buffer */
template <class BufferWriterClass>
void serializeDown(BufferWriterClass& buffer) const {
//buffer << this->dataDown;
}
/** Deserialize only up data in a buffer */
template <class BufferReaderClass>
void deserializeDown(BufferReaderClass& buffer){
//buffer >> this->dataDown;
}
/**
* 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 FAdaptCell<CellClass,LeafClass>& cell){
output << "( Cell Id " << cell.getGlobalId() << " Adpatative " << std::boolalpha << cell.isadaptive()
<< " sminM " << cell.isSminMCriteria()<< " "<< cell.getnbPart() ;
if(cell.getLeavesSize() >0){
output << " LF={" ;
for (int i=0; i <cell.getLeavesSize() ; ++i){
output << cell.getLeaf(i) << " ";
}
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={} " ;
}
output << " )" <<std::endl;
return output; // for multiple << operators.
}
};
#endif //FADAPTCELL_HPP
This diff is collapsed.
This diff is collapsed.
// ===================================================================================
// Copyright ScalFmm 2011 INRIA, Olivier Coulaud, Bérenger Bramas, Matthias Messner
// Copyright ScalFmm 2011 INRIA, Olivier Coulaud, Berenger Bramas, Matthias Messner
// olivier.coulaud@inria.fr, berenger.bramas@inria.fr
// This software is a computer program whose purpose is to compute the FMM.
//
......@@ -1039,6 +1039,48 @@ public:
return idxNeighbors;
}
/** This function fill an array with the neighbors of a cell
* @param inNeighbors the array to store the elements
* @param inIndex the index of the element we want the neighbors
* @param inLevel the level of the element
* @return the number of neighbors
*/
int getLeafsNeighbors(const CellClass* inNeighbors[27], const FTreeCoordinate& center, const int inLevel){
memset( inNeighbors, 0 , 27 * sizeof(CellClass*));
const int boxLimite = FMath::pow2(inLevel);
int idxNeighbors = 0;
// We test all cells around
for(int idxX = -1 ; idxX <= 1 ; ++idxX){
if(!FMath::Between(center.getX() + idxX,0,boxLimite)) continue;
for(int idxY = -1 ; idxY <= 1 ; ++idxY){
if(!FMath::Between(center.getY() + idxY,0,boxLimite)) continue;
for(int idxZ = -1 ; idxZ <= 1 ; ++idxZ){
if(!FMath::Between(center.getZ() + idxZ,0,boxLimite)) continue;
// if we are not on the current cell
if( idxX || idxY || idxZ ){
const FTreeCoordinate other(center.getX() + idxX,center.getY() + idxY,center.getZ() + idxZ);
const MortonIndex mortonOther = other.getMortonIndex(inLevel);
// get cell
// ContainerClass* const leaf = getLeafSrc(mortonOther);
CellClass** const leaf = getCellPt(mortonOther, inLevel);
// add to list if not null
if(leaf){
inNeighbors[(((idxX + 1) * 3) + (idxY +1)) * 3 + idxZ + 1] = leaf;
++idxNeighbors;
}
}
}
}
}
return idxNeighbors;
}
/** This function fill an array with the neighbors of a cell
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment