forked from moebiusband/NuSiF-Solver
		
	EnhancedSolver port complete
This commit is contained in:
		@@ -38,9 +38,22 @@ $(BUILD_DIR)/%.s:  %.c
 | 
			
		||||
	$(info ===>  GENERATE ASM  $@)
 | 
			
		||||
	$(CC) -S $(CPPFLAGS) $(CFLAGS) $< -o $@
 | 
			
		||||
 | 
			
		||||
.PHONY: clean distclean tags info asm format
 | 
			
		||||
.PHONY: clean distclean vis vis_clean tags info asm format
 | 
			
		||||
 | 
			
		||||
clean:
 | 
			
		||||
vis:
 | 
			
		||||
	$(info ===>  GENERATE VISUALIZATION)
 | 
			
		||||
	@gnuplot -e "filename='pressure.dat'" ./surface.plot
 | 
			
		||||
	@gnuplot -e "filename='velocity.dat'" ./vector.plot
 | 
			
		||||
	@gnuplot -e "filename='residual.dat'" ./residual.plot
 | 
			
		||||
 | 
			
		||||
vis_clean:
 | 
			
		||||
	$(info ===>  CLEAN VISUALIZATION)
 | 
			
		||||
	@rm -f *.dat
 | 
			
		||||
	@rm -f *.png
 | 
			
		||||
	@rm -f ./vis_files/*.dat
 | 
			
		||||
	@rm -f ./vis_files/*.gif
 | 
			
		||||
 | 
			
		||||
clean: vis_clean
 | 
			
		||||
	$(info ===>  CLEAN)
 | 
			
		||||
	@rm -rf $(BUILD_DIR)
 | 
			
		||||
	@rm -f tags
 | 
			
		||||
 
 | 
			
		||||
@@ -36,6 +36,13 @@ te      100.0   # final time
 | 
			
		||||
dt      0.02    # time stepsize
 | 
			
		||||
tau     0.5     # safety factor for time stepsize control (<0 constant delt)
 | 
			
		||||
 | 
			
		||||
# Multigrid data:
 | 
			
		||||
# ---------
 | 
			
		||||
 | 
			
		||||
levels        3         # Multigrid levels
 | 
			
		||||
presmooth     5         # Pre-smoothning iterations
 | 
			
		||||
postsmooth    5         # Post-smoothning iterations
 | 
			
		||||
 | 
			
		||||
# Pressure Iteration Data:
 | 
			
		||||
# -----------------------
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,12 +1,12 @@
 | 
			
		||||
# Supported: GCC, CLANG, ICC
 | 
			
		||||
TAG ?= CLANG
 | 
			
		||||
TAG ?= ICC
 | 
			
		||||
ENABLE_OPENMP ?= false
 | 
			
		||||
# Supported: sor, rb, mg
 | 
			
		||||
SOLVER ?= rb
 | 
			
		||||
SOLVER ?= mg
 | 
			
		||||
# Run in debug settings
 | 
			
		||||
DEBUG ?= false
 | 
			
		||||
 | 
			
		||||
#Feature options
 | 
			
		||||
OPTIONS +=  -DARRAY_ALIGNMENT=64
 | 
			
		||||
#OPTIONS +=  -DVERBOSE
 | 
			
		||||
OPTIONS +=  -DVERBOSE
 | 
			
		||||
#OPTIONS +=  -DDEBUG
 | 
			
		||||
 
 | 
			
		||||
@@ -36,6 +36,13 @@ te      10.0		# final time
 | 
			
		||||
dt      0.02	    # time stepsize
 | 
			
		||||
tau     0.5	    	# safety factor for time stepsize control (<0 constant delt)
 | 
			
		||||
 | 
			
		||||
# Multigrid data:
 | 
			
		||||
# ---------
 | 
			
		||||
 | 
			
		||||
levels        2         # Multigrid levels
 | 
			
		||||
presmooth     20         # Pre-smoothning iterations
 | 
			
		||||
postsmooth    5         # Post-smoothning iterations
 | 
			
		||||
 | 
			
		||||
# Solver Data:
 | 
			
		||||
# -----------------------
 | 
			
		||||
 | 
			
		||||
@@ -44,5 +51,4 @@ eps      0.001		# stopping tolerance for pressure iteration
 | 
			
		||||
rho      0.5
 | 
			
		||||
omg      1.7		# relaxation parameter for SOR iteration
 | 
			
		||||
gamma    0.9		# upwind differencing factor gamma
 | 
			
		||||
levels   5         # Multigrid levels
 | 
			
		||||
#===============================================================================
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										9
									
								
								BasicSolver/2D-seq/residual.plot
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								BasicSolver/2D-seq/residual.plot
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
			
		||||
set terminal png size 1800,768 enhanced font ,12
 | 
			
		||||
set output 'residual.png'
 | 
			
		||||
set datafile separator whitespace
 | 
			
		||||
set xlabel "Timestep"
 | 
			
		||||
set ylabel "Residual"
 | 
			
		||||
 | 
			
		||||
set logscale y 2
 | 
			
		||||
 | 
			
		||||
plot 'residual.dat' using 1:2 title "Residual"
 | 
			
		||||
@@ -20,8 +20,10 @@ int main(int argc, char** argv)
 | 
			
		||||
    Parameter p;
 | 
			
		||||
    Discretization d;
 | 
			
		||||
    Solver s;
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
    initParameter(&p);
 | 
			
		||||
    FILE* fp;
 | 
			
		||||
    fp = initResidualWriter();
 | 
			
		||||
 | 
			
		||||
    if (argc != 2) {
 | 
			
		||||
        printf("Usage: %s <configFile>\n", argv[0]);
 | 
			
		||||
@@ -32,7 +34,7 @@ int main(int argc, char** argv)
 | 
			
		||||
    printParameter(&p);
 | 
			
		||||
    initDiscretization(&d, &p);
 | 
			
		||||
    initSolver(&s, &d, &p);
 | 
			
		||||
    
 | 
			
		||||
 | 
			
		||||
#ifndef VERBOSE
 | 
			
		||||
    initProgress(d.te);
 | 
			
		||||
#endif
 | 
			
		||||
@@ -41,8 +43,9 @@ int main(int argc, char** argv)
 | 
			
		||||
    double te  = d.te;
 | 
			
		||||
    double t   = 0.0;
 | 
			
		||||
    int nt     = 0;
 | 
			
		||||
    double res = 0.0;
 | 
			
		||||
 | 
			
		||||
    timeStart = getTimeStamp();
 | 
			
		||||
    timeStart  = getTimeStamp();
 | 
			
		||||
    while (t <= te) {
 | 
			
		||||
        if (tau > 0.0) computeTimestep(&d);
 | 
			
		||||
        setBoundaryConditions(&d);
 | 
			
		||||
@@ -50,17 +53,21 @@ 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
 | 
			
		||||
    }
 | 
			
		||||
    fclose(fp);
 | 
			
		||||
    timeStop = getTimeStamp();
 | 
			
		||||
    stopProgress();
 | 
			
		||||
    printf("Solution took %.2fs\n", timeStop - timeStart);
 | 
			
		||||
 
 | 
			
		||||
@@ -24,6 +24,8 @@ void initParameter(Parameter* param)
 | 
			
		||||
    param->gamma   = 0.9;
 | 
			
		||||
    param->tau     = 0.5;
 | 
			
		||||
    param->levels  = 5;
 | 
			
		||||
    param->presmooth = 5;
 | 
			
		||||
    param->postsmooth = 5;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void readParameter(Parameter* param, const char* filename)
 | 
			
		||||
@@ -79,6 +81,8 @@ void readParameter(Parameter* param, const char* filename)
 | 
			
		||||
            PARSE_REAL(u_init);
 | 
			
		||||
            PARSE_REAL(v_init);
 | 
			
		||||
            PARSE_REAL(p_init);
 | 
			
		||||
            PARSE_INT(presmooth);
 | 
			
		||||
            PARSE_INT(postsmooth);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -18,6 +18,7 @@ typedef struct {
 | 
			
		||||
    char* name;
 | 
			
		||||
    int bcLeft, bcRight, bcBottom, bcTop;
 | 
			
		||||
    double u_init, v_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,7 @@
 | 
			
		||||
extern void initProgress(double);
 | 
			
		||||
extern void printProgress(double);
 | 
			
		||||
extern void stopProgress(void);
 | 
			
		||||
extern FILE* initResidualWriter(void);
 | 
			
		||||
extern void writeResidual(FILE*, double, double);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
 
 | 
			
		||||
@@ -84,6 +84,37 @@ static double smooth(Solver* s, double* p, double* rhs, int level, int imax, int
 | 
			
		||||
 | 
			
		||||
    jsw = 1;
 | 
			
		||||
 | 
			
		||||
    for (pass = 0; pass < 2; pass++) {
 | 
			
		||||
        isw = jsw;
 | 
			
		||||
 | 
			
		||||
        for (int j = 1; j < jmax + 1; j++) {
 | 
			
		||||
            for (int i = isw; i < imax + 1; i += 2) {
 | 
			
		||||
 | 
			
		||||
                P(i, j) -= factor * (RHS(i, j) -
 | 
			
		||||
                          ((P(i + 1, j) - 2.0 * P(i, j) + P(i - 1, j)) * idx2 +
 | 
			
		||||
                              (P(i, j + 1) - 2.0 * P(i, j) + P(i, j - 1)) * idy2));
 | 
			
		||||
 | 
			
		||||
            }
 | 
			
		||||
            isw = 3 - isw;
 | 
			
		||||
        }
 | 
			
		||||
        jsw = 3 - jsw;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static double calculateResidual(Solver* s, double* p, double* rhs, int level, int imax, int jmax)
 | 
			
		||||
{
 | 
			
		||||
    double dx2    = s->grid->dx * s->grid->dx;
 | 
			
		||||
    double dy2    = s->grid->dy * s->grid->dy;
 | 
			
		||||
    double idx2   = 1.0 / dx2;
 | 
			
		||||
    double idy2   = 1.0 / dy2;
 | 
			
		||||
    double factor = s->omega * 0.5 * (dx2 * dy2) / (dx2 + dy2);
 | 
			
		||||
    double* r     = s->r[level];
 | 
			
		||||
    double res    = 1.0;
 | 
			
		||||
    int pass, jsw, isw;
 | 
			
		||||
 | 
			
		||||
    jsw = 1;
 | 
			
		||||
 | 
			
		||||
    for (pass = 0; pass < 2; pass++) {
 | 
			
		||||
        isw = jsw;
 | 
			
		||||
 | 
			
		||||
@@ -94,7 +125,6 @@ static double smooth(Solver* s, double* p, double* rhs, int level, int imax, int
 | 
			
		||||
                          ((P(i + 1, j) - 2.0 * P(i, j) + P(i - 1, j)) * idx2 +
 | 
			
		||||
                              (P(i, j + 1) - 2.0 * P(i, j) + P(i, j - 1)) * idy2);
 | 
			
		||||
 | 
			
		||||
                P(i, j) -= (factor * R(i, j));
 | 
			
		||||
                res += (R(i, j) * R(i, j));
 | 
			
		||||
            }
 | 
			
		||||
            isw = 3 - isw;
 | 
			
		||||
@@ -110,7 +140,7 @@ static double multiGrid(Solver* s, double* p, double* rhs, int level, int imax,
 | 
			
		||||
{
 | 
			
		||||
    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);
 | 
			
		||||
@@ -118,17 +148,18 @@ static double multiGrid(Solver* s, double* p, double* rhs, int level, int imax,
 | 
			
		||||
        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);
 | 
			
		||||
        if (level == FINEST_LEVEL) setBoundaryCondition(p, imax, jmax);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    res = calculateResidual(s, p, rhs, level, imax, jmax);
 | 
			
		||||
 | 
			
		||||
    // restrict
 | 
			
		||||
    restrictMG(s, level, imax, jmax);
 | 
			
		||||
 | 
			
		||||
    // MGSolver on residual and error.
 | 
			
		||||
    // TODO: What if there is a rest?
 | 
			
		||||
    multiGrid(s, s->e[level + 1], s->r[level + 1], level + 1, imax / 2, jmax / 2);
 | 
			
		||||
 | 
			
		||||
    // prolongate
 | 
			
		||||
@@ -139,8 +170,8 @@ static double multiGrid(Solver* s, double* p, double* rhs, int level, int imax,
 | 
			
		||||
    if (level == FINEST_LEVEL) setBoundaryCondition(p, imax, jmax);
 | 
			
		||||
 | 
			
		||||
    // post-smoothing
 | 
			
		||||
    for (int i = 0; i < 5; i++) {
 | 
			
		||||
        res = smooth(s, p, rhs, level, imax, jmax);
 | 
			
		||||
    for (int i = 0; i < s->postsmooth; i++) {
 | 
			
		||||
        smooth(s, p, rhs, level, imax, jmax);
 | 
			
		||||
        if (level == FINEST_LEVEL) setBoundaryCondition(p, imax, jmax);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -154,6 +185,8 @@ void initSolver(Solver* s, Discretization* d, Parameter* p)
 | 
			
		||||
    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;
 | 
			
		||||
@@ -176,11 +209,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);
 | 
			
		||||
 | 
			
		||||
#ifdef VERBOSE
 | 
			
		||||
    printf("Residuum: %.6f\n", res);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
return res;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -15,7 +15,7 @@ void initSolver(Solver* s, Discretization* d, Parameter* p)
 | 
			
		||||
    s->omega   = p->omg;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void solve(Solver* solver, double* p, double* rhs)
 | 
			
		||||
double solve(Solver* solver, double* p, double* rhs)
 | 
			
		||||
{
 | 
			
		||||
    int imax      = solver->grid->imax;
 | 
			
		||||
    int jmax      = solver->grid->jmax;
 | 
			
		||||
@@ -73,4 +73,6 @@ void solve(Solver* solver, double* p, double* rhs)
 | 
			
		||||
#ifdef VERBOSE
 | 
			
		||||
    printf("Solver took %d iterations to reach %f\n", it, sqrt(res));
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    return res;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -15,7 +15,7 @@ void initSolver(Solver* s, Discretization* d, Parameter* p)
 | 
			
		||||
    s->omega   = p->omg;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void solve(Solver* solver, double* p, double* rhs)
 | 
			
		||||
double solve(Solver* solver, double* p, double* rhs)
 | 
			
		||||
{
 | 
			
		||||
    int imax      = solver->grid->imax;
 | 
			
		||||
    int jmax      = solver->grid->jmax;
 | 
			
		||||
@@ -65,4 +65,6 @@ void solve(Solver* solver, double* p, double* rhs)
 | 
			
		||||
#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
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user