$treeview $search $mathjax
|
Palabos
Version 1.1
$projectbrief
|
$projectbrief
|
$searchbox |
00001 /* This file is part of the Palabos library. 00002 * 00003 * Copyright (C) 2011 FlowKit Sarl 00004 * Avenue de Chailly 23 00005 * 1012 Lausanne, Switzerland 00006 * E-mail contact: contact@flowkit.com 00007 * 00008 * The most recent release of Palabos can be downloaded at 00009 * <http://www.palabos.org/> 00010 * 00011 * The library Palabos is free software: you can redistribute it and/or 00012 * modify it under the terms of the GNU Affero General Public License as 00013 * published by the Free Software Foundation, either version 3 of the 00014 * License, or (at your option) any later version. 00015 * 00016 * The library is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU Affero General Public License for more details. 00020 * 00021 * You should have received a copy of the GNU Affero General Public License 00022 * along with this program. If not, see <http://www.gnu.org/licenses/>. 00023 */ 00024 00025 #ifndef MAKE_SPARSE_3D_HH 00026 #define MAKE_SPARSE_3D_HH 00027 00028 #include "core/globalDefs.h" 00029 #include "offLattice/makeSparse3D.h" 00030 #include "parallelism/mpiManager.h" 00031 #include "atomicBlock/reductiveDataProcessingFunctional3D.h" 00032 #include "atomicBlock/atomicContainerBlock3D.h" 00033 #include "offLattice/domainClustering3D.h" 00034 00035 00036 namespace plb { 00037 00038 struct FlagData3D : public ContainerBlockData { 00039 bool keepThisBlock; 00040 virtual FlagData3D* clone() const { 00041 return new FlagData3D(*this); 00042 } 00043 }; 00044 00045 /* ******** ComputeSparsityFunctional3D ************************************ */ 00046 00047 template<typename T> 00048 ComputeSparsityFunctional3D<T>::ComputeSparsityFunctional3D() 00049 : numBlocksId(this->getStatistics().subscribeIntSum()) 00050 { } 00051 00052 template<typename T> 00053 void ComputeSparsityFunctional3D<T>::processGenericBlocks ( 00054 Box3D domain, std::vector<AtomicBlock3D*> blocks ) 00055 { 00056 PLB_PRECONDITION( blocks.size()==2 ); 00057 ScalarField3D<T>* field = dynamic_cast<ScalarField3D<T>*>(blocks[0]); 00058 AtomicContainerBlock3D* container = dynamic_cast<AtomicContainerBlock3D*>(blocks[1]); 00059 PLB_ASSERT( field ); 00060 PLB_ASSERT( container ); 00061 bool exclusivelyEliminateCells = true; 00062 for (plint iX=domain.x0; iX<=domain.x1; ++iX) { 00063 for (plint iY=domain.y0; iY<=domain.y1; ++iY) { 00064 for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) { 00065 if (field->get(iX,iY,iZ) != 0) { 00066 exclusivelyEliminateCells = false; 00067 } 00068 } 00069 } 00070 } 00071 FlagData3D* flagData = new FlagData3D; 00072 if (exclusivelyEliminateCells) { 00073 flagData->keepThisBlock = false; 00074 this->getStatistics().gatherIntSum(numBlocksId, 1); 00075 } 00076 else { 00077 flagData->keepThisBlock = true; 00078 } 00079 container->setData(flagData); 00080 } 00081 00082 template<typename T> 00083 ComputeSparsityFunctional3D<T>* ComputeSparsityFunctional3D<T>::clone() const { 00084 return new ComputeSparsityFunctional3D<T>(*this); 00085 } 00086 00087 template<typename T> 00088 void ComputeSparsityFunctional3D<T>::getTypeOfModification(std::vector<modif::ModifT>& modified) const { 00089 modified[0] = modif::nothing; // Scalar Field. 00090 modified[1] = modif::staticVariables; // Container Block with flag data. 00091 } 00092 00093 template<typename T> 00094 BlockDomain::DomainT ComputeSparsityFunctional3D<T>::appliesTo() const { 00095 return BlockDomain::bulk; 00096 } 00097 00098 template<typename T> 00099 pluint ComputeSparsityFunctional3D<T>::getNumBlocks() const { 00100 return this->getStatistics().getIntSum(numBlocksId); 00101 } 00102 00103 00104 /* ******** computeSparseManagement ************************************ */ 00105 00106 template<typename T> 00107 MultiBlockManagement3D computeSparseManagement ( 00108 MultiScalarField3D<T>& field, plint newEnvelopeWidth ) 00109 { 00110 MultiContainerBlock3D multiFlagBlock(field); 00111 std::vector<MultiBlock3D*> args; 00112 args.push_back(&field); 00113 args.push_back(&multiFlagBlock); 00114 ComputeSparsityFunctional3D<T> sparsityFunctional; 00115 applyProcessingFunctional ( 00116 sparsityFunctional, field.getBoundingBox(), args ); 00117 00118 MultiBlockManagement3D const& management = multiFlagBlock.getMultiBlockManagement(); 00119 ThreadAttribution const& threadAttribution = management.getThreadAttribution(); 00120 SparseBlockStructure3D const& sparseBlock = management.getSparseBlockStructure(); 00121 00122 std::map<plint,Box3D> const& domains = sparseBlock.getBulks(); 00123 std::vector<plint> domainIds(domains.size()); 00124 std::vector<int> keepThisBlock(domains.size()); 00125 00126 std::map<plint,Box3D>::const_iterator it = domains.begin(); 00127 plint pos = 0; 00128 for (; it != domains.end(); ++it) { 00129 plint id = it->first; 00130 domainIds[pos] = id; 00131 if (threadAttribution.isLocal(id)) { 00132 AtomicContainerBlock3D const& flagBlock = multiFlagBlock.getComponent(id); 00133 FlagData3D const* data = 00134 dynamic_cast<FlagData3D const*> (flagBlock.getData()); 00135 PLB_ASSERT( data ); 00136 keepThisBlock[pos] = data->keepThisBlock ? 1:0; 00137 } 00138 else { 00139 keepThisBlock[pos] = 0; 00140 } 00141 ++pos; 00142 } 00143 00144 #ifdef PLB_MPI_PARALLEL 00145 std::vector<int> tmp(keepThisBlock.size()); 00146 global::mpi().reduceVect(keepThisBlock, tmp, MPI_SUM); 00147 global::mpi().bCast(&tmp[0], tmp.size()); 00148 tmp.swap(keepThisBlock); 00149 #endif 00150 00151 SparseBlockStructure3D newSparseBlock(field.getBoundingBox()); 00152 plint newId = 0; 00153 for (pluint iBlock=0; iBlock<keepThisBlock.size(); ++iBlock) { 00154 if (keepThisBlock[iBlock]) { 00155 plint id = domainIds[iBlock]; 00156 Box3D bulk, uniqueBulk; 00157 sparseBlock.getBulk(id, bulk); 00158 sparseBlock.getUniqueBulk(id, uniqueBulk); 00159 newSparseBlock.addBlock(bulk, uniqueBulk, newId++); 00160 } 00161 } 00162 // If this assertion fails, that means that the domain covered 00163 // by the sparse block-structure is empty. 00164 PLB_ASSERT( newId>0 ); 00165 00166 ExplicitThreadAttribution* newAttribution = new ExplicitThreadAttribution; 00167 std::vector<std::pair<plint,plint> > ranges; 00168 plint numRanges = std::min(newId, (plint)global::mpi().getSize()); 00169 util::linearRepartition(0, newId-1, numRanges, ranges); 00170 00171 std::vector<plint> localBlocks; 00172 for (pluint iProc=0; iProc<ranges.size(); ++iProc) { 00173 for (plint blockId=ranges[iProc].first; blockId<=ranges[iProc].second; ++blockId) { 00174 newAttribution -> addBlock(blockId, iProc); 00175 if (iProc==(pluint)global::mpi().getRank()) { 00176 localBlocks.push_back(blockId); 00177 } 00178 } 00179 } 00180 00181 MultiBlockManagement3D newManagement ( 00182 newSparseBlock, newAttribution, 00183 newEnvelopeWidth, 00184 management.getRefinementLevel() ); 00185 return newManagement; 00186 } 00187 00188 } // namespace plb 00189 00190 #endif // MAKE_SPARSE_3D_HH 00191
1.6.3
1.6.3