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

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

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