forked from moebiusband/NuSiF-Solver
		
	EnhancedSolver port complete
This commit is contained in:
		| @@ -106,7 +106,7 @@ void initDiscretization(Discretization* d, Parameter* p) | ||||
|     d->dtBound       = 0.5 * d->re * 1.0 / invSqrSum; | ||||
|  | ||||
| #ifdef VERBOSE | ||||
|     printConfig(s); | ||||
|     printConfig(d); | ||||
| #endif /* VERBOSE */ | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -73,6 +73,9 @@ int main(int argc, char** argv) | ||||
|     Solver s; | ||||
|     initParameter(&p); | ||||
|  | ||||
|     FILE* fp; | ||||
|     fp = initResidualWriter(); | ||||
|  | ||||
|     if (argc != 2) { | ||||
|         printf("Usage: %s <configFile>\n", argv[0]); | ||||
|         exit(EXIT_SUCCESS); | ||||
| @@ -90,6 +93,7 @@ int main(int argc, char** argv) | ||||
|     double te  = d.te; | ||||
|     double t   = 0.0; | ||||
|     int nt     = 0; | ||||
|     double res = 0.0; | ||||
|  | ||||
|     timeStart = getTimeStamp(); | ||||
|     while (t <= te) { | ||||
| @@ -99,13 +103,16 @@ int main(int argc, char** argv) | ||||
|         computeFG(&d); | ||||
|         computeRHS(&d); | ||||
|         if (nt % 100 == 0) normalizePressure(&d); | ||||
|         solve(&s, d.p, d.rhs); | ||||
|         res = solve(&s, d.p, d.rhs); | ||||
|         adaptUV(&d); | ||||
|  | ||||
|         writeResidual(fp, t, res); | ||||
|  | ||||
|         t += d.dt; | ||||
|         nt++; | ||||
|  | ||||
| #ifdef VERBOSE | ||||
|         printf("TIME %f , TIMESTEP %f\n", t, solver.dt); | ||||
|         printf("TIME %f , TIMESTEP %f\n", t, d.dt); | ||||
| #else | ||||
|         printProgress(t); | ||||
| #endif | ||||
| @@ -123,7 +130,8 @@ int main(int argc, char** argv) | ||||
|     ug = allocate(64, bytesize); | ||||
|     vg = allocate(64, bytesize); | ||||
|     wg = allocate(64, bytesize); | ||||
|  | ||||
|      | ||||
|     fclose(fp); | ||||
|     createBulkArrays(&d, pg, ug, vg, wg); | ||||
|     VtkOptions opts = { .grid = d.grid }; | ||||
|     vtkOpen(&opts, d.problem); | ||||
|   | ||||
| @@ -14,19 +14,21 @@ | ||||
|  | ||||
| void initParameter(Parameter* param) | ||||
| { | ||||
|     param->xlength = 1.0; | ||||
|     param->ylength = 1.0; | ||||
|     param->zlength = 1.0; | ||||
|     param->imax    = 100; | ||||
|     param->jmax    = 100; | ||||
|     param->kmax    = 100; | ||||
|     param->itermax = 1000; | ||||
|     param->eps     = 0.0001; | ||||
|     param->omg     = 1.7; | ||||
|     param->re      = 100.0; | ||||
|     param->gamma   = 0.9; | ||||
|     param->tau     = 0.5; | ||||
|     param->levels  = 5; | ||||
|     param->xlength    = 1.0; | ||||
|     param->ylength    = 1.0; | ||||
|     param->zlength    = 1.0; | ||||
|     param->imax       = 100; | ||||
|     param->jmax       = 100; | ||||
|     param->kmax       = 100; | ||||
|     param->itermax    = 1000; | ||||
|     param->eps        = 0.0001; | ||||
|     param->omg        = 1.7; | ||||
|     param->re         = 100.0; | ||||
|     param->gamma      = 0.9; | ||||
|     param->tau        = 0.5; | ||||
|     param->levels     = 5; | ||||
|     param->presmooth  = 5; | ||||
|     param->postsmooth = 5; | ||||
| } | ||||
|  | ||||
| void readParameter(Parameter* param, const char* filename) | ||||
|   | ||||
| @@ -18,6 +18,7 @@ typedef struct { | ||||
|     char* name; | ||||
|     int bcLeft, bcRight, bcBottom, bcTop, bcFront, bcBack; | ||||
|     double u_init, v_init, w_init, p_init; | ||||
|     int presmooth, postsmooth; | ||||
| } Parameter; | ||||
|  | ||||
| void initParameter(Parameter*); | ||||
|   | ||||
| @@ -49,3 +49,22 @@ void stopProgress() | ||||
|     printf("\n"); | ||||
|     fflush(stdout); | ||||
| } | ||||
|  | ||||
| FILE* initResidualWriter() | ||||
| { | ||||
|     FILE* fp; | ||||
|     fp = fopen("residual.dat", "w"); | ||||
|  | ||||
|     if (fp == NULL) { | ||||
|         printf("Error!\n"); | ||||
|         exit(EXIT_FAILURE); | ||||
|     } | ||||
|  | ||||
|     return fp; | ||||
|  | ||||
| } | ||||
|  | ||||
| void writeResidual(FILE* fp, double ts, double res) | ||||
| { | ||||
|     fprintf(fp, "%f, %f\n", ts, res); | ||||
| } | ||||
| @@ -10,5 +10,6 @@ | ||||
| extern void initProgress(double); | ||||
| extern void printProgress(double); | ||||
| extern void stopProgress(void); | ||||
|  | ||||
| extern FILE* initResidualWriter(void); | ||||
| extern void writeResidual(FILE*, double, double); | ||||
| #endif | ||||
|   | ||||
| @@ -141,13 +141,62 @@ static double smooth( | ||||
|             for (int j = 1; j < jmax + 1; j++) { | ||||
|                 for (int i = isw; i < imax + 1; i += 2) { | ||||
|  | ||||
|                     R(i, j, k) = | ||||
|                         RHS(i, j, k) - | ||||
|                         ((P(i + 1, j, k) - 2.0 * P(i, j, k) + P(i - 1, j, k)) * idx2 + | ||||
|                             (P(i, j + 1, k) - 2.0 * P(i, j, k) + P(i, j - 1, k)) * idy2 + | ||||
|                             (P(i, j, k + 1) - 2.0 * P(i, j, k) + P(i, j, k - 1)) * idz2); | ||||
|                     P(i, j, k) -= | ||||
|                         factor * | ||||
|                         (RHS(i, j, k) - | ||||
|                             ((P(i + 1, j, k) - 2.0 * P(i, j, k) + P(i - 1, j, k)) * idx2 + | ||||
|                                 (P(i, j + 1, k) - 2.0 * P(i, j, k) + P(i, j - 1, k)) * | ||||
|                                     idy2 + | ||||
|                                 (P(i, j, k + 1) - 2.0 * P(i, j, k) + P(i, j, k - 1)) * | ||||
|                                     idz2)); | ||||
|                 } | ||||
|                 isw = 3 - isw; | ||||
|             } | ||||
|             jsw = 3 - jsw; | ||||
|         } | ||||
|         ksw = 3 - ksw; | ||||
|     } | ||||
| } | ||||
|  | ||||
| static double calculateResidual( | ||||
|     Solver* s, double* p, double* rhs, int level, int imax, int jmax, int kmax) | ||||
| { | ||||
|     double eps    = s->eps; | ||||
|     int itermax   = s->itermax; | ||||
|     double dx2    = s->grid->dx * s->grid->dx; | ||||
|     double dy2    = s->grid->dy * s->grid->dy; | ||||
|     double dz2    = s->grid->dz * s->grid->dz; | ||||
|     double idx2   = 1.0 / dx2; | ||||
|     double idy2   = 1.0 / dy2; | ||||
|     double idz2   = 1.0 / dz2; | ||||
|     double factor = s->omega * 0.5 * (dx2 * dy2 * dz2) / | ||||
|                     (dy2 * dz2 + dx2 * dz2 + dx2 * dy2); | ||||
|     double* r    = s->r[level]; | ||||
|     double epssq = eps * eps; | ||||
|     int it       = 0; | ||||
|     int pass, ksw, jsw, isw; | ||||
|     double res = 1.0; | ||||
|  | ||||
|     ksw = 1; | ||||
|  | ||||
|     for (pass = 0; pass < 2; pass++) { | ||||
|         jsw = ksw; | ||||
|  | ||||
|         for (int k = 1; k < kmax + 1; k++) { | ||||
|             isw = jsw; | ||||
|             for (int j = 1; j < jmax + 1; j++) { | ||||
|                 for (int i = isw; i < imax + 1; i += 2) { | ||||
|  | ||||
|                     R(i, | ||||
|                         j, | ||||
|                         k) = (RHS(i, j, k) - | ||||
|                               ((P(i + 1, j, k) - 2.0 * P(i, j, k) + P(i - 1, j, k)) * | ||||
|                                       idx2 + | ||||
|                                   (P(i, j + 1, k) - 2.0 * P(i, j, k) + P(i, j - 1, k)) * | ||||
|                                       idy2 + | ||||
|                                   (P(i, j, k + 1) - 2.0 * P(i, j, k) + P(i, j, k - 1)) * | ||||
|                                       idz2)); | ||||
|  | ||||
|                     P(i, j, k) -= (factor * R(i, j, k)); | ||||
|                     res += (R(i, j, k) * R(i, j, k)); | ||||
|                 } | ||||
|                 isw = 3 - isw; | ||||
| @@ -167,7 +216,7 @@ static double multiGrid( | ||||
| { | ||||
|     double res = 0.0; | ||||
|  | ||||
|     // coarsest level TODO: Use direct solver? | ||||
|     // coarsest level | ||||
|     if (level == COARSEST_LEVEL) { | ||||
|         for (int i = 0; i < 5; i++) { | ||||
|             smooth(s, p, rhs, level, imax, jmax, kmax); | ||||
| @@ -175,17 +224,18 @@ static double multiGrid( | ||||
|         return res; | ||||
|     } | ||||
|  | ||||
|     // pre-smoothing TODO: Make smoothing steps configurable? | ||||
|     for (int i = 0; i < 5; i++) { | ||||
|     // pre-smoothing | ||||
|     for (int i = 0; i < s->presmooth; i++) { | ||||
|         smooth(s, p, rhs, level, imax, jmax, kmax); | ||||
|         if (level == FINEST_LEVEL) setBoundaryCondition(p, imax, jmax, kmax); | ||||
|     } | ||||
|  | ||||
|     res = calculateResidual(s, p, rhs, level, imax, jmax, kmax); | ||||
|  | ||||
|     // restrict | ||||
|     restrictMG(s, level, imax, jmax, kmax); | ||||
|  | ||||
|     // MGSolver on residual and error. | ||||
|     // TODO: What if there is a rest? | ||||
|     multiGrid(s, | ||||
|         s->e[level + 1], | ||||
|         s->r[level + 1], | ||||
| @@ -202,8 +252,8 @@ static double multiGrid( | ||||
|     if (level == FINEST_LEVEL) setBoundaryCondition(p, imax, jmax, kmax); | ||||
|  | ||||
|     // post-smoothing | ||||
|     for (int i = 0; i < 5; i++) { | ||||
|         res = smooth(s, p, rhs, level, imax, jmax, kmax); | ||||
|     for (int i = 0; i < s->postsmooth; i++) { | ||||
|         smooth(s, p, rhs, level, imax, jmax, kmax); | ||||
|         if (level == FINEST_LEVEL) setBoundaryCondition(p, imax, jmax, kmax); | ||||
|     } | ||||
|  | ||||
| @@ -212,11 +262,13 @@ static double multiGrid( | ||||
|  | ||||
| void initSolver(Solver* s, Discretization* d, Parameter* p) | ||||
| { | ||||
|     s->eps     = p->eps; | ||||
|     s->omega   = p->omg; | ||||
|     s->itermax = p->itermax; | ||||
|     s->levels  = p->levels; | ||||
|     s->grid    = &d->grid; | ||||
|     s->eps        = p->eps; | ||||
|     s->omega      = p->omg; | ||||
|     s->itermax    = p->itermax; | ||||
|     s->levels     = p->levels; | ||||
|     s->grid       = &d->grid; | ||||
|     s->presmooth  = p->presmooth; | ||||
|     s->postsmooth = p->postsmooth; | ||||
|  | ||||
|     int imax   = s->grid->imax; | ||||
|     int jmax   = s->grid->jmax; | ||||
| @@ -240,11 +292,13 @@ void initSolver(Solver* s, Discretization* d, Parameter* p) | ||||
|     } | ||||
| } | ||||
|  | ||||
| void solve(Solver* s, double* p, double* rhs) | ||||
| double solve(Solver* s, double* p, double* rhs) | ||||
| { | ||||
|     double res = multiGrid(s, p, rhs, 0, s->grid->imax, s->grid->jmax, s->grid->kmax); | ||||
|  | ||||
| #ifdef VERBOSE | ||||
|     printf("Residuum: %.6f\n", res); | ||||
| #endif | ||||
|  | ||||
| return res; | ||||
| } | ||||
|   | ||||
							
								
								
									
										101
									
								
								BasicSolver/3D-seq/src/solver-rb.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								BasicSolver/3D-seq/src/solver-rb.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,101 @@ | ||||
| /* | ||||
|  * Copyright (C) NHR@FAU, University Erlangen-Nuremberg. | ||||
|  * All rights reserved. This file is part of nusif-solver. | ||||
|  * Use of this source code is governed by a MIT style | ||||
|  * license that can be found in the LICENSE file. | ||||
|  */ | ||||
| #include "solver.h" | ||||
| #include "util.h" | ||||
|  | ||||
| void initSolver(Solver* s, Discretization* d, Parameter* p) | ||||
| { | ||||
|     s->grid    = &d->grid; | ||||
|     s->itermax = p->itermax; | ||||
|     s->eps     = p->eps; | ||||
|     s->omega   = p->omg; | ||||
| } | ||||
|  | ||||
| double solve(Solver* s, double* p, double* rhs) | ||||
| { | ||||
|     int imax      = s->grid->imax; | ||||
|     int jmax      = s->grid->jmax; | ||||
|     int kmax      = s->grid->kmax; | ||||
|     double eps    = s->eps; | ||||
|     int itermax   = s->itermax; | ||||
|     double dx2    = s->grid->dx * s->grid->dx; | ||||
|     double dy2    = s->grid->dy * s->grid->dy; | ||||
|     double dz2    = s->grid->dz * s->grid->dz; | ||||
|     double idx2   = 1.0 / dx2; | ||||
|     double idy2   = 1.0 / dy2; | ||||
|     double idz2   = 1.0 / dz2; | ||||
|     double factor = s->omega * 0.5 * (dx2 * dy2 * dz2) / | ||||
|                     (dy2 * dz2 + dx2 * dz2 + dx2 * dy2); | ||||
|     double epssq = eps * eps; | ||||
|     int it       = 0; | ||||
|     double res   = 1.0; | ||||
|     int pass, ksw, jsw, isw; | ||||
|  | ||||
|     while ((res >= epssq) && (it < itermax)) { | ||||
|         res = 0.0; | ||||
|         ksw = 1; | ||||
|  | ||||
|         for (pass = 0; pass < 2; pass++) { | ||||
|             jsw = ksw; | ||||
|  | ||||
|             for (int k = 1; k < kmax + 1; k++) { | ||||
|                 isw = jsw; | ||||
|                 for (int j = 1; j < jmax + 1; j++) { | ||||
|                     for (int i = isw; i < imax + 1; i += 2) { | ||||
|  | ||||
|                         double r = | ||||
|                             RHS(i, j, k) - | ||||
|                             ((P(i + 1, j, k) - 2.0 * P(i, j, k) + P(i - 1, j, k)) * idx2 + | ||||
|                                 (P(i, j + 1, k) - 2.0 * P(i, j, k) + P(i, j - 1, k)) * | ||||
|                                     idy2 + | ||||
|                                 (P(i, j, k + 1) - 2.0 * P(i, j, k) + P(i, j, k - 1)) * | ||||
|                                     idz2); | ||||
|  | ||||
|                         P(i, j, k) -= (factor * r); | ||||
|                         res += (r * r); | ||||
|                     } | ||||
|                     isw = 3 - isw; | ||||
|                 } | ||||
|                 jsw = 3 - jsw; | ||||
|             } | ||||
|             ksw = 3 - ksw; | ||||
|         } | ||||
|  | ||||
|         for (int j = 1; j < jmax + 1; j++) { | ||||
|             for (int i = 1; i < imax + 1; i++) { | ||||
|                 P(i, j, 0)        = P(i, j, 1); | ||||
|                 P(i, j, kmax + 1) = P(i, j, kmax); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         for (int k = 1; k < kmax + 1; k++) { | ||||
|             for (int i = 1; i < imax + 1; i++) { | ||||
|                 P(i, 0, k)        = P(i, 1, k); | ||||
|                 P(i, jmax + 1, k) = P(i, jmax, k); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         for (int k = 1; k < kmax + 1; k++) { | ||||
|             for (int j = 1; j < jmax + 1; j++) { | ||||
|                 P(0, j, k)        = P(1, j, k); | ||||
|                 P(imax + 1, j, k) = P(imax, j, k); | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         res = res / (double)(imax * jmax * kmax); | ||||
| #ifdef DEBUG | ||||
|         printf("%d Residuum: %e\n", it, res); | ||||
| #endif | ||||
|         it++; | ||||
|     } | ||||
|  | ||||
| #ifdef VERBOSE | ||||
|     printf("Solver took %d iterations to reach %f\n", it, sqrt(res)); | ||||
| #endif | ||||
|  | ||||
| return res; | ||||
| } | ||||
| @@ -18,9 +18,10 @@ typedef struct { | ||||
|     int itermax; | ||||
|     int levels; | ||||
|     double **r, **e; | ||||
|     int presmooth, postsmooth; | ||||
| } Solver; | ||||
|  | ||||
| extern void initSolver(Solver*, Discretization*, Parameter*); | ||||
| extern void solve(Solver*, double*, double*); | ||||
| extern double solve(Solver*, double*, double*); | ||||
|  | ||||
| #endif | ||||
|   | ||||
| @@ -70,6 +70,7 @@ void vtkScalar(VtkOptions* o, char* name, double* s) | ||||
|         exit(EXIT_FAILURE); | ||||
|     } | ||||
|     fprintf(o->fh, "SCALARS %s float\n", name); | ||||
|     fprintf(o->fh, "LOOKUP_TABLE default\n"); | ||||
|  | ||||
|     for (int k = 0; k < kmax; k++) { | ||||
|         for (int j = 0; j < jmax; j++) { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user