$treeview $search $mathjax
Palabos  Version 1.1
$projectbrief
$projectbrief
$searchbox

offLatticeModel3D.hh

Go to the documentation of this file.
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 OFF_LATTICE_MODEL_3D_HH
00026 #define OFF_LATTICE_MODEL_3D_HH
00027 
00028 #include "offLattice/offLatticeModel3D.h"
00029 #include "latticeBoltzmann/geometricOperationTemplates.h"
00030 #include "latticeBoltzmann/externalFieldAccess.h"
00031 #include <algorithm>
00032 #include <cmath>
00033 
00034 namespace plb {
00035 
00036 template<typename T, class SurfaceData>
00037 OffLatticeModel3D<T,SurfaceData>::OffLatticeModel3D (
00038         BoundaryShape3D<T,SurfaceData>* shape_, int flowType_ )
00039     : shape(shape_),
00040       flowType(flowType_),
00041       velIsJflag(false),
00042       partialReplaceFlag(false)
00043 {
00044     PLB_ASSERT(flowType==voxelFlag::inside || flowType==voxelFlag::outside);
00045 }
00046 
00047 template<typename T, class SurfaceData>
00048 OffLatticeModel3D<T,SurfaceData>::OffLatticeModel3D (
00049         OffLatticeModel3D<T,SurfaceData> const& rhs )
00050     : shape(rhs.shape->clone()),
00051       flowType(rhs.flowType),
00052       velIsJflag(rhs.velIsJflag),
00053       partialReplaceFlag(rhs.partialReplaceFlag)
00054 { }
00055 
00056 template<typename T, class SurfaceData>
00057 OffLatticeModel3D<T,SurfaceData>& OffLatticeModel3D<T,SurfaceData>::operator= (
00058         OffLatticeModel3D<T,SurfaceData> const& rhs )
00059 {
00060     delete shape;
00061     shape = rhs.shape->clone();
00062     flowType = rhs.flowType;
00063     velIsJflag = rhs.velIsJflag;
00064     partialReplaceFlag = rhs.partialReplaceFlag;
00065 }
00066 
00067 template<typename T, class SurfaceData>
00068 OffLatticeModel3D<T,SurfaceData>::~OffLatticeModel3D() {
00069     delete shape;
00070 }
00071 
00072 template<typename T, class SurfaceData>
00073 void OffLatticeModel3D<T,SurfaceData>::provideShapeArguments (
00074             std::vector<AtomicBlock3D*> args )
00075 {
00076     BoundaryShape3D<T,SurfaceData>* newShape=shape->clone(args);
00077     std::swap(shape, newShape);
00078     delete newShape;
00079 }
00080 
00081 template<typename T, class SurfaceData>
00082 plint OffLatticeModel3D<T,SurfaceData>::getTag(plint id) const {
00083     return shape->getTag(id);
00084 }
00085 
00086 template<typename T, class SurfaceData>
00087 bool OffLatticeModel3D<T,SurfaceData>::pointOnSurface (
00088         Dot3D const& fromPoint, Dot3D const& direction,
00089         Array<T,3>& locatedPoint, T& distance,
00090         Array<T,3>& wallNormal, SurfaceData& surfaceData,
00091         OffBoundary::Type& bdType, plint& id ) const
00092 {
00093     return shape->gridPointOnSurface (
00094                fromPoint, direction, locatedPoint, distance, wallNormal, surfaceData, bdType, id );
00095 }
00096 
00097 template<typename T, class SurfaceData>
00098 Array<T,3> OffLatticeModel3D<T,SurfaceData>::computeContinuousNormal (
00099             Array<T,3> const& p, plint id, bool isAreaWeighted ) const
00100 {
00101     return shape->computeContinuousNormal(p, id, isAreaWeighted);
00102 }
00103 
00104 template<typename T, class SurfaceData>
00105 bool OffLatticeModel3D<T,SurfaceData>::intersectsSurface (
00106         Dot3D const& p1, Dot3D const& p2, plint& id ) const
00107 {
00108     return shape->intersectsSurface(p1, p2, id);
00109 }
00110 
00111 template<typename T, class SurfaceData>
00112 bool OffLatticeModel3D<T,SurfaceData>::isFluid(Dot3D const& location) const
00113 {
00114     if (flowType==voxelFlag::inside) {
00115         return shape->isInside(location);
00116     }
00117     else {
00118         return !shape->isInside(location);
00119     }
00120 }
00121 
00122 template<typename T, template<typename U> class Descriptor, class SurfaceData>
00123 OffLatticeCompletionFunctional3D<T,Descriptor,SurfaceData>::OffLatticeCompletionFunctional3D (
00124         OffLatticeModel3D<T,SurfaceData>* offLatticeModel_,
00125         plint numShapeArgs_, plint numCompletionArgs_ )
00126   : offLatticeModel(offLatticeModel_),
00127     numShapeArgs(numShapeArgs_),
00128     numCompletionArgs(numCompletionArgs_)
00129 { }
00130 
00131 template<typename T, template<typename U> class Descriptor, class SurfaceData>
00132 OffLatticeCompletionFunctional3D<T,Descriptor,SurfaceData>::~OffLatticeCompletionFunctional3D()
00133 {
00134     delete offLatticeModel;
00135 }
00136 
00137 template<typename T, template<typename U> class Descriptor, class SurfaceData>
00138 OffLatticeCompletionFunctional3D<T,Descriptor,SurfaceData>::
00139     OffLatticeCompletionFunctional3D (
00140             OffLatticeCompletionFunctional3D<T,Descriptor,SurfaceData> const& rhs)
00141     : offLatticeModel(rhs.offLatticeModel->clone()),
00142       numShapeArgs(rhs.numShapeArgs),
00143       numCompletionArgs(rhs.numCompletionArgs)
00144 { }
00145 
00146 template<typename T, template<typename U> class Descriptor, class SurfaceData>
00147 OffLatticeCompletionFunctional3D<T,Descriptor,SurfaceData>&
00148     OffLatticeCompletionFunctional3D<T,Descriptor,SurfaceData>::operator= (
00149             OffLatticeCompletionFunctional3D<T,Descriptor,SurfaceData> const& rhs )
00150 {
00151     OffLatticeCompletionFunctional3D<T,Descriptor,SurfaceData>(rhs).swap(*this);
00152 }
00153 
00154 template<typename T, template<typename U> class Descriptor, class SurfaceData>
00155 void OffLatticeCompletionFunctional3D<T,Descriptor,SurfaceData>::swap(
00156         OffLatticeCompletionFunctional3D<T,Descriptor,SurfaceData>& rhs)
00157 {
00158     std::swap(offLatticeModel, rhs.offLatticeModel);
00159     std::swap(numShapeArgs, rhs.numShapeArgs);
00160     std::swap(numCompletionArgs, rhs.numCompletionArgs);
00161 }
00162 
00163 
00164 template<typename T, template<typename U> class Descriptor, class SurfaceData>
00165 OffLatticeCompletionFunctional3D<T,Descriptor,SurfaceData>*
00166     OffLatticeCompletionFunctional3D<T,Descriptor,SurfaceData>::clone() const
00167 {
00168     return new OffLatticeCompletionFunctional3D<T,Descriptor,SurfaceData>(*this);
00169 }
00170 
00171 template<typename T, template<typename U> class Descriptor, class SurfaceData>
00172 void OffLatticeCompletionFunctional3D<T,Descriptor,SurfaceData>::getTypeOfModification (
00173         std::vector<modif::ModifT>& modified) const
00174 {
00175     PLB_ASSERT( (plint)modified.size() == 2+numShapeArgs+numCompletionArgs );
00176     modified[0] = modif::staticVariables;  // Lattice.
00177     modified[1] = modif::nothing; // Container for wet/dry nodes.
00178     // Possible additional parameters for the shape function and
00179     //   for the completion algorithm are read-only.
00180     for (pluint i=2; i<modified.size(); ++i) {
00181         modified[i] = modif::nothing;
00182     }
00183 }
00184 
00185 template<typename T, template<typename U> class Descriptor, class SurfaceData>
00186 BlockDomain::DomainT OffLatticeCompletionFunctional3D<T,Descriptor,SurfaceData>::appliesTo() const
00187 {
00188     return BlockDomain::bulk;
00189 }
00190 
00191 template<typename T, template<typename U> class Descriptor, class SurfaceData>
00192 void OffLatticeCompletionFunctional3D<T,Descriptor,SurfaceData>::processGenericBlocks (
00193         Box3D domain, std::vector<AtomicBlock3D*> fields )
00194 {
00195     PLB_PRECONDITION( (plint)fields.size() == 2+numShapeArgs+numCompletionArgs );
00196     AtomicBlock3D* lattice = fields[0];
00197     PLB_ASSERT( lattice );
00198 
00199     AtomicContainerBlock3D* container =  // Container for wet/dry nodes.
00200         dynamic_cast<AtomicContainerBlock3D*>(fields[1]);
00201     PLB_ASSERT( container );
00202 
00203     if (numShapeArgs>0) {
00204         std::vector<AtomicBlock3D*> shapeParameters(numShapeArgs);
00205         for (plint i=0; i<numShapeArgs; ++i) {
00206             shapeParameters[i] = fields[i+2];
00207         }
00208         offLatticeModel->provideShapeArguments(shapeParameters);
00209     }
00210     std::vector<AtomicBlock3D const*> completionParameters(numCompletionArgs);
00211     for (plint i=0; i<numCompletionArgs; ++i) {
00212         completionParameters[i] = fields[i+2+numShapeArgs];
00213     }
00214 
00215     offLatticeModel->boundaryCompletion(*lattice, *container, completionParameters);
00216 }
00217 
00218 
00219 template<typename T, class SurfaceData>
00220 OffLatticePatternFunctional3D<T,SurfaceData>::
00221     OffLatticePatternFunctional3D (
00222             OffLatticeModel3D<T,SurfaceData>* offLatticeModel_ )
00223   : offLatticeModel(offLatticeModel_)
00224 { }
00225 
00226 template<typename T, class SurfaceData>
00227 OffLatticePatternFunctional3D<T,SurfaceData>::~OffLatticePatternFunctional3D()
00228 {
00229     delete offLatticeModel;
00230 }
00231 
00232 template<typename T, class SurfaceData>
00233 OffLatticePatternFunctional3D<T,SurfaceData>::
00234     OffLatticePatternFunctional3D (
00235             OffLatticePatternFunctional3D<T,SurfaceData> const& rhs)
00236     : offLatticeModel(rhs.offLatticeModel->clone())
00237 { }
00238 
00239 template<typename T, class SurfaceData>
00240 OffLatticePatternFunctional3D<T,SurfaceData>&
00241     OffLatticePatternFunctional3D<T,SurfaceData>::operator= (
00242             OffLatticePatternFunctional3D<T,SurfaceData> const& rhs )
00243 {
00244     OffLatticePatternFunctional3D<T,SurfaceData>(rhs).swap(*this);
00245 }
00246 
00247 template<typename T, class SurfaceData>
00248 void OffLatticePatternFunctional3D<T,SurfaceData>::swap(
00249         OffLatticePatternFunctional3D<T,SurfaceData>& rhs)
00250 {
00251     std::swap(offLatticeModel, rhs.offLatticeModel);
00252 }
00253 
00254 
00255 template<typename T, class SurfaceData>
00256 OffLatticePatternFunctional3D<T,SurfaceData>*
00257     OffLatticePatternFunctional3D<T,SurfaceData>::clone() const
00258 {
00259     return new OffLatticePatternFunctional3D<T,SurfaceData>(*this);
00260 }
00261 
00262 template<typename T, class SurfaceData>
00263 void OffLatticePatternFunctional3D<T,SurfaceData>::getTypeOfModification (
00264         std::vector<modif::ModifT>& modified) const
00265 {
00266     modified[0] = modif::staticVariables;  // Container.
00267     // Possible additional parameters for the shape function are read-only.
00268     for (pluint i=1; i<modified.size(); ++i) {
00269         modified[i] = modif::nothing;
00270     }
00271 }
00272 
00273 template<typename T, class SurfaceData>
00274 BlockDomain::DomainT OffLatticePatternFunctional3D<T,SurfaceData>::appliesTo() const
00275 {
00276     return BlockDomain::bulk;
00277 }
00278 
00279 template<typename T, class SurfaceData>
00280 void OffLatticePatternFunctional3D<T,SurfaceData>::processGenericBlocks (
00281         Box3D domain, std::vector<AtomicBlock3D*> fields )
00282 {
00283     PLB_PRECONDITION( fields.size() >= 1 );
00284     AtomicContainerBlock3D* container =
00285         dynamic_cast<AtomicContainerBlock3D*>(fields[0]);
00286     PLB_ASSERT( container );
00287     ContainerBlockData* storeInfo = 
00288         offLatticeModel->generateOffLatticeInfo();
00289     container->setData(storeInfo);
00290 
00291     if (fields.size()>1) {
00292         std::vector<AtomicBlock3D*> shapeParameters(fields.size()-1);
00293         for (pluint i=0; i<shapeParameters.size(); ++i) {
00294             shapeParameters[i] = fields[i+1];
00295         }
00296         offLatticeModel->provideShapeArguments(shapeParameters);
00297     }
00298 
00299     for (plint iX=domain.x0; iX<=domain.x1; ++iX) {
00300         for (plint iY=domain.y0; iY<=domain.y1; ++iY) {
00301             for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) {
00302                 offLatticeModel->prepareCell(Dot3D(iX,iY,iZ), *container);
00303             }
00304         }
00305     }
00306 }
00307 
00308 
00309 template< typename T, class SurfaceData >
00310 GetForceOnObjectFunctional3D<T,SurfaceData>::GetForceOnObjectFunctional3D (
00311     OffLatticeModel3D<T,SurfaceData>* offLatticeModel_ )
00312         : offLatticeModel(offLatticeModel_),
00313           forceId (
00314                 this->getStatistics().subscribeSum(),
00315                 this->getStatistics().subscribeSum(),
00316                 this->getStatistics().subscribeSum() )
00317 { }
00318 
00319 template< typename T, class SurfaceData >
00320 GetForceOnObjectFunctional3D<T,SurfaceData>::~GetForceOnObjectFunctional3D()
00321 {
00322     delete offLatticeModel;
00323 }
00324 
00325 template< typename T, class SurfaceData >
00326 GetForceOnObjectFunctional3D<T,SurfaceData>::GetForceOnObjectFunctional3D (
00327         GetForceOnObjectFunctional3D<T,SurfaceData> const& rhs )
00328     : PlainReductiveBoxProcessingFunctional3D(rhs),
00329       offLatticeModel(rhs.offLatticeModel->clone()),
00330       forceId(rhs.forceId)
00331 { }
00332 
00333 template< typename T, class SurfaceData >
00334 GetForceOnObjectFunctional3D<T,SurfaceData>&
00335     GetForceOnObjectFunctional3D<T,SurfaceData>::operator= (
00336             GetForceOnObjectFunctional3D<T,SurfaceData> const& rhs )
00337 {
00338     delete offLatticeModel; offLatticeModel = rhs.offLatticeModel->clone();
00339     forceId = rhs.forceId;
00340     PlainReductiveBoxProcessingFunctional3D::operator=(rhs);
00341 }
00342 
00343 template< typename T, class SurfaceData >
00344 void GetForceOnObjectFunctional3D<T,SurfaceData>::processGenericBlocks (
00345         Box3D domain, std::vector<AtomicBlock3D*> fields )
00346 {
00347     PLB_PRECONDITION( fields.size() == 1 );
00348     AtomicContainerBlock3D* offLatticeInfo = 
00349         dynamic_cast<AtomicContainerBlock3D*>(fields[0]);
00350     PLB_ASSERT( offLatticeInfo );
00351 
00352     Array<T,3> force = offLatticeModel->getLocalForce(*offLatticeInfo);
00353     this->getStatistics().gatherSum(forceId[0], force[0]);
00354     this->getStatistics().gatherSum(forceId[1], force[1]);
00355     this->getStatistics().gatherSum(forceId[2], force[2]);
00356 }
00357 
00358 template< typename T, class SurfaceData >
00359 GetForceOnObjectFunctional3D<T,SurfaceData>*
00360     GetForceOnObjectFunctional3D<T,SurfaceData>::clone() const
00361 {
00362      return new GetForceOnObjectFunctional3D<T,SurfaceData>(*this);
00363 }
00364 
00365 template< typename T, class SurfaceData >
00366 void GetForceOnObjectFunctional3D<T,SurfaceData>::getTypeOfModification(std::vector<modif::ModifT>& modified) const
00367 {
00368     modified[0]=modif::nothing;  // Off-lattice info.
00369 }
00370 
00371 template< typename T, class SurfaceData >
00372 BlockDomain::DomainT GetForceOnObjectFunctional3D<T,SurfaceData>::appliesTo() const {
00373     return BlockDomain::bulk;
00374 }
00375 
00376 template< typename T, class SurfaceData >
00377 Array<T,3> GetForceOnObjectFunctional3D<T,SurfaceData>::getForce() const {
00378     return Array<T,3> (
00379             this->getStatistics().getSum(forceId[0]),
00380             this->getStatistics().getSum(forceId[1]),
00381             this->getStatistics().getSum(forceId[2]) );
00382 }
00383 
00384 }  // namespace plb
00385 
00386 #endif  // OFF_LATTICE_MODEL_3D_HH