UCFD_SPARSE  v1.1
Documentation
Loading...
Searching...
No Matches
lusgs.c
Go to the documentation of this file.
1
32#include "lusgs.h"
33#include "flux.h"
34
43void serial_pre_lusgs(UCFD_INT neles, UCFD_INT nface, UCFD_FLOAT factor, \
44 UCFD_FLOAT *fnorm_vol, UCFD_FLOAT *dt, UCFD_FLOAT *diag, UCFD_FLOAT *fspr)
45{
46 UCFD_INT idx; // Element index
47 UCFD_INT jdx; // Face index
48 UCFD_FLOAT lamf; // Spectral radius at each face
49
50 for (idx=0; idx<neles; idx++) {
51 // Diagonals of implicit operator
52 diag[idx] = 1.0/(dt[idx]*factor);
53
54 for (jdx=0; jdx<nface; jdx++) {
55 // Apply diffusive margin of wave speed at face
56 lamf = fspr[neles*jdx + idx]*1.01;
57
58 // Save spectral radius
59 fspr[neles*jdx + idx] = lamf;
60
61 // Add portion of lower and upper spectral radius
62 diag[idx] += 0.5*lamf*fnorm_vol[neles*jdx + idx];
63 }
64 }
65}
66
67
74void ns_serial_lower_sweep(UCFD_INT neles, UCFD_INT nface, UCFD_INT *nei_ele, UCFD_FLOAT *fnorm_vol, UCFD_FLOAT *vec_fnorm,
75 UCFD_FLOAT *uptsb, UCFD_FLOAT *rhsb, UCFD_FLOAT *dub, UCFD_FLOAT *diag, UCFD_FLOAT *fspr)
76{
77 UCFD_INT idx, neib, jdx, kdx;
78 UCFD_FLOAT du[NFVARS], dfj[NFVARS], df[NFVARS], nf[NDIMS];
79 UCFD_FLOAT u[NFVARS], f[NFVARS];
80
81 // Lower sweep via mapping
82 for (idx=0; idx<neles; idx++) {
83 // Initialize `df` array
84 for (kdx=0; kdx<NFVARS; kdx++) {
85 df[kdx] = 0.0;
86 }
87
88 // Set of faces surrounding a cell
89 for (jdx=0; jdx<nface; jdx++) {
90 // Get face normal vector
91 for (kdx=0; kdx<NDIMS; kdx++) {
92 nf[kdx] = vec_fnorm[NDIMS*neles*jdx + neles*kdx + idx];
93 }
94
95 // Neighbor element index meet at face
96 neib = nei_ele[neles*jdx + idx];
97
98 // Only for lower neighbor cell
99 if (neib < idx) {
100 for (kdx=0; kdx<NFVARS; kdx++) {
101 u[kdx] = uptsb[neles*kdx + neib];
102 du[kdx] = u[kdx] + dub[neles*kdx + neib];
103 }
104
105 ns_flux_container(u, nf, f);
106 ns_flux_container(du, nf, dfj);
107
108 for (kdx=0; kdx<NFVARS; kdx++) {
109 dfj[kdx] -= f[kdx];
110 }
111
112 for (kdx=0; kdx<NFVARS; kdx++) {
113 df[kdx] += (dfj[kdx] - fspr[neles*jdx + idx] \
114 * dub[neles*kdx + neib])*fnorm_vol[neles*jdx + idx];
115 }
116 }
117 }
118 // Update dub array
119 for (kdx=0; kdx<NFVARS; kdx++)
120 dub[neles*kdx + idx] = (rhsb[neles*kdx + idx] - 0.5*df[kdx])/diag[idx];
121 }
122}
123
129void rans_serial_lower_sweep(UCFD_INT neles, UCFD_INT nface, UCFD_INT *nei_ele, UCFD_FLOAT *fnorm_vol, UCFD_FLOAT *vec_fnorm,
130 UCFD_FLOAT *uptsb, UCFD_FLOAT *rhsb, UCFD_FLOAT *dub, UCFD_FLOAT *diag, UCFD_FLOAT *fspr, UCFD_FLOAT *dsrc)
131{
132 UCFD_INT idx, neib, jdx, kdx;
133 UCFD_FLOAT du[NVARS], dfj[NTURBVARS], df[NTURBVARS], nf[NDIMS];
134 UCFD_FLOAT u[NVARS], f[NTURBVARS];
135
136 // Lower sweep via mapping
137 for (idx=0; idx<neles; idx++) {
138 // Initialize `df` array
139 for (kdx=0; kdx<NTURBVARS; kdx++) {
140 df[kdx] = 0.0;
141 }
142
143 // Set of faces surrounding a cell
144 for (jdx=0; jdx<nface; jdx++) {
145 // Get face normal vector
146 for (kdx=0; kdx<NDIMS; kdx++) {
147 nf[kdx] = vec_fnorm[NDIMS*neles*jdx + neles*kdx + idx];
148 }
149
150 // Neighbor element index meet at face
151 neib = nei_ele[neles*jdx + idx];
152
153 // Only for lower neighbor cell
154 if (neib < idx) {
155 for (kdx=0; kdx<NVARS; kdx++) {
156 u[kdx] = uptsb[neles*kdx + neib];
157 du[kdx] = u[kdx];
158 }
159
160 for (kdx=NFVARS; kdx<NVARS; kdx++) {
161 du[kdx] += dub[neles*kdx + neib];
162 }
163
164 rans_flux_container(u, nf, f);
165 rans_flux_container(du, nf, dfj);
166
167 for (kdx=0; kdx<NTURBVARS; kdx++) {
168 dfj[kdx] -= f[kdx];
169 }
170
171 for (kdx=0; kdx<NTURBVARS; kdx++) {
172 df[kdx] += (dfj[kdx] - fspr[neles*jdx + idx] \
173 * dub[neles*(kdx+NFVARS) + neib]) * fnorm_vol[neles*jdx + idx];
174 }
175 }
176 }
177 // Update dub array
178 for (kdx=0; kdx<NTURBVARS; kdx++) {
179 dub[neles*(kdx+NFVARS) + idx] = (rhsb[neles*(kdx+NFVARS)+idx] - \
180 0.5*df[kdx])/(diag[idx]+dsrc[neles*(kdx+NFVARS)+idx]);
181 }
182 }
183}
184
185
193void ns_serial_upper_sweep(UCFD_INT neles, UCFD_INT nface, UCFD_INT *nei_ele, UCFD_FLOAT *fnorm_vol, UCFD_FLOAT *vec_fnorm,
194 UCFD_FLOAT *uptsb, UCFD_FLOAT *rhsb, UCFD_FLOAT *dub, UCFD_FLOAT *diag, UCFD_FLOAT *fspr)
195{
196 UCFD_INT idx, neib, jdx, kdx;
197 UCFD_FLOAT du[NFVARS], dfj[NFVARS], df[NFVARS], nf[NDIMS];
198 UCFD_FLOAT u[NFVARS], f[NFVARS];
199
200 // Upper sweep via mapping
201 for (idx=neles-1; idx>-1; idx--) {
202 // Initialize `df` array
203 for (kdx=0; kdx<NFVARS; kdx++) {
204 df[kdx] = 0.0;
205 }
206
207 // Set of faces surrounding a cell
208 for (jdx=0; jdx<nface; jdx++) {
209 // Get face normal vector
210 for (kdx=0; kdx<NDIMS; kdx++) {
211 nf[kdx] = vec_fnorm[NDIMS*neles*jdx + neles*kdx + idx];
212 }
213
214 // Neighbor element index meet at face
215 neib = nei_ele[neles*jdx + idx];
216
217 // Only for upper neighbor cell
218 if (neib > idx) {
219 for (kdx=0; kdx<NFVARS; kdx++) {
220 u[kdx] = uptsb[neles*kdx + neib];
221 du[kdx] = u[kdx] + rhsb[neles*kdx + neib];
222 }
223
224 ns_flux_container(u, nf, f);
225 ns_flux_container(du, nf, dfj);
226
227 for (kdx=0; kdx<NFVARS; kdx++) {
228 dfj[kdx] -= f[kdx];
229 }
230
231 for (kdx=0; kdx<NFVARS; kdx++) {
232 df[kdx] += (dfj[kdx] - fspr[neles*jdx + idx] \
233 * rhsb[neles*kdx + neib])*fnorm_vol[neles*jdx + idx];
234 }
235 }
236 }
237 // Update rhsb array
238 for (kdx=0; kdx<NFVARS; kdx++) {
239 rhsb[neles*kdx + idx] = dub[neles*kdx + idx] - 0.5*df[kdx]/diag[idx];
240 }
241 }
242}
243
244
251void rans_serial_upper_sweep(UCFD_INT neles, UCFD_INT nface, UCFD_INT *nei_ele, UCFD_FLOAT *fnorm_vol, UCFD_FLOAT *vec_fnorm,
252 UCFD_FLOAT *uptsb, UCFD_FLOAT *rhsb, UCFD_FLOAT *dub, UCFD_FLOAT *diag, UCFD_FLOAT *fspr, UCFD_FLOAT *dsrc)
253{
254 UCFD_INT idx, neib, jdx, kdx;
255 UCFD_FLOAT du[NVARS], dfj[NTURBVARS], df[NTURBVARS], nf[NDIMS];
256 UCFD_FLOAT u[NVARS], f[NTURBVARS];
257
258 // Upper sweep via mapping
259 for (idx=neles-1; idx>-1; idx--) {
260 // Initialize `df` array
261 for (kdx=0; kdx<NTURBVARS; kdx++) {
262 df[kdx] = 0.0;
263 }
264
265 // Set of faces surrounding a cell
266 for (jdx=0; jdx<nface; jdx++) {
267 // Get face normal vector
268 for (kdx=0; kdx<NDIMS; kdx++) {
269 nf[kdx] = vec_fnorm[NDIMS*neles*jdx + neles*kdx + idx];
270 }
271
272 // Neighbor element index meet at face
273 neib = nei_ele[neles*jdx + idx];
274
275 // Only for upper neighbor cell
276 if (neib > idx) {
277 for (kdx=0; kdx<NVARS; kdx++) {
278 u[kdx] = uptsb[neles*kdx + neib];
279 du[kdx] = u[kdx];
280 }
281
282 for (kdx=NFVARS; kdx<NVARS; kdx++) {
283 du[kdx] += rhsb[neles*kdx + neib];
284 }
285
286 rans_flux_container(u, nf, f);
287 rans_flux_container(du, nf, dfj);
288
289 for (kdx=0; kdx<NTURBVARS; kdx++) {
290 dfj[kdx] -= f[kdx];
291 }
292
293 for (kdx=0; kdx<NTURBVARS; kdx++) {
294 df[kdx] += (dfj[kdx] - fspr[neles*jdx+idx] \
295 * rhsb[neles*(kdx+NFVARS)+neib])*fnorm_vol[neles*jdx+idx];
296 }
297 }
298 }
299 // Update rhsb array
300 for (kdx=0; kdx<NTURBVARS; kdx++) {
301 rhsb[neles*(kdx+NFVARS)+idx] = dub[neles*(kdx+NFVARS)+idx] - \
302 0.5*df[kdx]/(diag[idx] + dsrc[neles*(kdx+NFVARS)+idx]);
303 }
304 }
305}
306
314{
315 UCFD_INT idx, kdx;
316
317 // Iterate for all cell
318 for (idx=0; idx<neles; idx++) {
319 // Update conservative variables
320 for (kdx=0; kdx<NFVARS; kdx++) {
321 // Indexing 2D array as 1D
322 uptsb[neles*kdx + idx] += rhsb[neles*kdx + idx];
323 }
324 }
325}
326
334{
335 UCFD_INT idx, kdx;
336
337 // Iterate for all cell
338 for (idx=0; idx<neles; idx++) {
339 // Update conservative variables
340 for (kdx=0; kdx<NVARS; kdx++) {
341 // Indexing 2D array as 1D
342 uptsb[neles*kdx + idx] += rhsb[neles*kdx + idx];
343 }
344 }
345}
int32_t UCFD_INT
Definition: config.h:20
double UCFD_FLOAT
Definition: config.h:29
void ns_flux_container(UCFD_FLOAT *u, UCFD_FLOAT *nf, UCFD_FLOAT *f)
Computes flux for Navier-Stokes equations.
Definition: flux.c:29
void rans_flux_container(UCFD_FLOAT *u, UCFD_FLOAT *nf, UCFD_FLOAT *f)
Computes flux for RANS equations.
Definition: flux.c:77
Header file for numerical flux funtions.
void lusgs_serial_update(UCFD_INT neles, UCFD_FLOAT *uptsb, UCFD_FLOAT *rhsb)
Updates solution array.
Definition: lusgs.c:333
void serial_pre_lusgs(UCFD_INT neles, UCFD_INT nface, UCFD_FLOAT factor, UCFD_FLOAT *fnorm_vol, UCFD_FLOAT *dt, UCFD_FLOAT *diag, UCFD_FLOAT *fspr)
Computes Diagonal matrix for LU-SGS method.
Definition: lusgs.c:43
void ns_serial_upper_sweep(UCFD_INT neles, UCFD_INT nface, UCFD_INT *nei_ele, UCFD_FLOAT *fnorm_vol, UCFD_FLOAT *vec_fnorm, UCFD_FLOAT *uptsb, UCFD_FLOAT *rhsb, UCFD_FLOAT *dub, UCFD_FLOAT *diag, UCFD_FLOAT *fspr)
Upper sweep of LU-SGS method for Navier-Stokes equations.
Definition: lusgs.c:193
void lusgs_serial_ns_update(UCFD_INT neles, UCFD_FLOAT *uptsb, UCFD_FLOAT *rhsb)
Updates solution array.
Definition: lusgs.c:313
void rans_serial_lower_sweep(UCFD_INT neles, UCFD_INT nface, UCFD_INT *nei_ele, UCFD_FLOAT *fnorm_vol, UCFD_FLOAT *vec_fnorm, UCFD_FLOAT *uptsb, UCFD_FLOAT *rhsb, UCFD_FLOAT *dub, UCFD_FLOAT *diag, UCFD_FLOAT *fspr, UCFD_FLOAT *dsrc)
Lower sweep of LU-SGS method for RANS equations.
Definition: lusgs.c:129
void ns_serial_lower_sweep(UCFD_INT neles, UCFD_INT nface, UCFD_INT *nei_ele, UCFD_FLOAT *fnorm_vol, UCFD_FLOAT *vec_fnorm, UCFD_FLOAT *uptsb, UCFD_FLOAT *rhsb, UCFD_FLOAT *dub, UCFD_FLOAT *diag, UCFD_FLOAT *fspr)
Lower sweep of LU-SGS method for Navier-Stokes equations.
Definition: lusgs.c:74
void rans_serial_upper_sweep(UCFD_INT neles, UCFD_INT nface, UCFD_INT *nei_ele, UCFD_FLOAT *fnorm_vol, UCFD_FLOAT *vec_fnorm, UCFD_FLOAT *uptsb, UCFD_FLOAT *rhsb, UCFD_FLOAT *dub, UCFD_FLOAT *diag, UCFD_FLOAT *fspr, UCFD_FLOAT *dsrc)
Upper sweep of LU-SGS method for RANS equations.
Definition: lusgs.c:251
Header file for serial LU-SGS method.