![]() |
MechSys
1.0
Computing library for simulations in continuum and discrete mechanics
|
00001 /************************************************************************ 00002 * MechSys - Open Library for Mechanical Systems * 00003 * Copyright (C) 2005 Dorival M. Pedroso, Raul Durand * 00004 * Copyright (C) 2009 Sergio Galindo * 00005 * * 00006 * This program is free software: you can redistribute it and/or modify * 00007 * it under the terms of the GNU General Public License as published by * 00008 * the Free Software Foundation, either version 3 of the License, or * 00009 * any later version. * 00010 * * 00011 * This program is distributed in the hope that it will be useful, * 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00014 * GNU General Public License for more details. * 00015 * * 00016 * You should have received a copy of the GNU General Public License * 00017 * along with this program. If not, see <http://www.gnu.org/licenses/> * 00018 ************************************************************************/ 00019 00020 #ifndef MECHSYS_LBM_CELL_H 00021 #define MECHSYS_LBM_CELL_H 00022 00023 // Std lib 00024 #ifdef USE_THREAD 00025 #include <pthread.h> 00026 #endif 00027 00028 // MechSys 00029 #include <mechsys/util/array.h> 00030 #include <mechsys/util/fatal.h> 00031 #include <mechsys/linalg/matvec.h> 00032 00033 enum LBMethod 00034 { 00035 D2Q9, 00036 D3Q15, 00037 D3Q27 00038 }; 00039 00040 class Cell 00041 { 00042 public: 00043 static const double WEIGHTSD2Q9 [ 9]; 00044 static const double WEIGHTSD3Q15 [15]; 00045 //static const double WEIGHTSD3Q27 [27]; ///< Weights for the equilibrium distribution functions (D3Q27) 00046 static Vec3_t LVELOCD2Q9 [ 9]; 00047 static Vec3_t LVELOCD3Q15 [15]; 00048 //static const Vec3_t LVELOCD3Q27 [27]; ///< Local velocities (D3Q27) 00049 static const size_t OPPOSITED2Q9 [ 9]; 00050 static const size_t OPPOSITED3Q15 [15]; 00051 //static const size_t OPPOSITED3Q27 [27]; ///< Opposite directions (D3Q27) 00052 00053 //Constructor 00054 Cell (size_t ID, LBMethod Method, iVec3_t Indexes, iVec3_t Ndim, double Cs, double Tau); 00055 00056 // Methods 00057 double Density(); 00058 void Velocity(Vec3_t & V); 00059 double VelDen(Vec3_t & V); 00060 double Feq(size_t k, Vec3_t const & V, double Rho); 00061 void Initialize(double Rho, Vec3_t const & V); 00062 void BounceBack(); 00063 00064 #ifdef USE_THREAD 00065 pthread_mutex_t lck; 00066 //std::mutex mtex; ///< to protect variables in multithreading 00067 #endif 00068 00069 // Data 00070 LBMethod Method; 00071 bool IsSolid; 00072 double Tau; 00073 double Gamma; 00074 double Gs; 00075 size_t Nneigh; 00076 size_t ID; 00077 double Cs; 00078 double Rho; 00079 iVec3_t Index; 00080 Vec3_t Vel; 00081 Vec3_t VelBC; 00082 Vec3_t BForce; 00083 Vec3_t BForcef; 00084 double RhoBC; 00085 00086 size_t const * Op; 00087 double const * W; 00088 Vec3_t const * C; 00089 Array<double> F; 00090 Array<double> Ftemp; 00091 Array<double> Omeis; 00092 Array<size_t> Neighs; 00093 }; 00094 00095 inline Cell::Cell(size_t TheID, LBMethod TheMethod, iVec3_t TheIndexes, iVec3_t TheNdim, double TheCs, double TheTau) 00096 { 00097 IsSolid= false; 00098 ID = TheID; 00099 Method = TheMethod; 00100 Index = TheIndexes; 00101 Cs = TheCs; 00102 Gamma = 0.0; 00103 Gs = 1.0; 00104 Tau = TheTau; 00105 if (Method==D2Q9) 00106 { 00107 Nneigh = 9; 00108 W = WEIGHTSD2Q9; 00109 C = LVELOCD2Q9; 00110 Op = OPPOSITED2Q9; 00111 } 00112 if (Method==D3Q15) 00113 { 00114 Nneigh = 15; 00115 W = WEIGHTSD3Q15; 00116 C = LVELOCD3Q15; 00117 Op = OPPOSITED3Q15; 00118 } 00119 F. Resize(Nneigh); 00120 Ftemp. Resize(Nneigh); 00121 Neighs.Resize(Nneigh); 00122 Omeis .Resize(Nneigh); 00123 BForcef = 0.0,0.0,0.0; 00124 00125 //Set neighbors 00126 for (size_t k=0;k<Nneigh;k++) 00127 { 00128 //iVec3_t nindex = Index + C[k]; 00129 blitz::TinyVector<int,3> nindex = Index + C[k]; 00130 if (nindex[0]== -1) nindex[0] = TheNdim[0]-1; 00131 if (nindex[0]==TheNdim[0]) nindex[0] = 0; 00132 if (nindex[1]== -1) nindex[1] = TheNdim[1]-1; 00133 if (nindex[1]==TheNdim[1]) nindex[1] = 0; 00134 if (nindex[2]== -1) nindex[2] = TheNdim[2]-1; 00135 if (nindex[2]==TheNdim[2]) nindex[2] = 0; 00136 00137 Neighs[k] = nindex[0] + nindex[1]*TheNdim[0] + nindex[2]*TheNdim[0]*TheNdim[1]; 00138 } 00139 #ifdef USE_THREAD 00140 pthread_mutex_init(&lck,NULL); 00141 #endif 00142 } 00143 00144 inline double Cell::Density() 00145 { 00146 if (IsSolid) return 0.0; 00147 double rho = 0.0; 00148 for (size_t k=0;k<Nneigh;k++) rho += F[k]; 00149 return rho; 00150 } 00151 00152 inline void Cell::Velocity(Vec3_t & V) 00153 { 00154 V = 0.0, 0.0, 0.0; 00155 if (IsSolid) return; 00156 double rho = Density(); 00157 if (rho<1.0e-12) return; 00158 for (size_t k=0;k<Nneigh;k++) V += F[k]*C[k]; 00159 V *= Cs/rho; 00160 } 00161 00162 inline double Cell::VelDen(Vec3_t & V) 00163 { 00164 V = 0.0, 0.0, 0.0; 00165 if (IsSolid) return 0.0; 00166 double rho = Density(); 00167 if (rho<1.0e-12) return 0.0; 00168 for (size_t k=1;k<Nneigh;k++) V += F[k]*C[k]; 00169 V *= Cs/rho; 00170 return rho; 00171 } 00172 00173 inline double Cell::Feq(size_t k, Vec3_t const & V, double TheRho) 00174 { 00175 double VdotC = dot(V,C[k]); 00176 double VdotV = dot(V,V); 00177 return W[k]*TheRho*(1.0 + 3.0*VdotC/Cs + 4.5*VdotC*VdotC/(Cs*Cs) - 1.5*VdotV/(Cs*Cs)); 00178 } 00179 00180 inline void Cell::Initialize(double TheRho, Vec3_t const & V) 00181 { 00182 for (size_t k=0;k<Nneigh;k++) F[k] = Feq(k,V,TheRho); 00183 Rho = VelDen(Vel); 00184 } 00185 00186 inline void Cell::BounceBack() 00187 { 00188 for (size_t j = 0;j<Nneigh;j++) Ftemp[j] = F[j]; 00189 for (size_t j = 0;j<Nneigh;j++) F[j] = Ftemp[Op[j]]; 00190 } 00191 00192 00193 const double Cell::WEIGHTSD2Q9 [ 9] = { 4./9., 1./9., 1./9., 1./9., 1./9., 1./36., 1./36., 1./36., 1./36. }; 00194 const double Cell::WEIGHTSD3Q15 [15] = { 2./9., 1./9., 1./9., 1./9., 1./9., 1./9., 1./9., 1./72., 1./72. , 1./72., 1./72., 1./72., 1./72., 1./72., 1./72.}; 00195 const size_t Cell::OPPOSITED2Q9 [ 9] = { 0, 3, 4, 1, 2, 7, 8, 5, 6 }; 00196 const size_t Cell::OPPOSITED3Q15 [15] = { 0, 2, 1, 4, 3, 6, 5, 8, 7, 10, 9, 12, 11, 14, 13}; 00197 Vec3_t Cell::LVELOCD2Q9 [ 9]; 00198 Vec3_t Cell::LVELOCD3Q15 [15]; 00199 00200 00201 /*TODO: Go back to the previous version since this is not nice 00202 * Changes made for g++ 4.3.2 */ 00203 int __allocate_constants () 00204 { 00205 Cell::LVELOCD2Q9 [0] = 0 , 0 , 0; 00206 Cell::LVELOCD2Q9 [1] = 1 , 0 , 0; 00207 Cell::LVELOCD2Q9 [2] = 0 , 1 , 0; 00208 Cell::LVELOCD2Q9 [3] = -1 , 0 , 0; 00209 Cell::LVELOCD2Q9 [4] = 0 , -1 , 0; 00210 Cell::LVELOCD2Q9 [5] = 1 , 1 , 0; 00211 Cell::LVELOCD2Q9 [6] = -1 , 1 , 0; 00212 Cell::LVELOCD2Q9 [7] = -1 , -1 , 0; 00213 Cell::LVELOCD2Q9 [8] = 1 , -1 , 0; 00214 00215 Cell::LVELOCD3Q15[ 0]= 0, 0, 0; Cell::LVELOCD3Q15[ 1]= 1, 0, 0; Cell::LVELOCD3Q15[ 2]=-1, 0, 0; Cell::LVELOCD3Q15[ 3]= 0, 1, 0; Cell::LVELOCD3Q15[ 4]= 0,-1, 0; 00216 Cell::LVELOCD3Q15[ 5]= 0, 0, 1; Cell::LVELOCD3Q15[ 6]= 0, 0,-1; Cell::LVELOCD3Q15[ 7]= 1, 1, 1; Cell::LVELOCD3Q15[ 8]=-1,-1,-1; Cell::LVELOCD3Q15[ 9]= 1, 1,-1; 00217 Cell::LVELOCD3Q15[10]=-1,-1, 1; Cell::LVELOCD3Q15[11]= 1,-1, 1; Cell::LVELOCD3Q15[12]=-1, 1,-1; Cell::LVELOCD3Q15[13]= 1,-1,-1; Cell::LVELOCD3Q15[14]=-1, 1, 1; 00218 00219 return 0; 00220 } 00221 int __dummy__allocate_constants = __allocate_constants(); 00222 00223 #endif // MECHSYS_LBM_CELL_H