MeshKit
1.0
|
00001 //****************************************************************************// 00002 // Acknowlegement: The original Code "Blend" from John Burkardt ( Under GNU 00003 // lincense) have been significantly modified. Anyhow full 00004 // credit is given to original developers. 00005 // 00006 // Document is also copied from the original code. 00007 // 00008 // Modification Date : 7th July 2009; 00009 // Modified By : Chaman Singh Verma 00010 // Argonne National Lab, Argonne, IL, USA. 00011 // Major Changes: 00012 // (1) Parameters range (-1,1) instead of (0,1). 00013 // (2) Probably better function names 00014 // (3) Better modularity and reuse 00015 // (4) Changed ordering (k,j,i) instead of (i,j,k) 00016 // (5) Guass point introduction. 00017 // (6) Probably much easier to understand than the original code. 00018 // (7) Probably better input parameter passing order. 00019 // (8) Error checking using assertions introduced. 00020 // Downside: 00021 // (1) May be little more expensive ( than the original code) because of 00022 // function calling overheads. 00023 // 00024 // (2) Redundant calculations to make code easier to understand. 00025 // 00027 00028 #include <assert.h> 00029 #include <fstream> 00030 #include <vector> 00031 #include <iostream> 00032 using namespace std; 00033 00034 namespace TFI { 00035 00036 double gauss_node(int i, int N) 00037 { 00038 double du = 2.0 / (double) (N - 1); 00039 return -1.0 + i*du; 00040 } 00041 00042 //****************************************************************************80 00043 00044 double linear_interpolation(double r, double x0, double x1) 00045 { 00046 00047 //************************************************************************80 00048 // 00049 // Purpose: extends scalar data at endpoints to a line. 00050 // 00051 // Diagram: 00052 // 00053 // 0-----r-----1 00054 // 00055 // Author: 00056 // 00057 // John Burkardt: Modified by Chaman Singh Verma 00058 // 00059 // Parameters: 00060 // 00061 // Input, double R, the coordinate where an interpolated value is desired. 00062 // 00063 // Input, double X0, X1, the data values at the ends of the line. 00064 // 00065 // Output, double *X, the interpolated data value at (R). 00066 // 00068 00069 assert(r >= -1.0 && r <= 1.0); 00070 00071 double val = (1.0 - r) * x0 + (1.0 + r) * x1; 00072 00073 val *= 0.5; 00074 00075 return val; 00076 } 00077 00078 //****************************************************************************80 00079 00080 double bilinear_interpolation(double r, double s, double *valCorners) 00081 { 00082 assert(r >= -1.0 && r <= 1.0); 00083 assert(s >= -1.0 && s <= 1.0); 00084 00085 double val = (1.0 - r) * (1.0 - s) * valCorners[0] + 00086 (1.0 + r) * (1.0 - s) * valCorners[1] + 00087 (1.0 + r) * (1.0 + s) * valCorners[2] + 00088 (1.0 - r) * (1.0 + s) * valCorners[3]; 00089 00090 val *= 0.25; 00091 return val; 00092 } 00093 00094 //****************************************************************************80 00095 00096 double bilinear_interpolation(double r, double s, 00097 double x00, double x10, double x11, double x01) 00098 { 00099 double valCorners[4]; 00100 00101 valCorners[0] = x00; 00102 valCorners[1] = x10; 00103 valCorners[2] = x11; 00104 valCorners[3] = x01; 00105 00106 double val = bilinear_interpolation(r, s, valCorners); 00107 00108 return val; 00109 } 00110 00111 //****************************************************************************80 00112 00113 double trilinear_interpolation(double r, double s, double t, double *valCorners) 00114 { 00115 assert(r >= -1.0 && r <= 1.0); 00116 assert(s >= -1.0 && s <= 1.0); 00117 assert(t >= -1.0 && t <= 1.0); 00118 00119 double val = (1.0 - r) * (1.0 - s) * (1.0 - t) * valCorners[0] + 00120 (1.0 + r) * (1.0 - s) * (1.0 - t) * valCorners[1] + 00121 (1.0 + r) * (1.0 + s) * (1.0 - t) * valCorners[2] + 00122 (1.0 - r) * (1.0 + s) * (1.0 - t) * valCorners[3] + 00123 (1.0 - r) * (1.0 - s) * (1.0 + t) * valCorners[4] + 00124 (1.0 + r) * (1.0 - s) * (1.0 + t) * valCorners[5] + 00125 (1.0 + r) * (1.0 + s) * (1.0 + t) * valCorners[6] + 00126 (1.0 - r) * (1.0 + s) * (1.0 + t) * valCorners[7]; 00127 00128 val *= 0.125; 00129 00130 return val; 00131 } 00132 00133 //****************************************************************************80 00134 00135 double trilinear_interpolation(double r, double s, double t, 00136 double x000, double x100, double x110, double x010, 00137 double x001, double x101, double x111, double x011) 00138 { 00139 double valCorners[8]; 00140 00141 valCorners[0] = x000; 00142 valCorners[1] = x100; 00143 valCorners[2] = x110; 00144 valCorners[3] = x010; 00145 00146 valCorners[4] = x001; 00147 valCorners[5] = x101; 00148 valCorners[6] = x111; 00149 valCorners[7] = x011; 00150 00151 double val = trilinear_interpolation(r, s, t, valCorners); 00152 00153 return val; 00154 } 00155 00156 //****************************************************************************80 00157 00158 double transfinite_blend(double r, double s, 00159 double x00, double x10, double x11, double x01, 00160 double xr0, double x1s, double xr1, double x0s) 00161 { 00162 00163 //****************************************************************************80 00164 // 00165 // Purpose: 00166 // 00167 // BLEND_1D1 extends scalar data along the boundary into a square. 00168 // 00169 // Diagram: 00170 // 00171 // 01-----r1-----11 00172 // | . | 00173 // | . | 00174 // 0s.....rs.....1s 00175 // | . | 00176 // | . | 00177 // 00-----r0-----10 00178 // 00179 // Formula: 00180 // 00181 // Written as a polynomial in R and S, the interpolation map has the form 00182 // 00183 // X(R,S) = 00184 // 1 * ( x0s + xr0 - x00 ) 00185 // + r * ( x00 + x1s - x0s - x10 ) 00186 // + s * ( x00 + xr0 - x01 - xr1 ) 00187 // + r * s * ( x01 + x10 - x00 - x11 ) 00188 // 00189 // The nonlinear term ( r * s ) has an important role: 00190 // 00191 // If ( x01 + x10 - x00 - x11 ) is zero, then the input data lies in a plane, 00192 // and the mapping is affine. All the interpolated data will lie 00193 // on the plane defined by the four corner values. In particular, 00194 // on any line through the square, data values at intermediate points 00195 // will lie between the values at the endpoints. 00196 // 00197 // If ( x01 + x10 - x00 - x11 ) is not zero, then the input data does 00198 // not lie in a plane, and the interpolation map is nonlinear. On 00199 // any line through the square, data values at intermediate points 00200 // may lie above or below the data values at the endpoints. The 00201 // size of the coefficient of r * s will determine how severe this 00202 // effect is. 00203 // 00204 // Author: 00205 // 00206 // John Burkardt: Modified by Chaman Singh Verma 00207 // 00208 // Reference: 00209 // 00210 // William Gordon, Charles A Hall, 00211 // Construction of Curvilinear Coordinate Systems and Application to 00212 // Mesh Generation, 00213 // International Journal of Numerical Methods in Engineering, 00214 // Volume 7, pages 461-477, 1973. 00215 // 00216 // Joe Thompson, Bharat Soni, Nigel Weatherill, 00217 // Handbook of Grid Generation, 00218 // CRC Press, 00219 // 1999. 00220 // 00221 // Parameters: 00222 // 00223 // Input, double R, S, the coordinates where an interpolated value is desired. 00224 // 00225 // Input, double X00, X01, X10, X11, the data values at the corners. 00226 // 00227 // Input, double XR0, XR1, X0S, X1S, the data values at points along the edges. 00228 // 00229 // Output, double *X, the interpolated data value at (R,S). 00230 // 00232 00233 double u = linear_interpolation(r, x0s, x1s); 00234 double v = linear_interpolation(s, xr0, xr1); 00235 double uv = bilinear_interpolation(r, s, x00, x10, x11, x01); 00236 00237 double val = u + v - uv; 00238 00239 return val; 00240 } 00241 //****************************************************************************80 00242 00243 double transfinite_blend(double r, double s, double t, 00244 double x000, double xr00, double x100, 00245 double x0s0, double xrs0, double x1s0, 00246 double x010, double xr10, double x110, 00247 double x00t, double xr0t, double x10t, 00248 double x0st, double x1st, 00249 double x01t, double xr1t, double x11t, 00250 double x001, double xr01, double x101, 00251 double x0s1, double xrs1, double x1s1, 00252 double x011, double xr11, double x111) 00253 { 00254 00255 //************************************************************************80 00256 // 00257 // Purpose: extends scalar data along the surface into a cube. 00258 // 00259 // Diagram: 00260 // 00261 // 010-----r10-----110 011-----r11-----111 00262 // | . | | . | 00263 // | . | | . | 00264 // 0s0.....rs0.....1s0 0s1.....rs1.....1s1 S 00265 // | . | | . | | 00266 // | . | | . | | 00267 // 000-----r00-----100 001-----r01-----101 +----R 00268 // BACK FRONT 00269 // 00270 // 001-----0s1-----011 101-----1s1-----111 00271 // | . | | . | 00272 // | . | | . | 00273 // 00t.....0st.....01t 10t.....1st.....11t T 00274 // | . | | . | | 00275 // | . | | . | | 00276 // 000-----0s0-----010 100-----1s0-----110 +----S 00277 // LEFT RIGHT 00278 00279 // 001-----r01-----101 011-----r11-----111 00280 // | . | | . | 00281 // | . | | . | 00282 // 00t.....r0t.....10t 01t.....r1t.....11t T 00283 // | . | | . | | 00284 // | . | | . | | 00285 // 000-----r0t-----100 010-----r10-----110 +----R 00286 // BOTTOM TOP 00287 // 00288 // Author: 00289 // 00290 // John Burkardt 00291 // 00292 // Reference: 00293 // 00294 // William Gordon, Charles A Hall, 00295 // Construction of Curvilinear Coordinate Systems and Application to 00296 // Mesh Generation, 00297 // International Journal of Numerical Methods in Engineering, 00298 // Volume 7, pages 461-477, 1973. 00299 // 00300 // Joe Thompson, Bharat Soni, Nigel Weatherill, 00301 // Handbook of Grid Generation, 00302 // CRC Press, 00303 // 1999. 00304 // 00305 // Parameters: 00306 // 00307 // Input, double R, S, T, the coordinates where an interpolated value is desired. 00308 // 00309 // Input, double X000, X001, X010, X011, X100, X101, X110, X111, the data 00310 // values at the corners. 00311 // 00312 // Input, double XR00, XR01, XR10, XR11, X0S0, X0S1, X1S0, X1S1, X00T, X01T, 00313 // X10T, X11T, the data values at points along the edges. 00314 // 00315 // Input, double X0ST, X1ST, XR0T, XR1T, XRS0, XRS1, the data values 00316 // at points on the faces. 00317 // 00318 // Output, double *X, the interpolated data value at (R,S,T). 00319 // 00321 00322 double u = linear_interpolation(r, x0st, x1st); 00323 double v = linear_interpolation(s, xr0t, xr1t); 00324 double w = linear_interpolation(t, xrs0, xrs1); 00325 00326 double uv = bilinear_interpolation(r, s, x00t, x10t, x11t, x01t); 00327 double uw = bilinear_interpolation(r, t, x0s0, x1s0, x1s1, x0s1); 00328 double vw = bilinear_interpolation(s, t, xr00, xr10, xr11, xr01); 00329 00330 double uvw = trilinear_interpolation(r, s, t, 00331 x000, x100, x110, x010, 00332 x001, x101, x111, x011); 00333 00334 double val = u + v + w - uw - uv - vw + uvw; 00335 00336 return val; 00337 } 00338 00339 //****************************************************************************80 00340 00341 void blend_from_corners(double *x, int n) 00342 { 00343 00344 //****************************************************************************80 00345 // 00346 // Purpose: extends indexed scalar data at endpoints along a line. 00347 // 00348 // Diagram: 00349 // 00350 // ( X0, ..., ..., ..., ..., ..., X6 ) 00351 // 00352 // Author: 00353 // 00354 // John Burkardt 00355 // 00356 // Reference: 00357 // 00358 // William Gordon, Charles A Hall, 00359 // Construction of Curvilinear Coordinate Systems and Application to 00360 // Mesh Generation, 00361 // International Journal of Numerical Methods in Engineering, 00362 // Volume 7, pages 461-477, 1973. 00363 // 00364 // Joe Thompson, Bharat Soni, Nigel Weatherill, 00365 // Handbook of Grid Generation, 00366 // CRC Press, 00367 // 1999. 00368 // 00369 // Parameters: 00370 // 00371 // Input/output, double X[M]. 00372 // 00373 // On input, X[0] and X[M-1] contain scalar values which are to be 00374 // interpolated through the entries X[1] through X[M-2]. It is assumed 00375 // that the dependence of the data is linear in the vector index I. 00376 // 00377 // On output, X[1] through X[M-2] have been assigned interpolated values. 00378 // 00379 // Input, int M, the number of entries in X. 00380 // 00381 int i; 00382 double r; 00383 00384 for (i = 1; i < n - 1; i++) { 00385 r = gauss_node(i, n); 00386 x[i] = linear_interpolation(r, x[0], x[n - 1]); 00387 } 00388 00389 return; 00390 } 00391 //****************************************************************************80 00392 00393 void blend_from_edges(double *x, int nx, int ny) 00394 { 00395 00396 //****************************************************************************80 00397 // 00398 // Purpose: extends indexed scalar data along edges into a table. 00399 // 00400 // Diagram: 00401 // 00402 // ( X00, X01, X02, X03, X04, X05, X06 ) 00403 // ( X10, ..., ..., ..., ..., ..., X16 ) 00404 // ( X20, ..., ..., ..., ..., ..., X26 ) 00405 // ( X30, ..., ..., ..., ..., ..., X36 ) 00406 // ( X40, X41, X42, X43, X44, X45, X46 ) 00407 // 00408 // Licensing: 00409 // 00410 // This code is distributed under the GNU LGPL license. 00411 // 00412 // Modified: 00413 // 00414 // 7th July December 2009 00415 // 00416 // Author: 00417 // 00418 // John Burkardt: Modified by Chaman Singh Verma 00419 // 00420 // Reference: 00421 // 00422 // William Gordon, Charles A Hall, 00423 // Construction of Curvilinear Coordinate Systems and Application to 00424 // Mesh Generation, 00425 // International Journal of Numerical Methods in Engineering, 00426 // Volume 7, pages 461-477, 1973. 00427 // 00428 // Joe Thompson, Bharat Soni, Nigel Weatherill, 00429 // Handbook of Grid Generation, 00430 // CRC Press, 00431 // 1999. 00432 // 00433 // Parameters: 00434 // 00435 // Input/output, double X[NX*NY], a singly dimensioned array that 00436 // is "really" doubly dimensioned. The double dimension index [I][J] 00437 // corresponds to the single dimension index J * NX + I. 00438 // 00439 // On input, data is contained in the "edge entries" 00440 // X[0][0], X[I][0], X[0][NY-1] and X[NX-1][NY-1], 00441 // for I = 0 to NX-1, and J = 0 to NY-1. 00442 // 00443 // On output, all entries in X have been assigned a value. 00444 // 00445 // Input, int NX, NY the number of rows and columns in X. 00446 // 00448 00449 double x0 = x[0]; 00450 double x1 = x[nx - 1]; 00451 double x2 = x[nx * ny - 1]; 00452 double x3 = x[nx * ny - nx]; 00453 00454 for (int j = 1; j < ny - 1; j++) { 00455 double s = gauss_node(j, ny); 00456 00457 for (int i = 1; i < nx - 1; i++) { 00458 double r = gauss_node(i, nx); 00459 int il = j*nx; 00460 int ir = j * nx + nx - 1; 00461 int it = (ny - 1) * nx + i; 00462 int ib = i; 00463 int offset = j * nx + i; 00464 00465 double xr0 = x[ib]; 00466 double x1s = x[ir]; 00467 double xr1 = x[it]; 00468 double x0s = x[il]; 00469 00470 x[offset] = transfinite_blend(r, s, x0, x1, x2, x3, xr0, x1s, xr1, x0s); 00471 } 00472 } 00473 return; 00474 } 00475 00477 00478 void blend_from_corners(double *x, int nx, int ny) 00479 { 00480 00481 //****************************************************************************80 00482 // 00483 // Purpose: extends indexed scalar data at corners into a table. 00484 // 00485 // Diagram: 00486 // 00487 // ( X00, ..., ..., ..., ..., ..., X06 ) 00488 // ( ..., ..., ..., ..., ..., ..., ... ) 00489 // ( ..., ..., ..., ..., ..., ..., ... ) 00490 // ( ..., ..., ..., ..., ..., ..., ... ) 00491 // ( X40, ..., ..., ..., ..., ..., X46 ) 00492 // 00493 // Licensing: 00494 // 00495 // This code is distributed under the GNU LGPL license. 00496 // 00497 // Modified: 00498 // 00499 // 19 December 1998 00500 // 00501 // Author: 00502 // 00503 // John Burkardt 00504 // 00505 // Reference: 00506 // 00507 // William Gordon, Charles A Hall, 00508 // Construction of Curvilinear Coordinate Systems and Application to 00509 // Mesh Generation, 00510 // International Journal of Numerical Methods in Engineering, 00511 // Volume 7, pages 461-477, 1973. 00512 // 00513 // Joe Thompson, Bharat Soni, Nigel Weatherill, 00514 // Handbook of Grid Generation, 00515 // CRC Press, 00516 // 1999. 00517 // 00518 // Parameters: 00519 // 00520 // Input/output, double X[NX*NY], a singly dimensioned array that 00521 // is "really" doubly dimensioned. The double dimension index [I][J] 00522 // corresponds to the single dimension index J * NX + I. 00523 // 00524 // On input, data values have been stored in the entries 00525 // [0], [NX-1], [NX*NY-NX] and [NX*NY-1], which correspond to the double 00526 // dimension entries [0][0], [1][NX-1], [0][NY-1] and [NX-1][NY-1]. 00527 // 00528 // On output, all entries in X have been assigned a value. 00529 // 00530 // Input, int NX, NY, the number of rows and columns in the doubly 00531 // dimensioned data. 00532 // 00534 00535 int offset; 00536 double r, s, x0, x1; 00537 00538 int nxy = nx*ny; 00539 00540 for (int i = 1; i < nx - 1; i++) { 00541 r = gauss_node(i, nx); 00542 00543 x0 = x[0]; 00544 x1 = x[nx - 1]; 00545 offset = i; 00546 x[offset] = linear_interpolation(r, x0, x1); 00547 00548 00549 x0 = x[nxy - nx]; 00550 x1 = x[nxy - 1 ]; 00551 offset = (ny - 1) * nx + i; 00552 x[offset] = linear_interpolation(r, x0, x1); 00553 } 00554 00555 00556 for (int j = 1; j < ny - 1; j++) { 00557 s = gauss_node(j, ny); 00558 00559 x0 = x[0]; 00560 x1 = x[nx * ny - nx]; 00561 offset = j*nx; 00562 x[offset] = linear_interpolation(s, x0, x1); 00563 00564 x0 = x[nx - 1]; 00565 x1 = x[nxy - 1]; 00566 offset = j * nx + (nx - 1); 00567 x[offset] = linear_interpolation(s, x0, x1); 00568 } 00569 00570 blend_from_edges(x, nx, ny); 00571 00572 return; 00573 } 00574 00575 00576 //****************************************************************************80 00577 00578 void blend_from_faces(double *x, int nx, int ny, int nz) 00579 { 00580 00581 //************************************************************************80 00582 // 00583 // Purpose: 00584 // 00585 // BLEND_FROM_FACES extends indexed scalar data along faces into a cubic table. 00586 // 00587 // Diagram: 00588 // 00589 // ( X000 X010 X020 X030 X040 X050 ) 00590 // ( X100 X110 X120 X130 X140 X150 ) 00591 // ( X200 X210 X220 X230 X240 X250 ) Layer 1 00592 // ( X300 X310 X320 X330 X340 X350 ) 00593 // ( X400 X410 X420 X430 X440 X450 ) 00594 // 00595 // ( X001 X011 X021 X031 X041 X051 ) 00596 // ( X101 ... .... .... .... X151 ) 00597 // ( X201 ... .... .... .... X251 ) Layer K 00598 // ( X301 ... .... .... .... X351 ) 1 < K < M3 00599 // ( X401 X411 X421 X431 X441 X451 ) 00600 // 00601 // ( X002 X012 X022 X032 X042 X052 ) 00602 // ( X102 X112 X122 X132 X142 X152 ) 00603 // ( X202 X212 X222 X232 X242 X252 ) Layer M3 00604 // ( X302 X312 X322 X332 X342 X352 ) 00605 // ( X402 X412 X422 X432 X442 X452 ) 00606 // 00607 // Licensing: 00608 // 00609 // This code is distributed under the GNU LGPL license. 00610 // 00611 // Modified: 00612 // 00613 // 22 December 1998 00614 // 00615 // Author: 00616 // 00617 // John Burkardt 00618 // 00619 // Reference: 00620 // 00621 // William Gordon, Charles A Hall, 00622 // Construction of Curvilinear Coordinate Systems and Application to 00623 // Mesh Generation, 00624 // International Journal of Numerical Methods in Engineering, 00625 // Volume 7, pages 461-477, 1973. 00626 // 00627 // Joe Thompson, Bharat Soni, Nigel Weatherill, 00628 // Handbook of Grid Generation, 00629 // CRC Press, 00630 // 1999. 00631 // 00632 // Parameters: 00633 // 00634 // Input/output, double X[NX*NY*NZ], a singly dimensioned array that 00635 // is "really" triply dimensioned. The triple dimension index 00636 // [I][J][K] corresponds to the single dimension index 00637 // K * NX*NY + J * NX + I 00638 // 00639 // On input, there is already scalar data in the entries X[I][J][K] 00640 // corresponding to "faces" of the table, that is, entries for which 00641 // at least one of the three indices I, J and K is equal to their 00642 // minimum or maximum possible values. 00643 // 00644 // On output, all entries in X have been assigned a value, using the 00645 // table indices as independent variables. 00646 // 00647 // Input, int NX, NY, NY, the number of rows, columns, and layers in X. 00648 // 00650 00651 double r, s, t; 00652 00653 int offset, nxy = nx*ny; 00654 00655 for (int k = 1; k < nz - 1; k++) { 00656 t = gauss_node(k, nz); 00657 for (int j = 1; j < ny - 1; j++) { 00658 s = gauss_node(j, ny); 00659 for (int i = 1; i < nx - 1; i++) { 00660 r = gauss_node(i, nx); 00661 00662 // Points on Back Plane 00663 double x000 = x[0]; 00664 double xr00 = x[i]; 00665 double x100 = x[(nx - 1)]; 00666 00667 double x0s0 = x[j * nx]; 00668 double xrs0 = x[i + j * nx]; 00669 double x1s0 = x[(nx - 1) + j * nx]; 00670 00671 double x010 = x[(ny - 1) * nx]; 00672 double xr10 = x[i + (ny - 1) * nx]; 00673 double x110 = x[(ny - 1) * nx + (nx - 1)]; 00674 00675 // Intermediate Plane 00676 00677 double x00t = x[k * nxy]; 00678 double xr0t = x[i + k * nxy]; 00679 double x10t = x[(nx - 1) + k * nxy]; 00680 00681 double x0st = x[j * nx + k * nxy]; 00682 double x1st = x[(nx - 1) + j * nx + k * nxy]; 00683 00684 double x01t = x[ (ny - 1) * nx + k * nxy]; 00685 double xr1t = x[i + (ny - 1) * nx + k * nxy]; 00686 double x11t = x[(nx - 1) + (ny - 1) * nx + k * nxy]; 00687 00688 // Front Plane 00689 double x001 = x[(nz - 1) * nxy]; 00690 double xr01 = x[ i + (nz - 1) * nxy]; 00691 double x101 = x[(nz - 1) * nxy + (nx - 1)]; 00692 00693 double x0s1 = x[ j * nx + (nz - 1) * nxy]; 00694 double xrs1 = x[ i + j * nx + (nz - 1) * nxy]; 00695 double x1s1 = x[ (nx - 1) + j * nx + (nz - 1) * nxy]; 00696 00697 double x011 = x[(ny - 1) * nx + (nz - 1) * nxy]; 00698 double xr11 = x[ i + (ny - 1) * nx + (nz - 1) * nxy]; 00699 double x111 = x[(nz - 1) * nxy + (ny - 1) * nx + (nx - 1)]; 00700 00701 offset = k * nxy + j * nx + i; 00702 x[offset] = transfinite_blend(r, s, t, 00703 x000, xr00, x100, 00704 x0s0, xrs0, x1s0, 00705 x010, xr10, x110, 00706 x00t, xr0t, x10t, 00707 x0st, x1st, 00708 x01t, xr1t, x11t, 00709 x001, xr01, x101, 00710 x0s1, xrs1, x1s1, 00711 x011, xr11, x111); 00712 } 00713 00714 } 00715 00716 } 00717 00718 return; 00719 } 00720 00722 00723 void blend_from_edges(double *x, int nx, int ny, int nz) 00724 { 00725 00726 //************************************************************************80 00727 // 00728 // Purpose: extends indexed scalar data along "edges" into a cubic table. 00729 // 00730 // Diagram: 00731 // 00732 // ( X000, X010, X020, X030, X040, X050 ) 00733 // ( X100, ..., ..., ..., ..., X150 ) 00734 // ( X200, ..., ..., ..., ..., X250 ) Layer 1 00735 // ( X300, ..., ..., ..., ..., X350 ) 00736 // ( X400, X410, X420, X430, X440, X450 ) 00737 // 00738 // ( X001, ..., ..., ..., ..., X051 ) 00739 // ( ...., ..., ..., ..., ..., ... ) 00740 // ( ...., ..., ..., ..., ..., ... ) Layer K 00741 // ( ...., ..., ..., ..., ..., ... ) 1 < K < M3 00742 // ( X401, ..., ..., ..., ..., X451 ) 00743 // 00744 // ( X002, X012, X022, X032, X042, X052 ) 00745 // ( X102, ..., ..., ..., ..., X152 ) 00746 // ( X202, ..., ..., ..., ..., X252 ) Layer M3 00747 // ( X302 ..., ..., ..., ..., X352 ) 00748 // ( X402, X412, X422, X432, X442, X452 ) 00749 // 00750 // Licensing: 00751 // 00752 // This code is distributed under the GNU LGPL license. 00753 // 00754 // Modified: 00755 // 00756 // 22 December 1998 00757 // 00758 // Author: 00759 // 00760 // John Burkardt 00761 // 00762 // Reference: 00763 // 00764 // William Gordon, Charles A Hall, 00765 // Construction of Curvilinear Coordinate Systems and Application to 00766 // Mesh Generation, 00767 // International Journal of Numerical Methods in Engineering, 00768 // Volume 7, pages 461-477, 1973. 00769 // 00770 // Joe Thompson, Bharat Soni, Nigel Weatherill, 00771 // Handbook of Grid Generation, 00772 // CRC Press, 00773 // 1999. 00774 // 00775 // Parameters: 00776 // 00777 // Input/output, double X[NX*NY*NZ], a singly dimensioned array that 00778 // is "really" triply dimensioned. The triple dimension index 00779 // [I][J][K] corresponds to the single dimension index 00780 // K * NX*NY + J * NX + I 00781 // 00782 // On input, there is already scalar data in the entries X[I][J][K] 00783 // corresponding to "edges" of the table, that is, entries for which 00784 // at least two of the three indices I, J and K are equal to their 00785 // minimum or maximum possible values. 00786 // 00787 // Input, int NX, NY, NZ, the number of rows, columns, and layers in X. 00788 // 00790 00791 int offset; 00792 int nxy = nx*ny; 00793 00794 double r, s, t; 00795 double x00, x10, x11, x01; 00796 double xs0, x1t, xs1, x0t; 00797 00798 for (int k = 1; k < nz - 1; k++) { 00799 t = gauss_node(k, nz); 00800 for (int j = 1; j < ny - 1; j++) { 00801 s = gauss_node(j, ny); 00802 //Left Face ... 00803 x00 = x[0]; 00804 x10 = x[(ny - 1) * nx]; 00805 x11 = x[(nz - 1) * nxy + (ny - 1) * nx]; 00806 x01 = x[(nz - 1) * nxy]; 00807 00808 xs0 = x[j * nx]; 00809 x1t = x[k * nxy + (ny - 1) * nx]; 00810 xs1 = x[(nz - 1) * nxy + j * nx]; 00811 x0t = x[k * nxy]; 00812 00813 offset = k * nxy + j*nx; 00814 00815 x[offset] = transfinite_blend(s, t, x00, x10, x11, x01, xs0, x1t, xs1, x0t); 00816 00817 // Right Face ... 00818 x00 = x[nx - 1]; 00819 x10 = x[(ny - 1) * nx + (nx - 1)]; 00820 x11 = x[(nz - 1) * nxy + (ny - 1) * nx + (nx - 1)]; 00821 x01 = x[(nz - 1) * nxy + (nx - 1)]; 00822 00823 xs0 = x[j * nx + (nx - 1)]; 00824 x1t = x[k * nxy + (ny - 1) * nx + (nx - 1)]; 00825 xs1 = x[(nz - 1) * nxy + j * nx + (nx - 1)]; 00826 x0t = x[k * nxy + (nx - 1)]; 00827 00828 offset = k * nxy + j * nx + nx - 1; 00829 00830 x[offset] = transfinite_blend(s, t, x00, x10, x11, x01, xs0, x1t, xs1, x0t); 00831 } 00832 } 00833 00834 double xr0, xr1; 00835 00836 for (int k = 1; k < nz - 1; k++) { 00837 t = gauss_node(k, nz); 00838 for (int i = 1; i < nx - 1; i++) { 00839 r = gauss_node(i, nx); 00840 00841 // Bottom Face ... 00842 x00 = x[0]; 00843 x10 = x[nx - 1]; 00844 x11 = x[(nz - 1) * nxy + (nx - 1)]; 00845 x01 = x[(nz - 1) * nxy]; 00846 00847 xr0 = x[i]; 00848 x1t = x[k * nxy + (nx - 1)]; 00849 00850 xr1 = x[(nz - 1) * nxy + i]; 00851 x0t = x[k * nxy]; 00852 00853 offset = k * nxy + i; 00854 00855 x[offset] = transfinite_blend(r, t, x00, x10, x11, x01, xr0, x1t, xr1, x0t); 00856 00857 // Top Face ... 00858 x00 = x[(ny - 1) * nx]; 00859 x10 = x[(ny - 1) * nx + nx - 1]; 00860 x11 = x[(nz - 1) * nxy + (ny - 1) * nx + nx - 1]; 00861 x01 = x[(nz - 1) * nxy + (ny - 1) * nx]; 00862 00863 xr0 = x[(ny - 1) * nx + i]; 00864 x1t = x[k * nxy + (ny - 1) * nx + nx - 1]; 00865 xr1 = x[(nz - 1) * nxy + (ny - 1) * nx + i]; 00866 x0t = x[k * nxy + (ny - 1) * nx]; 00867 00868 offset = k * nxy + (ny - 1) * nx + i; 00869 00870 x[offset] = transfinite_blend(r, t, x00, x10, x11, x01, xr0, x1t, xr1, x0t); 00871 00872 } 00873 } 00874 00875 double x0s, x1s; 00876 for (int j = 1; j < ny - 1; j++) { 00877 s = gauss_node(j, ny); 00878 for (int i = 1; i < nx - 1; i++) { 00879 r = gauss_node(i, nx); 00880 00881 // Back Face ... 00882 x00 = x[0]; 00883 x10 = x[nx - 1]; 00884 x11 = x[(ny - 1) * nx + (nx - 1)]; 00885 x01 = x[(ny - 1) * nx]; 00886 00887 xr0 = x[i]; 00888 x1s = x[j * nx + nx - 1]; 00889 xr1 = x[(ny - 1) * nx + i]; 00890 x0s = x[j * nx]; 00891 00892 offset = j * nx + i; 00893 00894 x[offset] = transfinite_blend(r, s, x00, x10, x11, x01, xr0, x1s, xr1, x0s); 00895 00896 // Front Face ... 00897 x00 = x[(nz - 1) * nxy]; 00898 x10 = x[(nz - 1) * nxy + nx - 1]; 00899 x11 = x[(nz - 1) * nxy + (ny - 1) * nx + (nx - 1)]; 00900 x01 = x[(nz - 1) * nxy + (ny - 1) * nx]; 00901 00902 xr0 = x[(nz - 1) * nxy + i]; 00903 x1s = x[(nz - 1) * nxy + j * nx + nx - 1]; 00904 xr1 = x[(nz - 1) * nxy + (ny - 1) * nx + i]; 00905 x0s = x[(nz - 1) * nxy + j * nx]; 00906 00907 offset = (nz - 1) * nx * ny + j * nx + i; 00908 00909 x[offset] = transfinite_blend(r, s, x00, x10, x11, x01, xr0, x1s, xr1, x0s); 00910 } 00911 } 00912 00913 blend_from_faces(x, nx, ny, nz); 00914 00915 return; 00916 } 00917 00919 00920 void blend_from_corners(double *x, int nx, int ny, int nz) 00921 { 00922 00923 //************************************************************************80 00924 // 00925 // Purpose: 00926 // 00927 // BLEND_IJK_0D1 extends indexed scalar data along corners into a cubic table. 00928 // 00929 // Diagram: 00930 // 00931 // ( X000, ..., ..., ..., ..., ..., X060 ) 00932 // ( ...., ..., ..., ..., ..., ..., ... ) 00933 // ( ...., ..., ..., ..., ..., ..., ... ) First "layer" 00934 // ( ...., ..., ..., ..., ..., ..., ... ) 00935 // ( X400, ..., ..., ..., ..., ..., X460 ) 00936 // 00937 // ( ...., ..., ..., ..., ..., ..., ... ) 00938 // ( ...., ..., ..., ..., ..., ..., ... ) 00939 // ( ...., ..., ..., ..., ..., ..., ... ) Middle "layers" 00940 // ( ...., ..., ..., ..., ..., ..., ... ) 00941 // ( ...., ..., ..., ..., ..., ..., ... ) 00942 // 00943 // ( X003, ..., ..., ..., ..., ..., X063 ) 00944 // ( ...., ..., ..., ..., ..., ..., ... ) 00945 // ( ...., ..., ..., ..., ..., ..., ... ) Last "layer" 00946 // ( ...., ..., ..., ..., ..., ..., ... ) 00947 // ( X403, ..., ..., ..., ..., ..., X463 ) 00948 // 00949 // Licensing: 00950 // 00951 // This code is distributed under the GNU LGPL license. 00952 // 00953 // Modified: 00954 // 00955 // 22 December 1998 00956 // 00957 // Author: 00958 // 00959 // John Burkardt 00960 // 00961 // Reference: 00962 // 00963 // William Gordon, Charles A Hall, 00964 // Construction of Curvilinear Coordinate Systems and Application to 00965 // Mesh Generation, 00966 // International Journal of Numerical Methods in Engineering, 00967 // Volume 7, pages 461-477, 1973. 00968 // 00969 // Joe Thompson, Bharat Soni, Nigel Weatherill, 00970 // Handbook of Grid Generation, 00971 // CRC Press, 00972 // 1999. 00973 // 00974 // Parameters: 00975 // 00976 // Input/output, double X[NX*NY*NZ], a singly dimensioned array that 00977 // is "really" triply dimensioned. The triple dimension index 00978 // [I][J][K] corresponds to the single dimension index 00979 // K * NX*NY + J * NX + I 00980 // 00981 // On input, there is already scalar data in the entries X[I][J][K] 00982 // corresponding to "cornders" of the table, that is, entries for which 00983 // each of the three indices I, J and K is equal to their 00984 // minimum or maximum possible values. 00985 // 00986 // Input, int NX, NY, NZ, the number of rows, columns, and layers in X. 00987 // 00989 00990 int offset; 00991 double r, s, t, x0, x1; 00992 00993 int nxy = nx*ny; 00994 00995 for (int i = 1; i < nx - 1; i++) { 00996 r = gauss_node(i, nx); 00997 00998 x0 = x[0]; 00999 x1 = x[nx - 1]; 01000 offset = i; 01001 x[offset] = linear_interpolation(r, x0, x1); 01002 01003 x0 = x[(ny - 1) * nx]; 01004 x1 = x[(ny - 1) * nx + nx - 1]; 01005 offset = (ny - 1) * nx + + i; 01006 x[offset] = linear_interpolation(r, x0, x1); 01007 01008 x0 = x[(nz - 1) * nxy]; 01009 x1 = x[(nz - 1) * nxy + nx - 1]; 01010 offset = (nz - 1) * nxy + i; 01011 x[offset] = linear_interpolation(r, x0, x1); 01012 01013 x0 = x[(nz - 1) * nxy + (ny - 1) * nx ]; 01014 x1 = x[(nz - 1) * nxy + (ny - 1) * nx + nx - 1]; 01015 offset = (nz - 1) * nxy + (ny - 1) * nx + i; 01016 x[offset] = linear_interpolation(r, x0, x1); 01017 01018 } 01019 01020 for (int j = 1; j < ny - 1; j++) { 01021 s = gauss_node(j, ny); 01022 01023 x0 = x[0]; 01024 x1 = x[ (ny - 1) * nx ]; 01025 offset = j*nx; 01026 x[offset] = linear_interpolation(s, x0, x1); 01027 01028 x0 = x[nx - 1]; 01029 x1 = x[(ny - 1) * nx + (nx - 1)]; 01030 offset = j * nx + nx - 1; 01031 x[offset] = linear_interpolation(s, x0, x1); 01032 01033 x0 = x[(nz - 1) * nxy]; 01034 x1 = x[(nz - 1) * nxy + (ny - 1) * nx]; 01035 offset = (nz - 1) * nxy + j*nx; 01036 x[offset] = linear_interpolation(s, x0, x1); 01037 01038 x0 = x[ (nz - 1) * nxy + nx - 1]; 01039 x1 = x[ (nz - 1) * nxy + (ny - 1) * nx + nx - 1]; 01040 offset = (nz - 1) * nxy + j * nx + nx - 1; 01041 x[offset] = linear_interpolation(s, x0, x1); 01042 } 01043 01044 for (int k = 1; k < nz - 1; k++) { 01045 t = gauss_node(k, nz); 01046 01047 x0 = x[0]; 01048 x1 = x[(nz - 1) * nxy]; 01049 offset = k*nxy; 01050 x[offset] = linear_interpolation(t, x0, x1); 01051 01052 x0 = x[nx - 1]; 01053 x1 = x[(nz - 1) * nxy + nx - 1]; 01054 offset = k * nxy + nx - 1; 01055 x[offset] = linear_interpolation(t, x0, x1); 01056 01057 x0 = x[(ny - 1) * nx]; 01058 x1 = x[(nz - 1) * nxy + (ny - 1) * nx ]; 01059 offset = k * nxy + (ny - 1) * nx; 01060 x[offset] = linear_interpolation(t, x0, x1); 01061 01062 x0 = x[(ny - 1) * nx + nx - 1]; 01063 x1 = x[(nz - 1) * nxy + (ny - 1) * nx + nx - 1]; 01064 offset = k * nx * ny + (ny - 1) * nx + nx - 1; 01065 x[offset] = linear_interpolation(t, x0, x1); 01066 } 01067 01068 blend_from_edges(x, nx, ny, nz); 01069 01070 return; 01071 } 01072 01073 } 01074 01076