/** * g++ main.cpp -std=c++17 -Wall -Wpedantic -pedantic -o main; ./main */ #include #include #include #define _USE_MATH_DEFINES /* enables math constants from cmath */ #include #ifdef USE_MPI #include #endif #include "Matrix.h" #include "Solver.h" int main(int argn, char* argv[]) { /******************************* MPI Setup ********************************/ #ifdef USE_MPI // Initialize MPI MPI_Init(nullptr, nullptr); // Get MPI config int mpi_size; /*< MPI pool size (a.k.a. total number of processes) */ int mpi_rank; /*< MPI rank (a.k.a. process ID in the context of MPI) */ MPI_Comm_size(MPI_COMM_WORLD, &mpi_size); MPI_Comm_rank(MPI_COMM_WORLD, &mpi_rank); #endif /**************************** Parse Arguments *****************************/ if (argn < 3) { std::cerr << "usage: " << argv[0] << " " << std::endl; return -1; } else if (argn > 3) { std::cerr << "warning: " << "ignoring all but the first two params" << std::endl; } // TODO: make this proper!!! size_t resolution = atol(argv[1]); size_t iterations = atol(argv[2]); if (resolution < 1 || resolution > 65536 || iterations < 1 || iterations > 65536) { std::cerr << "error: parsing arguments failed" << std::endl; } /************************* Initialize PDE Solver **************************/ size_t nx = resolution; size_t ny = resolution; const double k = M_PI; const double h = 1.0 / static_cast(resolution - 1); // Declare right hand side function f(x, y) = k^2 sin(2 pi x) sinh(2 pi y) std::function fun = [k](double x, double y) { return k * k * sin(M_2_PI * x) * sinh(M_2_PI * y); }; // Boundary conditions /** North boundary condition g(x) = k^2 sin(2 pi x) sinh(2 pi) */ std::function gN = [k](double x) { return k * k * sin(M_2_PI * x) * sinh(M_2_PI); }; /** East, South and West boundary conditions are simply = 0 */ std::function g0 = [k](double) { return 0.0; }; // Instanciate solver Solver solver(nx, ny, h, k, fun, gN, g0, g0, g0); // Set Diriclet boundary conditions (East, South and West to 0) for (auto dir : { Solver::Dir::E, Solver::Dir::S, Solver::Dir::W }) { MatrixView boundary = solver.boundary(dir); for (size_t i = 0; i < boundary.size(); ++i) { boundary(i) = 0.0; } } // The North boundary condition is g(x) = sin(2 pi x) sinh(2 pi) { MatrixView boundary = solver.boundary(Solver::Dir::North); for (size_t i = 0; i < boundary.size(); ++i) { double x = static_cast(i) / static_cast(nx - 1); boundary(i) = sin(M_2_PI * x) * sinh(M_2_PI); } } /******************************* Solve PDE ********************************/ // Run solver iterations for (size_t iter = 0; iter < iterations; ++iter) { solver.iterate(); } /****************************** Tests/Report ******************************/ // MPI shutdown/cleanup #ifdef USE_MPI MPI_Finalize(); #endif return 0; }