LILAC
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
rhs_SQGLE.cpp
Go to the documentation of this file.
1 /*
2 Copyright (c) 2014, Sam Schetterer, Nathan Kutz, University of Washington
3 Authors: Sam Schetterer
4 All rights reserved.
5 
6 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
7 
8 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
9 
10 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
11 
12 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
13 
14 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
15 
16 */
17 #include "rhs_SQGLE.h"
18 #include "engine/input.h"
19 #include "utils/inline_trig.h"
20 #include "utils/comp_funcs.hpp"
21 #include "controller/controller.h"
22 #include "types/type_register.hpp"
23 template class type_register<rhs_SQGLE>;
28 
29 inline comp _clog(comp inval){
30  return 0.5*log(_sqabs(inval)) + Id*atan2(_imag(inval), _real(inval));
31 }
32 
33 //This is still a hacky class, proably won't see much use anywhere
34 //since it is slow. As I result, clenaign it up isn't a big priority
35 
36 
37 int rhs_SQGLE::dxdt(ptr_passer x, ptr_passer _dx, double t){
38  comp* restr dx = _dx;
39  uf1= x;
40  //take the inverse fourier transform
42  //Inform compiler of alignment, if supported
43  ALIGNED(uf1);
44  ALIGNED(u1);
45  ALIGNED(sq1);
46  ALIGNED(comp_in);
47  ALIGNED(comp_out);
48  ALIGNED(k);
49  ALIGNED(ksq);
50 
51  for(size_t i = 0; i < NUM_TIME_STEPS; i++){
52  sq1[i] = _sqabs(u1[i]);
53  }
54  comp expr1 = (2.0*g0/(1.0+trap(sq1, NUM_TIME_STEPS)*dt/e0));
55  //calculate the ffts, helper arrays for the rhs
56  double help_mul=B*sin(2*a1-ap);
57  comp ce1 = std::exp(Id*K*(-1.0));
58  comp ce2 = std::exp(Id*K);
59  ce1=ce1*(cos(2*(a2-a3)-ap)+Id*cos(2*a3-ap));
60  ce2=ce2*(sin(2*(a2-a3)-ap)+Id*sin(2*a3-ap));
61  float trigvals1[4] __attribute__((aligned(16)));
62  float trigvals2[4] __attribute__((aligned(16)));
63  v4sf _trigout1 __attribute__((aligned(16)));
64  v4sf _trigout2 __attribute__((aligned(16)));
65  float* restr trigout1, * restr trigout2;
66  //vector inlines for the win
67 
68  for(size_t i = 0; i < NUM_TIME_STEPS;) {
69  //try vector inlines on the first one
70 
71  trigvals1[0] = 2*a1-ap-sq1[i]*help_mul;
72  trigvals1[1] = 2*a1-ap-sq1[i+1]*help_mul;
73  trigvals1[2] = 2*a1-ap-sq1[i+2]*help_mul;
74  trigvals1[3] = 2*a1-ap-sq1[i+3]*help_mul;
75  trigvals2[0] = ap-help_mul*sq1[i];
76  trigvals2[1] = ap-help_mul*sq1[i+1];
77  trigvals2[2] = ap-help_mul*sq1[i+2];
78  trigvals2[3] = ap-help_mul*sq1[i+3];
79 
80  _trigout1=cos_ps(*(v4sf*)&trigvals1);
81  _trigout2=cos_ps(*(v4sf*)&trigvals2);
82  trigout1 = (float*)&_trigout1;
83  trigout2 = (float*)&_trigout2;
84  comp_in[i] = ce1*(Id*(double)trigout1[0] - (double)trigout2[0]);
85  comp_in[i+1] = ce1*(Id*(double)trigout1[1] - (double)trigout2[1]);
86  comp_in[i+2] = ce1*(Id*(double)trigout1[2] - (double)trigout2[2]);
87  comp_in[i+3] = ce1*(Id*(double)trigout1[3] - (double)trigout2[3]);
88 
89  _trigout1=sin_ps(*(v4sf*)&trigvals1);
90  _trigout2=sin_ps(*(v4sf*)&trigvals2);
91 
92 
93  comp_in[i] += ce2*(Id*(double)trigout2[0] - (double)trigout1[0]);
94  comp_in[i+1] += ce2*(Id*(double)trigout2[1] - (double)trigout1[1]);
95  comp_in[i+2] += ce2*(Id*(double)trigout2[2] - (double)trigout1[2]);
96  comp_in[i+3] += ce2*(Id*(double)trigout2[3] - (double)trigout1[3]);
97 
98 
99  i+=4;
100  }
101 
102 
103  //can just reuse trigout here
104  for(size_t i = 0; i < NUM_TIME_STEPS;){
105  trigvals1[0] = _sqabs(comp_in[i]);
106  trigvals1[1] = _sqabs(comp_in[i+1]);
107  trigvals1[2] = _sqabs(comp_in[i+2]);
108  trigvals1[3] = _sqabs(comp_in[i+3]);
109  _trigout1 = log_ps(*(v4sf*)&trigvals1);
110  comp_in[i] = 0.5*trigout1[0] + atan2(_imag(comp_in[i]), _real(comp_in_r[i]))*Id + log(0.5);
111  comp_in[i+1] = 0.5*trigout1[1] + atan2(_imag(comp_in[i+1]), _real(comp_in[i+1]))*Id + log(0.5);
112  comp_in[i+2] = 0.5*trigout1[2] + atan2(_imag(comp_in[i+2]), _real(comp_in[i+2]))*Id + log(0.5);
113  comp_in[i+3] = 0.5*trigout1[3] + atan2(_imag(comp_in[i+3]), _real(comp_in[i+3]))*Id + log(0.5);
114  i+= 4;
115  }
116 
117  for(size_t i = 0; i < NUM_TIME_STEPS; i++){
118  //fft helper
119  comp_in[i] = u1[i]*Id*(expr1 + comp_in[i] + Id*sq1[i]-Gamma);
120  }
121  //fourier transform forwards nonlinear equations
122  fft(comp_in, comp_out, NUM_TIME_STEPS);
123 
124  for(size_t i = 0; i < NUM_TIME_STEPS; i++){
125  dx[i] = -1.0*Id*((D/2 - Id * expr1*tau)*ksq[i]*uf1[i] + comp_out[i]);
126  }
127  return 0;
128 }
129 
130 std::vector<std::string> rhs_SQGLE::dependencies() const{
131  std::string deps[] = {"g0", "e0", "t_int", "controller"};
132  return make_append(deps, rhs::dependencies());
133 }
134 
136  return "SQGLE";
137 }
142  rhs::postprocess(dat);
144  dat.retrieve(LENGTH_T, "t_int", this);
145  if(LENGTH_T <= 0){
146  std::string errmess = "t_int is invalid, must be >= 0";
147  err(errmess, "rhs_SQGLE::postprocess", "rhs/rhs_SQGLE.cpp",
148  dat["t_int"], FATAL_ERROR);
149  }
151  dat.retrieve(g0, "g0", this);
152  dat.retrieve(e0, "e0", this);
153  memp.create(dimension, &u1, &u2, &comp_in, &comp_out, &sq1, &ksq, &k);
154  //create k values
155 
156  double mulval=(2.0*PI/LENGTH_T)*(NUM_TIME_STEPS/2.0);
157  for(size_t i=0; i<NUM_TIME_STEPS/2; i++){
158  k[i] = mulval * (2.0*i/(1.0*NUM_TIME_STEPS));
159  ksq[i] = k[i]*k[i];
160  }
161  for(size_t i=NUM_TIME_STEPS/2; i<NUM_TIME_STEPS; i++){
162  k[i] = mulval * 2.0*(i-(int)NUM_TIME_STEPS)/(NUM_TIME_STEPS*1.0);
163  ksq[i] = k[i]*k[i];
164  }
165  controller* cont;
166  dat.retrieve(cont, "controller", this);
167  a1=a2=a3=ap=0;
168  std::shared_ptr<variable> vv = std::make_shared<variable>();
169  vv->holder=holder;
170  vv->setname("a1");
171  vv->set(a1);
172  vv->parse("0.1");
173  dat.insert_item(vv);
174  cont->addvar(vv);
175  dat.retrieve(a1, vv->name(), this);
176 
177  //a2
178  vv = std::make_shared<variable>();
179  vv->holder=holder;
180  vv->setname("a2");
181  vv->set(a2);
182  vv->parse("0.1");
183  dat.insert_item(vv);
184  cont->addvar(vv);
185  dat.retrieve(a2, vv->name(), this);
186  //a3
187  vv = std::make_shared<variable>();
188  vv->holder=holder;
189  vv->setname("a3");
190  vv->set(a3);
191  vv->parse("0.1");
192  dat.insert_item(vv);
193  cont->addvar(vv);
194  dat.retrieve(a3, vv->name(), this);
195  //ap
196  vv = std::make_shared<variable>();
197  vv->holder=holder;
198  vv->setname("ap");
199  vv->set(ap);
200  vv->parse("0.1");
201  dat.insert_item(vv);
202  cont->addvar(vv);
203  dat.retrieve(ap, vv->name(), this);
204  //temporary solution, add variables directly to controller
205 }