98 lines
3 KiB
C++
98 lines
3 KiB
C++
// MPI code in C++.
|
|
// See [Gropp/Lusk/Skjellum, "Using MPI", p.33/41 etc.]
|
|
// and /opt/mpich/include/mpi2c++/comm.h for details
|
|
|
|
#include "elements.h"
|
|
#include "geom.h"
|
|
#include "getmatrix.h"
|
|
#include "jacsolve.h"
|
|
#include "userset.h"
|
|
#include "vdop.h"
|
|
|
|
#include <cassert>
|
|
#include <chrono> // timing
|
|
#include <cmath>
|
|
#include <iostream>
|
|
#include <omp.h>
|
|
using namespace std;
|
|
using namespace std::chrono; // timing
|
|
|
|
int main(int /* argc */, char ** /* argv */ )
|
|
{
|
|
//#define PDE_2D
|
|
#ifdef PDE_2D
|
|
//Mesh const mesh("square_100.txt");
|
|
Mesh const mesh("square_tiny.txt");
|
|
//mesh.Debug();
|
|
//mesh.DebugEdgeBased();
|
|
//constexpr P1_2d_1dof elem;
|
|
//const P1_2d_1dof elem;
|
|
|
|
const P1_2d elem;
|
|
FEM_Matrix_2 SK(mesh, elem); // CRS matrix
|
|
|
|
vector<double> uv(SK.Nrows(), 0.0); // temperature
|
|
vector<double> fv(SK.Nrows(), 0.0); // r.h.s.
|
|
//SK.CalculateLaplace(fv);
|
|
SK.CalculateLaplace(fv, rhs_lap2);
|
|
//SK.CheckMatrix();
|
|
//SK.Debug();
|
|
//mesh.SetValues(uv, [](double x, double y) -> double {
|
|
//return x * x * std::sin(2.5 * M_PI * y);
|
|
//} );
|
|
mesh.SetValues(uv, sol_lap2);
|
|
|
|
SK.ApplyDirichletBC(uv, fv); // Dirichlet nodes are defines in input file
|
|
|
|
//////SK.writeBinary("sparseMatrix.bin");
|
|
//SK.Debug();
|
|
#else
|
|
//Mesh mesh("NS_3D.txt");
|
|
Mesh mesh("GH_NS_3D.txt");
|
|
FEM_Matrix_2 SK(mesh, P1_3d()); // CRS matrix
|
|
//mesh.liftToQuadratic();
|
|
////FEM_Matrix_2 SK(mesh,P2_3d(3)); // CRS matrix
|
|
//FEM_Matrix_2 SK(mesh,P1_2vec_3d()); // CRS matrix
|
|
|
|
vector<double> uv(SK.Nrows(), 0.0); // temperature
|
|
vector<double> fv(SK.Nrows(), 0.0); // r.h.s.
|
|
//SK.CalculateLaplace(fv);
|
|
SK.CalculateLaplace(fv,rhs_lap3);
|
|
//SK.CheckMatrix();
|
|
//mesh.SetValues(uv, [](double x, double y, double z) -> double {
|
|
//return x * x * std::sin(2.5 * M_PI * y) + z*z;
|
|
//} );
|
|
mesh.SetValues(uv, sol_lap3);
|
|
|
|
SK.ApplyDirichletBC_Box(uv, fv, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0); // brute force Dirichlet via box
|
|
//SK.ApplyDirichletBC_Box(uv,fv,5.0,6.0,5.0,6.0,0.0,0.0); // z==0 ==> Dirichlet-BC
|
|
#endif
|
|
|
|
|
|
//SK.Debug();
|
|
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<microseconds>(t4 - t3); // duration in microseconds
|
|
//double t_diff = static_cast<double>(duration.count()) / 1e6; // overall duration in seconds
|
|
//cout << "JacobiSolve: timing in sec. : " << t_diff << endl;
|
|
|
|
auto [val, idx] = findLargestAbsError(exact_sol, uv, 1e-6, 10);
|
|
cout << val << " :idx: " << idx << endl;
|
|
|
|
//cout << "exact: " << exact_sol << endl;
|
|
//cout << "numer: " << uv << endl;
|
|
|
|
////mesh.Visualize(getAbsError(exact_sol, uv));
|
|
|
|
|
|
////mesh.Write_ascii_matlab("uv.txt", uv);
|
|
mesh.Visualize(uv);
|
|
|
|
return 0;
|
|
}
|
|
|