#ifndef SIMULATION2D_HPP #define SIMULATION2D_HPP #include "Rod2d.hpp" #include "LiveAgg.hpp" #include #include /* This is used to calculate the convergence order of the particles */ inline void printProgress(double progress) { const int barWidth = 70; std::cout << "["; const int pos = static_cast(barWidth * progress); for (int i = 0; i < barWidth; ++i) { if (i < pos) { std::cout << "="; } else if (i == pos) { std::cout << ">"; } else { std::cout << " "; } } std::cout << "] " << int(progress * 100.0) << " % \r"; std::cout.flush(); } template void simulate(double L, int seed, const std::string &filename) { // we now simulate the msd after 10 steps Rod2d rod(L, 1e-5, seed); const int sampleWidth = 1000; std::vector msd(sampleWidth, LiveAgg()); std::vector oaf(sampleWidth, LiveAgg()); std::vector empxx(sampleWidth, LiveAgg()); std::vector empyy(sampleWidth, LiveAgg()); std::vector xPos(sampleWidth, 0.0); std::vector yPos(sampleWidth, 0.0); std::vector e1(sampleWidth, 0.0); std::vector e2(sampleWidth, 0.0); std::vector targetMSD(sampleWidth, 0.0); std::vector targetOAF(sampleWidth, 0.0); std::vector targetEMPXX(sampleWidth, 0.0); std::vector targetEMPYY(sampleWidth, 0.0); std::vector samplePoints(sampleWidth, 1); size_t temp = 1; const double Dmean = 0.5 * (rod.Dpara + rod.Dortho); const double deltaD = rod.Dortho - rod.Dpara; for (size_t i = 0; i < samplePoints.size(); ++i) { samplePoints[i] = temp; temp += 100; const double time = static_cast(temp) * rod.deltaT; targetMSD[i] = 4.0 * 0.5 * (rod.Dpara + rod.Dortho) * time; targetOAF[i] = std::exp(-rod.Drot * time); const double u = 4.0; targetEMPXX[i] = Dmean - deltaD / 2.0 * (1 - exp(-u * rod.Drot * time)) / u / rod.Drot / time; targetEMPYY[i] = Dmean + deltaD / 2.0 * (1 - exp(-u * rod.Drot * time)) / u / rod.Drot / time; } unsigned long long int iteration = 0; //const unsigned long long int maxItr = ((long int)10000)*1000000; const unsigned long long int maxItr = 10000000; const unsigned long long int updateInter = 10000; while (iteration < maxItr) { T(rod); iteration++; for (size_t i = 0; i < samplePoints.size(); ++i) { const size_t sample = samplePoints[i]; if (iteration % sample == 0) { msd[i].feed((rod.x1 - xPos[i]) * (rod.x1 - xPos[i]) + (rod.x2 - yPos[i]) * (rod.x2 - yPos[i])); oaf[i].feed(rod.e1 * e1[i] + rod.e2 * e2[i]); empxx[i].feed(std::pow((rod.x1 - xPos[i]) * e1[i] + (rod.x2 - yPos[i]) * e2[i], 2)); empyy[i].feed(std::pow((rod.x1 - xPos[i]) * e2[i] - (rod.x2 - yPos[i]) * e1[i], 2)); xPos[i] = rod.x1; yPos[i] = rod.x2; e1[i] = rod.e1; e2[i] = rod.e2; } } if (iteration % updateInter == 0) { printProgress(static_cast(iteration)/ maxItr); } } std::cout << "\n"; std::ofstream fileMSD(filename + "_" + std::to_string(L) + "_MSD.out"); std::ofstream fileOAF(filename + "_" + std::to_string(L) + "_OAF.out"); std::ofstream fileXX(filename + "_" + std::to_string(L) + "_XX.out"); std::ofstream fileYY(filename + "_" + std::to_string(L) + "_YY.out"); for (size_t i = 0; i < samplePoints.size(); ++i) { fileMSD << static_cast(samplePoints[i]) * rod.deltaT << "\t" << targetMSD[i] << "\t" << msd[i].getMean() << "\t" << msd[i].getSEM() << "\t" << msd[i].getSD() << "\t" << msd[i].getNumPoints() << "\n"; fileOAF << static_cast(samplePoints[i]) * rod.deltaT << "\t" << targetOAF[i] << "\t" << oaf[i].getMean() << "\t" << oaf[i].getSEM() << "\t" << oaf[i].getSD() << "\t" << oaf[i].getNumPoints() << "\n"; fileXX << static_cast(samplePoints[i]) * rod.deltaT << "\t" << targetEMPXX[i] << "\t" << empxx[i].getMean() << "\t" << empxx[i].getSEM() << "\t" << empxx[i].getSD() << "\t" << empxx[i].getNumPoints() << "\n"; fileYY << static_cast(samplePoints[i]) * rod.deltaT << "\t" << targetEMPYY[i] << "\t" << empyy[i].getMean() << "\t" << empyy[i].getSEM() << "\t" << empyy[i].getSD() << "\t" << empyy[i].getNumPoints() << "\n"; } fileMSD.close(); fileOAF.close(); fileXX.close(); fileYY.close(); } template void konvergenz(double L, int seed, double deltaT, const std::string &filename) { // we now simulate the msd after 10 steps Rod2d rod(L, deltaT, seed); const double time = 2; const int steps = static_cast(time / deltaT); const int minSteps = 1000; //const double targetMSD = 4.0*0.5*(rod.Dpara+rod.Dortho)*time; const double targetOAF = std::exp(-rod.Drot * time); /*const double u = 4.0; const double Dmean = 0.5*(rod.Dpara+rod.Dortho); const double deltaD = rod.Dortho - rod.Dpara; const double targetEMPXX = Dmean-deltaD/2.0*(1 - exp(-u*rod.Drot*time))/u/rod.Drot / time; const double targetEMPYY = Dmean+deltaD/2.0*(1 - exp(-u*rod.Drot*time))/u/rod.Drot / time;*/ //LiveAgg msd; LiveAgg oaf; //LiveAgg empxx; //LiveAgg empyy; int meanCount = 0; while (meanCount < minSteps or std::abs(targetOAF - oaf.getMean()) < oaf.getSEM() * 10) { //reset the position rod.reset(); for (int i = 0; i < steps; ++i) { T(rod); } //msd.feed(rod.x1*rod.x1+rod.x2*rod.x2); oaf.feed(rod.e1); //.feed(rod.x1*rod.x1/2/time); //empyy.feed(rod.x2*rod.x2/2/time); if (meanCount % 100000 == 0) { //std::cout<