1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
| #include <cstdlib> #include <iostream>
#include "palabos2D.h" #include "palabos2D.hh"
using namespace plb; using namespace std;
typedef double T;
#define DESCRIPTOR descriptors::ShanChenD2Q9Descriptor
template <typename T, template <typename U> class Descriptor> class RandomInitializer : public BoxProcessingFunctional2D_L<T, Descriptor> { public: RandomInitializer(T rho0_, T maxRho_, Box2D const &boundingBox_, uint32_t const *seed_) : rho0(rho0_), maxRho(maxRho_), nY(boundingBox_.getNy()), seed(seed_) {}; virtual void process(Box2D domain, BlockLattice2D<T, Descriptor> &lattice) { Dot2D location = lattice.getLocation(); sitmo::prng_engine eng(*seed); plint rng_index = 0; for (plint iX = domain.x0; iX <= domain.x1; ++iX) { plint globalX = nY * (iX + location.x); for (plint iY = domain.y0; iY <= domain.y1; ++iY) { plint globalY = iY + location.y + globalX; PLB_ASSERT(globalY >= rng_index); if (globalY > rng_index) { eng.discard(globalY - rng_index); rng_index = globalY; } T randNumber = (T)eng() / (T)sitmo::prng_engine::max(); ++rng_index;
T rho = rho0 + randNumber * maxRho; Array<T, 2> zeroVelocity(0., 0.);
iniCellAtEquilibrium(lattice.get(iX, iY), rho, zeroVelocity);
lattice.get(iX, iY).setExternalField( Descriptor<T>::ExternalField::densityBeginsAt, Descriptor<T>::ExternalField::sizeOfDensity, &rho); lattice.get(iX, iY).setExternalField( Descriptor<T>::ExternalField::momentumBeginsAt, Descriptor<T>::ExternalField::sizeOfMomentum, &zeroVelocity[0]); } } }; virtual RandomInitializer<T, Descriptor> *clone() const { return new RandomInitializer<T, Descriptor>(*this); }; virtual void getTypeOfModification(std::vector<modif::ModifT> &modified) const { modified[0] = modif::staticVariables; };
private: T rho0, maxRho; plint nY; uint32_t const *seed; };
int main(int argc, char *argv[]) { plbInit(&argc, &argv); global::directories().setOutputDir("./tmp/");
uint32_t seed = 1;
const T omega = 1.0; const int nx = 400; const int ny = 400; const T G = -120; #ifndef PLB_REGRESSION const int maxIter = 100001; const int saveIter = 100; #else const int maxIter = 1001; #endif const int statIter = 100;
const T rho0 = 200.0; const T deltaRho = 1.0; const T psi0 = 4.0;
MultiBlockLattice2D<T, DESCRIPTOR> lattice( nx, ny, new ExternalMomentBGKdynamics<T, DESCRIPTOR>(omega));
lattice.periodicity().toggleAll(true);
applyProcessingFunctional( new RandomInitializer<T, DESCRIPTOR>(rho0, deltaRho, lattice.getBoundingBox(), &seed), lattice.getBoundingBox(), lattice);
plint processorLevel = 1; integrateProcessingFunctional( new ShanChenSingleComponentProcessor2D<T, DESCRIPTOR>( G, new interparticlePotential::PsiShanChen94<T>(psi0, rho0)), lattice.getBoundingBox(), lattice, processorLevel);
lattice.initialize();
pcout << "Starting simulation" << endl; for (int iT = 0; iT < maxIter; ++iT) { if (iT % statIter == 0) { std::unique_ptr<MultiScalarField2D<T> > rho(computeDensity(lattice)); pcout << iT << ": Average rho fluid one = " << computeAverage(*rho) << endl; pcout << "Minimum density: " << computeMin(*rho) << endl; pcout << "Maximum density: " << computeMax(*rho) << endl; } #ifndef PLB_REGRESSION if (iT % saveIter == 0) { ImageWriter<T>("leeloo").writeScaledGif( createFileName("rho", iT, 6), *computeDensity(lattice)); } #endif
lattice.collideAndStream(); } }
|