Add SOR solver
This commit is contained in:
parent
d8185c0d0c
commit
3a201d35ca
@ -53,6 +53,6 @@ double getTime(void);
|
|||||||
const char *summary(void);
|
const char *summary(void);
|
||||||
double solve(HeatConfiguration *conf, int64_t rows, int64_t cols, int timesteps, void *extraData);
|
double solve(HeatConfiguration *conf, int64_t rows, int64_t cols, int timesteps, void *extraData);
|
||||||
void computeBlock(const int64_t rows, const int64_t cols, const int rstart, const int rend, const int cstart, const int cend, double M[rows][cols]);
|
void computeBlock(const int64_t rows, const int64_t cols, const int rstart, const int rend, const int cstart, const int cend, double M[rows][cols]);
|
||||||
double computeBlockResidual(const int64_t rows, const int64_t cols, const int rstart, const int rend, const int cstart, const int cend, double M[rows][cols]);
|
void computeBlockResidual(const int64_t rows, const int64_t cols, const int rstart, const int rend, const int cstart, const int cend, double M[rows][cols], double relax, double *residual, double *max_elem);
|
||||||
|
|
||||||
#endif // HEAT_H
|
#endif // HEAT_H
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include "common/heat.h"
|
#include "common/heat.h"
|
||||||
|
|
||||||
#ifndef SIMD
|
#ifndef SIMD
|
||||||
@ -19,6 +20,7 @@ void computeBlock(const int64_t rows, const int64_t cols,
|
|||||||
const int cstart, const int cend,
|
const int cstart, const int cend,
|
||||||
double M[rows][cols])
|
double M[rows][cols])
|
||||||
{
|
{
|
||||||
|
(void) cend;
|
||||||
// Assuming square blocks
|
// Assuming square blocks
|
||||||
const int bs = rend-rstart+1;
|
const int bs = rend-rstart+1;
|
||||||
for (int k = 0; k < bs; ++k) {
|
for (int k = 0; k < bs; ++k) {
|
||||||
@ -40,19 +42,74 @@ void computeBlock(const int64_t rows, const int64_t cols,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
double computeBlockResidual(const int64_t rows, const int64_t cols,
|
|
||||||
|
#if 1
|
||||||
|
|
||||||
|
void computeBlockResidual(const int64_t rows, const int64_t cols,
|
||||||
const int rstart, const int rend,
|
const int rstart, const int rend,
|
||||||
const int cstart, const int cend,
|
const int cstart, const int cend,
|
||||||
double M[rows][cols])
|
double M[rows][cols], double relax,
|
||||||
|
double *residual, double *max_elem)
|
||||||
{
|
{
|
||||||
double sum = 0.0;
|
//double relax = 1.95;
|
||||||
for (int r = rstart; r <= rend; ++r) {
|
for (int r = rstart; r <= rend; ++r) {
|
||||||
for (int c = cstart; c <= cend; ++c) {
|
for (int c = cstart; c <= cend; ++c) {
|
||||||
const double value = 0.25*(M[r-1][c] + M[r+1][c] + M[r][c-1] + M[r][c+1]);
|
double old = M[r][c];
|
||||||
const double diff = value - M[r][c];
|
double fdiff = 0.25*(M[r-1][c] + M[r+1][c] + M[r][c-1] + M[r][c+1]);
|
||||||
sum += diff*diff;
|
double new = (1 - relax) * old + relax * fdiff;
|
||||||
M[r][c] = value;
|
double diff = new - old;
|
||||||
|
/* Use the largest absolute error as residual */
|
||||||
|
*residual = fmax(*residual, fabs(diff));
|
||||||
|
*max_elem = fmax(*max_elem, fabs(new));
|
||||||
|
//fprintf(stderr, "residual = %e in (%4d, %4d)\n", residual, r, c);
|
||||||
|
M[r][c] = new;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return sum;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
/* Red-black parallelization */
|
||||||
|
void computeBlockResidual(const int64_t rows, const int64_t cols,
|
||||||
|
const int rstart, const int rend,
|
||||||
|
const int cstart, const int cend,
|
||||||
|
double M[rows][cols], double relax,
|
||||||
|
double * restrict residual, double * restrict max_elem)
|
||||||
|
{
|
||||||
|
(void)(residual);
|
||||||
|
(void)(max_elem);
|
||||||
|
|
||||||
|
const double A = 1 - relax;
|
||||||
|
const double B = 0.25 * relax;
|
||||||
|
|
||||||
|
//double relax = 1.95;
|
||||||
|
for (int r = rstart; r <= rend; r += 2) {
|
||||||
|
#pragma clang loop vectorize(enable)
|
||||||
|
for (int c = cstart; c <= cend; c += 2) {
|
||||||
|
double old = M[r][c];
|
||||||
|
double new = A * old + B * (M[r-1][c] + M[r+1][c] + M[r][c-1] + M[r][c+1]);
|
||||||
|
//double diff = new - old;
|
||||||
|
/* Use the largest absolute error as residual */
|
||||||
|
//*residual = fmax(*residual, fabs(diff));
|
||||||
|
//*max_elem = fmax(*max_elem, fabs(new));
|
||||||
|
//fprintf(stderr, "residual = %e in (%4d, %4d)\n", residual, r, c);
|
||||||
|
M[r][c] = new;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int r = rstart+1; r <= rend; r += 2) {
|
||||||
|
#pragma clang loop vectorize(enable)
|
||||||
|
for (int c = cstart+1; c <= cend; c += 2) {
|
||||||
|
double old = M[r][c];
|
||||||
|
double new = A * old + B * (M[r-1][c] + M[r+1][c] + M[r][c-1] + M[r][c+1]);
|
||||||
|
//double diff = new - old;
|
||||||
|
/* Use the largest absolute error as residual */
|
||||||
|
//*residual = fmax(*residual, fabs(diff));
|
||||||
|
//*max_elem = fmax(*max_elem, fabs(new));
|
||||||
|
//fprintf(stderr, "residual = %e in (%4d, %4d)\n", residual, r, c);
|
||||||
|
M[r][c] = new;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user