forked from moebiusband/NuSiF-Solver
		
	EnhancedSolver port complete
This commit is contained in:
		
							
								
								
									
										38
									
								
								EnhancedSolver/3D-seq/src/allocate.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								EnhancedSolver/3D-seq/src/allocate.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,38 @@ | ||||
| /* | ||||
|  * Copyright (C)  NHR@FAU, University Erlangen-Nuremberg. | ||||
|  * All rights reserved. | ||||
|  * Use of this source code is governed by a MIT-style | ||||
|  * license that can be found in the LICENSE file. | ||||
|  */ | ||||
| #include <errno.h> | ||||
| #include <stddef.h> | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
|  | ||||
| #include "allocate.h" | ||||
|  | ||||
| void* allocate(size_t alignment, size_t bytesize) | ||||
| { | ||||
|     int errorCode; | ||||
|     void* ptr; | ||||
|  | ||||
|     errorCode = posix_memalign(&ptr, alignment, bytesize); | ||||
|  | ||||
|     if (errorCode) { | ||||
|         if (errorCode == EINVAL) { | ||||
|             fprintf(stderr, "Error: Alignment parameter is not a power of two\n"); | ||||
|             exit(EXIT_FAILURE); | ||||
|         } | ||||
|         if (errorCode == ENOMEM) { | ||||
|             fprintf(stderr, "Error: Insufficient memory to fulfill the request\n"); | ||||
|             exit(EXIT_FAILURE); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     if (ptr == NULL) { | ||||
|         fprintf(stderr, "Error: posix_memalign failed!\n"); | ||||
|         exit(EXIT_FAILURE); | ||||
|     } | ||||
|  | ||||
|     return ptr; | ||||
| } | ||||
							
								
								
									
										13
									
								
								EnhancedSolver/3D-seq/src/allocate.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								EnhancedSolver/3D-seq/src/allocate.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | ||||
| /* | ||||
|  * Copyright (C)  NHR@FAU, University Erlangen-Nuremberg. | ||||
|  * All rights reserved. | ||||
|  * Use of this source code is governed by a MIT-style | ||||
|  * license that can be found in the LICENSE file. | ||||
|  */ | ||||
| #ifndef __ALLOCATE_H_ | ||||
| #define __ALLOCATE_H_ | ||||
| #include <stdlib.h> | ||||
|  | ||||
| extern void* allocate(size_t alignment, size_t bytesize); | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										1128
									
								
								EnhancedSolver/3D-seq/src/discretization.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1128
									
								
								EnhancedSolver/3D-seq/src/discretization.c
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										86
									
								
								EnhancedSolver/3D-seq/src/discretization.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								EnhancedSolver/3D-seq/src/discretization.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,86 @@ | ||||
| /* | ||||
|  * 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. | ||||
|  */ | ||||
| #ifndef __DISCRETIZATION_H_ | ||||
| #define __DISCRETIZATION_H_ | ||||
|  | ||||
| #include "grid.h" | ||||
| #include "parameter.h" | ||||
|  | ||||
| enum OBJECTBOUNDARY { | ||||
|     FLUID = 0, | ||||
|     /* Front Corners */ | ||||
|     FRONTTOPLEFTCORNER, | ||||
|     FRONTTOPRIGHTCORNER, | ||||
|     FRONTBOTTOMLEFTCORNER, | ||||
|     FRONTBOTTOMRIGHTCORNER, | ||||
|     /* Back Corners */ | ||||
|     BACKTOPLEFTCORNER, | ||||
|     BACKTOPRIGHTCORNER, | ||||
|     BACKBOTTOMLEFTCORNER, | ||||
|     BACKBOTTOMRIGHTCORNER, | ||||
|     /* Faces */ | ||||
|     FRONTFACE, | ||||
|     BACKFACE, | ||||
|     LEFTFACE, | ||||
|     RIGHTFACE, | ||||
|     TOPFACE, | ||||
|     BOTTOMFACE, | ||||
|     /* Front Lines remaining after Corners and Faces */ | ||||
|     FRONTLEFTLINE, | ||||
|     FRONTRIGHTLINE, | ||||
|     FRONTTOPLINE, | ||||
|     FRONTBOTTOMLINE, | ||||
|     /* Bottom Lines remaining after Corners and Faces */ | ||||
|     BACKLEFTLINE, | ||||
|     BACKRIGHTLINE, | ||||
|     BACKTOPLINE, | ||||
|     BACKBOTTOMLINE, | ||||
|     /* Mid Lines remaining after Corners and Faces */ | ||||
|     MIDTOPLEFTLINE, | ||||
|     MIDTOPRIGHTLINE, | ||||
|     MIDBOTTOMLEFTLINE, | ||||
|     MIDBOTTOMRIGHTLINE, | ||||
|     /* Local where its an object but not a boundary */ | ||||
|     OBSTACLE, | ||||
|     /*Ghost cells boundary */ | ||||
|     OUTSIDEBOUNDARY | ||||
| }; | ||||
|  | ||||
| enum BC { NOSLIP = 1, SLIP, OUTFLOW, PERIODIC }; | ||||
|  | ||||
|  | ||||
| enum SHAPE { NOSHAPE = 0, RECT, CIRCLE }; | ||||
|  | ||||
| typedef struct { | ||||
|     /* geometry and grid information */ | ||||
|     Grid grid; | ||||
|     /* arrays */ | ||||
|     double *p, *rhs; | ||||
|     double *f, *g, *h; | ||||
|     double *u, *v, *w; | ||||
|     double* s; | ||||
|     /* parameters */ | ||||
|     double eps, omega; | ||||
|     double re, tau, gamma; | ||||
|     double gx, gy, gz; | ||||
|     /* time stepping */ | ||||
|     double dt, te; | ||||
|     double dtBound; | ||||
|     char* problem; | ||||
|     int bcLeft, bcRight, bcBottom, bcTop, bcFront, bcBack; | ||||
| } Discretization; | ||||
|  | ||||
| extern void initDiscretization(Discretization*, Parameter*); | ||||
| extern void computeRHS(Discretization*); | ||||
| extern void normalizePressure(Discretization*); | ||||
| extern void computeTimestep(Discretization*); | ||||
| extern void setBoundaryConditions(Discretization*); | ||||
| extern void setObjectBoundaryCondition(Discretization*); | ||||
| extern void setSpecialBoundaryCondition(Discretization*); | ||||
| extern void computeFG(Discretization*); | ||||
| extern void adaptUV(Discretization*); | ||||
| #endif | ||||
							
								
								
									
										16
									
								
								EnhancedSolver/3D-seq/src/grid.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								EnhancedSolver/3D-seq/src/grid.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | ||||
| /* | ||||
|  * 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. | ||||
|  */ | ||||
| #ifndef __GRID_H_ | ||||
| #define __GRID_H_ | ||||
|  | ||||
| typedef struct { | ||||
|     double dx, dy, dz; | ||||
|     int imax, jmax, kmax; | ||||
|     double xlength, ylength, zlength; | ||||
| } Grid; | ||||
|  | ||||
| #endif // __GRID_H_ | ||||
							
								
								
									
										54
									
								
								EnhancedSolver/3D-seq/src/likwid-marker.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								EnhancedSolver/3D-seq/src/likwid-marker.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,54 @@ | ||||
| /* | ||||
|  * ======================================================================================= | ||||
|  * | ||||
|  *      Author:   Jan Eitzinger (je), jan.eitzinger@fau.de | ||||
|  *      Copyright (c) 2020 RRZE, University Erlangen-Nuremberg | ||||
|  * | ||||
|  *      Permission is hereby granted, free of charge, to any person obtaining a copy | ||||
|  *      of this software and associated documentation files (the "Software"), to deal | ||||
|  *      in the Software without restriction, including without limitation the rights | ||||
|  *      to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||
|  *      copies of the Software, and to permit persons to whom the Software is | ||||
|  *      furnished to do so, subject to the following conditions: | ||||
|  * | ||||
|  *      The above copyright notice and this permission notice shall be included in all | ||||
|  *      copies or substantial portions of the Software. | ||||
|  * | ||||
|  *      THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||
|  *      IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||
|  *      FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||
|  *      AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||
|  *      LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||
|  *      OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||||
|  *      SOFTWARE. | ||||
|  * | ||||
|  * ======================================================================================= | ||||
|  */ | ||||
| #ifndef LIKWID_MARKERS_H | ||||
| #define LIKWID_MARKERS_H | ||||
|  | ||||
| #ifdef LIKWID_PERFMON | ||||
| #include <likwid.h> | ||||
| #define LIKWID_MARKER_INIT                likwid_markerInit() | ||||
| #define LIKWID_MARKER_THREADINIT          likwid_markerThreadInit() | ||||
| #define LIKWID_MARKER_SWITCH              likwid_markerNextGroup() | ||||
| #define LIKWID_MARKER_REGISTER(regionTag) likwid_markerRegisterRegion(regionTag) | ||||
| #define LIKWID_MARKER_START(regionTag)    likwid_markerStartRegion(regionTag) | ||||
| #define LIKWID_MARKER_STOP(regionTag)     likwid_markerStopRegion(regionTag) | ||||
| #define LIKWID_MARKER_CLOSE               likwid_markerClose() | ||||
| #define LIKWID_MARKER_RESET(regionTag)    likwid_markerResetRegion(regionTag) | ||||
| #define LIKWID_MARKER_GET(regionTag, nevents, events, time, count)                       \ | ||||
|     likwid_markerGetRegion(regionTag, nevents, events, time, count) | ||||
| #else /* LIKWID_PERFMON */ | ||||
| #define LIKWID_MARKER_INIT | ||||
| #define LIKWID_MARKER_THREADINIT | ||||
| #define LIKWID_MARKER_SWITCH | ||||
| #define LIKWID_MARKER_REGISTER(regionTag) | ||||
| #define LIKWID_MARKER_START(regionTag) | ||||
| #define LIKWID_MARKER_STOP(regionTag) | ||||
| #define LIKWID_MARKER_CLOSE | ||||
| #define LIKWID_MARKER_GET(regionTag, nevents, events, time, count) | ||||
| #define LIKWID_MARKER_RESET(regionTag) | ||||
| #endif /* LIKWID_PERFMON */ | ||||
|  | ||||
| #endif /*LIKWID_MARKERS_H*/ | ||||
							
								
								
									
										157
									
								
								EnhancedSolver/3D-seq/src/main.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										157
									
								
								EnhancedSolver/3D-seq/src/main.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,157 @@ | ||||
| /* | ||||
|  * Copyright (C) NHR@FAU, University Erlangen-Nuremberg. | ||||
|  * All rights reserved. | ||||
|  * Use of this source code is governed by a MIT-style | ||||
|  * license that can be found in the LICENSE file. | ||||
|  */ | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <unistd.h> | ||||
|  | ||||
| #include "allocate.h" | ||||
| #include "discretization.h" | ||||
| #include "parameter.h" | ||||
| #include "particletracing.h" | ||||
| #include "progress.h" | ||||
| #include "solver.h" | ||||
| #include "timing.h" | ||||
| #include "vtkWriter.h" | ||||
|  | ||||
| #define G(v, i, j, k) v[(k) * (imax + 2) * (jmax + 2) + (j) * (imax + 2) + (i)] | ||||
|  | ||||
| static void createBulkArrays( | ||||
|     Discretization* s, double* pg, double* ug, double* vg, double* wg) | ||||
| { | ||||
|     int imax = s->grid.imax; | ||||
|     int jmax = s->grid.jmax; | ||||
|     int kmax = s->grid.kmax; | ||||
|     int idx  = 0; | ||||
|  | ||||
|     for (int k = 1; k < kmax + 1; k++) { | ||||
|         for (int j = 1; j < jmax + 1; j++) { | ||||
|             for (int i = 1; i < imax + 1; i++) { | ||||
|                 pg[idx++] = G(s->p, i, j, k); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     idx = 0; | ||||
|  | ||||
|     for (int k = 1; k < kmax + 1; k++) { | ||||
|         for (int j = 1; j < jmax + 1; j++) { | ||||
|             for (int i = 1; i < imax + 1; i++) { | ||||
|                 ug[idx++] = (G(s->u, i, j, k) + G(s->u, i - 1, j, k)) / 2.0; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     idx = 0; | ||||
|  | ||||
|     for (int k = 1; k < kmax + 1; k++) { | ||||
|         for (int j = 1; j < jmax + 1; j++) { | ||||
|             for (int i = 1; i < imax + 1; i++) { | ||||
|                 vg[idx++] = (G(s->v, i, j, k) + G(s->v, i, j - 1, k)) / 2.0; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     idx = 0; | ||||
|  | ||||
|     for (int k = 1; k < kmax + 1; k++) { | ||||
|         for (int j = 1; j < jmax + 1; j++) { | ||||
|             for (int i = 1; i < imax + 1; i++) { | ||||
|                 wg[idx++] = (G(s->w, i, j, k) + G(s->w, i, j, k - 1)) / 2.0; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| int main(int argc, char** argv) | ||||
| { | ||||
|     double timeStart, timeStop; | ||||
|     Parameter p; | ||||
|     Discretization d; | ||||
|     Solver s; | ||||
|     ParticleTracer particletracer; | ||||
|     initParameter(&p); | ||||
|  | ||||
|     FILE* fp; | ||||
|     fp = initResidualWriter(); | ||||
|  | ||||
|     if (argc != 2) { | ||||
|         printf("Usage: %s <configFile>\n", argv[0]); | ||||
|         exit(EXIT_SUCCESS); | ||||
|     } | ||||
|  | ||||
|     readParameter(&p, argv[1]); | ||||
|     printParameter(&p); | ||||
|     initDiscretization(&d, &p); | ||||
|     initSolver(&s, &d, &p); | ||||
|     initParticleTracer(&particletracer, &p); | ||||
|     printParticleTracerParameters(&particletracer); | ||||
|  | ||||
| #ifndef VERBOSE | ||||
|     initProgress(d.te); | ||||
| #endif | ||||
|  | ||||
|     double tau = d.tau; | ||||
|     double te  = d.te; | ||||
|     double t   = 0.0; | ||||
|     int nt     = 0; | ||||
|     double res = 0.0; | ||||
|  | ||||
|     timeStart = getTimeStamp(); | ||||
|     while (t <= te) { | ||||
|         if (tau > 0.0) computeTimestep(&d); | ||||
|         setBoundaryConditions(&d); | ||||
|         setSpecialBoundaryCondition(&d); | ||||
|         setObjectBoundaryCondition(&d); | ||||
|  | ||||
|         computeFG(&d); | ||||
|         computeRHS(&d); | ||||
|         if (nt % 100 == 0) normalizePressure(&d); | ||||
|         res = solve(&s, d.p, d.rhs); | ||||
|         adaptUV(&d); | ||||
|  | ||||
|         trace(&particletracer, d.u, d.v, d.w, d.s, t); | ||||
|  | ||||
|         writeResidual(fp, t, res); | ||||
|  | ||||
|         t += d.dt; | ||||
|         nt++; | ||||
|  | ||||
| #ifdef VERBOSE | ||||
|         printf("TIME %f , TIMESTEP %f\n", t, d.dt); | ||||
| #else | ||||
|         printProgress(t); | ||||
| #endif | ||||
|     } | ||||
|     timeStop = getTimeStamp(); | ||||
|     stopProgress(); | ||||
|     printf("Solution took %.2fs\n", timeStop - timeStart); | ||||
|  | ||||
|     timeStart = getTimeStamp(); | ||||
|     double *pg, *ug, *vg, *wg; | ||||
|  | ||||
|     size_t bytesize = (size_t)(d.grid.imax * d.grid.jmax * d.grid.kmax) * sizeof(double); | ||||
|  | ||||
|     pg = allocate(64, bytesize); | ||||
|     ug = allocate(64, bytesize); | ||||
|     vg = allocate(64, bytesize); | ||||
|     wg = allocate(64, bytesize); | ||||
|  | ||||
|     fclose(fp); | ||||
|     freeParticles(&particletracer); | ||||
|      | ||||
|     createBulkArrays(&d, pg, ug, vg, wg); | ||||
|     VtkOptions opts = { .grid = d.grid }; | ||||
|     vtkOpen(&opts, d.problem); | ||||
|     vtkScalar(&opts, "pressure", pg); | ||||
|     vtkVector(&opts, "velocity", (VtkVector) { ug, vg, wg }); | ||||
|     vtkClose(&opts); | ||||
|  | ||||
|     timeStop = getTimeStamp(); | ||||
|     printf("Result output took %.2fs\n", timeStop - timeStart); | ||||
|  | ||||
|     return EXIT_SUCCESS; | ||||
| } | ||||
							
								
								
									
										153
									
								
								EnhancedSolver/3D-seq/src/parameter.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										153
									
								
								EnhancedSolver/3D-seq/src/parameter.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,153 @@ | ||||
| /* | ||||
|  * 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 <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
|  | ||||
| #include "parameter.h" | ||||
| #include "util.h" | ||||
| #define MAXLINE 4096 | ||||
|  | ||||
| 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->presmooth  = 5; | ||||
|     param->postsmooth = 5; | ||||
| } | ||||
|  | ||||
| void readParameter(Parameter* param, const char* filename) | ||||
| { | ||||
|     FILE* fp = fopen(filename, "r"); | ||||
|     char line[MAXLINE]; | ||||
|     int i; | ||||
|  | ||||
|     if (!fp) { | ||||
|         fprintf(stderr, "Could not open parameter file: %s\n", filename); | ||||
|         exit(EXIT_FAILURE); | ||||
|     } | ||||
|  | ||||
|     while (!feof(fp)) { | ||||
|         line[0] = '\0'; | ||||
|         fgets(line, MAXLINE, fp); | ||||
|         for (i = 0; line[i] != '\0' && line[i] != '#'; i++) | ||||
|             ; | ||||
|         line[i] = '\0'; | ||||
|  | ||||
|         char* tok = strtok(line, " "); | ||||
|         char* val = strtok(NULL, " "); | ||||
|  | ||||
| #define PARSE_PARAM(p, f)                                                                \ | ||||
|     if (strncmp(tok, #p, sizeof(#p) / sizeof(#p[0]) - 1) == 0) {                         \ | ||||
|         param->p = f(val);                                                               \ | ||||
|     } | ||||
| #define PARSE_STRING(p) PARSE_PARAM(p, strdup) | ||||
| #define PARSE_INT(p)    PARSE_PARAM(p, atoi) | ||||
| #define PARSE_REAL(p)   PARSE_PARAM(p, atof) | ||||
|  | ||||
|         if (tok != NULL && val != NULL) { | ||||
|             PARSE_REAL(xlength); | ||||
|             PARSE_REAL(ylength); | ||||
|             PARSE_REAL(zlength); | ||||
|             PARSE_INT(imax); | ||||
|             PARSE_INT(jmax); | ||||
|             PARSE_INT(kmax); | ||||
|             PARSE_INT(itermax); | ||||
|             PARSE_INT(levels); | ||||
|             PARSE_REAL(eps); | ||||
|             PARSE_REAL(omg); | ||||
|             PARSE_REAL(re); | ||||
|             PARSE_REAL(tau); | ||||
|             PARSE_REAL(gamma); | ||||
|             PARSE_REAL(dt); | ||||
|             PARSE_REAL(te); | ||||
|             PARSE_REAL(gx); | ||||
|             PARSE_REAL(gy); | ||||
|             PARSE_REAL(gz); | ||||
|             PARSE_STRING(name); | ||||
|             PARSE_INT(bcLeft); | ||||
|             PARSE_INT(bcRight); | ||||
|             PARSE_INT(bcBottom); | ||||
|             PARSE_INT(bcTop); | ||||
|             PARSE_INT(bcFront); | ||||
|             PARSE_INT(bcBack); | ||||
|             PARSE_REAL(u_init); | ||||
|             PARSE_REAL(v_init); | ||||
|             PARSE_REAL(w_init); | ||||
|             PARSE_REAL(p_init); | ||||
|  | ||||
|             /* Added new particle tracing parameters */ | ||||
|             PARSE_INT(numberOfParticles); | ||||
|             PARSE_REAL(startTime); | ||||
|             PARSE_REAL(injectTimePeriod); | ||||
|             PARSE_REAL(writeTimePeriod); | ||||
|             PARSE_REAL(x1); | ||||
|             PARSE_REAL(y1); | ||||
|             PARSE_REAL(z1); | ||||
|             PARSE_REAL(x2); | ||||
|             PARSE_REAL(y2); | ||||
|             PARSE_REAL(z2); | ||||
|  | ||||
|             /* Added obstacle geometry parameters */ | ||||
|             PARSE_INT(shape); | ||||
|             PARSE_REAL(xCenter); | ||||
|             PARSE_REAL(yCenter); | ||||
|             PARSE_REAL(zCenter); | ||||
|             PARSE_REAL(xRectLength); | ||||
|             PARSE_REAL(yRectLength); | ||||
|             PARSE_REAL(zRectLength); | ||||
|             PARSE_REAL(circleRadius); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     fclose(fp); | ||||
| } | ||||
|  | ||||
| void printParameter(Parameter* param) | ||||
| { | ||||
|     printf("Parameters for %s\n", param->name); | ||||
|     printf("Boundary conditions Left:%d Right:%d Bottom:%d Top:%d Front:%d " | ||||
|            "Back:%d\n", | ||||
|         param->bcLeft, | ||||
|         param->bcRight, | ||||
|         param->bcBottom, | ||||
|         param->bcTop, | ||||
|         param->bcFront, | ||||
|         param->bcBack); | ||||
|     printf("\tReynolds number: %.2f\n", param->re); | ||||
|     printf("\tInit arrays: U:%.2f V:%.2f W:%.2f P:%.2f\n", | ||||
|         param->u_init, | ||||
|         param->v_init, | ||||
|         param->w_init, | ||||
|         param->p_init); | ||||
|     printf("Geometry data:\n"); | ||||
|     printf("\tDomain box size (x, y, z): %.2f, %.2f, %.2f\n", | ||||
|         param->xlength, | ||||
|         param->ylength, | ||||
|         param->zlength); | ||||
|     printf("\tCells (x, y, z): %d, %d, %d\n", param->imax, param->jmax, param->kmax); | ||||
|     printf("Timestep parameters:\n"); | ||||
|     printf("\tDefault stepsize: %.2f, Final time %.2f\n", param->dt, param->te); | ||||
|     printf("\tTau factor: %.2f\n", param->tau); | ||||
|     printf("Iterative solver parameters:\n"); | ||||
|     printf("\tMax iterations: %d\n", param->itermax); | ||||
|     printf("\tepsilon (stopping tolerance) : %f\n", param->eps); | ||||
|     printf("\tgamma (stopping tolerance) : %f\n", param->gamma); | ||||
|     printf("\tomega (SOR relaxation): %f\n", param->omg); | ||||
|     printf("\tMultiGrid levels : %d\n", param->levels); | ||||
| } | ||||
							
								
								
									
										35
									
								
								EnhancedSolver/3D-seq/src/parameter.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								EnhancedSolver/3D-seq/src/parameter.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,35 @@ | ||||
| /* | ||||
|  * 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. | ||||
|  */ | ||||
| #ifndef __PARAMETER_H_ | ||||
| #define __PARAMETER_H_ | ||||
|  | ||||
| typedef struct { | ||||
|     int imax, jmax, kmax; | ||||
|     double xlength, ylength, zlength; | ||||
|     int itermax, levels; | ||||
|     double eps, omg, rho; | ||||
|     double re, tau, gamma; | ||||
|     double te, dt; | ||||
|     double gx, gy, gz; | ||||
|     char* name; | ||||
|     int bcLeft, bcRight, bcBottom, bcTop, bcFront, bcBack; | ||||
|     double u_init, v_init, w_init, p_init; | ||||
|     int presmooth, postsmooth; | ||||
|  | ||||
|     int numberOfParticles; | ||||
|     double startTime, injectTimePeriod, writeTimePeriod; | ||||
|  | ||||
|     double x1, y1, z1, x2, y2, z2; | ||||
|  | ||||
|     int shape; | ||||
|     double xCenter, yCenter, zCenter, xRectLength, yRectLength, zRectLength, circleRadius; | ||||
| } Parameter; | ||||
|  | ||||
| void initParameter(Parameter*); | ||||
| void readParameter(Parameter*, const char*); | ||||
| void printParameter(Parameter*); | ||||
| #endif | ||||
							
								
								
									
										313
									
								
								EnhancedSolver/3D-seq/src/particletracing.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										313
									
								
								EnhancedSolver/3D-seq/src/particletracing.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,313 @@ | ||||
| /* | ||||
|  * Copyright (C) 2022 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 <float.h> | ||||
| #include <math.h> | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
|  | ||||
| #include "discretization.h" | ||||
| #include "vtkWriter.h" | ||||
|  | ||||
| #define U(i, j, k) u[(k) * (imax + 2) * (jmax + 2) + (j) * (imax + 2) + (i)] | ||||
| #define V(i, j, k) v[(k) * (imax + 2) * (jmax + 2) + (j) * (imax + 2) + (i)] | ||||
| #define W(i, j, k) w[(k) * (imax + 2) * (jmax + 2) + (j) * (imax + 2) + (i)] | ||||
| #define S(i, j, k) s[(k) * (imax + 2) * (jmax + 2) + (j) * (imax + 2) + (i)] | ||||
|  | ||||
| static int ts     = 0; | ||||
| unsigned int seed = 32767; | ||||
| void printParticles(ParticleTracer* particletracer) | ||||
| { | ||||
|     for (int i = 0; i < particletracer->totalParticles; ++i) { | ||||
|         printf("Particle position X : %.2f, Y : %.2f, flag : %d\n", | ||||
|             particletracer->particlePool[i].x, | ||||
|             particletracer->particlePool[i].y, | ||||
|             particletracer->particlePool[i].flag); | ||||
|     } | ||||
| } | ||||
| void injectParticles(ParticleTracer* particletracer, double* s) | ||||
| { | ||||
|  | ||||
|     int imax = particletracer->imax; | ||||
|     int jmax = particletracer->jmax; | ||||
|     int kmax = particletracer->kmax; | ||||
|  | ||||
|     for (int i = 0; i < particletracer->numberOfParticles; ++i) { | ||||
|  | ||||
|         particletracer->particlePool[particletracer->pointer].x = | ||||
|             (((double)rand() / RAND_MAX) * (particletracer->x2 - particletracer->x1)) + | ||||
|             particletracer->x1; | ||||
|         particletracer->particlePool[particletracer->pointer].y = | ||||
|             (((double)rand() / RAND_MAX) * (particletracer->y2 - particletracer->y1)) + | ||||
|             particletracer->y1; | ||||
|         particletracer->particlePool[particletracer->pointer].z = | ||||
|             (((double)rand() / RAND_MAX) * (particletracer->z2 - particletracer->z1)) + | ||||
|             particletracer->z1; | ||||
|  | ||||
|         int i = particletracer->particlePool[particletracer->pointer].x / | ||||
|                 particletracer->dx; | ||||
|         int j = particletracer->particlePool[particletracer->pointer].y / | ||||
|                 particletracer->dy; | ||||
|         int k = particletracer->particlePool[particletracer->pointer].z / | ||||
|                 particletracer->dz; | ||||
|  | ||||
|         if (S(i, j, k) == FLUID) { | ||||
|             particletracer->particlePool[particletracer->pointer].flag = true; | ||||
|             ++(particletracer->pointer); | ||||
|             ++(particletracer->totalParticles); | ||||
|         } else | ||||
|             particletracer->particlePool[particletracer->pointer].flag = false; | ||||
|     } | ||||
| } | ||||
|  | ||||
| void advanceParticles(ParticleTracer* particletracer, | ||||
|     double* restrict u, | ||||
|     double* restrict v, | ||||
|     double* restrict w, | ||||
|     double* restrict s, | ||||
|     double time) | ||||
| { | ||||
|     int imax = particletracer->imax; | ||||
|     int jmax = particletracer->jmax; | ||||
|     int kmax = particletracer->kmax; | ||||
|  | ||||
|     double dx = particletracer->dx; | ||||
|     double dy = particletracer->dy; | ||||
|     double dz = particletracer->dz; | ||||
|  | ||||
|     double xlength = particletracer->xlength; | ||||
|     double ylength = particletracer->ylength; | ||||
|     double zlength = particletracer->zlength; | ||||
|  | ||||
|     for (int i = 0; i < particletracer->totalParticles; ++i) { | ||||
|         if (particletracer->particlePool[i].flag == true) { | ||||
|             double x = particletracer->particlePool[i].x; | ||||
|             double y = particletracer->particlePool[i].y; | ||||
|             double z = particletracer->particlePool[i].z; | ||||
|  | ||||
|             int iCoord = (int)(x / dx) + 1; | ||||
|             int jCoord = (int)((y + 0.5 * dy) / dy) + 1; | ||||
|             int kCoord = (int)((z + 0.5 * dz) / dz) + 1; | ||||
|  | ||||
|             double x1 = (double)(iCoord - 1) * dx; | ||||
|             double y1 = ((double)(jCoord - 1) - 0.5) * dy; | ||||
|             double z1 = ((double)(kCoord - 1) - 0.5) * dz; | ||||
|  | ||||
|             double x2 = (double)iCoord * dx; | ||||
|             double y2 = ((double)jCoord - 0.5) * dy; | ||||
|             double z2 = ((double)kCoord - 0.5) * dz; | ||||
|  | ||||
|             double u_n = | ||||
|                 (1.0 / (dx * dy * dz)) * | ||||
|                 ((x2 - x) * (y2 - y) * (z2 - z) * U(iCoord - 1, jCoord - 1, kCoord - 1) + | ||||
|                     (x - x1) * (y2 - y) * (z2 - z) * U(iCoord, jCoord - 1, kCoord - 1) + | ||||
|                     (x2 - x) * (y - y1) * (z2 - z) * U(iCoord - 1, jCoord, kCoord - 1) + | ||||
|                     (x - x1) * (y - y1) * (z2 - z) * U(iCoord, jCoord, kCoord - 1) + | ||||
|                     (x2 - x) * (y2 - y) * (z - z1) * U(iCoord - 1, jCoord - 1, kCoord) + | ||||
|                     (x - x1) * (y2 - y) * (z - z1) * U(iCoord, jCoord - 1, kCoord) + | ||||
|                     (x2 - x) * (y - y1) * (z - z1) * U(iCoord - 1, jCoord, kCoord) + | ||||
|                     (x - x1) * (y - y1) * (z - z1) * U(iCoord, jCoord, kCoord)); | ||||
|  | ||||
|             double new_x                      = x + particletracer->dt * u_n; | ||||
|             particletracer->particlePool[i].x = new_x; | ||||
|  | ||||
|             iCoord = (int)((x + 0.5 * dx) / dx) + 1; | ||||
|             jCoord = (int)(y / dy) + 1; | ||||
|             kCoord = (int)((z + 0.5 * dz) / dz) + 1; | ||||
|  | ||||
|             x1 = ((double)(iCoord - 1) - 0.5) * dx; | ||||
|             y1 = (double)(jCoord - 1) * dy; | ||||
|             z1 = ((double)(kCoord - 1) - 0.5) * dz; | ||||
|  | ||||
|             x2 = ((double)iCoord - 0.5) * dx; | ||||
|             y2 = (double)jCoord * dy; | ||||
|             z2 = ((double)kCoord - 0.5) * dz; | ||||
|  | ||||
|             double v_n = | ||||
|                 (1.0 / (dx * dy * dz)) * | ||||
|                 ((x2 - x) * (y2 - y) * (z2 - z) * V(iCoord - 1, jCoord - 1, kCoord - 1) + | ||||
|                     (x - x1) * (y2 - y) * (z2 - z) * V(iCoord, jCoord - 1, kCoord - 1) + | ||||
|                     (x2 - x) * (y - y1) * (z2 - z) * V(iCoord - 1, jCoord, kCoord - 1) + | ||||
|                     (x - x1) * (y - y1) * (z2 - z) * V(iCoord, jCoord, kCoord - 1) + | ||||
|                     (x2 - x) * (y2 - y) * (z - z1) * V(iCoord - 1, jCoord - 1, kCoord) + | ||||
|                     (x - x1) * (y2 - y) * (z - z1) * V(iCoord, jCoord - 1, kCoord) + | ||||
|                     (x2 - x) * (y - y1) * (z - z1) * V(iCoord - 1, jCoord, kCoord) + | ||||
|                     (x - x1) * (y - y1) * (z - z1) * V(iCoord, jCoord, kCoord)); | ||||
|  | ||||
|             double new_y                      = y + particletracer->dt * v_n; | ||||
|             particletracer->particlePool[i].y = new_y; | ||||
|  | ||||
|             iCoord = (int)((x + 0.5 * dx) / dx) + 1; | ||||
|             jCoord = (int)((y + 0.5 * dy) / dy) + 1; | ||||
|             kCoord = (int)(z / dz) + 1; | ||||
|  | ||||
|             x1 = ((double)(iCoord - 1) - 0.5) * dx; | ||||
|             y1 = ((double)(jCoord - 1) - 0.5) * dy; | ||||
|             z1 = (double)(kCoord - 1) * dz; | ||||
|  | ||||
|             x2 = ((double)iCoord - 0.5) * dx; | ||||
|             y2 = ((double)jCoord - 0.5) * dy; | ||||
|             z2 = (double)kCoord * dz; | ||||
|  | ||||
|             double w_n = | ||||
|                 (1.0 / (dx * dy * dz)) * | ||||
|                 ((x2 - x) * (y2 - y) * (z2 - z) * W(iCoord - 1, jCoord - 1, kCoord - 1) + | ||||
|                     (x - x1) * (y2 - y) * (z2 - z) * W(iCoord, jCoord - 1, kCoord - 1) + | ||||
|                     (x2 - x) * (y - y1) * (z2 - z) * W(iCoord - 1, jCoord, kCoord - 1) + | ||||
|                     (x - x1) * (y - y1) * (z2 - z) * W(iCoord, jCoord, kCoord - 1) + | ||||
|                     (x2 - x) * (y2 - y) * (z - z1) * W(iCoord - 1, jCoord - 1, kCoord) + | ||||
|                     (x - x1) * (y2 - y) * (z - z1) * W(iCoord, jCoord - 1, kCoord) + | ||||
|                     (x2 - x) * (y - y1) * (z - z1) * W(iCoord - 1, jCoord, kCoord) + | ||||
|                     (x - x1) * (y - y1) * (z - z1) * W(iCoord, jCoord, kCoord)); | ||||
|  | ||||
|             double new_z                      = z + particletracer->dt * w_n; | ||||
|             particletracer->particlePool[i].z = new_z; | ||||
|  | ||||
|             if (((new_x < 0.0) || (new_x > xlength) || (new_y < 0.0) || | ||||
|                     (new_y > ylength) || (new_z < 0.0) || (new_z > zlength))) { | ||||
|                 particletracer->particlePool[i].flag = false; | ||||
|                 particletracer->removedParticles++; | ||||
|             } | ||||
|             int i_new = new_x / dx, j_new = new_y / dy, k_new = new_z / dz; | ||||
|  | ||||
|             if (S(i_new, j_new, k_new) != FLUID) { | ||||
|                 particletracer->particlePool[i].flag = false; | ||||
|                 particletracer->removedParticles++; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| void freeParticles(ParticleTracer* particletracer) { free(particletracer->particlePool); } | ||||
|  | ||||
| void writeParticles(ParticleTracer* particletracer) | ||||
| { | ||||
|     VtkOptions opts = { .particletracer = particletracer }; | ||||
|     compress(particletracer); | ||||
|  | ||||
|     char filename[50]; | ||||
|     snprintf(filename, 50, "vtk_files/particles%d.vtk", ts); | ||||
|     vtkOpenPT(&opts, filename, ts); | ||||
|     vtkParticle(&opts, "particle"); | ||||
|     vtkClose(&opts); | ||||
|     ++ts; | ||||
| } | ||||
|  | ||||
| void initParticleTracer(ParticleTracer* particletracer, Parameter* params) | ||||
| { | ||||
|     particletracer->numberOfParticles = params->numberOfParticles; | ||||
|     particletracer->startTime         = params->startTime; | ||||
|     particletracer->injectTimePeriod  = params->injectTimePeriod; | ||||
|     particletracer->writeTimePeriod   = params->writeTimePeriod; | ||||
|  | ||||
|     particletracer->dt = params->dt; | ||||
|     particletracer->dx = params->xlength / params->imax; | ||||
|     particletracer->dy = params->ylength / params->jmax; | ||||
|     particletracer->dz = params->zlength / params->kmax; | ||||
|  | ||||
|     particletracer->xlength = params->xlength; | ||||
|     particletracer->ylength = params->ylength; | ||||
|     particletracer->zlength = params->zlength; | ||||
|  | ||||
|     particletracer->x1 = params->x1; | ||||
|     particletracer->y1 = params->y1; | ||||
|     particletracer->z1 = params->z1; | ||||
|     particletracer->x2 = params->x2; | ||||
|     particletracer->y2 = params->y2; | ||||
|     particletracer->z2 = params->z2; | ||||
|  | ||||
|     particletracer->lastInjectTime = params->startTime; | ||||
|     particletracer->lastUpdateTime = params->startTime; | ||||
|     particletracer->lastWriteTime  = params->startTime; | ||||
|  | ||||
|     particletracer->pointer          = 0; | ||||
|     particletracer->totalParticles   = 0; | ||||
|     particletracer->removedParticles = 0; | ||||
|  | ||||
|     particletracer->imax = params->imax; | ||||
|     particletracer->jmax = params->jmax; | ||||
|     particletracer->kmax = params->kmax; | ||||
|  | ||||
|     particletracer->estimatedNumParticles = ((params->te - params->startTime) + 2) * | ||||
|                                             params->numberOfParticles; | ||||
|  | ||||
|     particletracer->particlePool = malloc( | ||||
|         sizeof(Particle) * particletracer->estimatedNumParticles); | ||||
| } | ||||
|  | ||||
| void printParticleTracerParameters(ParticleTracer* particletracer) | ||||
| { | ||||
|     printf("Particle Tracing data:\n"); | ||||
|     printf("\tNumber of particles : %d being injected for every period of %.2f\n", | ||||
|         particletracer->numberOfParticles, | ||||
|         particletracer->injectTimePeriod); | ||||
|     printf("\tstartTime : %.2f\n", particletracer->startTime); | ||||
|     printf("\t(Line along which the particles are to be injected) \n\tx1 : %.2f, y1 : " | ||||
|            "%.2f, z1 : %.2f, x2 : %.2f, y2 : %.2f, z2 : %.2f\n", | ||||
|         particletracer->x1, | ||||
|         particletracer->y1, | ||||
|         particletracer->z1, | ||||
|         particletracer->x2, | ||||
|         particletracer->y2, | ||||
|         particletracer->z2); | ||||
|     printf("\tPointer : %d, TotalParticles : %d\n", | ||||
|         particletracer->pointer, | ||||
|         particletracer->totalParticles); | ||||
|     printf("\tdt : %.2f, dx : %.2f, dy : %.2f,  dz : %.2f\n", | ||||
|         particletracer->dt, | ||||
|         particletracer->dx, | ||||
|         particletracer->dy, | ||||
|         particletracer->dz); | ||||
| } | ||||
|  | ||||
| void trace(ParticleTracer* particletracer, | ||||
|     double* u, | ||||
|     double* v, | ||||
|     double* w, | ||||
|     double* s, | ||||
|     double time) | ||||
| { | ||||
|     if (time >= particletracer->startTime) { | ||||
|         // printParticles(particletracer); | ||||
|         if ((time - particletracer->lastInjectTime) >= particletracer->injectTimePeriod) { | ||||
|             injectParticles(particletracer, s); | ||||
|             particletracer->lastInjectTime = time; | ||||
|         } | ||||
|         if ((time - particletracer->lastWriteTime) >= particletracer->writeTimePeriod) { | ||||
|             writeParticles(particletracer); | ||||
|             particletracer->lastWriteTime = time; | ||||
|         } | ||||
|         advanceParticles(particletracer, u, v, w, s, time); | ||||
|         if (particletracer->removedParticles > (particletracer->totalParticles * 0.2)) { | ||||
|             compress(particletracer); | ||||
|         } | ||||
|         particletracer->lastUpdateTime = time; | ||||
|     } | ||||
| } | ||||
|  | ||||
| void compress(ParticleTracer* particletracer) | ||||
| { | ||||
|     Particle* memPool = particletracer->particlePool; | ||||
|     Particle tempPool[particletracer->totalParticles]; | ||||
|     int totalParticles = 0; | ||||
|  | ||||
|     for (int i = 0; i < particletracer->totalParticles; ++i) { | ||||
|         if (memPool[i].flag == true) { | ||||
|             tempPool[totalParticles].x    = memPool[i].x; | ||||
|             tempPool[totalParticles].y    = memPool[i].y; | ||||
|             tempPool[totalParticles].z    = memPool[i].z; | ||||
|             tempPool[totalParticles].flag = memPool[i].flag; | ||||
|             ++totalParticles; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     particletracer->totalParticles   = totalParticles; | ||||
|     particletracer->removedParticles = 0; | ||||
|     particletracer->pointer          = totalParticles + 1; | ||||
|  | ||||
|     memcpy(particletracer->particlePool, tempPool, totalParticles * sizeof(Particle)); | ||||
| } | ||||
							
								
								
									
										46
									
								
								EnhancedSolver/3D-seq/src/particletracing.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								EnhancedSolver/3D-seq/src/particletracing.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,46 @@ | ||||
| /* | ||||
|  * Copyright (C) 2022 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. | ||||
|  */ | ||||
| #ifndef __PARTICLETRACING_H_ | ||||
| #define __PARTICLETRACING_H_ | ||||
| #include "allocate.h" | ||||
| #include "parameter.h" | ||||
|  | ||||
| #include <stdbool.h> | ||||
|  | ||||
| typedef enum COORD { X = 0, Y, NCOORD } COORD; | ||||
| typedef struct { | ||||
|     double x, y, z; | ||||
|     bool flag; | ||||
| } Particle; | ||||
|  | ||||
| typedef struct { | ||||
|     int numberOfParticles, totalParticles; | ||||
|     double startTime, injectTimePeriod, writeTimePeriod, lastInjectTime, lastUpdateTime, | ||||
|         lastWriteTime; | ||||
|  | ||||
|     int estimatedNumParticles, activeParticles, removedParticles; | ||||
|  | ||||
|     double dx, dy, dz, dt; | ||||
|     Particle* particlePool; | ||||
|  | ||||
|     int pointer; | ||||
|  | ||||
|     double imax, jmax, kmax, xlength, ylength, zlength; | ||||
|  | ||||
|     double x1, y1, x2, y2, z1, z2; | ||||
| } ParticleTracer; | ||||
|  | ||||
| extern void initParticleTracer(ParticleTracer*, Parameter*); | ||||
| extern void injectParticles(ParticleTracer*, double*); | ||||
| extern void advanceParticles(ParticleTracer*, double*, double*, double*, double*, double); | ||||
| extern void freeParticles(ParticleTracer*); | ||||
| extern void writeParticles(ParticleTracer*); | ||||
| extern void printParticleTracerParameters(ParticleTracer*); | ||||
| extern void printParticles(ParticleTracer*); | ||||
| extern void compress(ParticleTracer*); | ||||
| extern void trace(ParticleTracer*, double*, double*, double*, double*, double); | ||||
| #endif | ||||
							
								
								
									
										70
									
								
								EnhancedSolver/3D-seq/src/progress.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										70
									
								
								EnhancedSolver/3D-seq/src/progress.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,70 @@ | ||||
| /* | ||||
|  * 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 <math.h> | ||||
| #include <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
|  | ||||
| #include "progress.h" | ||||
|  | ||||
| static double _end; | ||||
| static int _current; | ||||
|  | ||||
| void initProgress(double end) | ||||
| { | ||||
|     _end     = end; | ||||
|     _current = 0; | ||||
|  | ||||
|     printf("[          ]"); | ||||
|     fflush(stdout); | ||||
| } | ||||
|  | ||||
| void printProgress(double current) | ||||
| { | ||||
|     int new = (int)rint((current / _end) * 10.0); | ||||
|  | ||||
|     if (new > _current) { | ||||
|         char progress[11]; | ||||
|         _current    = new; | ||||
|         progress[0] = 0; | ||||
|  | ||||
|         for (int i = 0; i < 10; i++) { | ||||
|             if (i < _current) { | ||||
|                 sprintf(progress + strlen(progress), "#"); | ||||
|             } else { | ||||
|                 sprintf(progress + strlen(progress), " "); | ||||
|             } | ||||
|         } | ||||
|         printf("\r[%s]", progress); | ||||
|     } | ||||
|     fflush(stdout); | ||||
| } | ||||
|  | ||||
| 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); | ||||
| } | ||||
							
								
								
									
										15
									
								
								EnhancedSolver/3D-seq/src/progress.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								EnhancedSolver/3D-seq/src/progress.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | ||||
| /* | ||||
|  * Copyright (C)  NHR@FAU, University Erlangen-Nuremberg. | ||||
|  * All rights reserved. | ||||
|  * Use of this source code is governed by a MIT-style | ||||
|  * license that can be found in the LICENSE file. | ||||
|  */ | ||||
| #ifndef __PROGRESS_H_ | ||||
| #define __PROGRESS_H_ | ||||
|  | ||||
| extern void initProgress(double); | ||||
| extern void printProgress(double); | ||||
| extern void stopProgress(void); | ||||
| extern FILE* initResidualWriter(void); | ||||
| extern void writeResidual(FILE*, double, double); | ||||
| #endif | ||||
							
								
								
									
										304
									
								
								EnhancedSolver/3D-seq/src/solver-mg.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										304
									
								
								EnhancedSolver/3D-seq/src/solver-mg.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,304 @@ | ||||
| /* | ||||
|  * 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 <stdio.h> | ||||
| #include <stdlib.h> | ||||
|  | ||||
| #include "allocate.h" | ||||
| #include "solver.h" | ||||
| #include "util.h" | ||||
|  | ||||
| #define FINEST_LEVEL   0 | ||||
| #define COARSEST_LEVEL (s->levels - 1) | ||||
| #define S(i, j, k)     s[(k) * (imax + 2) * (jmax + 2) + (j) * (imax + 2) + (i)] | ||||
| #define E(i, j, k)     e[(k) * (imax + 2) * (jmax + 2) + (j) * (imax + 2) + (i)] | ||||
| #define R(i, j, k)     r[(k) * (imax + 2) * (jmax + 2) + (j) * (imax + 2) + (i)] | ||||
| #define OLD(i, j, k)   old[(k) * (imax + 2) * (jmax + 2) + (j) * (imax + 2) + (i)] | ||||
|  | ||||
| static void restrictMG(Solver* s, int level, int imax, int jmax, int kmax) | ||||
| { | ||||
|     double* r   = s->r[level + 1]; | ||||
|     double* old = s->r[level]; | ||||
|  | ||||
|     for (int k = 1; k < kmax + 1; k++) { | ||||
|         for (int j = 1; j < jmax + 1; j++) { | ||||
|             for (int i = 1; i < imax + 1; ++i) { | ||||
|                 R(i, j, k) = (OLD(2 * i - 1, 2 * j - 1, 2 * k) + | ||||
|                                  OLD(2 * i, 2 * j - 1, 2 * k) * 2 + | ||||
|                                  OLD(2 * i + 1, 2 * j - 1, 2 * k) + | ||||
|                                  OLD(2 * i - 1, 2 * j, 2 * k) * 2 + | ||||
|                                  OLD(2 * i, 2 * j, 2 * k) * 8 + | ||||
|                                  OLD(2 * i + 1, 2 * j, 2 * k) * 2 + | ||||
|                                  OLD(2 * i - 1, 2 * j + 1, 2 * k) + | ||||
|                                  OLD(2 * i, 2 * j + 1, 2 * k) * 2 + | ||||
|                                  OLD(2 * i + 1, 2 * j + 1, 2 * k) + | ||||
|  | ||||
|                                  OLD(2 * i - 1, 2 * j - 1, 2 * k - 1) + | ||||
|                                  OLD(2 * i, 2 * j - 1, 2 * k - 1) * 2 + | ||||
|                                  OLD(2 * i + 1, 2 * j - 1, 2 * k - 1) + | ||||
|                                  OLD(2 * i - 1, 2 * j, 2 * k - 1) * 2 + | ||||
|                                  OLD(2 * i, 2 * j, 2 * k - 1) * 4 + | ||||
|                                  OLD(2 * i + 1, 2 * j, 2 * k - 1) * 2 + | ||||
|                                  OLD(2 * i - 1, 2 * j + 1, 2 * k - 1) + | ||||
|                                  OLD(2 * i, 2 * j + 1, 2 * k - 1) * 2 + | ||||
|                                  OLD(2 * i + 1, 2 * j + 1, 2 * k - 1) + | ||||
|  | ||||
|                                  OLD(2 * i - 1, 2 * j - 1, 2 * k + 1) + | ||||
|                                  OLD(2 * i, 2 * j - 1, 2 * k + 1) * 2 + | ||||
|                                  OLD(2 * i + 1, 2 * j - 1, 2 * k + 1) + | ||||
|                                  OLD(2 * i - 1, 2 * j, 2 * k + 1) * 2 + | ||||
|                                  OLD(2 * i, 2 * j, 2 * k + 1) * 4 + | ||||
|                                  OLD(2 * i + 1, 2 * j, 2 * k + 1) * 2 + | ||||
|                                  OLD(2 * i - 1, 2 * j + 1, 2 * k + 1) + | ||||
|                                  OLD(2 * i, 2 * j + 1, 2 * k + 1) * 2 + | ||||
|                                  OLD(2 * i + 1, 2 * j + 1, 2 * k + 1)) / | ||||
|                              64.0; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void prolongate(Solver* s, int level, int imax, int jmax, int kmax) | ||||
| { | ||||
|     double* old = s->r[level + 1]; | ||||
|     double* e   = s->r[level]; | ||||
|  | ||||
|     for (int k = 2; k < kmax + 1; k += 2) { | ||||
|         for (int j = 2; j < jmax + 1; j += 2) { | ||||
|             for (int i = 2; i < imax + 1; i += 2) { | ||||
|                 E(i, j, k) = OLD(i / 2, j / 2, k / 2); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void correct(Solver* s, double* p, int level, int imax, int jmax, int kmax) | ||||
| { | ||||
|     double* e = s->e[level]; | ||||
|  | ||||
|     for (int k = 1; k < kmax + 1; ++k) { | ||||
|         for (int j = 1; j < jmax + 1; ++j) { | ||||
|             for (int i = 1; i < imax + 1; ++i) { | ||||
|                 P(i, j, k) += E(i, j, k); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| static void setBoundaryCondition(double* p, int imax, int jmax, int kmax) | ||||
| { | ||||
|     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); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| static double smooth( | ||||
|     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) { | ||||
|  | ||||
|                     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)); | ||||
|  | ||||
|                     res += (R(i, j, k) * R(i, j, k)); | ||||
|                 } | ||||
|                 isw = 3 - isw; | ||||
|             } | ||||
|             jsw = 3 - jsw; | ||||
|         } | ||||
|         ksw = 3 - ksw; | ||||
|     } | ||||
|  | ||||
|     res = res / (double)(imax * jmax * kmax); | ||||
|  | ||||
|     return res; | ||||
| } | ||||
|  | ||||
| static double multiGrid( | ||||
|     Solver* s, double* p, double* rhs, int level, int imax, int jmax, int kmax) | ||||
| { | ||||
|     double res = 0.0; | ||||
|  | ||||
|     // coarsest level | ||||
|     if (level == COARSEST_LEVEL) { | ||||
|         for (int i = 0; i < 5; i++) { | ||||
|             smooth(s, p, rhs, level, imax, jmax, kmax); | ||||
|         } | ||||
|         return res; | ||||
|     } | ||||
|  | ||||
|     // 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. | ||||
|     multiGrid(s, | ||||
|         s->e[level + 1], | ||||
|         s->r[level + 1], | ||||
|         level + 1, | ||||
|         imax / 2, | ||||
|         jmax / 2, | ||||
|         kmax / 2); | ||||
|  | ||||
|     // prolongate | ||||
|     prolongate(s, level, imax, jmax, kmax); | ||||
|  | ||||
|     // correct p on finer level using residual | ||||
|     correct(s, p, level, imax, jmax, kmax); | ||||
|     if (level == FINEST_LEVEL) setBoundaryCondition(p, imax, jmax, kmax); | ||||
|  | ||||
|     // post-smoothing | ||||
|     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); | ||||
|     } | ||||
|  | ||||
|     return res; | ||||
| } | ||||
|  | ||||
| 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->presmooth  = p->presmooth; | ||||
|     s->postsmooth = p->postsmooth; | ||||
|  | ||||
|     int imax   = s->grid->imax; | ||||
|     int jmax   = s->grid->jmax; | ||||
|     int kmax   = s->grid->kmax; | ||||
|     int levels = s->levels; | ||||
|     printf("Using Multigrid solver with %d levels\n", levels); | ||||
|  | ||||
|     s->r = malloc(levels * sizeof(double*)); | ||||
|     s->e = malloc(levels * sizeof(double*)); | ||||
|  | ||||
|     size_t size = (imax + 2) * (jmax + 2) * (kmax + 2); | ||||
|  | ||||
|     for (int j = 0; j < levels; j++) { | ||||
|         s->r[j] = allocate(64, size * sizeof(double)); | ||||
|         s->e[j] = allocate(64, size * sizeof(double)); | ||||
|  | ||||
|         for (size_t i = 0; i < size; i++) { | ||||
|             s->r[j][i] = 0.0; | ||||
|             s->e[j][i] = 0.0; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| 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
									
								
								EnhancedSolver/3D-seq/src/solver-rb.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										101
									
								
								EnhancedSolver/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; | ||||
| } | ||||
							
								
								
									
										27
									
								
								EnhancedSolver/3D-seq/src/solver.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										27
									
								
								EnhancedSolver/3D-seq/src/solver.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,27 @@ | ||||
| /* | ||||
|  * 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. | ||||
|  */ | ||||
| #ifndef __SOLVER_H_ | ||||
| #define __SOLVER_H_ | ||||
| #include "discretization.h" | ||||
| #include "grid.h" | ||||
| #include "parameter.h" | ||||
|  | ||||
| typedef struct { | ||||
|     /* geometry and grid information */ | ||||
|     Grid* grid; | ||||
|     /* parameters */ | ||||
|     double eps, omega, rho; | ||||
|     int itermax; | ||||
|     int levels; | ||||
|     double **r, **e; | ||||
|     int presmooth, postsmooth; | ||||
| } Solver; | ||||
|  | ||||
| extern void initSolver(Solver*, Discretization*, Parameter*); | ||||
| extern double solve(Solver*, double*, double*); | ||||
|  | ||||
| #endif | ||||
							
								
								
									
										22
									
								
								EnhancedSolver/3D-seq/src/timing.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								EnhancedSolver/3D-seq/src/timing.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | ||||
| /* | ||||
|  * Copyright (C)  NHR@FAU, University Erlangen-Nuremberg. | ||||
|  * All rights reserved. | ||||
|  * Use of this source code is governed by a MIT-style | ||||
|  * license that can be found in the LICENSE file. | ||||
|  */ | ||||
| #include <stdlib.h> | ||||
| #include <time.h> | ||||
|  | ||||
| double getTimeStamp(void) | ||||
| { | ||||
|     struct timespec ts; | ||||
|     clock_gettime(CLOCK_MONOTONIC, &ts); | ||||
|     return (double)ts.tv_sec + (double)ts.tv_nsec * 1.e-9; | ||||
| } | ||||
|  | ||||
| double getTimeResolution(void) | ||||
| { | ||||
|     struct timespec ts; | ||||
|     clock_getres(CLOCK_MONOTONIC, &ts); | ||||
|     return (double)ts.tv_sec + (double)ts.tv_nsec * 1.e-9; | ||||
| } | ||||
							
								
								
									
										13
									
								
								EnhancedSolver/3D-seq/src/timing.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								EnhancedSolver/3D-seq/src/timing.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | ||||
| /* | ||||
|  * Copyright (C)  NHR@FAU, University Erlangen-Nuremberg. | ||||
|  * All rights reserved. | ||||
|  * Use of this source code is governed by a MIT-style | ||||
|  * license that can be found in the LICENSE file. | ||||
|  */ | ||||
| #ifndef __TIMING_H_ | ||||
| #define __TIMING_H_ | ||||
|  | ||||
| extern double getTimeStamp(void); | ||||
| extern double getTimeResolution(void); | ||||
|  | ||||
| #endif // __TIMING_H_ | ||||
							
								
								
									
										32
									
								
								EnhancedSolver/3D-seq/src/util.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										32
									
								
								EnhancedSolver/3D-seq/src/util.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,32 @@ | ||||
| /* | ||||
|  * Copyright (C)  NHR@FAU, University Erlangen-Nuremberg. | ||||
|  * All rights reserved. | ||||
|  * Use of this source code is governed by a MIT-style | ||||
|  * license that can be found in the LICENSE file. | ||||
|  */ | ||||
| #ifndef __UTIL_H_ | ||||
| #define __UTIL_H_ | ||||
| #define HLINE                                                                            \ | ||||
|     "----------------------------------------------------------------------------\n" | ||||
|  | ||||
| #ifndef MIN | ||||
| #define MIN(x, y) ((x) < (y) ? (x) : (y)) | ||||
| #endif | ||||
| #ifndef MAX | ||||
| #define MAX(x, y) ((x) > (y) ? (x) : (y)) | ||||
| #endif | ||||
| #ifndef ABS | ||||
| #define ABS(a) ((a) >= 0 ? (a) : -(a)) | ||||
| #endif | ||||
|  | ||||
| #define P(i, j, k)   p[(k) * (imax + 2) * (jmax + 2) + (j) * (imax + 2) + (i)] | ||||
| #define F(i, j, k)   f[(k) * (imax + 2) * (jmax + 2) + (j) * (imax + 2) + (i)] | ||||
| #define G(i, j, k)   g[(k) * (imax + 2) * (jmax + 2) + (j) * (imax + 2) + (i)] | ||||
| #define H(i, j, k)   h[(k) * (imax + 2) * (jmax + 2) + (j) * (imax + 2) + (i)] | ||||
| #define U(i, j, k)   u[(k) * (imax + 2) * (jmax + 2) + (j) * (imax + 2) + (i)] | ||||
| #define V(i, j, k)   v[(k) * (imax + 2) * (jmax + 2) + (j) * (imax + 2) + (i)] | ||||
| #define W(i, j, k)   w[(k) * (imax + 2) * (jmax + 2) + (j) * (imax + 2) + (i)] | ||||
| #define S(i, j, k)   s[(k) * (imax + 2) * (jmax + 2) + (j) * (imax + 2) + (i)] | ||||
| #define RHS(i, j, k) rhs[(k) * (imax + 2) * (jmax + 2) + (j) * (imax + 2) + (i)] | ||||
|  | ||||
| #endif // __UTIL_H_ | ||||
							
								
								
									
										198
									
								
								EnhancedSolver/3D-seq/src/vtkWriter.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										198
									
								
								EnhancedSolver/3D-seq/src/vtkWriter.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,198 @@ | ||||
| /* | ||||
|  * 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 <stdio.h> | ||||
| #include <stdlib.h> | ||||
| #include <string.h> | ||||
|  | ||||
| #include "vtkWriter.h" | ||||
| #define G(v, i, j, k) v[(k)*imax * jmax + (j)*imax + (i)] | ||||
|  | ||||
| static float floatSwap(float f) | ||||
| { | ||||
|     union { | ||||
|         float f; | ||||
|         char b[4]; | ||||
|     } dat1, dat2; | ||||
|  | ||||
|     dat1.f    = f; | ||||
|     dat2.b[0] = dat1.b[3]; | ||||
|     dat2.b[1] = dat1.b[2]; | ||||
|     dat2.b[2] = dat1.b[1]; | ||||
|     dat2.b[3] = dat1.b[0]; | ||||
|     return dat2.f; | ||||
| } | ||||
|  | ||||
| static void writeHeader(VtkOptions* o) | ||||
| { | ||||
|     fprintf(o->fh, "# vtk DataFile Version 3.0\n"); | ||||
|     fprintf(o->fh, "PAMPI cfd solver output\n"); | ||||
|     if (o->fmt == ASCII) { | ||||
|         fprintf(o->fh, "ASCII\n"); | ||||
|     } else if (o->fmt == BINARY) { | ||||
|         fprintf(o->fh, "BINARY\n"); | ||||
|     } | ||||
|  | ||||
|     fprintf(o->fh, "DATASET STRUCTURED_POINTS\n"); | ||||
|     fprintf(o->fh, "DIMENSIONS %d %d %d\n", o->grid.imax, o->grid.jmax, o->grid.kmax); | ||||
|     fprintf(o->fh, | ||||
|         "ORIGIN %f %f %f\n", | ||||
|         o->grid.dx * 0.5, | ||||
|         o->grid.dy * 0.5, | ||||
|         o->grid.dz * 0.5); | ||||
|     fprintf(o->fh, "SPACING %f %f %f\n", o->grid.dx, o->grid.dy, o->grid.dz); | ||||
|     fprintf(o->fh, "POINT_DATA %d\n", o->grid.imax * o->grid.jmax * o->grid.kmax); | ||||
| } | ||||
|  | ||||
| void vtkOpen(VtkOptions* o, char* problem) | ||||
| { | ||||
|     char filename[50]; | ||||
|     snprintf(filename, 50, "%s.vtk", problem); | ||||
|     o->fh = fopen(filename, "w"); | ||||
|     writeHeader(o); | ||||
|  | ||||
|     printf("Writing VTK output for %s\n", problem); | ||||
| } | ||||
|  | ||||
| void vtkScalar(VtkOptions* o, char* name, double* s) | ||||
| { | ||||
|     int imax = o->grid.imax; | ||||
|     int jmax = o->grid.jmax; | ||||
|     int kmax = o->grid.kmax; | ||||
|  | ||||
|     printf("Register scalar %s\n", name); | ||||
|  | ||||
|     if (o->fh == NULL) { | ||||
|         printf("vtkWriter not initialize! Call vtkOpen first!\n"); | ||||
|         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++) { | ||||
|             for (int i = 0; i < imax; i++) { | ||||
|                 if (o->fmt == ASCII) { | ||||
|                     fprintf(o->fh, "%f\n", G(s, i, j, k)); | ||||
|                 } else if (o->fmt == BINARY) { | ||||
|                     fwrite((float[1]) { floatSwap(G(s, i, j, k)) }, | ||||
|                         sizeof(float), | ||||
|                         1, | ||||
|                         o->fh); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     if (o->fmt == BINARY) fprintf(o->fh, "\n"); | ||||
| } | ||||
|  | ||||
| void vtkVector(VtkOptions* o, char* name, VtkVector vec) | ||||
| { | ||||
|     int imax = o->grid.imax; | ||||
|     int jmax = o->grid.jmax; | ||||
|     int kmax = o->grid.kmax; | ||||
|  | ||||
|     if (o->fh == NULL) { | ||||
|         printf("vtkWriter not initialize! Call vtkOpen first!\n"); | ||||
|         exit(EXIT_FAILURE); | ||||
|     } | ||||
|  | ||||
|     fprintf(o->fh, "VECTORS %s float\n", name); | ||||
|  | ||||
|     for (int k = 0; k < kmax; k++) { | ||||
|         for (int j = 0; j < jmax; j++) { | ||||
|             for (int i = 0; i < imax; i++) { | ||||
|                 if (o->fmt == ASCII) { | ||||
|                     fprintf(o->fh, | ||||
|                         "%f %f %f\n", | ||||
|                         G(vec.u, i, j, k), | ||||
|                         G(vec.v, i, j, k), | ||||
|                         G(vec.w, i, j, k)); | ||||
|                 } else if (o->fmt == BINARY) { | ||||
|                     fwrite((float[3]) { floatSwap(G(vec.u, i, j, k)), | ||||
|                                floatSwap(G(vec.v, i, j, k)), | ||||
|                                floatSwap(G(vec.w, i, j, k)) }, | ||||
|                         sizeof(float), | ||||
|                         3, | ||||
|                         o->fh); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     if (o->fmt == BINARY) fprintf(o->fh, "\n"); | ||||
| } | ||||
|  | ||||
| void vtkClose(VtkOptions* o) | ||||
| { | ||||
|     fclose(o->fh); | ||||
|     o->fh = NULL; | ||||
| } | ||||
|  | ||||
| static void writeHeaderPT(VtkOptions* o, int ts) | ||||
| { | ||||
|     fprintf(o->fh, "# vtk DataFile Version 3.0\n"); | ||||
|     fprintf(o->fh, "PAMPI cfd solver particle tracing file\n"); | ||||
|     if (o->fmt == ASCII) { | ||||
|         fprintf(o->fh, "ASCII\n"); | ||||
|     } else if (o->fmt == BINARY) { | ||||
|         fprintf(o->fh, "BINARY\n"); | ||||
|     } | ||||
|  | ||||
|     fprintf(o->fh, "DATASET UNSTRUCTURED_GRID\n"); | ||||
|     fprintf(o->fh, "FIELD FieldData 2\n"); | ||||
|     fprintf(o->fh, "TIME 1 1 double\n"); | ||||
|     fprintf(o->fh, "%d\n", ts); | ||||
|     fprintf(o->fh, "CYCLE 1 1 int\n"); | ||||
|     fprintf(o->fh, "1\n"); | ||||
| } | ||||
|  | ||||
| void vtkOpenPT(VtkOptions* o, char* problem, int ts) | ||||
| { | ||||
|     o->fh = fopen(problem, "w"); | ||||
|  | ||||
|     if (o->fh == NULL) { | ||||
|         printf("vtkWriter not initialize! Call vtkOpen first!\n"); | ||||
|         exit(EXIT_FAILURE); | ||||
|     } | ||||
|  | ||||
|     writeHeaderPT(o, ts); | ||||
|  | ||||
|     // printf("Writing VTK output for %s\n", problem); | ||||
| } | ||||
|  | ||||
| void vtkParticle(VtkOptions* o, char* name) | ||||
| { | ||||
|     Particle* particlePool = o->particletracer->particlePool; | ||||
|  | ||||
|     if (o->fh == NULL) { | ||||
|         printf("vtkWriter not initialize! Call vtkOpen first!\n"); | ||||
|         exit(EXIT_FAILURE); | ||||
|     } | ||||
|  | ||||
|     fprintf(o->fh, "POINTS %d float\n", o->particletracer->totalParticles); | ||||
|  | ||||
|     for (int i = 0; i < o->particletracer->totalParticles; ++i) { | ||||
|         double x = particlePool[i].x; | ||||
|         double y = particlePool[i].y; | ||||
|         double z = particlePool[i].z; | ||||
|         fprintf(o->fh, "%.2f %.2f %.2f\n", x, y, z); | ||||
|     } | ||||
|  | ||||
|     fprintf(o->fh, | ||||
|         "CELLS %d %d\n", | ||||
|         o->particletracer->totalParticles, | ||||
|         2 * o->particletracer->totalParticles); | ||||
|  | ||||
|     for (int i = 0; i < o->particletracer->totalParticles; ++i) { | ||||
|         fprintf(o->fh, "1 %d\n", i); | ||||
|     } | ||||
|  | ||||
|     fprintf(o->fh, "CELL_TYPES %d\n", o->particletracer->totalParticles); | ||||
|  | ||||
|     for (int i = 0; i < o->particletracer->totalParticles; ++i) { | ||||
|         fprintf(o->fh, "1\n"); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										34
									
								
								EnhancedSolver/3D-seq/src/vtkWriter.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								EnhancedSolver/3D-seq/src/vtkWriter.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,34 @@ | ||||
| /* | ||||
|  * 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. | ||||
|  */ | ||||
| #ifndef __VTKWRITER_H_ | ||||
| #define __VTKWRITER_H_ | ||||
| #include <stdio.h> | ||||
|  | ||||
| #include "grid.h" | ||||
| #include "particletracing.h" | ||||
|  | ||||
| typedef enum VtkFormat { ASCII = 0, BINARY } VtkFormat; | ||||
|  | ||||
| typedef struct VtkOptions { | ||||
|     VtkFormat fmt; | ||||
|     Grid grid; | ||||
|     FILE* fh; | ||||
|     ParticleTracer* particletracer; | ||||
| } VtkOptions; | ||||
|  | ||||
| typedef struct VtkVector { | ||||
|     double *u, *v, *w; | ||||
| } VtkVector; | ||||
|  | ||||
| extern void vtkOpen(VtkOptions* opts, char* filename); | ||||
| extern void vtkVector(VtkOptions* opts, char* name, VtkVector vec); | ||||
| extern void vtkScalar(VtkOptions* opts, char* name, double* p); | ||||
| extern void vtkClose(VtkOptions* opts); | ||||
|  | ||||
| extern void vtkOpenPT(VtkOptions* opts, char* filename, int ts); | ||||
| extern void vtkParticle(VtkOptions* opts, char* name); | ||||
| #endif // __VTKWRITER_H_ | ||||
		Reference in New Issue
	
	Block a user