MeshKit  1.0
tfiblend.cpp
Go to the documentation of this file.
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 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines