$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 00029 #ifndef THERMAL_DYNAMICS_HH 00030 #define THERMAL_DYNAMICS_HH 00031 00032 #include <algorithm> 00033 #include <limits> 00034 #include "basicDynamics/thermalDynamics.h" 00035 #include "core/cell.h" 00036 #include "latticeBoltzmann/dynamicsTemplates.h" 00037 #include "latticeBoltzmann/momentTemplates.h" 00038 #include "latticeBoltzmann/externalForceTemplates.h" 00039 #include "latticeBoltzmann/offEquilibriumTemplates.h" 00040 #include "latticeBoltzmann/d3q13Templates.h" 00041 #include "latticeBoltzmann/geometricOperationTemplates.h" 00042 #include "core/latticeStatistics.h" 00043 00044 namespace plb { 00045 00046 /* *************** Class ThermalBulkDynamics ************************************ */ 00047 00048 template<typename T, template<typename U> class Descriptor> 00049 ThermalBulkDynamics<T,Descriptor>::ThermalBulkDynamics(T omega_) 00050 : BasicBulkDynamics<T,Descriptor>(omega_) 00051 { } 00052 00053 template<typename T, template<typename U> class Descriptor> 00054 void ThermalBulkDynamics<T,Descriptor>::regularize ( 00055 Cell<T,Descriptor>& cell, T rhoBar, Array<T,Descriptor<T>::d> const& j, 00056 T jSqr, Array<T,SymmetricTensor<T,Descriptor>::n> const& PiNeq, T thetaBar ) const 00057 { 00058 00059 Array<T,SymmetricRankThreeTensor<T,Descriptor>::n> qNeq; 00060 momentTemplates<T,Descriptor>::compute_Qneq(cell, rhoBar, j,thetaBar,qNeq ); 00061 00062 typedef Descriptor<T> L; 00063 for (plint iPop=0; iPop < L::q; ++iPop) { 00064 cell[iPop] = computeEquilibrium(iPop, rhoBar, j, jSqr, thetaBar); 00065 T fNeq = offEquilibriumTemplatesImpl<T,L>::fromPiAndQtoFneq(iPop, PiNeq, qNeq); 00066 cell[iPop] += fNeq; 00067 } 00068 } 00069 00070 template<typename T, template<typename U> class Descriptor> 00071 T ThermalBulkDynamics<T,Descriptor>::computeTemperature(Cell<T,Descriptor> const& cell) const 00072 { 00073 T rhoBar; 00074 Array<T,Descriptor<T>::d> j; 00075 computeRhoBarJ(cell,rhoBar,j); 00076 T jSqr = VectorTemplate<T,Descriptor>::normSqr(j); 00077 return momentTemplates<T,Descriptor>::compute_theta(cell, rhoBar, jSqr); 00078 } 00079 00080 template<typename T, template<typename U> class Descriptor> 00081 void ThermalBulkDynamics<T,Descriptor>::computeDeviatoricStress ( 00082 Cell<T,Descriptor> const& cell, Array<T,SymmetricTensor<T,Descriptor>::n>& PiNeq ) const 00083 { 00084 T rhoBar; 00085 Array<T,Descriptor<T>::d> j; 00086 computeRhoBarJ(cell,rhoBar,j); 00087 T jSqr = VectorTemplate<T,Descriptor>::normSqr(j); 00088 T thetaBar = momentTemplates<T,Descriptor>::compute_theta(cell, rhoBar, jSqr)-(T)1; 00089 momentTemplates<T,Descriptor>::compute_thermal_PiNeq(cell, rhoBar, thetaBar, j, PiNeq); 00090 } 00091 00092 template<typename T, template<typename U> class Descriptor> 00093 void ThermalBulkDynamics<T,Descriptor>::computeHeatFlux ( 00094 Cell<T,Descriptor> const& cell, Array<T,Descriptor<T>::d>& q ) const 00095 { 00096 T rhoBar; 00097 Array<T,Descriptor<T>::d> j; 00098 computeRhoBarJ(cell,rhoBar,j); 00099 T jSqr = VectorTemplate<T,Descriptor>::normSqr(j); 00100 T thetaBar = momentTemplates<T,Descriptor>::compute_theta(cell, rhoBar, jSqr)-(T)1; 00101 momentTemplates<T,Descriptor>::compute_heat_flux(cell, rhoBar, j,thetaBar,q ); 00102 } 00103 00104 template<typename T, template<typename U> class Descriptor> 00105 T ThermalBulkDynamics<T,Descriptor>::computeEbar(Cell<T,Descriptor> const& cell) const 00106 { 00107 return momentTemplates<T,Descriptor>::get_eBar(cell); 00108 } 00109 00110 // TODO needs to be extended from iso-thermal to thermal case 00111 template<typename T, template<typename U> class Descriptor> 00112 plint ThermalBulkDynamics<T,Descriptor>::numDecomposedVariables(plint order) const { 00113 plint numVariables = 00114 // Order 0: density + velocity + fNeq 00115 ( order == 0 ) ? ( 1 + Descriptor<T>::d + 1 + Descriptor<T>::q ) // rhoBar, j, thetaBar, fNeq 00116 // Order >=1: density + velocity + PiNeq 00117 : ( 1 + Descriptor<T>::d + 1 + SymmetricTensor<T,Descriptor>::n + SymmetricRankThreeTensor<T,Descriptor>::n); // rhoBar, j, thetaBar, piNeq, qNeq 00118 00119 numVariables += Descriptor<T>::ExternalField::numScalars; 00120 return numVariables; 00121 } 00122 00123 // TODO needs to be extended from iso-thermal to thermal case 00124 template<typename T, template<typename U> class Descriptor> 00125 void ThermalBulkDynamics<T,Descriptor>::decompose ( 00126 Cell<T,Descriptor> const& cell, std::vector<T>& rawData, plint order ) const 00127 { 00128 rawData.resize(numDecomposedVariables(order)); 00129 00130 if (order==0) { 00131 decomposeOrder0(cell, rawData); 00132 } 00133 else { 00134 decomposeOrder1(cell, rawData); 00135 } 00136 } 00137 00138 // TODO needs to be extended from iso-thermal to thermal case 00139 template<typename T, template<typename U> class Descriptor> 00140 void ThermalBulkDynamics<T,Descriptor>::recompose ( 00141 Cell<T,Descriptor>& cell, std::vector<T> const& rawData, plint order ) const 00142 { 00143 PLB_PRECONDITION( (plint) rawData.size() == numDecomposedVariables(order) ); 00144 00145 if (order==0) { 00146 recomposeOrder0(cell, rawData); 00147 } 00148 else { 00149 recomposeOrder1(cell, rawData); 00150 } 00151 } 00152 00153 // TODO needs to be extended from iso-thermal to thermal case 00154 template<typename T, template<typename U> class Descriptor> 00155 void ThermalBulkDynamics<T,Descriptor>::rescale ( 00156 std::vector<T>& rawData, T xDxInv, T xDt, plint order ) const 00157 { 00158 PLB_PRECONDITION( (plint) rawData.size()==numDecomposedVariables(order) ); 00159 00160 if (order==0) { 00161 rescaleOrder0(rawData, xDxInv, xDt); 00162 } 00163 else { 00164 rescaleOrder1(rawData, xDxInv, xDt); 00165 } 00166 } 00167 00168 template<typename T, template<typename U> class Descriptor> 00169 void ThermalBulkDynamics<T,Descriptor>::decomposeOrder0 ( 00170 Cell<T,Descriptor> const& cell, std::vector<T>& rawData ) const 00171 { 00172 T rhoBar, thetaBar; 00173 Array<T,Descriptor<T>::d> j; 00174 momentTemplates<T,Descriptor>::get_rhoBar_j_thetaBar(cell, rhoBar, j, thetaBar); 00175 T jSqr = VectorTemplate<T,Descriptor>::normSqr(j); 00176 rawData[0] = rhoBar; 00177 j.to_cArray(&rawData[1]); 00178 rawData[1+Descriptor<T>::d] = thetaBar; 00179 00180 for (plint iPop=0; iPop<Descriptor<T>::q; ++iPop) { 00181 rawData[2+Descriptor<T>::d+iPop] = 00182 cell[iPop] - this->computeEquilibrium(iPop, rhoBar, j, jSqr); 00183 } 00184 00185 int offset = 2+Descriptor<T>::d+Descriptor<T>::q; 00186 for (plint iExt=0; iExt<Descriptor<T>::ExternalField::numScalars; ++iExt) { 00187 rawData[offset+iExt] = *cell.getExternal(iExt); 00188 } 00189 } 00190 00191 template<typename T, template<typename U> class Descriptor> 00192 void ThermalBulkDynamics<T,Descriptor>::decomposeOrder1 ( 00193 Cell<T,Descriptor> const& cell, std::vector<T>& rawData ) const 00194 { 00195 T rhoBar, thetaBar; 00196 Array<T,Descriptor<T>::d> j; 00197 Array<T,SymmetricTensor<T,Descriptor>::n> PiNeq; 00198 Array<T,SymmetricRankThreeTensor<T,Descriptor>::n> qNeq; 00199 momentTemplates<T,Descriptor>::compute_rhoBar_thetaBar_j_PiNeq_qNeq(cell, rhoBar, thetaBar, j, PiNeq, qNeq); 00200 00201 rawData[0] = rhoBar; 00202 j.to_cArray(&rawData[1]); 00203 rawData[1+Descriptor<T>::d] = thetaBar; 00204 PiNeq.to_cArray(&rawData[2+Descriptor<T>::d]); 00205 qNeq.to_cArray(&rawData[2+Descriptor<T>::d+SymmetricTensor<T,Descriptor>::n+SymmetricRankThreeTensor<T,Descriptor>::n]); 00206 00207 int offset = 2+Descriptor<T>::d+SymmetricTensor<T,Descriptor>::n+SymmetricRankThreeTensor<T,Descriptor>::n; 00208 for (plint iExt=0; iExt<Descriptor<T>::ExternalField::numScalars; ++iExt) { 00209 rawData[offset+iExt] = *cell.getExternal(iExt); 00210 } 00211 } 00212 00213 template<typename T, template<typename U> class Descriptor> 00214 void ThermalBulkDynamics<T,Descriptor>::recomposeOrder0 ( 00215 Cell<T,Descriptor>& cell, std::vector<T> const& rawData ) const 00216 { 00217 T rhoBar = rawData[0]; 00218 Array<T,Descriptor<T>::d> j; 00219 j.from_cArray(&rawData[1]); 00220 T jSqr = VectorTemplate<T,Descriptor>::normSqr(j); 00221 T thetaBar = rawData[1+Descriptor<T>::d]; 00222 00223 for (plint iPop=0; iPop<Descriptor<T>::q; ++iPop) { 00224 cell[iPop] = this->computeEquilibrium(iPop, rhoBar, j, jSqr, thetaBar) 00225 + rawData[2+Descriptor<T>::d+iPop]; 00226 } 00227 00228 int offset = 2+Descriptor<T>::d+Descriptor<T>::q; 00229 for (plint iExt=0; iExt<Descriptor<T>::ExternalField::numScalars; ++iExt) { 00230 *cell.getExternal(iExt) = rawData[offset+iExt]; 00231 } 00232 } 00233 00234 template<typename T, template<typename U> class Descriptor> 00235 void ThermalBulkDynamics<T,Descriptor>::recomposeOrder1 ( 00236 Cell<T,Descriptor>& cell, std::vector<T> const& rawData ) const 00237 { 00238 typedef Descriptor<T> L; 00239 00240 T rhoBar, thetaBar; 00241 Array<T,Descriptor<T>::d> j; 00242 Array<T,SymmetricTensor<T,Descriptor>::n> PiNeq; 00243 Array<T,SymmetricRankThreeTensor<T,Descriptor>::n> qNeq; 00244 00245 rhoBar = rawData[0]; 00246 j.from_cArray(&rawData[1]); 00247 thetaBar = rawData[1+Descriptor<T>::d]; 00248 T jSqr = VectorTemplate<T,Descriptor>::normSqr(j); 00249 PiNeq.from_cArray(&rawData[2+Descriptor<T>::d]); 00250 qNeq.from_cArray(&rawData[2+Descriptor<T>::d+SymmetricTensor<T,Descriptor>::n]); 00251 00252 for (plint iPop=0; iPop<L::q; ++iPop) { 00253 cell[iPop] = this->computeEquilibrium(0, rhoBar, j, jSqr, thetaBar) 00254 + offEquilibriumTemplates<T,Descriptor>::fromPiAndQtoFneq(0, PiNeq, qNeq); 00255 } 00256 00257 int offset = 2+Descriptor<T>::d+SymmetricTensor<T,Descriptor>::n; 00258 for (plint iExt=0; iExt<Descriptor<T>::ExternalField::numScalars; ++iExt) { 00259 *cell.getExternal(iExt) = rawData[offset+iExt]; 00260 } 00261 } 00262 00263 template<typename T, template<typename U> class Descriptor> 00264 void ThermalBulkDynamics<T,Descriptor>::rescaleOrder0 ( 00265 std::vector<T>& rawData, T xDxInv, T xDt ) const 00266 { 00267 // Don't change rho (rawData[0]), because it is invariant 00268 00269 // Change velocity, according to its units dx/dt 00270 T velScale = xDt * xDxInv; 00271 for (plint iVel=0; iVel<Descriptor<T>::d; ++iVel) { 00272 rawData[1+iVel] *= velScale; 00273 } 00274 00275 // Change off-equilibrium, according to its units 1/dt 00276 T fNeqScale = xDt; 00277 for (plint iFneq=0; iFneq<Descriptor<T>::q; ++iFneq) { 00278 rawData[1+Descriptor<T>::d+iFneq] *= fNeqScale; 00279 } 00280 00281 // Don't change external fields; their scaling must be taken care of 00282 // in specialized versions of this class. 00283 } 00284 00285 template<typename T, template<typename U> class Descriptor> 00286 void ThermalBulkDynamics<T,Descriptor>::rescaleOrder1 ( 00287 std::vector<T>& rawData, T xDxInv, T xDt ) const 00288 { 00289 // Don't change rho (rawData[0]), because it is invariant 00290 00291 // Change velocity, according to its units dx/dt 00292 T velScale = xDt * xDxInv; 00293 for (plint iVel=0; iVel<Descriptor<T>::d; ++iVel) { 00294 rawData[1+iVel] *= velScale; 00295 } 00296 00297 // Change off-equilibrium stress, according to its units 1/dt 00298 T PiNeqScale = xDt; 00299 for (plint iPi=0; iPi<SymmetricTensor<T,Descriptor>::n; ++iPi) { 00300 rawData[1+Descriptor<T>::d+iPi] *= PiNeqScale; 00301 } 00302 00303 // Don't change external fields; their scaling must be taken care of 00304 // in specialized versions of this class. 00305 } 00306 00307 /* *************** Class ThermalBGKdynamics *********************************************** */ 00308 00309 template<typename T, template<typename U> class Descriptor> 00310 int ThermalBGKdynamics<T,Descriptor>::id = 00311 meta::registerOneParamDynamics<T,Descriptor,ThermalBGKdynamics<T,Descriptor> >("BGK_Thermal"); 00312 00315 template<typename T, template<typename U> class Descriptor> 00316 ThermalBGKdynamics<T,Descriptor>::ThermalBGKdynamics(T omega_ ) : ThermalBulkDynamics<T,Descriptor>(omega_) 00317 { } 00318 00319 template<typename T, template<typename U> class Descriptor> 00320 ThermalBGKdynamics<T,Descriptor>* ThermalBGKdynamics<T,Descriptor>::clone() const { 00321 return new ThermalBGKdynamics<T,Descriptor>(*this); 00322 } 00323 00324 template<typename T, template<typename U> class Descriptor> 00325 int ThermalBGKdynamics<T,Descriptor>::getId() const { 00326 return id; 00327 } 00328 00329 template<typename T, template<typename U> class Descriptor> 00330 T ThermalBGKdynamics<T,Descriptor>:: 00331 computeEquilibrium(plint iPop, T rhoBar, Array<T,Descriptor<T>::d> const& j, 00332 T jSqr, T thetaBar) const { 00333 00334 T invRho = Descriptor<T>::invRho(rhoBar); 00335 T rhoThetaBar = Descriptor<T>::fullRho(rhoBar)*thetaBar; // thetaBar = theta - 1 00336 return dynamicsTemplates<T,Descriptor>::bgk_ma4_equilibrium(iPop, rhoBar, invRho, j, jSqr, rhoThetaBar); 00337 } 00338 00339 template<typename T, template<typename U> class Descriptor> 00340 void ThermalBGKdynamics<T,Descriptor>::collide ( 00341 Cell<T,Descriptor>& cell, 00342 BlockStatistics& statistics ) 00343 { 00344 T rhoBar; 00345 Array<T,Descriptor<T>::d> j; 00346 computeRhoBarJ(cell,rhoBar,j); 00347 T jSqr = VectorTemplate<T,Descriptor>::normSqr(j); 00348 T rhoThetaBar = momentTemplates<T,Descriptor>::compute_rhoThetaBar(cell,rhoBar,jSqr); 00349 00350 T uSqr = dynamicsTemplates<T,Descriptor>::bgk_ma4_collision(cell, rhoBar, j, rhoThetaBar, this->getOmega()); 00351 00352 if (cell.takesStatistics()) { 00353 gatherStatistics(statistics, rhoBar, uSqr); 00354 } 00355 } 00356 00357 00358 } 00359 00360 #endif
1.6.3
1.6.3