Changeset 7447


Ignore:
Timestamp:
02/15/11 11:03:15 (14 years ago)
Author:
Mathieu Morlighem
Message:

Added Bilinear interpolation by default. MUCH SMOOTHER

Location:
issm/trunk/src/c
Files:
1 deleted
6 edited

Legend:

Unmodified
Added
Removed
  • issm/trunk/src/c/EnumDefinitions/EnumDefinitions.h

    r7405 r7447  
    88
    99enum definitions{
    10 
    1110        /*Datasets {{{1*/
    1211        ConstraintsEnum,
     
    411410        SsetEnum,
    412411        GroundingLineMigrationEnum,
    413         YtsEnum
     412        YtsEnum,
     413        /*}}}*/
     414        /*Interpolation {{{1*/
     415        TriangleInterpEnum,
     416        BilinearInterpEnum,
     417        NearestInterpEnum
    414418        /*}}}*/
    415419};
  • issm/trunk/src/c/EnumDefinitions/EnumToString.cpp

    r7405 r7447  
    366366                case GroundingLineMigrationEnum : return "GroundingLineMigration";
    367367                case YtsEnum : return "Yts";
     368                case TriangleInterpEnum : return "TriangleInterp";
     369                case BilinearInterpEnum : return "BilinearInterp";
     370                case NearestInterpEnum : return "NearestInterp";
    368371                default : return "unknown";
    369372
  • issm/trunk/src/c/EnumDefinitions/StringToEnum.cpp

    r7405 r7447  
    364364        else if (strcmp(name,"GroundingLineMigration")==0) return GroundingLineMigrationEnum;
    365365        else if (strcmp(name,"Yts")==0) return YtsEnum;
     366        else if (strcmp(name,"TriangleInterp")==0) return TriangleInterpEnum;
     367        else if (strcmp(name,"BilinearInterp")==0) return BilinearInterpEnum;
     368        else if (strcmp(name,"NearestInterp")==0) return NearestInterpEnum;
    366369        else _error_("Enum %s not found",name);
    367370
  • issm/trunk/src/c/Makefile.am

    r7391 r7447  
    505505                                        ./modules/InterpFromGridToMeshx/InterpFromGridToMeshx.cpp\
    506506                                        ./modules/InterpFromGridToMeshx/InterpFromGridToMeshx.h\
    507                                         ./modules/InterpFromGridToMeshx/InterpFromGridToMeshxt.cpp\
    508507                                        ./modules/InterpFromMesh2dx/InterpFromMesh2dx.cpp\
    509508                                        ./modules/InterpFromMesh2dx/InterpFromMesh2dxt.cpp\
     
    10841083                                        ./modules/InterpFromMesh2dx/InterpFromMesh2dxt.cpp\
    10851084                                        ./modules/InterpFromMesh2dx/InterpFromMesh2dx.h\
    1086                                         ./modules/InterpFromGridToMeshx/InterpFromGridToMeshxt.cpp\
    10871085                                        ./modules/InterpFromMeshToMesh2dx/InterpFromMeshToMesh2dx.cpp\
    10881086                                        ./modules/InterpFromMeshToMesh2dx/InterpFromMeshToMesh2dx.h\
  • issm/trunk/src/c/modules/InterpFromGridToMeshx/InterpFromGridToMeshx.cpp

    r7439 r7447  
    33 */
    44
     5/*Include {{{*/
    56#ifdef HAVE_CONFIG_H
    67        #include "config.h"
     
    1213#include "../../shared/shared.h"
    1314#include "../../include/include.h"
    14 
    15 int InterpFromGridToMeshx( Vec* pdata_mesh,double* x_in, int x_rows, double* y_in, int y_rows, double* data, int M, int N, double* x_mesh, double* y_mesh, int nods,double default_value) {
    16 
     15/*}}}*/
     16
     17/*InterpFromGridToMeshx{{{*/
     18int InterpFromGridToMeshx( Vec* pdata_mesh,double* x_in, int x_rows, double* y_in, int y_rows, double* data, int M, int N, double* x_mesh, double* y_mesh, int nods,double default_value, int interpenum){
    1719
    1820        /*output: */
     
    2830        InterpFromGridToMeshxThreadStruct gate;
    2931        int num=1;
    30 
    3132        #ifdef _MULTITHREADING_
    3233        num=_NUMTHREADS_;
     
    8283        gate.M=M;
    8384        gate.N=N;
     85        gate.interp=interpenum;
    8486
    8587        /*launch the thread manager with InterpFromGridToMeshxt as a core: */
     
    8991        *pdata_mesh=data_mesh;
    9092}
     93/*}}}*/
     94/*InterpFromGridToMeshxt {{{1*/
     95void* InterpFromGridToMeshxt(void* vpthread_handle){
     96
     97        /*gate variables :*/
     98        InterpFromGridToMeshxThreadStruct *gate    = NULL;
     99        pthread_handle                    *handle  = NULL;
     100        int my_thread;
     101        int num_threads;
     102        int i0,i1;
     103
     104        /*intermediary: */
     105        int    i,m,n;
     106        double x_grid;
     107        double y_grid;
     108        double data_value;
     109        double x1,x2,y1,y2;
     110        double Q11,Q12,Q21,Q22;
     111
     112        /*recover handle and gate: */
     113        handle=(pthread_handle*)vpthread_handle;
     114        gate=(InterpFromGridToMeshxThreadStruct*)handle->gate;
     115        my_thread=handle->id;
     116        num_threads=handle->num;
     117
     118        /*recover parameters :*/
     119        double *x_mesh        = gate->x_mesh;
     120        double *y_mesh        = gate->y_mesh;
     121        int     x_rows        = gate->x_rows;
     122        int     y_rows        = gate->y_rows;
     123        double *x             = gate->x;
     124        double *y             = gate->y;
     125        int     nods          = gate->nods;
     126        Vec     data_mesh     = gate->data_mesh;
     127        double *data          = gate->data;
     128        double  default_value = gate->default_value;
     129        int     interpenum    = gate->interp;
     130        int     M             = gate->M;
     131        int     N             = gate->N;
     132
     133        /*partition loop across threads: */
     134        PartitionRange(&i0,&i1,nods,num_threads,my_thread);
     135        for (i=i0;i<i1;i++) {
     136
     137                x_grid=*(x_mesh+i);
     138                y_grid=*(y_mesh+i);
     139
     140                /*Find indices m and n into y and x, for which  y(m)<=y_grids<=y(m+1) and x(n)<=x_grid<=x(n+1)*/
     141                if(findindices(&n,&m,x,x_rows, y,y_rows, x_grid,y_grid)){
     142
     143                        /*    Q12             Q22
     144                         * y2 x---------+-----x
     145                         *    |         |     |
     146                         *    |         |P    |
     147                         *    |---------+-----|
     148                         *    |         |     |
     149                         *    |         |     |
     150                         * y1 x---------+-----x Q21
     151                         *    x1                 x2       
     152                         *
     153                         */
     154                        x1=x[n]; x2=x[n+1];
     155                        y1=y[m]; y2=y[m+1];
     156                        Q11=data[m*N+n];
     157                        Q12=data[(m+1)*N+n];
     158                        Q21=data[m*N+n+1];
     159                        Q22=data[(m+1)*N+n+1];
     160
     161                        switch(interpenum){
     162                                case TriangleInterpEnum:
     163                                        data_value=triangleinterp(x1,x2,y1,y2,Q11,Q12,Q21,Q22,x_grid,y_grid);
     164                                        break;
     165                                case BilinearInterpEnum:
     166                                        data_value=bilinearinterp(x1,x2,y1,y2,Q11,Q12,Q21,Q22,x_grid,y_grid);
     167                                        break;
     168                                case NearestInterpEnum:
     169                                        data_value=nearestinterp(x1,x2,y1,y2, Q11,Q12,Q21,Q22,x_grid,y_grid);
     170                                        break;
     171                                default:
     172                                        printf("Interpolation %s not supported yet\n",EnumToString(interpenum));
     173                                        return NULL; /*WARNING: no error because it would blow up the multithreading!*/
     174                        }
     175                        if(isnan(data_value)) data_value=default_value;
     176                }
     177                else{
     178                        data_value=default_value;
     179                }
     180
     181                VecSetValue(data_mesh,i,data_value,INSERT_VALUES);
     182        }
     183}/*}}}*/
     184
     185/*findindices {{{1*/
     186bool findindices(int* pn,int* pm,double* x,int x_rows, double* y,int y_rows, double xgrid,double ygrid){
     187
     188        bool foundx=false,foundy=false;
     189        int m=-1,n=-1;
     190        int i;
     191
     192        for (i=0;i<x_rows-1;i++){
     193                if ((x[i]<=xgrid) && (xgrid<x[i+1])){
     194                        n=i;
     195                        foundx=true;
     196                        break;
     197                }
     198        }
     199        if(xgrid==x[x_rows-1]){
     200                n=x_rows-2;
     201                foundx=true;
     202        }
     203
     204        for (i=0;i<y_rows-1;i++){
     205                if ((y[i]<=ygrid) && (ygrid<y[i+1])){
     206                        m=i;
     207                        foundy=true;
     208                        break;
     209                }
     210        }
     211        if(ygrid==y[y_rows-1]){
     212                m=y_rows-2;
     213                foundy=true;
     214        }
     215
     216        /*Assign output pointers:*/
     217        *pm=m; *pn=n;
     218        return (foundx && foundy);
     219}/*}}}*/
     220/*triangleinterp{{{1*/
     221double triangleinterp(double x1,double x2,double y1,double y2,double Q11,double Q12,double Q21,double Q22,double x,double y){
     222        /*split the rectangle in 2 triangle and
     223         * use Lagrange P1 interpolation
     224         *       
     225         *   +3----+2,3' Q12----Q22
     226         *   |    /|     |    /|
     227         *   |   / |     |   / |
     228         *   |  /  |     |  /  |
     229         *   | /   |     | /   |
     230         *   |/    |     |/    |
     231         *   1-----2'    Q11---Q21        */
     232
     233        /*Intermediaries*/
     234        double area,area_1,area_2,area_3;
     235
     236        /*Checks*/
     237        _assert_(x2>x1 && y2>y1);
     238        _assert_(x<=x2 && x>=x1 && y<=y2 && y>=y1);
     239
     240        /*area of the rectangle*/
     241        area=(x2-x1)*(y2-y1);
     242
     243        /*is it the upper left triangle?*/
     244        if ((x-x1)/(x2-x1)<(y-y1)/(y2-y1)){
     245
     246                area_1=((y2-y)*(x2-x1))/area;
     247                area_2=((x-x1)*(y2-y1))/area;
     248                area_3=1-area_1-area_2;
     249
     250                return area_1*Q11+area_2*Q22+area_3*Q12;
     251        }
     252        else {
     253
     254                area_1=((y-y1)*(x2-x1))/area;
     255                area_2=((x2-x)*(y2-y1))/area;
     256                area_3=1-area_1-area_2;
     257
     258                return area_1*Q22+area_2*Q11+area_3*Q21;
     259        }
     260}/*}}}*/
     261/*bilinearinterp{{{1*/
     262double bilinearinterp(double x1,double x2,double y1,double y2,double Q11,double Q12,double Q21,double Q22,double x,double y){
     263        /*Bilinear  interpolation: (http://en.wikipedia.org/wiki/Bilinear_interpolation) */
     264
     265        /*    Q12    R2        Q22
     266         * y2 x------x---------x
     267         *    |      |         |
     268         *    |      |         |
     269         *    |      +P        |
     270         *    |      |         |
     271         *    |Q11   R1        Q21
     272         * y1 x------x---------x
     273         *    x1               x2
     274         *
     275         */
     276
     277        /*Checks*/
     278        _assert_(x2>x1 && y2>y1);
     279        _assert_(x<=x2 && x>=x1 && y<=y2 && y>=y1);
     280
     281        return
     282          +Q11*(x2-x)*(y2-y)/((x2-x1)*(y2-y1))
     283          +Q21*(x-x1)*(y2-y)/((x2-x1)*(y2-y1))
     284          +Q12*(x2-x)*(y-y1)/((x2-x1)*(y2-y1))
     285          +Q22*(x-x1)*(y-y1)/((x2-x1)*(y2-y1));
     286}
     287/*}}}*/
     288/*nearestinterp{{{1*/
     289double nearestinterp(double x1,double x2,double y1,double y2,double Q11,double Q12,double Q21,double Q22,double x,double y){
     290        /*Nearest neighbor interpolation*/
     291
     292        /*    Q12             Q22
     293         * y2 x--------x---------x
     294         *    |        |         |
     295         *    |        |  xP     |
     296         * ym |--------+---------|
     297         *    |        |         |
     298         *    |        |         |
     299         * y1 x--------x---------x Q21
     300         *    x1       xm        x2
     301         *
     302         */
     303        /*Checks*/
     304        _assert_(x2>x1 && y2>y1);
     305        _assert_(x<=x2 && x>=x1 && y<=y2 && y>=y1);
     306       
     307        double xm=(x2-x1)/2;
     308        double ym=(y2-y1)/2;
     309
     310        if (x<xm && y<ym) return Q11;
     311        if (x<xm && y>ym) return Q12;
     312        if (x>xm && y<ym) return Q21;
     313        else return Q22;
     314}
     315/*}}}*/
  • issm/trunk/src/c/modules/InterpFromGridToMeshx/InterpFromGridToMeshx.h

    r3913 r7447  
    77
    88#include "../../toolkits/toolkits.h"
    9 
    10 
     9#include "../../EnumDefinitions/EnumDefinitions.h"
    1110
    1211/*threading: */
    1312typedef struct{
    14 
     13        double* x;
     14        int     x_rows;
     15        double* y;
     16        int     y_rows;
     17        double* data;
     18        double  default_value;
     19        int     interp;
     20        int     M;
     21        int     N;
     22        int     nods;
    1523        double* x_mesh;
    1624        double* y_mesh;
    17         int     x_rows;
    18         int     y_rows;
    19         double* x;
    20         double* y;
    21         int     nods;
    22         double  default_value;
    2325        Vec     data_mesh;
    24         double* data;
    25         int     M;
    26         int     N;
    27 
    2826} InterpFromGridToMeshxThreadStruct;
    2927
    30 int findindices(int* pm,int* pn,double* x,int x_rows, double* y,int y_rows, double xgrid,double ygrid);
    31 
    32 int InterpFromGridToMeshx( Vec* pdata_mesh,double* x, int x_rows, double* y, int y_rows, double* data, int M, int N, double* x_mesh, double* y_mesh, int nods, double default_value);
    33 
    34 void* InterpFromGridToMeshxt(void* vInterpFromGridToMeshxThreadStruct);
    35 
     28int    InterpFromGridToMeshx( Vec* pdata_mesh,double* x, int x_rows, double* y, int y_rows, double* data, int M, int N, double* x_mesh, double* y_mesh, int nods, double default_value, int interpenum=BilinearInterpEnum);
     29void*  InterpFromGridToMeshxt(void* vInterpFromGridToMeshxThreadStruct);
     30bool   findindices(int* pn,int* pm,double* x,int x_rows, double* y,int y_rows, double xgrid,double ygrid);
     31double triangleinterp(double x1,double x2,double y1,double y2,double Q11,double Q12,double Q21,double Q22,double x,double y);
     32double bilinearinterp(double x1,double x2,double y1,double y2,double Q11,double Q12,double Q21,double Q22,double x,double y);
     33double nearestinterp(double x1,double x2,double y1,double y2,double Q11,double Q12,double Q21,double Q22,double x,double y);
    3634
    3735#endif /* _INTERPFROMGRIDTOMESHX_H */
    38 
Note: See TracChangeset for help on using the changeset viewer.