int main(){
    cout<<"2D, NS <-> PE <-> NP"<<endl;

    /* Parameter definitions */
    int nx = 50;
    int ny = 101;

    int tNP = 50;
    int tPE = 10000;
      int tNS = tNP;//tNP;
    int tMain = 1000;

    int tMod = 1; //undersök i detalj.... ok.

    double l0 = 1e-6/(ny-1); //PE, NP
    double C0 = 1e-4*PHYS_N_A; //NP
    double u0 = 1e-2; //NP, NS
    double dt = 1.0;
    double V0 = -50e-3; //PE
    double rho0 = 1e3; //NS

    double nu = 1.0e-6; //m^2/s
    double D = 1.0e-10; //m^2/s
    double u0x = 0.0;
    double T = 293;
    double eps_r = 80;
    double rho_surface = -0.25e-1;//-50e-3*eps_r*PHYS_EPS0/1e-7/V0*l0;
    double bulk_charge = 1.0;
    double gamma = PHYS_E_CHARGE/(PHYS_KB*T);
    double E = 1.0;//1e3 * l0/(rho0 * u0 * u0); //lattice units
    double bulkConductivity = 1.5e-3; //conductivity [S/m]

    double Pe = u0*l0/D;
    double Re = u0*1e4*l0/nu;
    double wNP = 1.0/(3.0/Pe + 0.5);
    double wPE = 1.0;
    double wNS = 1.0/(3.0/Re + 0.5);

    /*print parameters*/
    printLine(20);
    cout<<"DIM = ("<<nx<<", "<<ny<<")"<<endl;
    cout<<"T = "<<T<<endl;
    cout<<"RHO_SURFACE = "<<rho_surface<<", "<<rho_surface*V0/l0*PHYS_EPS0*eps_r<<" C/M^2"<<endl;
    cout<<"BULK_CHARGE = "<<bulk_charge<<endl;
    cout<<"PE = "<<Pe<<endl;
    cout<<endl;
    cout<<"w_np = "<<wNP<<endl;
    cout<<"w_pe = "<<wPE<<endl;
    cout<<endl;
    cout<<"l0 = "<<l0<<endl;
    cout<<"V0 = "<<V0<<endl;
    cout<<"GAMMA: "<<gamma<<endl;
    cout<<"l0*gamma/Pe *V0/l0 = "<<l0*gamma/Pe*V0/l0<<endl;
    cout<<"l0^2*gamma/Pe *V0/l0^2 = "<<l0*l0*gamma/Pe*V0/l0/l0<<endl;
    cout<<"1/Pe = "<<1/Pe<<endl;
    cout<<"E = "<<E<<endl;
    printLine(20);

    /* Allocate memory for velocity and grad. potential arrays */
    double **ux = allocate2DArray(ny, nx);
    double **uy = allocate2DArray(ny, nx);
    double **dPsix = allocate2DArray(ny, nx);
    double **dPsiy = allocate2DArray(ny, nx);
    double **rho_eps = allocate2DArray(ny, nx);
    double **fx = allocate2DArray(ny, nx);
    double **fy = allocate2DArray(ny, nx);

    for(int j = 0; j < ny; j++){
        for(int i = 0; i < nx; i++){
            ux[j][i] = 0;
            uy[j][i] = 0;
            fx[j][i] = 0;
            fy[j][i] = 0;
            dPsix[j][i] = 0.0;
            dPsiy[j][i] = 0.0;
            rho_eps[j][i] = 0.0;//-l0*l0/V0*2*PHYS_E_CHARGE*C0/(eps_r *PHYS_EPS0)*\
                            (cos(j*2*M_PI/(ny-1)) + 1)*0.5;
        }
    }

    /* Poisson eq. solver */
    CollisionD2Q9BGKPE *cmPE = new CollisionD2Q9BGKPE();
    StreamD2Q9Periodic *smPE = new StreamD2Q9Periodic();
    Lattice2D *lmPE = new Lattice2D(nx, ny);
    UnitHandlerLPM *uhPE = new UnitHandlerLPM();

    cmPE->setRHS(rho_eps);
    cmPE->setW(wPE);
    cmPE->setC(1.0);
    cmPE->setUnitHandler(uhPE);
    uhPE->setCharLength(l0);
    uhPE->setCharVoltage(V0);
    uhPE->setTimeStep(1.0);

    LBM *lbmPE = new LBM(lmPE, cmPE, smPE);
    lbmPE->init();

//    HeZouLPMChaiNodes *bds = new HeZouLPMChaiNodes();
//    bds->setCollisionModel(cmPE);
//    for(int i = 0; i < nx; i++){
//        bds->addNode(i, 0, 0, 1.0/1.8);
//        bds->addNode(i, ny-1, 0, 1.0/1.8);
//    }

    /* Boundary conds. for Poission solver */
    NeumannNodesPESlip *bds = new NeumannNodesPESlip();
    lbmPE->addBoundaryNodes(bds);
    bds->setCollisionModel(cmPE);
    double sc = 0;
    for(int i = 0; i < nx; i++){
        sc = rho_surface * ((i >= nx*0.5) - (i < nx*0.5));
        cout<<"surface charge for: "<<i<<" = "<<sc<<endl;
        bds->addNode(i, 0, 0, sc, 2);
        bds->addNode(i, ny-1, 0, sc, 4);
    }
    bds->init();

    /* Nernst Planck solver */
    CollisionD2Q9AD *cmNPneg = new CollisionD2Q9AD();
    CollisionD2Q9AD *cmNPpos = new CollisionD2Q9AD();
    StreamD2Q9Periodic *sm = new StreamD2Q9Periodic();
    LatticeModel *lm = new Lattice2D(nx, ny);
    StreamD2Q9Periodic *sm2 = new StreamD2Q9Periodic();
    LatticeModel *lm2 = new Lattice2D(nx, ny);

    cmNPneg->setW(wNP);
    cmNPneg->setC(1);
    cmNPneg->setZ(-1);
    cmNPneg->setInitC(bulk_charge);
    cmNPneg->setUx(ux);
    cmNPneg->setUy(uy);
    cmNPneg->setDPsix(dPsix);
    cmNPneg->setDPsiy(dPsiy);
    cmNPneg->setT(T);
    cmNPneg->setPe(Pe);
    //cmNPneg->setRHS(rho_eps);

    cmNPpos->setW(wNP);
    cmNPpos->setC(1);
    cmNPpos->setZ(1);
    cmNPpos->setInitC(bulk_charge);
    cmNPpos->setUx(ux);
    cmNPpos->setUy(uy);
    cmNPpos->setDPsix(dPsix);
    cmNPpos->setDPsiy(dPsiy);
    cmNPpos->setT(T);
    cmNPpos->setPe(Pe);
    //cmNPpos->setRHS(rho_eps);

    LBM *lbmNPneg = new LBM(lm, cmNPneg, sm);
    LBM *lbmNPpos = new LBM(lm2, cmNPpos, sm2);

    /* Boundary conds for NP solver*/
    SlipNodes<CollisionD2Q9AD> *bbnNeg = new SlipNodes<CollisionD2Q9AD>();
    lbmNPneg->addBoundaryNodes(bbnNeg);
    bbnNeg->setCollisionModel(cmNPneg);
    for(int i = 0; i < nx; i++){
        bbnNeg->addNode(i, 0, 0, 2);
        bbnNeg->addNode(i, ny-1, 0, 4);
    }
    bbnNeg->init();

    SlipNodes<CollisionD2Q9AD> *bbnPos = new SlipNodes<CollisionD2Q9AD>();
    lbmNPpos->addBoundaryNodes(bbnPos);
    bbnPos->setCollisionModel(cmNPpos);
    for(int i = 0; i < nx; i++){
        bbnPos->addNode(i, 0, 0, 2);
        bbnPos->addNode(i, ny-1, 0, 4);
    }
    bbnPos->init();

    /* Initialize solver */
    lbmNPneg->init();
    lbmNPpos->init();


    /* NS Solver */
    CollisionD2Q9BGKNSF *cmNS = new CollisionD2Q9BGKNSF();
    StreamD2Q9Periodic *smNS = new StreamD2Q9Periodic();
    Lattice2D *lmNS = new Lattice2D(nx, ny);

    cmNS->setW(wNS);
    cmNS->setC(1.0);

    LBM *lbmNS = new LBM(lmNS, cmNS, smNS);

    /* Set boundary conditions for flow */
    BounceBackNodes<CollisionD2Q9BGKNSF> *bbNS =
            new BounceBackNodes<CollisionD2Q9BGKNSF>();
    bbNS->setCollisionModel(cmNS);
    for(int i = 0; i < nx; i++){
        bbNS->addNode(i, 0, 0);
        bbNS->addNode(i, ny-1, 0);
    }
    lbmNS->addBoundaryNodes(bbNS);

    lbmNS->init();
    cmNS->setForce(fx, fy);

    for(int t = 0; t < tNS; t++){
        cout<<"T: "<<t<<endl;
        lbmNS->collideAndStream();
    }


    /* Main loops */
    for(int tt = 0; tt < tMain; tt++){
        cout<<"TT: "<<tt<<endl;

//        if(tt == 12){ tNP = 8; tNS = 8;}

        /* Update net charge density */
        updateRho(rho_eps, cmNPneg, cmNPpos, lm, eps_r, V0, l0, C0);
        cmPE->reset();

        for(int t = 0; t < tPE; t++){
            //cout<<"tPE "<<t<<endl;
            lbmPE->collideAndStream();
        }
        cmPE->getDPsi(dPsix, dPsiy);

        //scale potential gradients to SI units *l0
        rescale2DArray(dPsix, V0, ny, nx);
        rescale2DArray(dPsiy, V0, ny, nx);

        for(int t = 0; t < tNP; t++){
            lbmNPneg->collideAndStream();
            lbmNPpos->collideAndStream();
        }


        updateForce(fx, fy, ux, uy, rho_eps,\
                         lmNS, eps_r, u0, l0, V0, C0,\
                         bulkConductivity, E, cmNPpos, cmNPneg);
        for(int t = 0; t < tNS; t++){

            lbmNS->collideAndStream();
        }

        /* update velocities */
        cmNS->getU(ux, uy);

        /*write result to file*/
        stringstream ss;
        string base = "vis_scripts/data";
        if(tt % tMod == 0){
            //dPsiY
            ss.str("");
            ss<<base<<"PSI";
            ss<<tt/tMod<<"/";
            createDirectory(ss.str());
            ss<<"dpsiy.csv";
            write2DArray(dPsiy, NULL, ss.str(), nx, ny);

            //potential
            ss.str("");
            ss<<base<<"PE";
            ss<<tt/tMod<<"/";
            createDirectory(ss.str());
            ss<<"rho.csv";
            cmPE->dataToFile(ss.str());

            //C_neg
            ss.str("");
            ss<<base<<"NP";
            ss<<tt/tMod<<"/";
            createDirectory(ss.str());
            ss<<"ni_neg.csv";
            cmNPneg->dataToFile(ss.str());

            //C_pos
            ss.str("");
            ss<<base<<"NP";
            ss<<tt/tMod<<"/";
            ss<<"ni_pos.csv";
            cmNPpos->dataToFile(ss.str());

            //U and rho_m
            ss.str("");
            ss<<base<<"NS";
            ss<<tt/tMod<<"/";
            createDirectory(ss.str());
            cmNS->dataToFile(ss.str());

            //fx
            ss.str("");
            ss<<base<<"FX";
            ss<<tt/tMod<<"/";
            createDirectory(ss.str());
            ss<<"fx.csv";
            write2DArray(fx, NULL, ss.str(), nx, ny);
        }
    }

    cout<<"done LNP."<<endl;

    return 0;
}
Beispiel #2
0
int main() {
  int nx = 100, ny = 100, tMax = 2000, tMod = 100;
  int tInit = 64;
  double c = 1.0; //DX/DT;
  double cs2 = c * c / 3.0;
  double nu = 0.05;
  cout << "nu: " << nu << endl;
  double w = 1.0 / (nu / cs2 + 0.5);
  cout << "omega: " << w << endl;
  double u0 = 0.01; //sqrt(0.001);
  double G = u0 * u0;
  //u0 *= DT/DX;
  cout << "u0: " << u0 << endl;
  cout << "Taylor vortex flow..." << endl;

  StreamD2Q9Periodic *sm = new StreamD2Q9Periodic();
  CollisionD2Q9BGKNSF *cm = new CollisionD2Q9BGKNSF();
  Lattice2D *lm = new Lattice2D(nx, ny);

  LBM *lbm = new LBM(lm, cm, sm);

  double **fx = allocate2DArray(nx, ny);
  double **fy = allocate2DArray(nx, ny);
  double **uxInit = allocate2DArray(nx, ny);
  double **uyInit = allocate2DArray(nx, ny);
  double **rhoInit = allocate2DArray(nx, ny);

  double a2 = (2 * M_PI / nx) * (2 * M_PI / nx);

  for (int j = 0; j < ny; j++) {
    for (int i = 0; i < nx; i++) {
      uxInit[j][i] = -u0 * cos(Xc(i)) * sin(Yc(j));
      uyInit[j][i] = u0 * sin(Xc(i)) * cos(Yc(j));
      rhoInit[j][i] = -0.25 * cs2 * u0 * u0 * (cos(2 * Xc(i)) + cos(2 * Yc(j)))
          + 1;
      fx[j][i] = -2 * nu * a2 * u0 * cos(Xc(i)) * sin(Yc(j));
      cout << "fx: " << fx[j][i] << endl;
      fy[j][i] = 2 * nu * a2 * u0 * sin(Xc(i)) * cos(Yc(j));
    }
  }

//	double x, y;
//	for(int i = 0; i < nx; i++){
//		x = (((double)i)/(nx))*2*M_PI;
//		cout<<"cos: "<<cos(x)<<endl;
//		for(int j = 0; j < ny; j++){
//			y = (((double)j)/(ny))*2*M_PI;
//			uxInit[i][j] = -u0*cos(x)*sin(y);
//			uyInit[i][j] = u0*sin(x)*cos(y);
//			rhoInit[i][j] = 1.0 - u0*u0/4.0*(cos(2*x) + cos(2*y))*3;
//		}
//	}

  /* Initialize solver */

  cm->setW(w);
  cm->setC(c);
  //lbm->initVelocity(uxInit, uyInit);
  //lbm->initRho(rhoInit);
  lbm->init();

  cm->setForce(fx, fy);
  cm->init(rhoInit, uxInit, uyInit);

  //lbm->calcMacroscopicVars();
  //lbm->handleWetBoundaries();
  //lbm->dataToFile();

  /*init...*/
  // updateForce(0, G, nu, fx, fy, lm);
//
//	for(int t = 1; t < tInit; t++){
//        lbm->collideAndStream();
//    }
//
//    cm->dataToFile("vis_scripts/dataNS0/");
  stringstream ss;
  string base = "vis_scripts/data";

  /* Main loop */
  for (int t = 0; t < tMax; t++) {
    cout << t << endl;
    //updateForce(t, G, nu, fx, fy, lm);

    if (t == 1756) { //% tMod == 0){
      ss.str("");
      ss << base << "NS";
      ss << t / tMod << "/";
      createDirectory(ss.str());
      cm->dataToFile(ss.str());
    }

    lbm->collideAndStream();
  }

  cout << "done T. - V." << endl;

  return 0;
}