UCFD_SPARSE  v1.1
Documentation
Loading...
Searching...
No Matches
coloredblusgs.c
Go to the documentation of this file.
1
25#include "coloredblusgs.h"
26#include "flux.h"
27#include "inverse.h"
28#include <stdio.h>
29#include <omp.h>
30
31#define nsmatdim NFVARS*NFVARS
32#define ransmatdim NTURBVARS*NTURBVARS
33
41 UCFD_FLOAT *fnorm_vol, UCFD_FLOAT *dt, UCFD_FLOAT *diag, UCFD_FLOAT *fjmat)
42{
43 UCFD_INT idx, jdx, kdx, row, col;
44 UCFD_FLOAT fv, dti;
45 UCFD_FLOAT dmat[NFVARS][NFVARS];
46
47 #pragma omp parallel for private(jdx, kdx, row, col, fv, dmat, dti)
48 for (idx=0; idx<neles; idx++) {
49 // Initialize diagonal matrix
50 for (row=0; row<NFVARS; row++) {
51 for (col=0; col<NFVARS; col++)
52 dmat[row][col] = 0.0;
53 }
54
55 // Computes diagonal matrix based on neighbor cells
56 for (jdx=0; jdx<nface; jdx++) {
57 fv = fnorm_vol[neles*jdx + idx];
58 for (row=0; row<NFVARS; row++) {
59 for (col=0; col<NFVARS; col++) {
60 dmat[row][col] \
61 += fjmat[idx+neles*jdx+nface*neles*col+NFVARS*nface*neles*row]*fv;
62 }
63 }
64 }
65
66 // Complete implicit operator
67 dti = 1.0/(dt[idx]*factor);
68 for (kdx=0; kdx<NFVARS; kdx++) {
69 dmat[kdx][kdx] += dti;
70 }
71
72 // LU decomposition for inverse process
73 ludcmp(NFVARS, dmat);
74
75 // Allocate temporal matrix to diag array
76 for (row=0; row<NFVARS; row++) {
77 for (col=0; col<NFVARS; col++) {
78 diag[idx+neles*col+neles*NFVARS*row] = dmat[row][col];
79 }
80 }
81 }
82}
83
84
92 UCFD_FLOAT *fnorm_vol, UCFD_FLOAT *uptsb, UCFD_FLOAT *dt,
93 UCFD_FLOAT *tdiag, UCFD_FLOAT *tjmat, UCFD_FLOAT *dsrc)
94{
95 UCFD_INT idx, jdx, kdx, row, col;
96 UCFD_FLOAT fv;
97 UCFD_FLOAT tmat[NTURBVARS][NTURBVARS];
98 UCFD_FLOAT uf[NVARS], dsrcf[NVARS];
99
100 #pragma omp parallel for private(jdx, kdx, row, col, fv, tmat, uf, dsrcf)
101 for (idx=0; idx<neles; idx++) {
102 // Initialize diagonal matrix
103 for (row=0; row<NTURBVARS; row++) {
104 for (col=0; col<NTURBVARS; col++)
105 tmat[row][col] = 0.0;
106 }
107
108 for (kdx=0; kdx<NVARS; kdx++) {
109 uf[kdx] = uptsb[idx+neles*kdx];
110 dsrcf[kdx] = dsrc[idx+neles*kdx];
111 }
112
113 // Computes diagonal matrix based on neighbor cells
114 for (jdx=0; jdx<nface; jdx++) {
115 fv = fnorm_vol[neles*jdx + idx];
116 for (row=0; row<NTURBVARS; row++) {
117 for (col=0; col<NTURBVARS; col++) {
118 tmat[row][col] \
119 += tjmat[idx+neles*jdx+nface*neles*col+NTURBVARS*nface*neles*row]*fv;
120 }
121 }
122 }
123
124 // Computes Source term Jacobian
125 if (rans_source_jacobian(uf, tmat, dsrcf) == UCFD_STATUS_NOT_SUPPORTED)
126 printf("Error::Invalid `NTURBVARS` value\n");
127
128 // Complete implicit operator
129 for (kdx=0; kdx<NTURBVARS; kdx++) {
130 tmat[kdx][kdx] += 1.0/(dt[idx]*factor);
131 }
132
133 // LU decomposition for inverse process
134 ludcmp(NTURBVARS, tmat);
135
136 // Allocate temporal matrix to diag array
137 for (row=0; row<NTURBVARS; row++) {
138 for (col=0; col<NTURBVARS; col++) {
139 tdiag[idx+neles*col+neles*NTURBVARS*row] = tmat[row][col];
140 }
141 }
142 }
143}
144
145
156 UCFD_INT *nei_ele, UCFD_INT *icolor, UCFD_INT *lcolor, UCFD_FLOAT *fnorm_vol,
157 UCFD_FLOAT *rhsb, UCFD_FLOAT *dub, UCFD_FLOAT *diag, UCFD_FLOAT *fjmat)
158{
159 UCFD_INT _idx, idx, jdx, kdx, neib, curr_level;
160 UCFD_INT row, col;
161 UCFD_FLOAT val, fv;
162 UCFD_FLOAT rhs[NFVARS], dmat[NFVARS][NFVARS];
163
164 // Lower/Upper sweep via coloring
165 #pragma omp parallel for private(idx, jdx, kdx, neib, curr_level, row, col, rhs, dmat, val, fv)
166 for (_idx=n0; _idx<ne; _idx++) {
167 idx = icolor[_idx];
168 curr_level = lcolor[idx];
169
170 // Initialize
171 for (kdx=0; kdx<NFVARS; kdx++) {
172 rhs[kdx] = rhsb[idx+kdx*neles];
173 }
174
175 for (row=0; row<NFVARS; row++) {
176 for (col=0; col<NFVARS; col++) {
177 dmat[row][col] = diag[idx+neles*col+NFVARS*neles*row];
178 }
179 }
180
181 for (jdx=0; jdx<nface; jdx++) {
182 neib = nei_ele[idx+neles*jdx];
183
184 if (lcolor[neib] != curr_level) {
185 fv = fnorm_vol[idx+neles*jdx];
186
187 for (row=0; row<NFVARS; row++) {
188 val = 0.0;
189 for (col=0; col<NFVARS; col++) {
190 val += fjmat[idx+neles*jdx+nface*neles*col+NFVARS*nface*neles*row] \
191 * dub[neib+neles*col];
192 }
193 rhs[row] -= val*fv;
194 }
195 }
196 }
197
198 lusub(NFVARS, dmat, rhs);
199
200 for (kdx=0; kdx<NFVARS; kdx++) {
201 dub[idx+neles*kdx] = rhs[kdx];
202 }
203 }
204}
205
206
216 UCFD_INT *nei_ele, UCFD_INT *icolor, UCFD_INT *lcolor, UCFD_FLOAT *fnorm_vol,
217 UCFD_FLOAT *rhsb, UCFD_FLOAT *dub, UCFD_FLOAT *tdiag, UCFD_FLOAT *tjmat)
218{
219 UCFD_INT _idx, idx, jdx, kdx, neib, curr_level;
220 UCFD_INT row, col;
221 UCFD_FLOAT val, fv;
222 UCFD_FLOAT rhs[NTURBVARS], tmat[NTURBVARS][NTURBVARS];
223
224 // Lower/Upper sweep via coloring
225 #pragma omp parallel for private(idx, jdx, kdx, neib, curr_level, row, col, rhs, tmat, val, fv)
226 for (_idx=n0; _idx<ne; _idx++) {
227 idx = icolor[_idx];
228 curr_level = lcolor[idx];
229
230 //Initialize
231 for (kdx=0; kdx<NTURBVARS; kdx++) {
232 rhs[kdx] = rhsb[idx+(kdx+NFVARS)*neles];
233 }
234
235 for (row=0; row<NTURBVARS; row++) {
236 for (col=0; col<NTURBVARS; col++) {
237 tmat[row][col] = tdiag[idx+neles*col+neles*NTURBVARS*row];
238 }
239 }
240
241 for (jdx=0; jdx<nface; jdx++) {
242 neib = nei_ele[idx+neles*jdx];
243
244 if (lcolor[neib] != curr_level) {
245 fv = fnorm_vol[idx+neles*jdx];
246
247 for (row=0; row<NTURBVARS; row++) {
248 val = 0.0;
249 for (col=0; col<NTURBVARS; col++) {
250 val += tjmat[idx+neles*jdx+nface*neles*col+NTURBVARS*nface*neles*row] \
251 * dub[neib+neles*(col+NFVARS)];
252 }
253 rhs[row] -= val*fv;
254 }
255 }
256 }
257
258 // Compute inverse of diagonal matrix multiplication
259 lusub(NTURBVARS, tmat, rhs);
260
261 // Update dub array
262 for (kdx=0; kdx<NTURBVARS; kdx++) {
263 dub[idx+neles*(kdx+NFVARS)] = rhs[kdx];
264 }
265 }
266}
267
268
273{
274 UCFD_INT idx, kdx;
275
276 #pragma omp parallel for private(kdx)
277 for (idx=0; idx<neles; idx++) {
278 for (kdx=0; kdx<NFVARS; kdx++) {
279 uptsb[idx+neles*kdx] += dub[idx+neles*kdx];
280
281 // Initialize dub array
282 dub[idx+neles*kdx] = 0.0;
283 }
284 // Initialize sub-residual array
285 subres[idx] = 0.0;
286 }
287}
288
289
294{
295 UCFD_INT idx, kdx;
296
297 #pragma omp parallel for private(kdx)
298 for (idx=0; idx<neles; idx++) {
299 for (kdx=0; kdx<NVARS; kdx++) {
300 uptsb[idx+neles*kdx] += dub[idx+neles*kdx];
301
302 // Initialize dub array
303 dub[idx+neles*kdx] = 0.0;
304 }
305 // Initialize sub-residual array
306 subres[idx] = 0.0;
307 }
308}
void ns_parallel_block_sweep(UCFD_INT n0, UCFD_INT ne, UCFD_INT neles, UCFD_INT nface, UCFD_INT *nei_ele, UCFD_INT *icolor, UCFD_INT *lcolor, UCFD_FLOAT *fnorm_vol, UCFD_FLOAT *rhsb, UCFD_FLOAT *dub, UCFD_FLOAT *diag, UCFD_FLOAT *fjmat)
void ns_parallel_pre_blusgs(UCFD_INT neles, UCFD_INT nface, UCFD_FLOAT factor, UCFD_FLOAT *fnorm_vol, UCFD_FLOAT *dt, UCFD_FLOAT *diag, UCFD_FLOAT *fjmat)
Definition: coloredblusgs.c:40
void blusgs_parallel_ns_update(UCFD_INT neles, UCFD_FLOAT *uptsb, UCFD_FLOAT *dub, UCFD_FLOAT *subres)
void rans_parallel_pre_blusgs(UCFD_INT neles, UCFD_INT nface, UCFD_FLOAT factor, UCFD_FLOAT *fnorm_vol, UCFD_FLOAT *uptsb, UCFD_FLOAT *dt, UCFD_FLOAT *tdiag, UCFD_FLOAT *tjmat, UCFD_FLOAT *dsrc)
Definition: coloredblusgs.c:91
void blusgs_parallel_update(UCFD_INT neles, UCFD_FLOAT *uptsb, UCFD_FLOAT *dub, UCFD_FLOAT *subres)
void rans_parallel_block_sweep(UCFD_INT n0, UCFD_INT ne, UCFD_INT neles, UCFD_INT nface, UCFD_INT *nei_ele, UCFD_INT *icolor, UCFD_INT *lcolor, UCFD_FLOAT *fnorm_vol, UCFD_FLOAT *rhsb, UCFD_FLOAT *dub, UCFD_FLOAT *tdiag, UCFD_FLOAT *tjmat)
Header file for colored Block LU-SGS method.
int32_t UCFD_INT
Definition: config.h:20
double UCFD_FLOAT
Definition: config.h:29
ucfd_status_t rans_source_jacobian(UCFD_FLOAT *uf, UCFD_FLOAT tmat[NTURBVARS][NTURBVARS], UCFD_FLOAT *dsrc)
Computes source term Jacobian matrix for RANS equations.
Definition: flux.c:93
Header file for numerical flux funtions.
void lusub(UCFD_FLOAT *LU, UCFD_FLOAT *b)
Forward/Backward substitution function.
Definition: inverse.c:75
void ludcmp(UCFD_FLOAT *A)
LU Decomposition function.
Definition: inverse.c:37
@ UCFD_STATUS_NOT_SUPPORTED
Definition: ucfd_types.h:18