Nek5000
SEM for Incompressible NS
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
tensor.h
Go to the documentation of this file.
1 #ifndef TENSOR_H
2 #define TENSOR_H
3 
4 #if !defined(TYPES_H) || !defined(NAME_H)
5 #warning "tensor.h" requires "types.h" and "name.h"
6 #endif
7 
8 #if defined(USE_CBLAS)
9 # include <cblas.h>
10 # define tensor_dot(a,b,n) cblas_ddot((int)(n),a,1,b,1)
11 # define tensor_mxv(y,ny,A,x,nx) \
12  cblas_dgemv(CblasColMajor,CblasNoTrans,(int)ny,(int)nx, \
13  1.0,A,(int)ny,x,1,0.0,y,1)
14 # define tensor_mtxv(y,ny,A,x,nx) \
15  cblas_dgemv(CblasColMajor,CblasTrans,(int)nx,(int)ny, \
16  1.0,A,(int)nx,x,1,0.0,y,1)
17 # define tensor_mxm(C,nc,A,na,B,nb) \
18  cblas_dgemm(CblasColMajor,CblasNoTrans,CblasNoTrans, \
19  (int)nc,(int)nb,(int)na,1.0, \
20  A,(int)nc,B,(int)na,0.0,C,(int)nc)
21 # define tensor_mtxm(C,nc,A,na,B,nb) \
22  cblas_dgemm(CblasColMajor,CblasTrans,CblasNoTrans, \
23  (int)nc,(int)nb,(int)na,1.0, \
24  A,(int)na,B,(int)na,0.0,C,(int)nc)
25 #else
26 # define tensor_dot PREFIXED_NAME(tensor_dot )
27 # define tensor_mtxm PREFIXED_NAME(tensor_mtxm)
28 double tensor_dot(const double *a, const double *b, uint n);
29 
30 /* C (nc x nb) = [A (na x nc)]^T * B (na x nb); all column-major */
31 void tensor_mtxm(double *C, uint nc,
32  const double *A, uint na, const double *B, uint nb);
33 # if defined(USE_NAIVE_BLAS)
34 # define tensor_mxv PREFIXED_NAME(tensor_mxv )
35 # define tensor_mtxv PREFIXED_NAME(tensor_mtxv)
36 # define tensor_mxm PREFIXED_NAME(tensor_mxm )
37 /* y = A x */
38 void tensor_mxv(double *y, uint ny, const double *A, const double *x, uint nx);
39 
40 /* y = A^T x */
41 void tensor_mtxv(double *y, uint ny, const double *A, const double *x, uint nx);
42 
43 /* C (nc x nb) = A (nc x na) * B (na x nb); all column-major */
44 void tensor_mxm(double *C, uint nc,
45  const double *A, uint na, const double *B, uint nb);
46 # else
47 # define nek_mxm FORTRAN_UNPREFIXED(mxm,MXM)
48 /* C (na x nc) = A (na x nb) * B (nb x nc); all column-major */
49 void nek_mxm(const double *A, const uint *na,
50  const double *B, const uint *nb,
51  double *C, const uint *nc);
52 /* C (nc x nb) = A (nc x na) * B (na x nb); all column-major */
53 static void tensor_mxm(double *C, uint nc,
54  const double *A, uint na, const double *B, uint nb)
55 { nek_mxm(A,&nc,B,&na,C,&nb); }
56 
57 /* y = A x */
58 static void tensor_mxv(double *y, uint ny,
59  const double *A, const double *x, uint nx)
60 { uint one=1; nek_mxm(A,&ny,x,&nx,y,&one); }
61 
62 /* y = A^T x */
63 static void tensor_mtxv(double *y, uint ny,
64  const double *A, const double *x, uint nx)
65 { uint one=1; nek_mxm(x,&one,A,&nx,y,&ny); }
66 
67 # endif
68 #endif
69 
70 /*--------------------------------------------------------------------------
71  1-,2-,3-d Tensor Application of Row Vectors (for Interpolation)
72 
73  the 3d case:
74  v = tensor_i3(Jr,nr, Js,ns, Jt,nt, u, work)
75  gives v = [ Jr (x) Js (x) Jt ] u
76  where Jr, Js, Jt are row vectors (interpolation weights)
77  u is nr x ns x nt in column-major format (inner index is r)
78  v is a scalar
79  --------------------------------------------------------------------------*/
80 
81 static double tensor_i1(const double *Jr, uint nr, const double *u)
82 {
83  return tensor_dot(Jr,u,nr);
84 }
85 
86 /* work holds ns doubles */
87 static double tensor_i2(const double *Jr, uint nr,
88  const double *Js, uint ns,
89  const double *u, double *work)
90 {
91  tensor_mtxv(work,ns, u, Jr,nr);
92  return tensor_dot(Js,work,ns);
93 }
94 
95 /* work holds ns*nt + nt doubles */
96 static double tensor_i3(const double *Jr, uint nr,
97  const double *Js, uint ns,
98  const double *Jt, uint nt,
99  const double *u, double *work)
100 {
101  double *work2 = work+nt;
102  tensor_mtxv(work2,ns*nt, u, Jr,nr);
103  tensor_mtxv(work ,nt , work2, Js,ns);
104  return tensor_dot(Jt,work,nt);
105 }
106 
107 /*--------------------------------------------------------------------------
108  1-,2-,3-d Tensor Application of Row Vectors
109  for simultaneous Interpolation and Gradient computation
110 
111  the 3d case:
112  v = tensor_ig3(g, wtr,nr, wts,ns, wtt,nt, u, work)
113  gives v = [ Jr (x) Js (x) Jt ] u
114  g_0 = [ Dr (x) Js (x) Jt ] u
115  g_1 = [ Jr (x) Ds (x) Jt ] u
116  g_2 = [ Jr (x) Js (x) Dt ] u
117  where Jr,Dr,Js,Ds,Jt,Dt are row vectors,
118  Jr=wtr, Dr=wtr+nr, etc.
119  (interpolation & derivative weights)
120  u is nr x ns x nt in column-major format (inner index is r)
121  v is a scalar, g is an array of 3 doubles
122  --------------------------------------------------------------------------*/
123 
124 static double tensor_ig1(double g[1],
125  const double *wtr, uint nr,
126  const double *u)
127 {
128  g[0] = tensor_dot(wtr+nr,u,nr);
129  return tensor_dot(wtr ,u,nr);
130 }
131 
132 /* work holds 2*nr doubles */
133 static double tensor_ig2(double g[2],
134  const double *wtr, uint nr,
135  const double *wts, uint ns,
136  const double *u, double *work)
137 {
138  tensor_mxm(work,nr, u,ns, wts,2);
139  g[0] = tensor_dot(wtr+nr,work ,nr);
140  g[1] = tensor_dot(wtr ,work+nr,nr);
141  return tensor_dot(wtr ,work ,nr);
142 }
143 
144 /* work holds 2*nr*ns + 3*nr doubles */
145 static double tensor_ig3(double g[3],
146  const double *wtr, uint nr,
147  const double *wts, uint ns,
148  const double *wtt, uint nt,
149  const double *u, double *work)
150 {
151  const uint nrs = nr*ns;
152  double *a = work, *b = work+2*nrs, *c=b+2*nr;
153  tensor_mxm(a,nrs, u,nt, wtt,2);
154  tensor_mxm(b,nr, a,ns, wts,2);
155  tensor_mxv(c,nr, a+nrs, wts,ns);
156  g[0] = tensor_dot(b , wtr+nr, nr);
157  g[1] = tensor_dot(b+nr, wtr , nr);
158  g[2] = tensor_dot(c , wtr , nr);
159  return tensor_dot(b , wtr , nr);
160 }
161 
162 /*
163  out - nr x ns
164  u - mr x ms
165  Jrt - mr x nr, Jst - ms x ns
166  work - nr x ms
167 */
168 static void tensor_2t(double *out,
169  const double *Jrt, uint nr, uint mr,
170  const double *Jst, uint ns, uint ms,
171  const double *u, double *work)
172 {
173  tensor_mtxm(work,nr, Jrt,mr, u,ms);
174  tensor_mxm(out,nr, work,ms, Jst,ns);
175 }
176 
177 /*
178  out - nr x ns x nt
179  u - mr x ms x mt
180  Jrt - mr x nr, Jst - ms x ns, Jtt - mt x nt
181  work - nr*ms*mt + nr*ns*mt = nr*(ms+ns)*mt
182 */
183 static void tensor_3t(double *out,
184  const double *Jrt, uint nr, uint mr,
185  const double *Jst, uint ns, uint ms,
186  const double *Jtt, uint nt, uint mt,
187  const double *u, double *work)
188 {
189  const uint nrs=nr*ns, mst=ms*mt, nrms=nr*ms;
190  uint k;
191  double *work2 = work+nr*mst;
192  double *p; const double *q;
193  tensor_mtxm(work,nr, Jrt,mr, u,mst);
194  for(k=0,p=work2,q=work;k<mt;++k,p+=nrs,q+=nrms)
195  tensor_mxm(p,nr, q,ms, Jst,ns);
196  tensor_mxm(out,nrs, work2,mt, Jtt,nt);
197 }
198 
199 #endif
static double tensor_ig2(double g[2], const double *wtr, uint nr, const double *wts, uint ns, const double *u, double *work)
Definition: tensor.h:133
static double Jr[NR *TNR]
#define uint
Definition: types.h:70
static double tensor_i2(const double *Jr, uint nr, const double *Js, uint ns, const double *u, double *work)
Definition: tensor.h:87
static const unsigned mr[D]
static double tensor_ig1(double g[1], const double *wtr, uint nr, const double *u)
Definition: tensor.h:124
static void tensor_mxv(double *y, uint ny, const double *A, const double *x, uint nx)
Definition: tensor.h:58
static void tensor_mtxv(double *y, uint ny, const double *A, const double *x, uint nx)
Definition: tensor.h:63
n
Definition: xxt_test.m:73
static void tensor_mxm(double *C, uint nc, const double *A, uint na, const double *B, uint nb)
Definition: tensor.h:53
#define x
ulong A[NUM][SI]
Definition: sort_test.c:17
uint B[NUM][SI]
Definition: sort_test.c:18
static void tensor_2t(double *out, const double *Jrt, uint nr, uint mr, const double *Jst, uint ns, uint ms, const double *u, double *work)
Definition: tensor.h:168
ns
Definition: xxt_test.m:43
static double tensor_i1(const double *Jr, uint nr, const double *u)
Definition: tensor.h:81
p
Definition: xxt_test2.m:1
static double tensor_ig3(double g[3], const double *wtr, uint nr, const double *wts, uint ns, const double *wtt, uint nt, const double *u, double *work)
Definition: tensor.h:145
#define nek_mxm
Definition: tensor.h:47
#define tensor_dot
Definition: tensor.h:26
static double Js[NS *TNS]
static double tensor_i3(const double *Jr, uint nr, const double *Js, uint ns, const double *Jt, uint nt, const double *u, double *work)
Definition: tensor.h:96
static const unsigned nr[3]
ulong out[N]
Definition: sort_test2.c:20
static void tensor_3t(double *out, const double *Jrt, uint nr, uint mr, const double *Jst, uint ns, uint ms, const double *Jtt, uint nt, uint mt, const double *u, double *work)
Definition: tensor.h:183
static double work[TNR *NS]
#define tensor_mtxm
Definition: tensor.h:27
static double y[NR *NS *NT *N]
Definition: obbox_test.c:31
const uint nx[3]
Definition: xxt_test.c:41
static double Jt[NT *TNT]