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

parallelDynamics.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 PARALLEL_DYNAMICS_HH
00029 #define PARALLEL_DYNAMICS_HH
00030 
00031 #include "parallelism/mpiManager.h"
00032 #include "parallelism/parallelDynamics.h"
00033 
00034 namespace plb {
00035 
00036 
00037 #ifdef PLB_MPI_PARALLEL
00038 
00039 
00041 
00042 template<typename T, template<typename U> class Descriptor>
00043 ParallelDynamics<T,Descriptor>::ParallelDynamics(std::vector<Cell<T,Descriptor>*>& baseCells_, bool hasBulkCell_)
00044     : baseCells(baseCells_), hasBulkCell(hasBulkCell_)
00045 { }
00046 
00047 template<typename T, template<typename U> class Descriptor>
00048 Dynamics<T,Descriptor>* ParallelDynamics<T,Descriptor>::clone() const {
00049     return new ParallelDynamics(*this);
00050 }
00051 
00052 template<typename T, template<typename U> class Descriptor>
00053 void ParallelDynamics<T,Descriptor>::collide(Cell<T,Descriptor>& cell, BlockStatistics& statistics_) {
00054     for (pluint iCell=0; iCell<baseCells.size(); ++iCell) {
00055         baseCells[iCell] -> collide(statistics_);
00056     }
00057 }
00058 
00059 template<typename T, template<typename U> class Descriptor>
00060 T ParallelDynamics<T,Descriptor>::computeEquilibrium (
00061         plint iPop, T rhoBar, Array<T,Descriptor<T>::d> const& j, T jSqr, T thetaBar) const
00062 {
00063     T eq = T();
00064     if (hasBulkCell) {
00065         eq = baseCells[0] -> computeEquilibrium(iPop, rhoBar, j, jSqr, thetaBar);
00066     }
00067     global::mpi().bCastThroughMaster(&eq, 1, hasBulkCell);
00068     return eq;
00069 }
00070 
00071 template<typename T, template<typename U> class Descriptor>
00072 void ParallelDynamics<T,Descriptor>::regularize (
00073         Cell<T,Descriptor>& cell, T rhoBar, Array<T,Descriptor<T>::d> const& j,
00074         T jSqr, Array<T,SymmetricTensor<T,Descriptor>::n> const& PiNeq, T thetaBar ) const
00075 {
00076     for (pluint iCell=0; iCell<baseCells.size(); ++iCell) {
00077         baseCells[iCell] -> regularize(rhoBar, j, jSqr, PiNeq, thetaBar);
00078     }
00079 }
00080 
00081 template<typename T, template<typename U> class Descriptor>
00082 T ParallelDynamics<T,Descriptor>::computeDensity(Cell<T,Descriptor> const& cell) const {
00083     T rho = T();
00084     if (hasBulkCell) {
00085         rho = baseCells[0] -> computeDensity();
00086     }
00087     global::mpi().bCastThroughMaster(&rho, 1, hasBulkCell);
00088     return rho;
00089 }
00090 
00091 template<typename T, template<typename U> class Descriptor>
00092 T ParallelDynamics<T,Descriptor>::computePressure(Cell<T,Descriptor> const& cell) const {
00093     T p = T();
00094     if (hasBulkCell) {
00095         p = baseCells[0] -> computePressure();
00096     }
00097     global::mpi().bCastThroughMaster(&p, 1, hasBulkCell);
00098     return p;
00099 }
00100 
00101 template<typename T, template<typename U> class Descriptor>
00102 void ParallelDynamics<T,Descriptor>::computeVelocity(Cell<T,Descriptor> const& cell,
00103                                                      Array<T,Descriptor<T>::d>& u ) const
00104 {
00105     if (hasBulkCell) {
00106         baseCells[0] -> computeVelocity(u);
00107     }
00108     global::mpi().bCastThroughMaster(&u[0], Descriptor<T>::d, hasBulkCell);
00109 }
00110 
00111 template<typename T, template<typename U> class Descriptor>
00112 T ParallelDynamics<T,Descriptor>::computeTemperature(Cell<T,Descriptor> const& cell) const {
00113     T theta = T();
00114     if (hasBulkCell) {
00115         theta = baseCells[0] -> computeTemperature();
00116     }
00117     global::mpi().bCastThroughMaster(&theta, 1, hasBulkCell);
00118     return theta;
00119 }
00120 
00121 template<typename T, template<typename U> class Descriptor>
00122 void ParallelDynamics<T,Descriptor>::computeDeviatoricStress (
00123         Cell<T,Descriptor> const& cell, Array<T,SymmetricTensor<T,Descriptor>::n>& PiNeq ) const
00124 {
00125     if (hasBulkCell) {
00126         baseCells[0] -> getDynamics().computeDeviatoricStress(*baseCells[0], PiNeq);
00127     }
00128     global::mpi().bCastThroughMaster(&PiNeq[0], SymmetricTensor<T,Descriptor>::n, hasBulkCell);
00129 }
00130 
00131 template<typename T, template<typename U> class Descriptor>
00132 void ParallelDynamics<T,Descriptor>::computeHeatFlux(Cell<T,Descriptor> const& cell,
00133                                                      Array<T,Descriptor<T>::d>& q ) const
00134 {
00135     if (hasBulkCell) {
00136         baseCells[0] -> computeHeatFlux(q);
00137     }
00138     global::mpi().bCastThroughMaster(&q[0], Descriptor<T>::d, hasBulkCell);
00139 }
00140 
00141 template<typename T, template<typename U> class Descriptor>
00142 void ParallelDynamics<T,Descriptor>::computeMoment(Cell<T,Descriptor> const& cell, plint momentId, T* moment) const
00143 {
00144     // Cannot transfer generic moment through MPI,
00145     // because the type size is unknown
00146     PLB_PRECONDITION(false);
00147 }
00148 
00149 template<typename T, template<typename U> class Descriptor>
00150 T ParallelDynamics<T,Descriptor>::getOmega() const {
00151     T omega = T();
00152     if (hasBulkCell) {
00153         omega = baseCells[0] -> getDynamics().getOmega();
00154     }
00155     global::mpi().bCastThroughMaster(&omega, 1, hasBulkCell);
00156     return omega;
00157 }
00158 
00159 template<typename T, template<typename U> class Descriptor>
00160 void ParallelDynamics<T,Descriptor>::setOmega(T omega_) {
00161     for (pluint iCell=0; iCell<baseCells.size(); ++iCell) {
00162         baseCells[iCell] -> getDynamics().setOmega(omega_);
00163     }
00164 }
00165 
00166 template<typename T, template<typename U> class Descriptor>
00167 T ParallelDynamics<T,Descriptor>::getParameter(plint whichParameter) const {
00168     T parameter = T();
00169     if (hasBulkCell) {
00170         parameter = baseCells[0] -> getDynamics().getParameter(whichParameter);
00171     }
00172     global::mpi().bCastThroughMaster(&parameter, 1, hasBulkCell);
00173     return parameter;
00174 }
00175 
00176 template<typename T, template<typename U> class Descriptor>
00177 void ParallelDynamics<T,Descriptor>::setParameter(plint whichParameter, T value) {
00178     for (pluint iCell=0; iCell<baseCells.size(); ++iCell) {
00179         baseCells[iCell] -> getDynamics().setParameter(whichParameter, value);
00180     }
00181 }
00182 
00183 template<typename T, template<typename U> class Descriptor>
00184 plint ParallelDynamics<T,Descriptor>::numDecomposedVariables(plint order) const {
00185     plint numVariables = 0;
00186     if (hasBulkCell) {
00187         numVariables = baseCells[0] -> getDynamics().numDecomposedVariables(order);
00188     }
00189     global::mpi().bCastThroughMaster(&numVariables, 1, hasBulkCell);
00190     return numVariables;
00191 
00192 }
00193 
00194 template<typename T, template<typename U> class Descriptor>
00195 void ParallelDynamics<T,Descriptor>::decompose(Cell<T,Descriptor> const& cell, std::vector<T>& rawData, plint order) const
00196 {
00197     if (hasBulkCell) {
00198         baseCells[0] -> getDynamics().decompose(cell, rawData, order);
00199     }
00200     plint numVariables = numDecomposedVariables(order);
00201     global::mpi().bCastThroughMaster(&rawData[0], numVariables, hasBulkCell);
00202 }
00203 
00204 template<typename T, template<typename U> class Descriptor>
00205 void ParallelDynamics<T,Descriptor>::recompose(Cell<T,Descriptor>& cell, std::vector<T> const& rawData, plint order) const
00206 {
00207     for (pluint iCell=0; iCell<baseCells.size(); ++iCell) {
00208         baseCells[iCell] -> getDynamics().recompose(cell, rawData, order);
00209     }
00210 }
00211 
00212 template<typename T, template<typename U> class Descriptor>
00213 void ParallelDynamics<T,Descriptor>::rescale(std::vector<T>& rawData, T xDxInv, T xDt, plint order) const
00214 {
00215     if (hasBulkCell) {
00216         baseCells[0] -> getDynamics().rescale(rawData, xDxInv, xDt, order);
00217     }
00218     plint numVariables = numDecomposedVariables(order);
00219     global::mpi().bCastThroughMaster(&rawData[0], numVariables, hasBulkCell);
00220 }
00221 
00222 
00223 template<typename T, template<typename U> class Descriptor>
00224 void ParallelDynamics<T,Descriptor>::getPopulations(Cell<T,Descriptor> const& cell, Array<T,Descriptor<T>::q>& f) const
00225 {
00226     if (hasBulkCell) {
00227         baseCells[0] -> getPopulations(f);
00228     }
00229     global::mpi().bCastThroughMaster(&f[0], Descriptor<T>::q, hasBulkCell);
00230 }
00231 
00232 template<typename T, template<typename U> class Descriptor>
00233 void ParallelDynamics<T,Descriptor>::getExternalField (
00234         Cell<T,Descriptor> const& cell, plint pos, plint size, T* ext ) const
00235 {
00236     if (hasBulkCell) {
00237         baseCells[0] -> getExternalField(pos, size, ext);
00238     }
00239     global::mpi().bCastThroughMaster(ext, Descriptor<T>::ExternalField::numScalars, hasBulkCell);
00240 }
00241 
00242 template<typename T, template<typename U> class Descriptor>
00243 void ParallelDynamics<T,Descriptor>::setPopulations(Cell<T,Descriptor>& cell, Array<T,Descriptor<T>::q> const& f)
00244 {
00245     for (pluint iCell=0; iCell<baseCells.size(); ++iCell) {
00246         baseCells[iCell] -> setPopulations(f);
00247     }
00248 }
00249 
00250 template<typename T, template<typename U> class Descriptor>
00251 void ParallelDynamics<T,Descriptor>::setExternalField (
00252         Cell<T,Descriptor>& cell, plint pos, plint size, const T* ext )
00253 {
00254     for (pluint iCell=0; iCell<baseCells.size(); ++iCell) {
00255         baseCells[iCell] -> setExternalField(pos, size, ext);
00256     }
00257 }
00258 
00259 template<typename T, template<typename U> class Descriptor>
00260 void ParallelDynamics<T,Descriptor>::defineDensity(Cell<T,Descriptor>& cell, T rho) {
00261     for (pluint iCell=0; iCell<baseCells.size(); ++iCell) {
00262         baseCells[iCell] -> defineDensity(rho);
00263     }
00264 }
00265 
00266 template<typename T, template<typename U> class Descriptor>
00267 void ParallelDynamics<T,Descriptor>::defineVelocity(Cell<T,Descriptor>& cell, Array<T,Descriptor<T>::d> const& u) {
00268     for (pluint iCell=0; iCell<baseCells.size(); ++iCell) {
00269         baseCells[iCell] -> defineVelocity(u);
00270     }
00271 }
00272 
00273 template<typename T, template<typename U> class Descriptor>
00274 void ParallelDynamics<T,Descriptor>::defineTemperature(Cell<T,Descriptor>& cell, T temperature) {
00275     for (pluint iCell=0; iCell<baseCells.size(); ++iCell) {
00276         baseCells[iCell] -> defineTemperature(temperature);
00277     }
00278 }
00279 
00280 template<typename T, template<typename U> class Descriptor>
00281 void ParallelDynamics<T,Descriptor>::defineHeatFlux(Cell<T,Descriptor>& cell, Array<T,Descriptor<T>::d> const& q) {
00282     for (pluint iCell=0; iCell<baseCells.size(); ++iCell) {
00283         baseCells[iCell] -> defineHeatFlux(q);
00284     }
00285 }
00286 
00287 template<typename T, template<typename U> class Descriptor>
00288 void ParallelDynamics<T,Descriptor>::defineDeviatoricStress (
00289     Cell<T,Descriptor>& cell, Array<T,SymmetricTensor<T,Descriptor>::n> const& PiNeq)
00290 {
00291     for (pluint iCell=0; iCell<baseCells.size(); ++iCell) {
00292         baseCells[iCell] -> defineDeviatoricStress(PiNeq);
00293     }
00294 }
00295 
00296 template<typename T, template<typename U> class Descriptor>
00297 void ParallelDynamics<T,Descriptor>::defineMoment (
00298         Cell<T,Descriptor>& cell, plint momentId, T const* value)
00299 {
00300     for (pluint iCell=0; iCell<baseCells.size(); ++iCell) {
00301         baseCells[iCell] -> defineMoment(momentId, value);
00302     }
00303 }
00304 
00305 template<typename T, template<typename U> class Descriptor>
00306 T ParallelDynamics<T,Descriptor>::computeRhoBar(Cell<T,Descriptor> const& cell) const
00307 {
00308     T rhoBar = T();
00309     if (hasBulkCell) {
00310         baseCells[0] -> getDynamics().computeRhoBar(*baseCells[0]);
00311     }
00312     global::mpi().bCastThroughMaster(&rhoBar, 1, hasBulkCell);
00313     return rhoBar;
00314 }
00315 
00316 template<typename T, template<typename U> class Descriptor>
00317 void ParallelDynamics<T,Descriptor>::computeRhoBarJ (
00318         Cell<T,Descriptor> const& cell, T& rhoBar, Array<T,Descriptor<T>::d>& j ) const
00319 {
00320     if (hasBulkCell) {
00321         baseCells[0] -> getDynamics().computeRhoBarJ(*baseCells[0],rhoBar, j);
00322     }
00323     global::mpi().bCastThroughMaster(&rhoBar, 1, hasBulkCell);
00324     global::mpi().bCastThroughMaster(&j[0], Descriptor<T>::d, hasBulkCell);
00325 }
00326 
00327 template<typename T, template<typename U> class Descriptor>
00328 void ParallelDynamics<T,Descriptor>::computeRhoBarJPiNeq (
00329         Cell<T,Descriptor> const& cell, T& rhoBar, Array<T,Descriptor<T>::d>& j,
00330         Array<T,SymmetricTensor<T,Descriptor>::n>& PiNeq ) const
00331 {
00332     if (hasBulkCell) {
00333         baseCells[0] -> getDynamics().computeRhoBarJPiNeq(*baseCells[0],rhoBar, j, PiNeq);
00334     }
00335     global::mpi().bCastThroughMaster(&rhoBar, 1, hasBulkCell);
00336     global::mpi().bCastThroughMaster(&j[0], Descriptor<T>::d, hasBulkCell);
00337     global::mpi().bCastThroughMaster(&PiNeq[0], SymmetricTensor<T,Descriptor>::n, hasBulkCell);
00338 }
00339 
00340 template<typename T, template<typename U> class Descriptor>
00341 T ParallelDynamics<T,Descriptor>::computeEbar(Cell<T,Descriptor> const& cell) const {
00342     T eBar = T();
00343     if (hasBulkCell) {
00344         eBar = baseCells[0] -> getDynamics().computeEbar(*baseCells[0]);
00345     }
00346     global::mpi().bCastThroughMaster(&eBar, 1, hasBulkCell);
00347     return eBar;
00348 }
00349 
00350 
00352 
00353 
00354 template<typename T, template<typename U> class Descriptor>
00355 ConstParallelDynamics<T,Descriptor>::ConstParallelDynamics(std::vector<Cell<T,Descriptor> const*>& baseCells_, bool hasBulkCell_)
00356     : baseCells(baseCells_), hasBulkCell(hasBulkCell_)
00357 { }
00358 
00359 template<typename T, template<typename U> class Descriptor>
00360 Dynamics<T,Descriptor>* ConstParallelDynamics<T,Descriptor>::clone() const {
00361     return new ConstParallelDynamics(*this);
00362 }
00363 
00364 template<typename T, template<typename U> class Descriptor>
00365 void ConstParallelDynamics<T,Descriptor>::collide(Cell<T,Descriptor>& cell, BlockStatistics& statistics_)
00366 { }
00367 
00368 template<typename T, template<typename U> class Descriptor>
00369 T ConstParallelDynamics<T,Descriptor>::computeEquilibrium (
00370         plint iPop, T rhoBar, Array<T,Descriptor<T>::d> const& j, T jSqr, T thetaBar) const
00371 {
00372     T eq = T();
00373     if (hasBulkCell) {
00374         eq = baseCells[0] -> computeEquilibrium(iPop, rhoBar, j, jSqr, thetaBar);
00375     }
00376     global::mpi().bCastThroughMaster(&eq, 1, hasBulkCell);
00377     return eq;
00378 }
00379 
00380 template<typename T, template<typename U> class Descriptor>
00381 void ConstParallelDynamics<T,Descriptor>::regularize (
00382         Cell<T,Descriptor>& cell, T rhoBar, Array<T,Descriptor<T>::d> const& j,
00383         T jSqr, Array<T,SymmetricTensor<T,Descriptor>::n> const& PiNeq, T thetaBar ) const
00384 { }
00385 
00386 template<typename T, template<typename U> class Descriptor>
00387 T ConstParallelDynamics<T,Descriptor>::computeDensity(Cell<T,Descriptor> const& cell) const {
00388     T rho = T();
00389     if (hasBulkCell) {
00390         rho = baseCells[0] -> computeDensity();
00391     }
00392     global::mpi().bCastThroughMaster(&rho, 1, hasBulkCell);
00393     return rho;
00394 }
00395 
00396 template<typename T, template<typename U> class Descriptor>
00397 T ConstParallelDynamics<T,Descriptor>::computePressure(Cell<T,Descriptor> const& cell) const {
00398     T p = T();
00399     if (hasBulkCell) {
00400         p = baseCells[0] -> computePressure();
00401     }
00402     global::mpi().bCastThroughMaster(&p, 1, hasBulkCell);
00403     return p;
00404 }
00405 
00406 template<typename T, template<typename U> class Descriptor>
00407 void ConstParallelDynamics<T,Descriptor>::computeVelocity(Cell<T,Descriptor> const& cell,
00408                                                           Array<T,Descriptor<T>::d>& u ) const
00409 {
00410     if (hasBulkCell) {
00411         baseCells[0] -> computeVelocity(u);
00412     }
00413     global::mpi().bCastThroughMaster(&u[0], Descriptor<T>::d, hasBulkCell);
00414 }
00415 
00416 
00417 template<typename T, template<typename U> class Descriptor>
00418 T ConstParallelDynamics<T,Descriptor>::computeTemperature(Cell<T,Descriptor> const& cell) const {
00419     T theta = T();
00420     if (hasBulkCell) {
00421         theta = baseCells[0] -> computeTemperature();
00422     }
00423     global::mpi().bCastThroughMaster(&theta, 1, hasBulkCell);
00424     return theta;
00425 }
00426 
00427 template<typename T, template<typename U> class Descriptor>
00428 void ConstParallelDynamics<T,Descriptor>::computeDeviatoricStress (
00429         Cell<T,Descriptor> const& cell, Array<T,SymmetricTensor<T,Descriptor>::n>& PiNeq ) const
00430 {
00431     if (hasBulkCell) {
00432         baseCells[0] -> getDynamics().computeDeviatoricStress(*baseCells[0], PiNeq);
00433     }
00434     global::mpi().bCastThroughMaster(&PiNeq[0], SymmetricTensor<T,Descriptor>::n, hasBulkCell);
00435 }
00436 
00437 template<typename T, template<typename U> class Descriptor>
00438 void ConstParallelDynamics<T,Descriptor>::computeHeatFlux(Cell<T,Descriptor> const& cell,
00439                                                           Array<T,Descriptor<T>::d>& q ) const
00440 {
00441     if (hasBulkCell) {
00442         baseCells[0] -> computeHeatFlux(q);
00443     }
00444     global::mpi().bCastThroughMaster(&q[0], Descriptor<T>::d, hasBulkCell);
00445 }
00446 
00447 template<typename T, template<typename U> class Descriptor>
00448 void ConstParallelDynamics<T,Descriptor>::computeMoment(Cell<T,Descriptor> const& cell, plint momentId, T* moment) const
00449 {
00450     // Cannot transfer generic moment through MPI,
00451     // because the type size is unknown
00452     PLB_PRECONDITION(false);
00453 }
00454 
00455 template<typename T, template<typename U> class Descriptor>
00456 T ConstParallelDynamics<T,Descriptor>::getOmega() const {
00457     T omega = T();
00458     if (hasBulkCell) {
00459         omega = baseCells[0] -> getDynamics().getOmega();
00460     }
00461     global::mpi().bCastThroughMaster(&omega, 1, hasBulkCell);
00462     return omega;
00463 }
00464 
00465 template<typename T, template<typename U> class Descriptor>
00466 void ConstParallelDynamics<T,Descriptor>::setOmega(T omega_)
00467 { }
00468 
00469 template<typename T, template<typename U> class Descriptor>
00470 T ConstParallelDynamics<T,Descriptor>::getParameter(plint whichParameter) const {
00471     T parameter = T();
00472     if (hasBulkCell) {
00473         parameter = baseCells[0] -> getDynamics().getParameter(whichParameter);
00474     }
00475     global::mpi().bCastThroughMaster(&parameter, 1, hasBulkCell);
00476     return parameter;
00477 }
00478 
00479 template<typename T, template<typename U> class Descriptor>
00480 void ConstParallelDynamics<T,Descriptor>::setParameter(plint whichParameter, T value)
00481 { }
00482 
00483 template<typename T, template<typename U> class Descriptor>
00484 plint ConstParallelDynamics<T,Descriptor>::numDecomposedVariables(plint order) const {
00485     plint numVariables = 0;
00486     if (hasBulkCell) {
00487         numVariables = baseCells[0] -> getDynamics().numDecomposedVariables(order);
00488     }
00489     global::mpi().bCastThroughMaster(&numVariables, 1, hasBulkCell);
00490     return numVariables;
00491 
00492 }
00493 
00494 template<typename T, template<typename U> class Descriptor>
00495 void ConstParallelDynamics<T,Descriptor>::decompose(Cell<T,Descriptor> const& cell, std::vector<T>& rawData, plint order) const
00496 {
00497     if (hasBulkCell) {
00498         baseCells[0] -> getDynamics().decompose(cell, rawData, order);
00499     }
00500     plint numVariables = numDecomposedVariables(order);
00501     global::mpi().bCastThroughMaster(&rawData[0], numVariables, hasBulkCell);
00502 }
00503 
00504 template<typename T, template<typename U> class Descriptor>
00505 void ConstParallelDynamics<T,Descriptor>::recompose(Cell<T,Descriptor>& cell, std::vector<T> const& rawData, plint order) const
00506 {
00507     for (pluint iCell=0; iCell<baseCells.size(); ++iCell) {
00508         baseCells[iCell] -> getDynamics().recompose(cell, rawData, order);
00509     }
00510 }
00511 
00512 template<typename T, template<typename U> class Descriptor>
00513 void ConstParallelDynamics<T,Descriptor>::rescale(std::vector<T>& rawData, T xDxInv, T xDt, plint order) const
00514 {
00515     if (hasBulkCell) {
00516         baseCells[0] -> getDynamics().rescale(rawData, xDxInv, xDt, order);
00517     }
00518     plint numVariables = numDecomposedVariables(order);
00519     global::mpi().bCastThroughMaster(&rawData[0], numVariables, hasBulkCell);
00520 }
00521 
00522 template<typename T, template<typename U> class Descriptor>
00523 void ConstParallelDynamics<T,Descriptor>::getPopulations(Cell<T,Descriptor> const& cell, Array<T,Descriptor<T>::q>& f) const
00524 {
00525     if (hasBulkCell) {
00526         baseCells[0] -> getPopulations(f);
00527     }
00528     global::mpi().bCastThroughMaster(&f[0], Descriptor<T>::q, hasBulkCell);
00529 }
00530 
00531 template<typename T, template<typename U> class Descriptor>
00532 void ConstParallelDynamics<T,Descriptor>::getExternalField (
00533         Cell<T,Descriptor> const& cell, plint pos, plint size, T* ext ) const
00534 {
00535     if (hasBulkCell) {
00536         baseCells[0] -> getExternalField(pos, size, ext);
00537     }
00538     global::mpi().bCastThroughMaster(ext, Descriptor<T>::ExternalField::numScalars, hasBulkCell);
00539 }
00540 
00541 template<typename T, template<typename U> class Descriptor>
00542 void ConstParallelDynamics<T,Descriptor>::setPopulations(Cell<T,Descriptor>& cell, Array<T,Descriptor<T>::q> const& f)
00543 { }
00544 
00545 template<typename T, template<typename U> class Descriptor>
00546 void ConstParallelDynamics<T,Descriptor>::setExternalField (
00547         Cell<T,Descriptor>& cell, plint pos, plint size, const T* ext )
00548 { }
00549 
00550 template<typename T, template<typename U> class Descriptor>
00551 void ConstParallelDynamics<T,Descriptor>::defineDensity(Cell<T,Descriptor>& cell, T rho)
00552 { }
00553 
00554 template<typename T, template<typename U> class Descriptor>
00555 void ConstParallelDynamics<T,Descriptor>::defineVelocity(Cell<T,Descriptor>& cell, Array<T,Descriptor<T>::d> const& u)
00556 { }
00557 
00558 template<typename T, template<typename U> class Descriptor>
00559 void ConstParallelDynamics<T,Descriptor>::defineTemperature(Cell<T,Descriptor>& cell, T temperature)
00560 { }
00561 
00562 template<typename T, template<typename U> class Descriptor>
00563 void ConstParallelDynamics<T,Descriptor>::defineHeatFlux(Cell<T,Descriptor>& cell, Array<T,Descriptor<T>::d> const& q)
00564 { }
00565 
00566 template<typename T, template<typename U> class Descriptor>
00567 void ConstParallelDynamics<T,Descriptor>::defineDeviatoricStress (
00568     Cell<T,Descriptor>& cell, Array<T,SymmetricTensor<T,Descriptor>::n> const& PiNeq)
00569 { }
00570 
00571 template<typename T, template<typename U> class Descriptor>
00572 void ConstParallelDynamics<T,Descriptor>::defineMoment (
00573         Cell<T,Descriptor>& cell, plint momentId, T const* value)
00574 { }
00575 
00576 template<typename T, template<typename U> class Descriptor>
00577 T ConstParallelDynamics<T,Descriptor>::computeRhoBar(Cell<T,Descriptor> const& cell) const
00578 {
00579     T rhoBar = T();
00580     if (hasBulkCell) {
00581         baseCells[0] -> getDynamics().computeRhoBar(*baseCells[0]);
00582     }
00583     global::mpi().bCastThroughMaster(&rhoBar, 1, hasBulkCell);
00584     return rhoBar;
00585 }
00586 
00587 template<typename T, template<typename U> class Descriptor>
00588 void ConstParallelDynamics<T,Descriptor>::computeRhoBarJ (
00589         Cell<T,Descriptor> const& cell, T& rhoBar, Array<T,Descriptor<T>::d>& j ) const
00590 {
00591     if (hasBulkCell) {
00592         baseCells[0] -> getDynamics().computeRhoBarJ(*baseCells[0], rhoBar, j);
00593     }
00594     global::mpi().bCastThroughMaster(&rhoBar, 1, hasBulkCell);
00595     global::mpi().bCastThroughMaster(&j[0], Descriptor<T>::d, hasBulkCell);
00596 }
00597 
00598 template<typename T, template<typename U> class Descriptor>
00599 void ConstParallelDynamics<T,Descriptor>::computeRhoBarJPiNeq (
00600         Cell<T,Descriptor> const& cell, T& rhoBar, Array<T,Descriptor<T>::d>& j,
00601         Array<T,SymmetricTensor<T,Descriptor>::n>& PiNeq ) const
00602 {
00603     if (hasBulkCell) {
00604         baseCells[0] -> getDynamics().computeRhoBarJPiNeq(*baseCells[0],rhoBar, j, PiNeq);
00605     }
00606     global::mpi().bCastThroughMaster(&rhoBar, 1, hasBulkCell);
00607     global::mpi().bCastThroughMaster(&j[0], Descriptor<T>::d, hasBulkCell);
00608     global::mpi().bCastThroughMaster(&PiNeq[0], SymmetricTensor<T,Descriptor>::n, hasBulkCell);
00609 }
00610 
00611 template<typename T, template<typename U> class Descriptor>
00612 T ConstParallelDynamics<T,Descriptor>::computeEbar(Cell<T,Descriptor> const& cell) const {
00613     T eBar = T();
00614     if (hasBulkCell) {
00615         eBar = baseCells[0] -> getDynamics().computeEbar(*baseCells[0]);
00616     }
00617     global::mpi().bCastThroughMaster(&eBar, 1, hasBulkCell);
00618     return eBar;
00619 }
00620 
00621 #endif
00622 
00623 }  // namespace plb
00624 
00625 #endif // defined MULTIBLOCK_DYNAMICS_H