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

fdWrapper3D.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 
00028 #ifndef FINITE_DIFFERENCE_WRAPPER_3D_HH
00029 #define FINITE_DIFFERENCE_WRAPPER_3D_HH
00030 
00031 #include "finiteDifference/fdWrapper3D.h"
00032 #include "finiteDifference/fdFunctional3D.h"
00033 #include "atomicBlock/reductiveDataProcessorWrapper3D.h"
00034 #include "atomicBlock/dataProcessorWrapper3D.h"
00035 #include "multiBlock/reductiveMultiDataProcessorWrapper3D.h"
00036 #include "multiBlock/multiDataProcessorWrapper3D.h"
00037 
00038 
00039 
00040 namespace plb {
00041 
00042 template<typename T>
00043 void computeXderivative(MultiScalarField3D<T>& value, MultiScalarField3D<T>& derivative, Box3D const& domain) {
00044     plint boundaryWidth = 1;
00045     applyProcessingFunctional (
00046             new BoxXderivativeFunctional3D<T>, domain, value, derivative, boundaryWidth );
00047 }
00048 
00049 template<typename T>
00050 std::auto_ptr<MultiScalarField3D<T> > computeXderivative(MultiScalarField3D<T>& value, Box3D const& domain) {
00051     MultiScalarField3D<T>* derivative = new MultiScalarField3D<T>(value, domain);
00052     computeXderivative(value, *derivative, domain);
00053     return std::auto_ptr<MultiScalarField3D<T> >(derivative);
00054 }
00055 
00056 template<typename T>
00057 std::auto_ptr<MultiScalarField3D<T> > computeXderivative(MultiScalarField3D<T>& value) {
00058     return computeXderivative(value, value.getBoundingBox());
00059 }
00060 
00061 
00062 template<typename T>
00063 void computeYderivative(MultiScalarField3D<T>& value, MultiScalarField3D<T>& derivative, Box3D const& domain) {
00064     plint boundaryWidth = 1;
00065     applyProcessingFunctional (
00066             new BoxYderivativeFunctional3D<T>, domain, value, derivative, boundaryWidth );
00067 }
00068 
00069 template<typename T>
00070 std::auto_ptr<MultiScalarField3D<T> > computeYderivative(MultiScalarField3D<T>& value, Box3D const& domain) {
00071     MultiScalarField3D<T>* derivative = new MultiScalarField3D<T>(value, domain);
00072     computeYderivative(value, *derivative, domain);
00073     return std::auto_ptr<MultiScalarField3D<T> >(derivative);
00074 }
00075 
00076 template<typename T>
00077 std::auto_ptr<MultiScalarField3D<T> > computeYderivative(MultiScalarField3D<T>& value) {
00078     return computeYderivative(value, value.getBoundingBox());
00079 }
00080 
00081 template<typename T>
00082 void computeZderivative(MultiScalarField3D<T>& value, MultiScalarField3D<T>& derivative, Box3D const& domain) {
00083     plint boundaryWidth = 1;
00084     applyProcessingFunctional (
00085             new BoxZderivativeFunctional3D<T>, domain, value, derivative, boundaryWidth );
00086 }
00087 
00088 template<typename T>
00089 std::auto_ptr<MultiScalarField3D<T> > computeZderivative(MultiScalarField3D<T>& value, Box3D const& domain) {
00090     MultiScalarField3D<T>* derivative = new MultiScalarField3D<T>(value, domain);
00091     computeZderivative(value, *derivative, domain);
00092     return std::auto_ptr<MultiScalarField3D<T> >(derivative);
00093 }
00094 
00095 template<typename T>
00096 std::auto_ptr<MultiScalarField3D<T> > computeZderivative(MultiScalarField3D<T>& value) {
00097     return computeZderivative(value, value.getBoundingBox());
00098 }
00099 
00100 template<typename T>
00101 void computeGradientNorm(MultiScalarField3D<T>& value, MultiScalarField3D<T>& derivative, Box3D const& domain) {
00102     plint boundaryWidth = 1;
00103     applyProcessingFunctional (
00104             new BoxGradientNormFunctional3D<T>, domain, value, derivative, boundaryWidth );
00105 }
00106 
00107 template<typename T>
00108 std::auto_ptr<MultiScalarField3D<T> > computeGradientNorm(MultiScalarField3D<T>& value, Box3D const& domain) {
00109     MultiScalarField3D<T>* derivative = new MultiScalarField3D<T>(value, domain);
00110     computeGradientNorm(value, *derivative, domain);
00111     return std::auto_ptr<MultiScalarField3D<T> >(derivative);
00112 }
00113 
00114 template<typename T>
00115 std::auto_ptr<MultiScalarField3D<T> > computeGradientNorm(MultiScalarField3D<T>& value) {
00116     return computeGradientNorm(value, value.getBoundingBox());
00117 }
00118 
00119 template<typename T>
00120 std::auto_ptr<MultiScalarField3D<T> > computePoissonRHS(MultiTensorField3D<T,3>& velocity, Box3D const& domain)
00121 {
00122     std::auto_ptr<MultiScalarField3D<T> > ux = extractComponent(velocity, domain, 0);
00123     std::auto_ptr<MultiScalarField3D<T> > uy = extractComponent(velocity, domain, 1);
00124     std::auto_ptr<MultiScalarField3D<T> > uz = extractComponent(velocity, domain, 2);
00125 
00126     std::auto_ptr<MultiScalarField3D<T> > dx_ux = computeXderivative(*ux, domain);
00127     std::auto_ptr<MultiScalarField3D<T> > dy_ux = computeYderivative(*ux, domain);
00128     std::auto_ptr<MultiScalarField3D<T> > dz_ux = computeZderivative(*ux, domain);
00129     std::auto_ptr<MultiScalarField3D<T> > dx_uy = computeXderivative(*uy, domain);
00130     std::auto_ptr<MultiScalarField3D<T> > dy_uy = computeYderivative(*uy, domain);
00131     std::auto_ptr<MultiScalarField3D<T> > dz_uy = computeZderivative(*uy, domain);
00132     std::auto_ptr<MultiScalarField3D<T> > dx_uz = computeXderivative(*uz, domain);
00133     std::auto_ptr<MultiScalarField3D<T> > dy_uz = computeYderivative(*uz, domain);
00134     std::auto_ptr<MultiScalarField3D<T> > dz_uz = computeZderivative(*uz, domain);
00135 
00136     std::auto_ptr<MultiScalarField3D<T> > term1 = multiply(*dx_ux, *dx_ux, domain);
00137     std::auto_ptr<MultiScalarField3D<T> > term2 = multiply(*dy_uy, *dy_uy, domain);
00138     std::auto_ptr<MultiScalarField3D<T> > term3 = multiply(*dz_uz, *dz_uz, domain);
00139     
00140     std::auto_ptr<MultiScalarField3D<T> > term4 = multiply((T)2, *multiply(*dx_uy, *dy_ux, domain), domain);
00141     std::auto_ptr<MultiScalarField3D<T> > term5 = multiply((T)2, *multiply(*dx_uz, *dz_ux, domain), domain);
00142     std::auto_ptr<MultiScalarField3D<T> > term6 = multiply((T)2, *multiply(*dy_uz, *dz_uy, domain), domain);
00143 
00144     std::auto_ptr<MultiScalarField3D<T> > rhs = add(*term6, *add(*term5, *add(*term4, *add(*term1, *add(*term2, *term3)))));
00145     return rhs;
00146 }
00147 
00148 template<typename T>
00149 std::auto_ptr<MultiScalarField3D<T> > computePoissonRHS(MultiTensorField3D<T,3>& velocity) {
00150     return computePoissonRHS(velocity, velocity.getBoundingBox());
00151 }
00152 
00153 template<typename T>
00154 void poissonIterate(MultiScalarField3D<T>& oldPressure, MultiScalarField3D<T>& newPressure,
00155                     MultiScalarField3D<T>& rhs, T beta, Box3D const& domain, plint boundaryWidth)
00156 {
00157     std::vector<MultiScalarField3D<T>* > fields;
00158     fields.push_back(&oldPressure);
00159     fields.push_back(&newPressure);
00160     fields.push_back(&rhs);
00161     applyProcessingFunctional (
00162             new BoxPoissonIteration3D<T>(beta), domain, fields, boundaryWidth );
00163 }
00164 
00165 template<typename T>
00166 T computePoissonResidue(MultiScalarField3D<T>& pressure, MultiScalarField3D<T>& rhs, Box3D const& domain) {
00167     BoxPoissonResidueFunctional3D<T> functional;
00168     applyProcessingFunctional(functional, domain, pressure, rhs);
00169     return functional.getMaxResidue();
00170 }
00171 
00172 
00173 // ========================================================================= //
00174 // PERIODIC VERSIONS OF THE DERIVATIVES AND POISSON SCHEMES //
00175 // ========================================================================= //
00176 
00177 
00178 template<typename T>
00179 void computeXperiodicDerivative(MultiScalarField3D<T>& value, MultiScalarField3D<T>& derivative, Box3D const& domain) {
00180     plint boundaryWidth = 1;
00181     applyProcessingFunctional (
00182             new BoxXperiodicDerivativeFunctional3D<T>, domain, value, derivative, boundaryWidth );
00183 }
00184 
00185 template<typename T>
00186 std::auto_ptr<MultiScalarField3D<T> > computeXperiodicDerivative(MultiScalarField3D<T>& value, Box3D const& domain) {
00187     MultiScalarField3D<T>* derivative = new MultiScalarField3D<T>(value, domain);
00188     computeXperiodicDerivative(value, *derivative, domain);
00189     return std::auto_ptr<MultiScalarField3D<T> >(derivative);
00190 }
00191 
00192 template<typename T>
00193 std::auto_ptr<MultiScalarField3D<T> > computeXperiodicDerivative(MultiScalarField3D<T>& value) {
00194     return computeXperiodicDerivative(value, value.getBoundingBox());
00195 }
00196 
00197 
00198 template<typename T>
00199 void computeYperiodicDerivative(MultiScalarField3D<T>& value, MultiScalarField3D<T>& derivative, Box3D const& domain) {
00200     plint boundaryWidth = 1;
00201     applyProcessingFunctional (
00202             new BoxYperiodicDerivativeFunctional3D<T>, domain, value, derivative, boundaryWidth );
00203 }
00204 
00205 template<typename T>
00206 std::auto_ptr<MultiScalarField3D<T> > computeYperiodicDerivative(MultiScalarField3D<T>& value, Box3D const& domain) {
00207     MultiScalarField3D<T>* derivative = new MultiScalarField3D<T>(value, domain);
00208     computeYperiodicDerivative(value, *derivative, domain);
00209     return std::auto_ptr<MultiScalarField3D<T> >(derivative);
00210 }
00211 
00212 template<typename T>
00213 std::auto_ptr<MultiScalarField3D<T> > computeYperiodicDerivative(MultiScalarField3D<T>& value) {
00214     return computeYperiodicDerivative(value, value.getBoundingBox());
00215 }
00216 
00217 template<typename T>
00218 void computeZperiodicDerivative(MultiScalarField3D<T>& value, MultiScalarField3D<T>& derivative, Box3D const& domain) {
00219     plint boundaryWidth = 1;
00220     applyProcessingFunctional (
00221             new BoxZperiodicDerivativeFunctional3D<T>, domain, value, derivative, boundaryWidth );
00222 }
00223 
00224 template<typename T>
00225 std::auto_ptr<MultiScalarField3D<T> > computeZperiodicDerivative(MultiScalarField3D<T>& value, Box3D const& domain) {
00226     MultiScalarField3D<T>* derivative = new MultiScalarField3D<T>(value, domain);
00227     computeZperiodicDerivative(value, *derivative, domain);
00228     return std::auto_ptr<MultiScalarField3D<T> >(derivative);
00229 }
00230 
00231 template<typename T>
00232 std::auto_ptr<MultiScalarField3D<T> > computeZperiodicDerivative(MultiScalarField3D<T>& value) {
00233     return computeZperiodicDerivative(value, value.getBoundingBox());
00234 }
00235 
00236 template<typename T>
00237 void computePeriodicGradientNorm(MultiScalarField3D<T>& value, MultiScalarField3D<T>& derivative, Box3D const& domain) {
00238     plint boundaryWidth = 1;
00239     applyProcessingFunctional (
00240             new BoxGradientNormFunctional3D<T>, domain, value, derivative, boundaryWidth );
00241 }
00242 
00243 template<typename T>
00244 std::auto_ptr<MultiScalarField3D<T> > computePeriodicGradientNorm(MultiScalarField3D<T>& value, Box3D const& domain) {
00245     MultiScalarField3D<T>* derivative = new MultiScalarField3D<T>(value, domain);
00246     computePeriodicGradientNorm(value, *derivative, domain);
00247     return std::auto_ptr<MultiScalarField3D<T> >(derivative);
00248 }
00249 
00250 template<typename T>
00251 std::auto_ptr<MultiScalarField3D<T> > computePeriodicGradientNorm(MultiScalarField3D<T>& value) {
00252     return computePeriodicGradientNorm(value, value.getBoundingBox());
00253 }
00254 
00255 template<typename T>
00256 std::auto_ptr<MultiScalarField3D<T> > computePeriodicPoissonRHS(MultiTensorField3D<T,3>& velocity, Box3D const& domain)
00257 {
00258     std::auto_ptr<MultiScalarField3D<T> > ux = extractComponent(velocity, domain, 0);
00259     ux->periodicity().toggleAll(true);
00260     std::auto_ptr<MultiScalarField3D<T> > uy = extractComponent(velocity, domain, 1);
00261     uy->periodicity().toggleAll(true);
00262     std::auto_ptr<MultiScalarField3D<T> > uz = extractComponent(velocity, domain, 2);
00263     uz->periodicity().toggleAll(true);
00264 
00265     std::auto_ptr<MultiScalarField3D<T> > dx_ux = computeXperiodicDerivative(*ux, domain);
00266     std::auto_ptr<MultiScalarField3D<T> > dy_ux = computeYperiodicDerivative(*ux, domain);
00267     std::auto_ptr<MultiScalarField3D<T> > dz_ux = computeZperiodicDerivative(*ux, domain);
00268     std::auto_ptr<MultiScalarField3D<T> > dx_uy = computeXperiodicDerivative(*uy, domain);
00269     std::auto_ptr<MultiScalarField3D<T> > dy_uy = computeYperiodicDerivative(*uy, domain);
00270     std::auto_ptr<MultiScalarField3D<T> > dz_uy = computeZperiodicDerivative(*uy, domain);
00271     std::auto_ptr<MultiScalarField3D<T> > dx_uz = computeXperiodicDerivative(*uz, domain);
00272     std::auto_ptr<MultiScalarField3D<T> > dy_uz = computeYperiodicDerivative(*uz, domain);
00273     std::auto_ptr<MultiScalarField3D<T> > dz_uz = computeZperiodicDerivative(*uz, domain);
00274 
00275     std::auto_ptr<MultiScalarField3D<T> > term1 = multiply(*dx_ux, *dx_ux, domain);
00276     std::auto_ptr<MultiScalarField3D<T> > term2 = multiply(*dy_uy, *dy_uy, domain);
00277     std::auto_ptr<MultiScalarField3D<T> > term3 = multiply(*dz_uz, *dz_uz, domain);
00278     
00279     std::auto_ptr<MultiScalarField3D<T> > term4 = multiply((T)2, *multiply(*dx_uy, *dy_ux, domain), domain);
00280     std::auto_ptr<MultiScalarField3D<T> > term5 = multiply((T)2, *multiply(*dx_uz, *dz_ux, domain), domain);
00281     std::auto_ptr<MultiScalarField3D<T> > term6 = multiply((T)2, *multiply(*dy_uz, *dz_uy, domain), domain);
00282 
00283     std::auto_ptr<MultiScalarField3D<T> > rhs = add(*term6, *add(*term5, *add(*term4, *add(*term1, *add(*term2, *term3)))));
00284     return rhs;
00285 }
00286 
00287 template<typename T>
00288 std::auto_ptr<MultiScalarField3D<T> > computePeriodicPoissonRHS(MultiTensorField3D<T,3>& velocity) {
00289     return computePeriodicPoissonRHS(velocity, velocity.getBoundingBox());
00290 }
00291 
00292 template<typename T>
00293 void periodicPoissonIterate(MultiScalarField3D<T>& oldPressure, MultiScalarField3D<T>& newPressure,
00294                     MultiScalarField3D<T>& rhs, T beta, Box3D const& domain)
00295 {
00296     std::vector<MultiScalarField3D<T>* > fields;
00297     fields.push_back(&oldPressure);
00298     fields.push_back(&newPressure);
00299     fields.push_back(&rhs);
00300     applyProcessingFunctional (
00301         new BoxPeriodicPoissonIteration3D<T>(beta), domain, fields );
00302 }
00303 
00304 
00305 
00306 }  // namespace plb
00307 
00308 #endif  // FINITE_DIFFERENCE_WRAPPER_3D_HH