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

finiteDifference2D.h

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 FINITE_DIFFERENCE_2D_H
00026 #define FINITE_DIFFERENCE_2D_H
00027 
00028 #include "core/globalDefs.h"
00029 #include "finiteDifference/fdStencils1D.h"
00030 
00031 namespace plb {
00032 
00033 namespace fd {
00034 
00035     template<typename T, template<typename U> class Descriptor,
00036              int direction, int orientation,
00037              bool orthogonal>
00038     struct DirectedGradients2D {
00041         static void o1_velocityDerivative(Array<T,Descriptor<T>::d>& velDeriv,
00042                                           BlockLattice2D<T,Descriptor> const& blockLattice,
00043                                           plint iX, plint iY);
00046         static void o1_densityDerivative(T& rhoDeriv,
00047                                          BlockLattice2D<T,Descriptor> const& blockLattice,
00048                                          plint iX, plint iY);
00051         static void o2_velocityDerivative(Array<T,Descriptor<T>::d>& velDeriv,
00052                                           BlockLattice2D<T,Descriptor> const& blockLattice,
00053                                           plint iX, plint iY);
00056         static void o2_densityDerivative(T& rhoDeriv,
00057                                          BlockLattice2D<T,Descriptor> const& blockLattice,
00058                                          plint iX, plint iY);
00059     };
00060 
00061     // Implementation for orthogonal==true; i.e. the derivative is along
00062     //   the boundary normal.
00063     template<typename T, template<typename U> class Descriptor,
00064              int direction, int orientation>
00065     struct DirectedGradients2D<T, Descriptor, direction, orientation, true> {
00066         static void o1_velocityDerivative(Array<T,Descriptor<T>::d>& velDeriv,
00067                                           BlockLattice2D<T,Descriptor> const& blockLattice,
00068                                           plint iX, plint iY)
00069         {
00070             Array<T,Descriptor<T>::d> u0, u1;
00071             
00072             blockLattice.get(iX,iY).computeVelocity(u0);
00073             blockLattice.get (
00074                 iX+(direction==0 ? (-orientation):0),
00075                 iY+(direction==1 ? (-orientation):0) ).computeVelocity(u1);
00076 
00077             for (int iD=0; iD<Descriptor<T>::d; ++iD) {
00078                 velDeriv[iD] = -orientation * fd::o1_fwd_diff(u0[iD], u1[iD]);
00079             }
00080         }
00081 
00082         static void o1_densityDerivative(T& rhoDeriv,
00083                                          BlockLattice2D<T,Descriptor> const& blockLattice,
00084                                          plint iX, plint iY)
00085         {
00086             T rho0 = blockLattice.get(iX,iY).computeDensity();
00087             T rho1 = blockLattice.get (
00088                           iX+(direction==0 ? (-orientation):0),
00089                           iY+(direction==1 ? (-orientation):0) ).computeDensity();
00090 
00091             rhoDeriv = -orientation * fd::o1_fwd_diff(rho0, rho1);
00092 
00093         }
00094         static void o2_velocityDerivative(Array<T,Descriptor<T>::d>& velDeriv,
00095                                           BlockLattice2D<T,Descriptor> const& blockLattice,
00096                                           plint iX, plint iY)
00097         {
00098             Array<T,Descriptor<T>::d> u0, u1, u2;
00099             
00100             blockLattice.get(iX,iY).computeVelocity(u0);
00101             blockLattice.get (
00102                 iX+(direction==0 ? (-orientation):0),
00103                 iY+(direction==1 ? (-orientation):0) ).computeVelocity(u1);
00104             blockLattice.get (
00105                 iX+(direction==0 ? (-2*orientation):0),
00106                 iY+(direction==1 ? (-2*orientation):0) ).computeVelocity(u2);
00107 
00108             for (int iD=0; iD<Descriptor<T>::d; ++iD) {
00109                 velDeriv[iD] = -orientation * fd::fwd_diff(u0[iD], u1[iD], u2[iD]);
00110             }
00111         }
00112 
00113         static void o2_densityDerivative(T& rhoDeriv,
00114                                          BlockLattice2D<T,Descriptor> const& blockLattice,
00115                                          plint iX, plint iY)
00116         {
00117             T rho0 = blockLattice.get(iX,iY).computeDensity();
00118             T rho1 = blockLattice.get (
00119                           iX+(direction==0 ? (-orientation):0),
00120                           iY+(direction==1 ? (-orientation):0) ).computeDensity();
00121             T rho2 = blockLattice.get (
00122                             iX+(direction==0 ? (-2*orientation):0),
00123                         iY+(direction==1 ? (-2*orientation):0) ).computeDensity();
00124 
00125             rhoDeriv = -orientation * fd::fwd_diff(rho0, rho1, rho2);
00126 
00127         }
00128     };
00129 
00130 
00131     // Implementation for orthogonal==false; i.e. the derivative is aligned
00132     // with the boundary.
00133     template<typename T, template<typename U> class Descriptor,
00134              int direction, int orientation>
00135     struct DirectedGradients2D<T, Descriptor, direction, orientation, false> {
00136 
00137         static void o1_velocityDerivative(Array<T,Descriptor<T>::d>& velDeriv,
00138                                           BlockLattice2D<T,Descriptor> const& blockLattice,
00139                                           plint iX, plint iY)
00140         {
00141             // Along the boundary, second-order accuracy is achieved with a nearest-
00142             //   neighbor scheme.
00143             o2_velocityDerivative(velDeriv, blockLattice, iX, iY);
00144         }
00145         static void o1_densityDerivative(T& rhoDeriv,
00146                                          BlockLattice2D<T,Descriptor> const& blockLattice,
00147                                          plint iX, plint iY)
00148         {
00149             // Along the boundary, second-order accuracy is achieved with a nearest-
00150             //   neighbor scheme.
00151             o2_densityDerivative(rhoDeriv, blockLattice, iX, iY);
00152         }
00153         static void o2_velocityDerivative(Array<T,Descriptor<T>::d>& velDeriv,
00154                                           BlockLattice2D<T,Descriptor> const& blockLattice,
00155                                           plint iX, plint iY)
00156         {
00157             Array<T,Descriptor<T>::d> u_p1, u_m1;
00158             
00159             int deriveDirection = 1-direction;
00160             blockLattice.get (
00161                 iX+(deriveDirection==0 ? 1:0),
00162                 iY+(deriveDirection==1 ? 1:0) ).computeVelocity(u_p1);
00163             blockLattice.get (
00164                 iX+(deriveDirection==0 ? (-1):0),
00165                 iY+(deriveDirection==1 ? (-1):0) ).computeVelocity(u_m1);
00166 
00167             for (int iD=0; iD<Descriptor<T>::d; ++iD) {
00168                  velDeriv[iD] = fd::ctl_diff(u_p1[iD],u_m1[iD]);
00169             }
00170         }
00171 
00172         static void o2_densityDerivative(T& rhoDeriv,
00173                                          BlockLattice2D<T,Descriptor> const& blockLattice,
00174                                          plint iX, plint iY)
00175         {
00176             int deriveDirection = 1-direction;
00177             T rho_p1 = blockLattice.get (
00178                           iX+(deriveDirection==0 ? 1:0),
00179                           iY+(deriveDirection==1 ? 1:0) ).computeDensity();
00180             T rho_m1 = blockLattice.get (
00181                           iX+(deriveDirection==0 ? (-1):0),
00182                           iY+(deriveDirection==1 ? (-1):0) ).computeDensity();
00183 
00184             rhoDeriv = fd::ctl_diff(rho_p1, rho_m1);
00185 
00186         }
00187     };
00188 
00189 }  // namespace fd
00190 
00191 }  // namespace plb
00192 
00193 
00194 #endif