Spectral Integral Suite in C++
Ex_11.cpp
Go to the documentation of this file.
1 
7 #define EIGEN_USE_BLAS
8 #define SIS_USE_LAPACK
9 #include <fstream>
10 #include <iostream>
11 #include <sis.hpp>
12 #include <string>
13 
14 using namespace std;
15 typedef complex<double> Cd_t;
16 typedef valarray<complex<double> > Vcd_t;
17 complex<double> ii(0.0, 1.0);
18 
19 int main()
20 {
21  using namespace sis;
22  int bre;
23  // Number of Chebyshev polynomials
24  N = 63;
25  sis_setup();
26  // Number of Eigenvalues to compute:
27  int num_vals = 40;
28 
29  // Number of fourier modes in span-wise direction:
30  int Nz = 4;
31  int Nx = 4;
32  // Length of domain:
33  valarray<double> kz(Nz);
34  valarray<double> kx(Nx);
35  valarray<double> z(Nz);
36  valarray<double> x(Nx);
37  valarray<double> omval(Nx);
38 
39  kx[0] = 1.0;
40  kx[1] = 1.0;
41  kx[2] = -1.0;
42  kx[3] = -1.0;
43 
44  kz[0] = 1.0;
45  kz[1] = -1.0;
46  kz[2] = 1.0;
47  kz[3] = -1.0;
48 
49  omval[0] = -1.0;
50  omval[1] = -1.0;
51  omval[2] = 1.0;
52  omval[3] = 1.0;
53  double omega = 0.385;
54 
55  omval = omega * omval;
56 
57  valarray<double> y, Uy, U, Uyy(N + 1);
58  // Set in cheb-point
59  setChebPts(y);
60 
61  // Velocity and derivative for PP flow
62  U = 1.0 - pow(y, 2.0);
63  Uy = -2.0 * y;
64  Uyy = -2.0;
65  double Re = 2000.0;
66 
67  Linop<double> Dy(1);
68  Dy.coef << 1.0, 0.0;
69 
70  LinopMat<std::complex<double> > A, B(2, 3), C(3, 2);
71  BcMat<std::complex<double> > Lbc(4, 4), Rbc(4, 4), bc(8, 4);
72 
73  Lbc.resize(4, 4);
74  Rbc.resize(4, 4);
75  Lbc.L << 1.0, 0.0, 0.0, 0.0, //
76  0.0, 1.0, 0.0, 0.0, //
77  0.0, 0.0, 1.0, 0.0, //
78  0.0, Dy, 0.0, 0.0;
79  Rbc.L << 1.0, 0.0, 0.0, 0.0, //
80  0.0, 1.0, 0.0, 0.0, //
81  0.0, 0.0, 1.0, 0.0, //
82  0.0, Dy, 0.0, 0.0;
83  Lbc.eval.setConstant(-1.0);
84  Rbc.eval.setConstant(1.0);
85  bc.L << Lbc.L, //
86  Rbc.L;
87  bc.eval << Lbc.eval, //
88  Rbc.eval;
89 
91 
92  ofstream outf;
93 
94  B.resize(4, 3);
95  C.resize(3, 4);
96  B << 1.0, 0.0, 0.0, //
97  0.0, 1.0, 0.0, //
98  0.0, 0.0, 1.0, //
99  0.0, 0.0, 0.0;
100  C << 1.0, 0.0, 0.0, 0.0, //
101  0.0, 1.0, 0.0, 0.0, //
102  0.0, 0.0, 1.0, 0.0; //
103  outf.open("data/file2.txt");
104 
105  // Below are 3D matrices stored in row-major format in a 1D array in the order
106  // Ny x Nx x Nz. In the row-major format, the element (i,j,k) in the 3D matrix
107  // is indexed by (i * Nx * Nz + j * Nz + k) in a 1D array.
108  // These can be easily manipulated using valarray slices.
109  //
110  // slice notation : slice(start, size, stride);
111  //
112  // slice to access nl(:,j,k) in matlab notation:
113  // slice(j * Nz + k, N + 1, Nx * Nz)
114  //
115  // slice to access nl(i,:,:) in matlab notation: slice(i * Nx * Nz, Nx * Nz,
116  // 1);
117  //
118  // Replace Nz by Nz / 2 in above 3 lines for complex type due to
119  // conjugate symmetry as all values have to be real in
120  // physical space.
121  //
122  // Here, I sketch the symmetry of a 8 x 8 matrix. Note that the Nyquist
123  // frequency values have to be set to zero, here we denote zeros by blanks
124  // "-". Numbers refer to element indices for matrices, indices start from 0 to
125  // conform with C++.
126  //
127  // Note that we choose (x,z) - x for rows, z columns.
128  // IMP: 00 must be real.
129  // 00 01 02 03 - 03* 02* 01*
130  // 10 11 12 13 - 73* 72* 71*
131  // 20 21 22 23 - 63* 62* 61*
132  // 30 31 32 33 - 53* 52* 51*
133  // - - - - - - - -
134  // 30* 51 52 53 - 33* 32* 31*
135  // 20* 61 62 63 - 23* 22* 21*
136  // 10* 71 72 73 - 13* 12* 11*
137  //
138  // Hence we store only the elements (:,1:Nz/2) in Matlab notation. There is
139  // slight repetition, that is 30*, 20* and 10* not needed to be stored.
140 
141  valarray<complex<double> > uvec(Cd_t(0.0, 0.0), (N + 1) * 4),
142  vvec(Cd_t(0.0, 0.0), (N + 1) * 4), wvec(Cd_t(0.0, 0.0), (N + 1) * 4),
143  pvec(Cd_t(0.0, 0.0), (N + 1) * 4);
144  valarray<double> u3d((N + 1) * Nx * Nz), v3d((N + 1) * Nx * Nz),
145  w3d((N + 1) * Nx * Nz), p3d((N + 1) * Nx * Nz);
146 
147  for (int k = 0; k < 4; k++)
148  {
149  complex<double> iiomega = ii * omega;
150  double k2 = kx[k] * kx[k] + kz[k] * kz[k];
151  double k4 = k2 * k2;
152  Linop<double> Delta(2), Delta2(4);
153  LinopMat<complex<double> > Lmat(4, 4), Mmat(4, 4);
154 
155  Delta.coef << 1.0, 0.0, -k2;
156  Delta2.coef << 1.0, 0.0, -2 * k2, 0.0, k4;
157 
158  Mmat << 1.0, 0.0, 0.0, 0.0, //
159  0.0, 1.0, 0.0, 0.0, //
160  0.0, 0.0, 1.0, 0.0, //
161  0.0, 0.0, 0.0, 0.0 * Delta;
162 
163  Lmat << (-ii * kx[k] * U) + (Delta / Re), -Uy, 0.0, -ii * kx[k], //
164  0.0, (-ii * kx[k] * U) + (Delta / Re), 0.0, -Dy, //
165  0.0, 0.0, (-ii * kx[k] * U) + (Delta / Re), -ii * kz[k], //
166  ii * kx[k], Dy, ii * kz[k], 0.0;
167 
168  A.resize(4, 4);
169  A = ((iiomega * Mmat) - Lmat);
170 
171  svd.compute(A, B, C, Lbc, Rbc, Lbc, Rbc, 15 * (N + 1));
172  std::cout << "eigenvalue: " << svd.eigenvalues[0] << "\n";
173  num_vals = svd.eigenvalues.size();
174 
175  // Store first two eigenvalues.
176  outf << kx[k] << " " << kz[k] << " " << svd.eigenvalues[0].real() << " "
177  << svd.eigenvalues[1].real() << "\n";
178 
179  uvec[slice(k,N+1,Nz)] =
180  // svd.eigenvalues[0].real() *
181  svd.eigenvectors(0,0).v;
182 
183  vvec[slice(k,N+1,Nz)] =
184  //svd.eigenvalues[0].real() *
185  svd.eigenvectors(1,0).v;
186 
187  wvec[slice(k,N+1,Nz)] =
188  // svd.eigenvalues[0].real() *
189  svd.eigenvectors(2,0).v;
190 
191  pvec[slice(k,N+1,Nz)] =
192  // svd.eigenvalues[0].real() *
193  svd.eigenvectors(3,0).v;
194 
195  }
196  Eigen::VectorXd xval, zval;
197 
198  zval = Eigen::VectorXd::LinSpaced(100, -7.8, 7.8);
199  xval = Eigen::VectorXd::LinSpaced(100, 0, 12.7);
200  Nx = 100;
201  Nz = 100;
202  Vcd_t u3dc(Cd_t(0.0, 0.0), (N + 1) * Nx * Nz),
203  v3dc(Cd_t(0.0, 0.0), (N + 1) * Nx * Nz),
204  w3dc(Cd_t(0.0, 0.0), (N + 1) * Nx * Nz),
205  p3dc(Cd_t(0.0, 0.0), (N + 1) * Nx * Nz);
206 
207  for (int j = 0; j < xval.size(); j++)
208  {
209  double x = xval[j];
210  for (int k = 0; k < zval.size(); k++)
211  {
212  double z = zval[k];
213  for (int i = 0; i < 4; i++)
214  {
215  double kx1 = kx[i];
216  double kz1 = kz[i];
217  u3dc[slice(j * Nz + k, N + 1, Nx * Nz)] +=
218  Vcd_t(uvec[slice(i, N + 1, 4)]) *
219  exp((ii * kx1 * x) + (ii * kz1 * z));
220  v3dc[slice(j * Nz + k, N + 1, Nx * Nz)] +=
221  Vcd_t(vvec[slice(i, N + 1, 4)]) *
222  exp((ii * kx1 * x) + (ii * kz1 * z));
223  w3dc[slice(j * Nz + k, N + 1, Nx * Nz)] +=
224  Vcd_t(wvec[slice(i, N + 1, 4)]) *
225  exp((ii * kx1 * x) + (ii * kz1 * z));
226  p3dc[slice(j * Nz + k, N + 1, Nx * Nz)] +=
227  Vcd_t(pvec[slice(i, N + 1, 4)]) *
228  exp((ii * kx1 * x) + (ii * kz1 * z));
229  }
230  }
231  }
232  u3d = real(u3dc);
233  v3d = real(v3dc);
234  w3d = real(w3dc);
235  p3d = real(p3dc);
236 
237  x.resize(xval.size());
238  z.resize(zval.size());
239  std::cout << "xval: \n"
240  << xval << '\n';
241  std::cout << "zval: \n"
242  << zval << '\n';
243  std::cout << "x.size(): " << xval.size() << '\n';
244  std::cout << "z.size(): " << zval.size() << '\n';
245  for (int i = 0; i < xval.size(); i++)
246  {
247  x[i] = xval[i];
248  }
249  for (int i = 0; i < zval.size(); i++)
250  {
251  z[i] = zval[i];
252  }
253 
254  outf.close();
255  string filename("data/Ex11vec_noscale0385");
256  std::cout << "z.size(): " << z.size() << '\n';
257 
258  // Export to a vtk file:
259  vtkExportCartesian3D(filename, x, y, z, u3d, v3d, w3d, p3d);
260 
261  return 0;
262 }
void sis_setup()
Definition: sis.hpp:954
BcMat will hold general Boundary conditions as LinopMats at evealuation points, as given by operator ...
Definition: sis.hpp:529
valarray< complex< double > > Vcd_t
Definition: Ex_11.cpp:16
Eigen::Matrix< T, Eigen::Dynamic, Eigen::Dynamic > eval
Definition: sis.hpp:8832
Linop This class creates a Linear operator to solve TPBVPs.
Definition: sis.hpp:2560
Definition: sis.hpp:260
complex< double > ii(0.0, 1.0)
void vtkExportCartesian3D(const std::string &flnm, const std::valarray< double > &x, const std::valarray< double > &y, const std::valarray< double > &z, const std::valarray< double > &u, const std::valarray< double > &v, const std::valarray< double > &w, const std::valarray< double > &p)
Exports all data of 3D velocity to a file. VTK file can be directly exported into paraview...
Definition: sis.hpp:11862
Eigen::Matrix< std::complex< T >, Eigen::Dynamic, 1 > eigenvalues
Definition: sis.hpp:3257
This class represents a block matrix operator. It is a matrix of operators.
Definition: sis.hpp:528
Definition: sis.hpp:461
void compute(const LinopMat< T > &A_, const BcMat< T > &Lbc_, const BcMat< T > &Rbc_, int num_vals)
Computes the singular values/functions of a Linear block matrix operator.
Definition: sis.hpp:9139
Eigen::Matrix< T, Eigen::Dynamic, 1 > coef
Stores the coefficients in the differential equation.
Definition: sis.hpp:2569
void setChebPts(std::valarray< T > &in)
This function sets points to evaluate a function so that a DCT will give represent the same function ...
Definition: sis.hpp:920
valarray< complex< T > > pow(valarray< complex< T > > base, T power)
Definition: sis.hpp:453
int main()
Definition: Ex_11.cpp:19
LinopMat< T > L
Definition: sis.hpp:8831
This class computes various SingularValues of a differential block matrix operator using using it&#39;s a...
Definition: sis.hpp:531
int N
Specifies number of Chebyshev polynomials, default N = 31.
Definition: sis.hpp:472
valarray< T > real(const valarray< complex< T > > &in)
real part of a complex valarray
Definition: sis.hpp:280
complex< double > Cd_t
Definition: Ex_11.cpp:15
std::valarray< SIS_TYPE > y(N+1)
void resize(int r_, int c_)
This clears all contents in the LinopMat, and then creates a fresh LinopMat of size r_ x c_...
Definition: sis.hpp:8214