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; }
//------------------------------------------------------- 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; }
void tic(std::string key){ globalTimer.tic(key); }