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

boussinesqThermalProcessor3D.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 /* Main author: Orestis Malaspinas
00026  */
00027 
00028 #ifndef BOUSSINESQ_THERMAL_PROCESSOR_3D_HH
00029 #define BOUSSINESQ_THERMAL_PROCESSOR_3D_HH
00030 
00031 #include "multiPhysics/boussinesqThermalProcessor3D.h"
00032 #include "atomicBlock/blockLattice3D.h"
00033 #include "core/util.h"
00034 #include "finiteDifference/finiteDifference3D.h"
00035 #include "latticeBoltzmann/geometricOperationTemplates.h"
00036 
00037 namespace plb {
00038 
00039 template< typename T,
00040           template<typename U1> class FluidDescriptor, 
00041           template<typename U2> class TemperatureDescriptor
00042         >
00043 BoussinesqThermalProcessor3D<T,FluidDescriptor,TemperatureDescriptor>::
00044         BoussinesqThermalProcessor3D(T gravity_, T T0_, T deltaTemp_, Array<T,FluidDescriptor<T>::d> dir_)
00045     :  gravity(gravity_), T0(T0_), deltaTemp(deltaTemp_),
00046        dir(dir_)
00047 {
00048     // We normalize the direction of the force vector.
00049     T normDir = sqrt(VectorTemplate<T,FluidDescriptor>::normSqr(dir));
00050     for (pluint iD = 0; iD < FluidDescriptor<T>::d; ++iD) {
00051         dir[iD] /= normDir;
00052     }
00053 }
00054 
00055 template< typename T,
00056           template<typename U1> class FluidDescriptor, 
00057           template<typename U2> class TemperatureDescriptor
00058         >
00059 void BoussinesqThermalProcessor3D<T,FluidDescriptor,TemperatureDescriptor>::process (
00060         Box3D domain,
00061         BlockLattice3D<T,FluidDescriptor>& fluid,
00062         BlockLattice3D<T,TemperatureDescriptor>& temperature )
00063 {
00064     typedef FluidDescriptor<T> D;
00065     enum {
00066         velOffset   = TemperatureDescriptor<T>::ExternalField::velocityBeginsAt,
00067         forceOffset = FluidDescriptor<T>::ExternalField::forceBeginsAt
00068     };
00069     Dot3D offset = computeRelativeDisplacement(fluid, temperature);
00070     
00071     Array<T,D::d> gravOverDeltaTemp (
00072             gravity*dir[0]/deltaTemp,
00073             gravity*dir[1]/deltaTemp,
00074             gravity*dir[2]/deltaTemp );
00075            
00076     for (plint iX=domain.x0; iX<=domain.x1; ++iX) 
00077     {
00078         for (plint iY=domain.y0; iY<=domain.y1; ++iY) 
00079         {
00080             for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) 
00081             {
00082                 // Velocity coupling
00083                 T *u = temperature.get(iX+offset.x,iY+offset.y,iZ+offset.z).getExternal(velOffset);
00084                 Array<T,FluidDescriptor<T>::d> vel;
00085                 fluid.get(iX,iY,iZ).computeVelocity(vel);
00086                 vel.to_cArray(u);
00087                 
00088                 // Computation of the Boussinesq force
00089                 T *force = fluid.get(iX,iY,iZ).getExternal(forceOffset);
00090                 // Temperature is the order-0 moment of the advection-diffusion lattice.
00091                 //   You can compute it with the method computeDensity().
00092                 T localTemperature = temperature.get(iX+offset.x,iY+offset.y,iZ+offset.z).computeDensity();
00093                 const T diffT = localTemperature - T0;
00094                 for (pluint iD = 0; iD < D::d; ++iD) 
00095                 {
00096                     force[iD] = gravOverDeltaTemp[iD] * diffT;
00097                 }
00098             }
00099         }
00100     }
00101 }
00102 
00103 template< typename T,
00104           template<typename U1> class FluidDescriptor, 
00105           template<typename U2> class TemperatureDescriptor
00106         >
00107 BoussinesqThermalProcessor3D<T,FluidDescriptor,TemperatureDescriptor>*
00108     BoussinesqThermalProcessor3D<T,FluidDescriptor,TemperatureDescriptor>::clone() const
00109 {
00110     return new BoussinesqThermalProcessor3D<T,FluidDescriptor,TemperatureDescriptor>(*this);
00111 }
00112 
00113 
00114 /*
00115 template< typename T,
00116           template<typename U1> class FluidDescriptor, 
00117           template<typename U2> class TemperatureDescriptor
00118         >
00119 SmagorinskyBoussinesqThermalProcessor3D<T,FluidDescriptor,TemperatureDescriptor>::
00120         SmagorinskyBoussinesqThermalProcessor3D(T gravity_, T T0_, T deltaTemp_, Array<T,FluidDescriptor<T>::d> dir_,
00121         T cSmagoFluid_, T cSmagoTemp_ )
00122     :  gravity(gravity_), T0(T0_), deltaTemp(deltaTemp_),
00123        dir(dir_),
00124        cSmagoFluid(cSmagoFluid_),
00125        cSmagoTemp(cSmagoTemp_),
00126        nu0(nu0_), d0(d0_)
00127 {
00128     // We normalize the direction of the force vector.
00129     T normDir = sqrt(VectorTemplate<T,FluidDescriptor>::normSqr(dir));
00130     for (pluint iD = 0; iD < FluidDescriptor<T>::d; ++iD) {
00131         dir[iD] /= normDir;
00132     }
00133 }
00134 
00135 template< typename T,
00136           template<typename U1> class FluidDescriptor, 
00137           template<typename U2> class TemperatureDescriptor
00138         >
00139 void SmagorinskyBoussinesqThermalProcessor3D<T,FluidDescriptor,TemperatureDescriptor>::process (
00140         Box3D domain,
00141         BlockLattice3D<T,FluidDescriptor>& fluid,
00142         BlockLattice3D<T,TemperatureDescriptor>& temperature )
00143 {
00144     typedef FluidDescriptor<T> D;
00145     enum {
00146         velOffset   = TemperatureDescriptor<T>::ExternalField::velocityBeginsAt,
00147         forceOffset = FluidDescriptor<T>::ExternalField::forceBeginsAt
00148     };
00149     Dot3D offset = computeRelativeDisplacement(fluid, temperature);
00150     
00151     Array<T,D::d> gravOverDeltaTemp (
00152             gravity*dir[0]/deltaTemp,
00153             gravity*dir[1]/deltaTemp,
00154             gravity*dir[2]/deltaTemp );
00155            
00156     for (plint iX=domain.x0; iX<=domain.x1; ++iX) 
00157     {
00158         for (plint iY=domain.y0; iY<=domain.y1; ++iY) 
00159         {
00160             for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) 
00161             {
00162                 // Velocity coupling
00163                 T *u = temperature.get(iX+offset.x,iY+offset.y,iZ+offset.z).getExternal(velOffset);
00164                 Array<T,FluidDescriptor<T>::d> vel;
00165                 fluid.get(iX,iY,iZ).computeVelocity(vel);
00166                 vel.to_cArray(u);
00167                 
00168                 // Computation of the Boussinesq force
00169                 T *force = fluid.get(iX,iY,iZ).getExternal(forceOffset);
00170                 // Temperature is the order-0 moment of the advection-diffusion lattice.
00171                 //   You can compute it with the method computeDensity().
00172                 T localTemperature = temperature.get(iX+offset.x,iY+offset.y,iZ+offset.z).computeDensity();
00173                 const T diffT = localTemperature - T0;
00174                 for (pluint iD = 0; iD < D::d; ++iD) 
00175                 {
00176                     force[iD] = gravOverDeltaTemp[iD] * diffT;
00177                 }
00178             }
00179         }
00180     }
00181 }
00182 
00183 template< typename T,
00184           template<typename U1> class FluidDescriptor, 
00185           template<typename U2> class TemperatureDescriptor
00186         >
00187 SmagorinskyBoussinesqThermalProcessor3D<T,FluidDescriptor,TemperatureDescriptor>*
00188     SmagorinskyBoussinesqThermalProcessor3D<T,FluidDescriptor,TemperatureDescriptor>::clone() const
00189 {
00190     return new SmagorinskyBoussinesqThermalProcessor3D<T,FluidDescriptor,TemperatureDescriptor>(*this);
00191 }
00192 
00193 */
00194 
00195 
00196 template< typename T, template<typename U> class TemperatureDescriptor >
00197 void VelocityToPassiveAdvDiff3D<T,TemperatureDescriptor>::process (
00198         Box3D domain,
00199         BlockLattice3D<T,TemperatureDescriptor>& temperature,
00200         TensorField3D<T,3>& velocity )
00201 {
00202     const int velOffset = TemperatureDescriptor<T>::ExternalField::velocityBeginsAt;
00203     for (plint iX=domain.x0; iX<=domain.x1; ++iX) {
00204         for (plint iY=domain.y0; iY<=domain.y1; ++iY) {
00205             for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) {
00206                 T *u = temperature.get(iX,iY,iZ).getExternal(velOffset);
00207                 velocity.get(iX,iY,iZ).to_cArray(u);
00208             }
00209         }
00210     }
00211 }
00212 
00213 template< typename T, template<typename U> class TemperatureDescriptor >
00214 VelocityToPassiveAdvDiff3D<T,TemperatureDescriptor>*
00215     VelocityToPassiveAdvDiff3D<T,TemperatureDescriptor>::clone() const
00216 {
00217     return new VelocityToPassiveAdvDiff3D<T,TemperatureDescriptor>(*this);
00218 }
00219 
00220 
00221 template< typename T,
00222           template<typename U1> class FluidDescriptor, 
00223           template<typename U2> class ScalarDescriptor
00224         >
00225 LatticeToPassiveAdvDiff3D<T,FluidDescriptor,ScalarDescriptor>::LatticeToPassiveAdvDiff3D(T scaling_)
00226     : scaling(scaling_)
00227 { }
00228 
00229 template< typename T,
00230           template<typename U1> class FluidDescriptor, 
00231           template<typename U2> class ScalarDescriptor
00232         >
00233 void LatticeToPassiveAdvDiff3D<T,FluidDescriptor,ScalarDescriptor>::process (
00234               Box3D domain,
00235               BlockLattice3D<T,FluidDescriptor>& fluid,
00236               BlockLattice3D<T,ScalarDescriptor>& scalar )
00237 {
00238     const int velOffset = ScalarDescriptor<T>::ExternalField::velocityBeginsAt;
00239     for (plint iX=domain.x0; iX<=domain.x1; ++iX) {
00240         for (plint iY=domain.y0; iY<=domain.y1; ++iY) {
00241             for (plint iZ=domain.z0; iZ<=domain.z1; ++iZ) {
00242                 T *u = scalar.get(iX,iY,iZ).getExternal(velOffset);
00243                 Array<T,3> velocity;
00244                 fluid.get(iX,iY,iZ).computeVelocity(velocity);
00245                 velocity *= scaling;
00246                 velocity.to_cArray(u);
00247             }
00248         }
00249     }
00250 }
00251 
00252 template< typename T,
00253           template<typename U1> class FluidDescriptor, 
00254           template<typename U2> class ScalarDescriptor
00255         >
00256 LatticeToPassiveAdvDiff3D<T,FluidDescriptor,ScalarDescriptor>*
00257     LatticeToPassiveAdvDiff3D<T,FluidDescriptor,ScalarDescriptor>::clone() const
00258 {
00259     return new LatticeToPassiveAdvDiff3D<T,FluidDescriptor,ScalarDescriptor>(*this);
00260 }
00261 
00262 template< typename T,
00263           template<typename U1> class FluidDescriptor, 
00264           template<typename U2> class ScalarDescriptor
00265         >
00266 BlockDomain::DomainT LatticeToPassiveAdvDiff3D<T,FluidDescriptor,ScalarDescriptor>::appliesTo() const {
00267     return BlockDomain::bulk;
00268 }
00269 
00270 template< typename T,
00271           template<typename U1> class FluidDescriptor, 
00272           template<typename U2> class ScalarDescriptor
00273         >
00274 void LatticeToPassiveAdvDiff3D<T,FluidDescriptor,ScalarDescriptor>::getTypeOfModification (
00275         std::vector<modif::ModifT>& modified ) const
00276 {
00277     modified[0] = modif::nothing;
00278     modified[1] = modif::staticVariables;
00279 }
00280 
00281 }  // namespace plb
00282 
00283 #endif