Пример #1
0
int main()
{
    double length_x, length_y, length_z, dt, Tmax, tolerance = 1e-6;
    int num_nodes_x, num_nodes_y, num_nodes_z, frequency, tdma_iter = 20;
    double porosity, permeability, mu_w, mu_o, Srw, Sro;
    double injection, pres_out, Sw_in;
    int idt_p;

    // Reading data from the input file
    std::ifstream input_cin ("inputBL3D");
    input_cin >> length_x >> length_y >> length_z
              >> num_nodes_x >> num_nodes_y >> num_nodes_z
              >> porosity
              >> permeability
              >> mu_w
              >> mu_o
              >> Srw
              >> Sro
              >> injection
              >> pres_out
              >> Sw_in
              >> dt
              >> Tmax
              >> idt_p
              >> frequency;
    input_cin.close();


    cout << "\n --- Injection ---> " << injection << endl ;
    double Gamma = permeability;

    StructuredMesh<Uniform<double, 3> > mesh(length_x, num_nodes_x,
            length_y, num_nodes_y,
            length_z, num_nodes_z);
    double dx = mesh.getDelta(X);
    double dy = mesh.getDelta(Y);
    double dz = mesh.getDelta(Z);
    mesh.print();

    ScalarField3D p ( mesh.getExtentVolumes() );
    ScalarField3D Sw ( mesh.getExtentVolumes() );
    ScalarField3D p_n( mesh.getExtentNodes()   );
    ScalarField3D Sw_n( mesh.getExtentNodes()   );

    // Initial conditions
    Sw = 0;
    p = pres_out;

    Range all = Range::all();
    // Boundary condition
    Sw(0, all, all) = Sw_in;

    NumUtils::interpolateToNodes(p_n, p);
    InOut::writeToFile_DX(p_n, 0, "../DataBL3D/pres.", dx, dy, dz);
    NumUtils::interpolateToNodes(Sw_n, Sw);
    InOut::writeToFile_DX(Sw_n, 0, "../DataBL3D/satu.", dx, dy, dz);

    SparseMatrix< Diagonal< double, 3> > A(num_nodes_x, num_nodes_y, num_nodes_z);

    ScalarField3D              b(num_nodes_x, num_nodes_y, num_nodes_z);

    TwoPhaseEquation< BLIP5<double, 3> > pressure(p, A, b, mesh.getDeltas());
    pressure.setDeltaTime(dt);
    pressure.setPermeability(permeability);
    pressure.setPorosity(porosity);
    pressure.setSrw(Srw);
    pressure.setSro(Sro);
    pressure.setViscosity_w(mu_w);
    pressure.setViscosity_o(mu_o);
    pressure.setNeumann  (LEFT_WALL, -injection * mu_w / permeability);
    pressure.setDirichlet(RIGHT_WALL);
    pressure.setNeumann  (TOP_WALL);
    pressure.setNeumann  (BOTTOM_WALL);
    pressure.setNeumann  (FRONT_WALL);
    pressure.setNeumann  (BACK_WALL);
    pressure.setSaturation(Sw);
    pressure.print();

    //
    // In these case, the boundary conditions are calculated in
    // the numerical scheme (the adaptor BLES1).
    //
    TwoPhaseEquation< BLES5<double, 3> > saturation(Sw, A, b, mesh.getDeltas());
    saturation.setDeltaTime(dt);
    saturation.setPermeability(permeability);
    saturation.setPorosity(porosity);
    saturation.setSrw(Srw);
    saturation.setSro(Sro);
    saturation.setViscosity_w(mu_w);
    saturation.setViscosity_o(mu_o);
    saturation.applyBounds(1, Sw.ubound(firstDim)-1);// just to move the indexes
    saturation.setNeumann(TOP_WALL);
    saturation.setNeumann(BOTTOM_WALL);
    saturation.setNeumann(FRONT_WALL);
    saturation.setNeumann(BACK_WALL);
    saturation.setPressure(p);
    saturation.print();


    ofstream error_fp("./DataBL3D/error"),
             residual_fp("./DataBL3D/residual");
    int iteration = 0, idprint = 0;
    double t = dt;
    double error = 1.0;
    double residual = 1.0;

    int pausa;

    int bi = saturation.get_bi(), ei = saturation.get_ei();
    int bj = saturation.get_bj(), ej = saturation.get_ej();
    int bk = saturation.get_bk(), ek = saturation.get_ek();

    frequency *= (86400 / dt);

    double total_time = 0, pres_time = 0, sat_time = 0;

    while (t <= Tmax) {

        if ( !(iteration % idt_p) ) {
            crono.tic();
            pressure.calcCoefficients();
            Solver::TDMA3D(pressure, tolerance, 20, 1);
            pres_time += crono.toc();

            residual = pressure.calcResidual();
            error = pressure.calcErrorL1();

            error_fp << iteration << "\t" << error << std::endl;
            residual_fp << iteration << "\t" << residual << std::endl;

            pressure.update();
        }

        crono.tic();
        saturation.calcCoefficients();
        Solver::solExplicit3D(saturation);
        sat_time += crono.toc();

        error = saturation.calcErrorL1();
        saturation.update();

        /** **/
        for(int kk = 0; kk <= (ek+1); ++kk)
            for(int j = 0; j <= (ej+1); ++j)
                for(int i = 0; i <= (ei+1); ++i) {
                    if ( Sw(i,j,kk) > Sw_in) Sw(i,j,kk) = Sw_in;
                    if ( Sw(i,j,kk) < Srw) Sw(i,j,kk) = Srw;
                }
        saturation.updatePhi(Sw);
        /** **/

        ++iteration;
        t += dt;

        if ( !(iteration % frequency) ) {
            idprint++;
            NumUtils::interpolateToNodes(p_n, p);
            InOut::writeToFile_DX(p_n, idprint, "./DataBL3D/pres.",dx, dy, dz);
            NumUtils::interpolateToNodes(Sw_n, Sw);
            InOut::writeToFile_DX(Sw_n, idprint, "./DataBL3D/satu.",dx, dy, dz);

            std::cout << "\n ---- Iteration " << iteration
                      << "\t time = " << t
                      << "\t Res = " << residual
                      << "\t Err = " << error
                      << "\n ---- ID print " << idprint;
        }
    }

    cout << "\n\n Presure Elapsed time = " << pres_time << " segs \n";
    cout << "\n Saturation Elapsed time = " << sat_time << " segs \n";

    std::cout << "\n\n NOTE: The data were written in the [./DataBL3D] directory \n\n";

    return 0;
}
Пример #2
0
//-------------------------------------------------------
int main( int argc, char **argv)
{


    MPI::Init(argc, argv);
    rank = MPI::COMM_WORLD.Get_rank();       
    size = MPI::COMM_WORLD.Get_size(); 
    
// ----- Construction of a Cartesian topolog
    CartComm<2> cart(argc, argv, rank);   
    Isub = cart.get_I();
    Jsub = cart.get_J();
    num_subdom_x = cart.getNumProc_I(); 
    num_subdom_y = cart.getNumProc_J();
    //    cart.print();    

// Reading and broadcasting data from the input file 
    read_data_and_Bcast(cart);   

// Global Mesh
    StructuredMesh<Uniform<double, 2> > mesh(lx_g, num_nodes_x_g,
					     ly_g, num_nodes_y_g);
    double dx = mesh.getDelta(X);
    double dy = mesh.getDelta(Y);

    //    mesh.print();

    /***/
// Subdomain
    SubDomain<double, 2> subdom(cart);
    
    double ovlp_l = subdom.createOverlap(LEFT,  nc_ovlp_l, dx);
    double ovlp_r = subdom.createOverlap(RIGHT, nc_ovlp_r, dx);
    double ovlp_d = subdom.createOverlap(DOWN,  nc_ovlp_d, dy);
    double ovlp_u = subdom.createOverlap(UP,    nc_ovlp_u, dy);
  
// Local mesh for subdomains of equal length
    length_x = lx_g / num_subdom_x; // Non-overlapping
    length_y = ly_g / num_subdom_y; // Non-overlapping
    
    // Restriction: (num_nodes_x_g - 1) % num_subdomx = 0 
    num_nodes_x = (num_nodes_x_g - 1) / num_subdom_x + 1; 
    // Restriction: (num_nodes_y_g - 1) % num_subdomy = 0 
    num_nodes_y = (num_nodes_y_g - 1) / num_subdom_y + 1; 

// Adding the overlapping
    length_x += ovlp_l + ovlp_r; 
    length_y += ovlp_d + ovlp_u; 
    num_nodes_x += nc_ovlp_l + nc_ovlp_r;
    num_nodes_y += nc_ovlp_d + nc_ovlp_u;

// Resizing the mesh to the local values for the subdomain
    mesh.resize(length_x,  num_nodes_x, length_y, num_nodes_y);

    mesh.print();
// Define the info to be exchanged between subdomains
    subdom.setupInfoExchange(mesh);
    subdom.print();

    double Gamma = permeability;

    ScalarField2D p ( mesh.getExtentVolumes() );
    ScalarField2D Sw ( mesh.getExtentVolumes() ); 
    ScalarField2D p_n( mesh.getExtentNodes()   );
    ScalarField2D Sw_n( mesh.getExtentNodes()   );

    // Initial conditions
    Sw = 0;
    p = pres_out; 
 
    Range all = Range::all();
    // Boundary condition
    Sw(0, all) = Sw_in;  

    /** */
    NumUtils::interpolateToNodes(p_n, p);
    NumUtils::interpolateToNodes(Sw_n, Sw);

    if (rank == 0) {
      InOut::writeToFile_DX(Sw_n, 0, "./DataBL/00/satu.", dx, dy);
      InOut::writeToFile_DX(p_n, 0, "./DataBL/00/pres.", dx, dy);    
    }    
    if (rank == 1) {
      InOut::writeToFile_DX(p_n, 0, "./DataBL/01/pres.", dx, dy);    
      InOut::writeToFile_DX(Sw_n, 0, "./DataBL/01/satu.", dx, dy);
    }
    if (rank == 2) {
      InOut::writeToFile_DX(Sw_n, 0, "./DataBL/02/satu.", dx, dy);
      InOut::writeToFile_DX(p_n, 0, "./DataBL/02/pres.", dx, dy);    
    }    
    if (rank == 3) {
      InOut::writeToFile_DX(p_n, 0, "./DataBL/03/pres.", dx, dy);    
      InOut::writeToFile_DX(Sw_n, 0, "./DataBL/03/satu.", dx, dy);
    }
    
    //    SparseMatrix< Diagonal< double, 2> > A(num_nodes_x, num_nodes_y); 
    DiagonalMatrix< double, 2> A(num_nodes_x, num_nodes_y); 
    ScalarField2D              b(num_nodes_x, num_nodes_y);

    TwoPhaseEquation< BLIP1<double, 2> > pressure(p, A, b, mesh.getDeltas());
    pressure.setDeltaTime(dt); 
    pressure.setPermeability(permeability);
    pressure.setPorosity(porosity);
    pressure.setSrw(Srw);
    pressure.setSro(Sro);
    pressure.setViscosity_w(mu_w);
    pressure.setViscosity_o(mu_o);
    pressure.setNeumann  (LEFT_WALL, -injection * mu_w / permeability);
    pressure.setDirichlet(RIGHT_WALL);
    pressure.setNeumann  (TOP_WALL);
    pressure.setNeumann  (BOTTOM_WALL);
    pressure.setSaturation(Sw);
    pressure.print();

    //
    // In these case, the boundary conditions are calculated in
    // the numerical scheme (the adaptor BLES1).
    //
    TwoPhaseEquation< BLES1<double, 2> > saturation(Sw, A, b, mesh.getDeltas());
    saturation.setDeltaTime(dt); 
    saturation.setPermeability(permeability);
    saturation.setPorosity(porosity);
    saturation.setSrw(Srw);
    saturation.setSro(Sro);
    saturation.setViscosity_w(mu_w);  
    saturation.setViscosity_o(mu_o); 
    saturation.applyBounds(1, Sw.ubound(firstDim)-1);// just to move the indexes
    saturation.setNeumann(TOP_WALL);
    saturation.setNeumann(BOTTOM_WALL);
    saturation.setPressure(p);
    saturation.print();

    ofstream error_fp, residual_fp;
    
    if (rank == 0){
      error_fp.open("./DataBL/00/error"); 
      residual_fp.open ("./DataBL/00/residual");
    }
    if (rank == 1) {
      error_fp.open("./DataBL/01/error"); 
      residual_fp.open("./DataBL/01/residual");
    }
 
    int iteration = 1, idprint = 1;
    double t = dt;
    double error = 1.0;
    double residual = 1.0;

    //    int pausa;

    int bi = saturation.get_bi(), bj = saturation.get_bj();
    int ei = saturation.get_ei(), ej = saturation.get_ej();

    frequency *= (86400 / dt);

    double total_time = 0, pres_time = 0, sat_time = 0;
    while (t <= Tmax) {

      if ( !(iteration % idt_p) ) {
	crono.tic();
	pressure.calcCoefficients();
	Solver::TDMA2DX(pressure, tolerance, tdma_iter, 1.0);
	pres_time += crono.toc();
	
	residual = pressure.calcResidual();
	error = pressure.calcErrorL1();
	
	error_fp << iteration << "\t" << error << std::endl;
	residual_fp << iteration << "\t" << residual << std::endl;	
	
	pressure.update();
      }  

      crono.tic();
      saturation.calcCoefficients();
      Solver::solExplicit2D(saturation);
      sat_time += crono.toc();

      error = saturation.calcErrorL1();
      saturation.update();



      /* */
      // just to avoid go out of boundary conditions.
      for(int j = 0; j <= (ej+1); ++j)
	for(int i = 0; i <= (ei+0); ++i) {
	  if ( Sw(i,j) > Sw_in) Sw(i,j) = Sw_in;
	  if ( Sw(i,j) <= 0 ) {
	    Sw(i+1,j) = 0.0;
	  }
	}
      saturation.updatePhi(Sw);
      /* */
     
      if ( !(iteration % frequency) ) {

	NumUtils::interpolateToNodes(p_n, p);
	NumUtils::interpolateToNodes(Sw_n, Sw);

	if (rank == 0) {
	  InOut::writeToFile_DX(p_n, idprint, "./DataBL/00/pres.",dx, dy);	
	  InOut::writeToFile_DX(Sw_n, idprint, "./DataBL/00/satu.",dx, dy);
	}
	if (rank == 1) {
	  InOut::writeToFile_DX(p_n, idprint, "./DataBL/01/pres.",dx, dy);	
	  InOut::writeToFile_DX(Sw_n, idprint, "./DataBL/01/satu.",dx, dy);
	}
	if (rank == 2) {
	  InOut::writeToFile_DX(p_n, idprint, "./DataBL/02/pres.",dx, dy);	
	  InOut::writeToFile_DX(Sw_n, idprint, "./DataBL/02/satu.",dx, dy);
	}
	if (rank == 3) {
	  InOut::writeToFile_DX(p_n, idprint, "./DataBL/03/pres.",dx, dy);	
	  InOut::writeToFile_DX(Sw_n, idprint, "./DataBL/03/satu.",dx, dy);
	}

	std::cout << "\n\n ---- ID print => " << idprint
		  << "\t - Iteration => " << iteration
		  << "\t Step = " << t
		  << "\n ---- Res = " << residual
		  << "\t Err = " << error;
	//std::cout.flush();
	++idprint;
      }
    

      /* */
      subdom.infoExchange1(p);
      pressure.updatePhi(p);

      subdom.infoExchange1(Sw);
      saturation.updatePhi(Sw);
      /* */
      // just to avoid go out of boundary conditions.
      for(int j = 0; j <= (ej+1); ++j)
	for(int i = 0; i <= (ei+0); ++i) {
	  if ( Sw(i,j) > Sw_in) Sw(i,j) = Sw_in;
	  if ( Sw(i,j) <= 0 ) {
	    Sw(i+1,j) = 0.0;
	  }
	}
      saturation.updatePhi(Sw);
      /* */

      ++iteration;
      t += dt;
    }

    cout << "\n Pres Etime = " << pres_time << " segs \n";
    cout << "\n Sat Etime = " << sat_time << " segs \n";

/* **/

    MPI::Finalize();
    return 0;
}
Пример #3
0
 void tic(std::string key){
   globalTimer.tic(key);
 }