add setNumberThreads method

This commit is contained in:
Hannes Signer 2023-08-23 18:34:48 +02:00
parent 32b05a8a87
commit 6b8368d9f7
4 changed files with 41 additions and 29 deletions

View File

@ -142,6 +142,8 @@ class Simulation {
*/
void setSolver(SOLVER solver);
void setNumberThreads(int num_threads);
/**
* @brief Return the currently set iterations to be calculated.
*
@ -185,6 +187,7 @@ class Simulation {
double timestep;
int iterations;
int innerIterations;
int numThreads;
CSV_OUTPUT csv_output;
CONSOLE_OUTPUT console_output;
TIME_MEASURE time_measure;

View File

@ -9,7 +9,7 @@
#include <tug/Boundary.hpp>
#include <omp.h>
#define NUM_THREADS_BTCS 1
#define NUM_THREADS_BTCS 10
using namespace Eigen;
@ -87,7 +87,6 @@ static SparseMatrix<double> createCoeffMatrix(MatrixXd &alpha, vector<BoundaryEl
// inner columns
int n = numCols-1;
#pragma omp parallel for num_threads(NUM_THREADS_BTCS)
for (int i = 1; i < n; i++) {
cm.insert(i,i-1) = -sx * calcAlphaIntercell(alpha(rowIndex,i-1), alpha(rowIndex,i));
cm.insert(i,i) = 1 + sx * (
@ -202,7 +201,6 @@ static VectorXd createSolutionVector(MatrixXd &concentrations, MatrixXd &alphaX,
// inner rows
if (rowIndex > 0 && rowIndex < numRows-1) {
#pragma omp parallel for num_threads(NUM_THREADS_BTCS)
for (int i = 0; i < length; i++) {
sv(i) = sy * calcAlphaIntercell(alphaY(rowIndex,i), alphaY(rowIndex+1,i))
* concentrations(rowIndex+1,i)
@ -220,7 +218,6 @@ static VectorXd createSolutionVector(MatrixXd &concentrations, MatrixXd &alphaX,
// first row
if (rowIndex == 0) {
#pragma omp parallel for num_threads(NUM_THREADS_BTCS)
for (int i = 0; i < length; i++) {
type = bcTop[i].getType();
if (type == BC_TYPE_CONSTANT) {
@ -235,7 +232,6 @@ static VectorXd createSolutionVector(MatrixXd &concentrations, MatrixXd &alphaX,
// last row
if (rowIndex == numRows-1) {
#pragma omp parallel for num_threads(NUM_THREADS_BTCS)
for (int i = 0; i < length; i++) {
type = bcBottom[i].getType();
if (type == BC_TYPE_CONSTANT) {
@ -357,7 +353,7 @@ static void BTCS_1D(Grid &grid, Boundary &bc, double &timestep, VectorXd (*solve
// BTCS solution for 2D grid
static void BTCS_2D(Grid &grid, Boundary &bc, double &timestep, VectorXd (*solverFunc) (SparseMatrix<double> &A, VectorXd &b)) {
static void BTCS_2D(Grid &grid, Boundary &bc, double &timestep, VectorXd (*solverFunc) (SparseMatrix<double> &A, VectorXd &b), int &numThreads) {
int rowMax = grid.getRow();
int colMax = grid.getCol();
double sx = timestep / (2 * grid.getDeltaCol() * grid.getDeltaCol());
@ -377,7 +373,7 @@ static void BTCS_2D(Grid &grid, Boundary &bc, double &timestep, VectorXd (*solve
vector<BoundaryElement> bcBottom = bc.getBoundarySide(BC_SIDE_BOTTOM);
MatrixXd concentrations = grid.getConcentrations();
#pragma omp parallel for num_threads(NUM_THREADS_BTCS) private(A, b, row_t1)
#pragma omp parallel for num_threads(numThreads) private(A, b, row_t1)
for (int i = 0; i < rowMax; i++) {
@ -397,7 +393,7 @@ static void BTCS_2D(Grid &grid, Boundary &bc, double &timestep, VectorXd (*solve
alphaX.transposeInPlace();
alphaY.transposeInPlace();
#pragma omp parallel for num_threads(NUM_THREADS_BTCS) private(A, b, row_t1)
#pragma omp parallel for num_threads(numThreads) private(A, b, row_t1)
for (int i = 0; i < colMax; i++) {
// swap alphas, boundary conditions and sx/sy for column-wise calculation
@ -417,22 +413,22 @@ static void BTCS_2D(Grid &grid, Boundary &bc, double &timestep, VectorXd (*solve
// entry point for EigenLU solver; differentiate between 1D and 2D grid
static void BTCS_LU(Grid &grid, Boundary &bc, double &timestep) {
static void BTCS_LU(Grid &grid, Boundary &bc, double &timestep, int &numThreads) {
if (grid.getDim() == 1) {
BTCS_1D(grid, bc, timestep, EigenLUAlgorithm);
} else if (grid.getDim() == 2) {
BTCS_2D(grid, bc, timestep, EigenLUAlgorithm);
BTCS_2D(grid, bc, timestep, EigenLUAlgorithm, numThreads);
} else {
throw_invalid_argument("Error: Only 1- and 2-dimensional grids are defined!");
}
}
// entry point for Thomas algorithm solver; differentiate 1D and 2D grid
static void BTCS_Thomas(Grid &grid, Boundary &bc, double &timestep) {
static void BTCS_Thomas(Grid &grid, Boundary &bc, double &timestep, int &numThreads) {
if (grid.getDim() == 1) {
BTCS_1D(grid, bc, timestep, ThomasAlgorithm);
} else if (grid.getDim() == 2) {
BTCS_2D(grid, bc, timestep, ThomasAlgorithm);
BTCS_2D(grid, bc, timestep, ThomasAlgorithm, numThreads);
} else {
throw_invalid_argument("Error: Only 1- and 2-dimensional grids are defined!");
}

View File

@ -259,7 +259,7 @@ static void FTCS_1D(Grid &grid, Boundary &bc, double &timestep) {
// FTCS solution for 2D grid
static void FTCS_2D(Grid &grid, Boundary &bc, double &timestep) {
static void FTCS_2D(Grid &grid, Boundary &bc, double &timestep, int numThreads) {
int rowMax = grid.getRow();
int colMax = grid.getCol();
double deltaRow = grid.getDeltaRow();
@ -271,7 +271,7 @@ static void FTCS_2D(Grid &grid, Boundary &bc, double &timestep) {
// inner cells
// these are independent of the boundary condition type
// omp_set_num_threads(10);
#pragma omp parallel for num_threads(NUM_THREADS)
#pragma omp parallel for num_threads(numThreads)
for (int row = 1; row < rowMax-1; row++) {
for (int col = 1; col < colMax-1; col++) {
concentrations_t1(row, col) = grid.getConcentrations()(row, col)
@ -291,7 +291,7 @@ static void FTCS_2D(Grid &grid, Boundary &bc, double &timestep) {
// left without corners / looping over rows
// hold column constant at index 0
int col = 0;
#pragma omp parallel for num_threads(NUM_THREADS)
#pragma omp parallel for num_threads(numThreads)
for (int row = 1; row < rowMax-1; row++) {
concentrations_t1(row, col) = grid.getConcentrations()(row,col)
+ timestep / (deltaCol*deltaCol)
@ -308,7 +308,7 @@ static void FTCS_2D(Grid &grid, Boundary &bc, double &timestep) {
// right without corners / looping over rows
// hold column constant at max index
col = colMax-1;
#pragma omp parallel for num_threads(NUM_THREADS)
#pragma omp parallel for num_threads(numThreads)
for (int row = 1; row < rowMax-1; row++) {
concentrations_t1(row,col) = grid.getConcentrations()(row,col)
+ timestep / (deltaCol*deltaCol)
@ -326,7 +326,7 @@ static void FTCS_2D(Grid &grid, Boundary &bc, double &timestep) {
// top without corners / looping over columns
// hold row constant at index 0
int row = 0;
#pragma omp parallel for num_threads(NUM_THREADS)
#pragma omp parallel for num_threads(numThreads)
for (int col=1; col<colMax-1;col++){
concentrations_t1(row, col) = grid.getConcentrations()(row, col)
+ timestep / (deltaRow*deltaRow)
@ -343,7 +343,7 @@ static void FTCS_2D(Grid &grid, Boundary &bc, double &timestep) {
// bottom without corners / looping over columns
// hold row constant at max index
row = rowMax-1;
#pragma omp parallel for num_threads(NUM_THREADS)
#pragma omp parallel for num_threads(numThreads)
for(int col=1; col<colMax-1;col++){
concentrations_t1(row, col) = grid.getConcentrations()(row, col)
+ timestep / (deltaRow*deltaRow)
@ -424,11 +424,11 @@ static void FTCS_2D(Grid &grid, Boundary &bc, double &timestep) {
// entry point; differentiate between 1D and 2D grid
static void FTCS(Grid &grid, Boundary &bc, double &timestep) {
static void FTCS(Grid &grid, Boundary &bc, double &timestep, int &numThreads) {
if (grid.getDim() == 1) {
FTCS_1D(grid, bc, timestep);
} else if (grid.getDim() == 2) {
FTCS_2D(grid, bc, timestep);
FTCS_2D(grid, bc, timestep, numThreads);
} else {
throw_invalid_argument("Error: Only 1- and 2-dimensional grids are defined!");
}

View File

@ -4,6 +4,7 @@
#include <stdexcept>
#include <string>
#include <tug/Simulation.hpp>
#include <omp.h>
#include <fstream>
@ -22,6 +23,7 @@ Simulation::Simulation(Grid &grid, Boundary &bc, APPROACH approach) : grid(grid)
this->timestep = -1; // error per default
this->iterations = -1;
this->innerIterations = 1;
this->numThreads = omp_get_num_procs();
this->csv_output = CSV_OUTPUT_OFF;
this->console_output = CONSOLE_OUTPUT_OFF;
@ -138,6 +140,17 @@ void Simulation::setSolver(SOLVER solver) {
this->solver = solver;
}
void Simulation::setNumberThreads(int numThreads){
if(numThreads>0 && numThreads<=omp_get_num_procs()){
this->numThreads=numThreads;
}
else{
int maxThreadNumber = omp_get_num_procs();
throw_invalid_argument("Number of threads exceeds the number of processor cores or is less than 1.");
}
}
int Simulation::getIterations() {
return this->iterations;
}
@ -227,14 +240,14 @@ void Simulation::run() {
printConcentrationsCSV(filename);
}
FTCS(this->grid, this->bc, this->timestep);
FTCS(this->grid, this->bc, this->timestep, this->numThreads);
if (i % (iterations * innerIterations / 100) == 0) {
double percentage = (double)i / ((double)iterations * (double)innerIterations) * 100;
if ((int)percentage % 10 == 0) {
cout << "Progress: " << percentage << "%" << endl;
}
}
// if (i % (iterations * innerIterations / 100) == 0) {
// double percentage = (double)i / ((double)iterations * (double)innerIterations) * 100;
// if ((int)percentage % 10 == 0) {
// cout << "Progress: " << percentage << "%" << endl;
// }
// }
}
} else if (approach == BTCS_APPROACH) { // BTCS case
@ -248,7 +261,7 @@ void Simulation::run() {
printConcentrationsCSV(filename);
}
BTCS_LU(this->grid, this->bc, this->timestep);
BTCS_LU(this->grid, this->bc, this->timestep, this->numThreads);
}
} else if (solver == THOMAS_ALGORITHM_SOLVER) {
@ -260,7 +273,7 @@ void Simulation::run() {
printConcentrationsCSV(filename);
}
BTCS_Thomas(this->grid, this->bc, this->timestep);
BTCS_Thomas(this->grid, this->bc, this->timestep, this->numThreads);
}
}