#include "geom.h" #include "getmatrix.h" #include "jacsolve.h" #include "userset.h" #include "vdop.h" #include #include // timing #include #include #include using namespace std; using namespace std::chrono; // timing void Test_solver(int lev, vector const &nthreads, Multigrid &ggm); int main(int argc, char **argv ) { #undef MG #ifndef MG // Jacobi iteration int nrefine = 0; if (argc > 1) nrefine = atoi(argv[1]); // generating the mesh Mesh const mesh_c("../generate_mesh/coffee_cup.txt", "../generate_mesh/coffee_cup_sd.txt"); //Mesh const mesh_c("square_tiny.txt"); bool ba = mesh_c.checkObtuseAngles(); if (ba) cout << "mesh corrected" << endl; gMesh_Hierarchy ggm(mesh_c, nrefine); const Mesh &mesh = ggm.finest(); //mesh.Debug(); //mesh.DebugEdgeBased(); // Initializing FEM matrix !pattern! (only zero entries now) FEM_Matrix SK(mesh); // CRS matrix //SK.writeBinary("sparseMatrix.bin"); //SK.Debug(); // Initialize RHS vector fv(SK.Nrows(), 0.0); // r.h.s. // Calculate Matrix entries SK.CalculateLaplaceMult(fv); // matrix //SK.Debug(); // Calculate RHS SK.CalculateRHS(fv, [](double x, double y) { // rhs return std::sin(M_PI * 2.5 * y) * (M_PI * M_PI * 2.5 * 2.5 * x * x - 2); }); //SK.CheckRowSum(); SK.CheckMatrix(); // Initialize temperature vector uv(SK.Nrows(), 0.0); // temperature mesh.Init_Solution_mult(uv, 0, [](double x, double y) -> double { return 18; }); // mug mesh.Init_Solution_mult(uv, 1, [](double x, double y) -> double { return 80; }); // fluid mesh.Init_Solution_mult(uv, 2, [](double x, double y) -> double { return 18; }); // air // Apply BC SK.ApplyDirichletBC(uv, fv); // Solve auto exact_sol(uv); //SK.Mult(fv,uv); auto t3 = system_clock::now(); // start timer // JacobiSolve(SK, fv, uv ); // solve the system of equations auto t4 = system_clock::now(); // stop timer auto duration = duration_cast(t4 - t3); // duration in microseconds double t_diff = static_cast(duration.count()) / 1e6; // overall duration in seconds cout << "JacobiSolve: timing in sec. : " << t_diff << endl; // Calculate error and visualize auto [val, idx] = findLargestAbsError(exact_sol, uv, 1e+6, 100); //mesh.Visualize(getAbsError(exact_sol, uv)); mesh.Visualize(uv); #else // multigrid iteration int nrefine = 3; if (argc > 1) nrefine = atoi(argv[1]); //Multigrid ggm(Mesh("square_tiny.txt"),nrefine); Multigrid ggm(Mesh("square_100.txt"), nrefine); ggm.DefineOperators(); cout << "\n############# SOLVE ###############\n"; double tstart = omp_get_wtime(); // OpenMP //ggm.JacobiSolve(my_level); //ggm.MG_Step(my_level, 1, true, 1); ggm.MG_Solve(2, 1e-6, 1); double t1 = omp_get_wtime() - tstart; // OpenMP cout << "MgSolve: timing in sec. : " << t1 << " for " << ggm.Ndofs() << " dofs" << endl; Test_solver(nrefine - 1, {1, 2, 4, 8, 16, 32, 64, 128, 256}, ggm); //int my_level=nrefine-1; //const auto &ml=ggm.GetMesh(my_level); //const auto &sl=ggm.GetSolution(my_level); //ml.Visualize(sl); //////ml.Visualize_paraview(sl); ////ml.Export_scicomp("level_"+to_string(my_level)); //int my_level=nrefine-1; //const auto &mesh=ggm.GetMesh(my_level); //const auto &uv=ggm.GetSolution(my_level); //vector exact_sol(size(uv)); //mesh.SetValues(exact_sol, [](double x, double y) -> double { //return x * x * std::sin(2.5 * M_PI * y); //} ); //mesh.Visualize(getAbsError(exact_sol, uv)); #endif return 0; } void Test_solver(int /*lev*/, vector const &nthreads, Multigrid &ggm) { cout << endl << endl << "-------------------------------------" << endl; cout << "MgSolve: timing in sec. for " << ggm.Ndofs() << " dofs" << endl; cout << "sec threads" << endl; vector mg_time(size(nthreads), -1.0); for (size_t k = 0; k < size(nthreads); ++k) { omp_set_num_threads(nthreads.at(k)); double tstart = omp_get_wtime(); ggm.MG_Solve(2, 1e-6, 1); double t1 = omp_get_wtime() - tstart; mg_time.at(k) = t1; cout << t1 << " : " << nthreads.at(k) << endl; } }