NCCOOS Trac Projects: Top | Web | Platforms | Processing | Viz | Sprints | Sandbox | (Wind)

root/gliderproc/trunk/MATLAB/opnml/MEX/divgmex5.c

Revision 495 (checked in by cbc, 12 years ago)

Initial import of Stark code.

Line 
1 #include <math.h>
2 #include <stdio.h>
3 #include "mex.h"
4 #include "opnml_mex5_allocs.c"
5
6 /* PROTOTYPES */
7 void bandmsolve_c(int,
8                   double **,
9                   double *,
10                   int,
11                   int);
12 void divg(int nn,
13           int ne,
14           double *x,
15           double *y,
16           int *ele,
17           double *u,
18           double *v,
19           double *dv);
20
21 /************************************************************
22
23   ####     ##     #####  ######  #    #    ##     #   #
24  #    #   #  #      #    #       #    #   #  #     # #
25  #       #    #     #    #####   #    #  #    #     #
26  #  ###  ######     #    #       # ## #  ######     #
27  #    #  #    #     #    #       ##  ##  #    #     #
28   ####   #    #     #    ######  #    #  #    #     #
29
30 ************************************************************/
31
32 void mexFunction(int            nlhs,
33                  mxArray       *plhs[],
34                  int            nrhs,
35                  const mxArray *prhs[])
36 {
37    int cnt,*ele,i,j,nn,ne;
38    double *x, *y, *u, *v;
39    double *dele;
40    double *dv;
41
42 /* ---- divgmex will be called as :
43         dv=divg(x,y,ele,u,v);
44                                       ------------------------------- */
45        
46 /* ---- check I/O arguments ----------------------------------------- */
47    if (nrhs != 5)
48       mexErrMsgTxt("DIVG requires 5 input arguments.");
49    else if (nlhs != 1)
50       mexErrMsgTxt("DIVG requires 1 output arguments.");
51
52 /* ---- dereference input arrays ------------------------------------ */
53    x=mxGetPr(prhs[0]);
54    y=mxGetPr(prhs[1]);
55    dele=mxGetPr(prhs[2]);
56    u=mxGetPr(prhs[3]);
57    v=mxGetPr(prhs[4]);
58    nn=mxGetM(prhs[0]);
59    ne=mxGetM(prhs[2]);   
60
61 /* ---- allocate space for int representation of dele &
62         convert double element representation to int  &
63         shift node numbers toward 0 by 1 for proper indexing -------- */
64    ele=(int *)mxIvector(0,3*ne);
65    for (i=0;i<3*ne;i++){
66       ele[i]=(int)dele[i];
67       ele[i]=ele[i]-1;
68    }
69    
70 /* ---- allocate space for divergence list dv following
71         NRC allocation style                            ------------- */
72    dv = (double *)  mxDvector(0,nn-1);
73    
74 /* ---- call divergence routine  ------------------------------------ */
75    divg(nn,ne,x,y,ele,u,v,dv);
76      
77 /* ---- Set elements of return matrix, pointed to by plhs[0] -------- */
78    plhs[0]=mxCreateDoubleMatrix(nn,1,mxREAL);
79    mxSetPr(plhs[0],dv);
80
81 /* --- No need to free memory allocated with "mxCalloc"; MATLAB
82    does this automatically.  The CMEX allocation functions in
83    "opnml_allocs.c" use mxCalloc. ----------------------------------- */   
84    
85    return;
86 }
87
88 /*----------------------------------------------------------------------
89
90  #####     #    #    #    ####
91  #    #    #    #    #   #    #
92  #    #    #    #    #   #
93  #    #    #    #    #   #  ###
94  #    #    #     #  #    #    #
95  #####     #      ##      ####
96  
97 ----------------------------------------------------------------------*/
98 void divg(int nn,int ne,
99           double *x,
100           double *y,
101           int *ele,
102           double *u,
103           double *v,
104           double *dv)
105
106 #define ELE(i,j,m) ele[i+m*j]
107
108 {
109    double *ar,**av,**dx,**dy;
110    double area6,area12;
111    int i,j,l,m,n;
112    int nbw=0, nh=0, nhm=0, n0 ,n1, n2, l01, l02, l12;
113
114 /* ---- Compute half bandwidth -------------------------------------- */
115    for (i=0;i<ne;i++){
116       l01=abs(ELE(i,0,ne)-ELE(i,1,ne));
117       l02=abs(ELE(i,0,ne)-ELE(i,2,ne));
118       l12=abs(ELE(i,1,ne)-ELE(i,2,ne));
119       nhm=IMAX(l01,IMAX(l02,l12)); 
120       nh=IMAX(nh,nhm);   
121    }
122    nbw=2*nh+1;
123    fprintf(stderr,"BW = %d\n",nbw);
124
125 /* ---- ALLOCATE space for dx, dy, ar, av and dv -------------------- */
126    ar = (double *)  mxDvector(0,ne-1);
127    av = (double **) mxDmatrix(0,nbw-1,0,nn-1);
128    dx = (double **) mxDmatrix(0,2,0,ne-1);
129    dy = (double **) mxDmatrix(0,2,0,ne-1);   
130    puts("Local Arrays Allocated");
131            
132 /* ---- Compute dx,dy and element areas ----------------------------- */
133    for(l=0;l<ne;l++){
134       dx[0][l]=x[ELE(l,1,ne)]-x[ELE(l,2,ne)];
135       dx[1][l]=x[ELE(l,2,ne)]-x[ELE(l,0,ne)];
136       dx[2][l]=x[ELE(l,0,ne)]-x[ELE(l,1,ne)];
137       dy[0][l]=y[ELE(l,1,ne)]-y[ELE(l,2,ne)];
138       dy[1][l]=y[ELE(l,2,ne)]-y[ELE(l,0,ne)];
139       dy[2][l]=y[ELE(l,0,ne)]-y[ELE(l,1,ne)];
140       ar[l]=.5*(x[ELE(l,0,ne)]*dy[0][l]+
141                 x[ELE(l,1,ne)]*dy[1][l]+
142                 x[ELE(l,2,ne)]*dy[2][l]);     
143    }
144    puts("Element areas and edge lengths computed");
145    
146 /* ---- Assemble LHS (av) ------------------------------------------- */
147    for(l=0;l<ne;l++){
148       area6=ar[l]/6.;
149       area12=ar[l]/12.;
150       for(j=0;j<3;j++){
151          m=ELE(l,j,ne);
152          for(i=0;i<3;i++){
153             n=nh+ELE(l,i,ne)-ELE(l,j,ne);
154             if(i==j) av[n][m]+=area6;
155             else     av[n][m]+=area12;     
156          }
157       }
158    }
159    puts("LHS (av) assembled");
160
161 /* ---- Assemble RHS (dv) ------------------------------------------- */
162    for(l=0;l<ne;l++){
163       for(j=0;j<3;j++){
164          m=ELE(l,j,ne);
165          for(i=0;i<3;i++)
166               dv[m]+=u[ELE(l,i,ne)]*dy[i][l]/6.
167                     -v[ELE(l,i,ne)]*dx[i][l]/6.;
168       }
169    }
170    puts("RHS (dv) assembled");
171
172 /* ---- Call banded Matrix solver to triangularize av --------------- */
173    bandmsolve_c(0,av,dv,nn,nh);
174    puts("Left side triangularized");
175    
176 /* ---- Call banded Matrix solver to solve for dv ------------------- */
177    bandmsolve_c(1,av,dv,nn,nh);
178    puts("Divergence computed");
179  
180    return;     
181 }
182
183
184
185
186
187
188
Note: See TracBrowser for help on using the browser.