Nektar++
ExtractCriticalLayer.cpp
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 // File ExtractCriticalLayer.cpp
4 //
5 // For more information, please see: http://www.nektar.info
6 //
7 // The MIT License
8 //
9 // Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
10 // Department of Aeronautics, Imperial College London (UK), and Scientific
11 // Computing and Imaging Institute, University of Utah (USA).
12 //
13 // Permission is hereby granted, free of charge, to any person obtaining a
14 // copy of this software and associated documentation files (the "Software"),
15 // to deal in the Software without restriction, including without limitation
16 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
17 // and/or sell copies of the Software, and to permit persons to whom the
18 // Software is furnished to do so, subject to the following conditions:
19 //
20 // The above copyright notice and this permission notice shall be included
21 // in all copies or substantial portions of the Software.
22 //
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29 // DEALINGS IN THE SOFTWARE.
30 //
31 // Description: Extract location of critical layer from streak file
32 //
33 ///////////////////////////////////////////////////////////////////////////////
34 
35 #include <cstdio>
36 #include <cstdlib>
37 
38 #include <MultiRegions/ExpList.h>
39 #include <MultiRegions/ExpList2D.h>
40 
41 
43  Array<OneD, NekDouble> &xc,
44  Array<OneD, NekDouble> &yc,
45  NekDouble cr,
46  NekDouble trans);
47 
48 int main(int argc, char *argv[])
49 {
50  int i,j;
51  NekDouble cr = 0;
52 
53  if(argc !=3)
54  {
55  fprintf(stderr,"Usage: ./ExtractCriticalLayer meshfile fieldfile \n");
56  exit(1);
57  }
58 
59  //------------------------------------------------------------
60  // Create Session file.
62  = LibUtilities::SessionReader::CreateInstance(argc, argv);
63  //-----------------------------------------------------------
64 
65  //-------------------------------------------------------------
66  // Read in mesh from input file
67  SpatialDomains::MeshGraphSharedPtr graphShPt = SpatialDomains::MeshGraph::Read(vSession);
68  //------------------------------------------------------------
69 
70  //-------------------------------------------------------------
71  // Define Streak Expansion
73 
74  streak = MemoryManager<MultiRegions::ExpList2D>
75  ::AllocateSharedPtr(vSession,graphShPt);
76 
77  //---------------------------------------------------------------
78 
79  //----------------------------------------------
80  // Import field file.
81  string fieldfile(argv[argc-1]);
82  vector<SpatialDomains::FieldDefinitionsSharedPtr> fielddef;
83  vector<vector<NekDouble> > fielddata;
84  graphShPt->Import(fieldfile,fielddef,fielddata);
85  //----------------------------------------------
86 
87  //----------------------------------------------
88  // Copy data from field file
89  string streak_field("w");
90  for(unsigned int i = 0; i < fielddata.size(); ++i)
91  {
92  streak->ExtractDataToCoeffs(fielddef [i],
93  fielddata[i],
94  streak_field);
95  }
96  //----------------------------------------------
97 
98  int npts;
99  vSession->LoadParameter("NumCriticalLayerPts",npts,30);
100  Array<OneD, NekDouble> x_c(npts);
101  Array<OneD, NekDouble> y_c(npts);
102  NekDouble xc, yc;
103 
104  NekDouble trans;
105  vSession->LoadParameter("WidthOfLayers",trans,0.1);
106 
107  Computestreakpositions(streak,x_c, y_c,cr,trans);
108 
109  cout << "# x_c y_c" << endl;
110  for(i = 0; i < npts; ++i)
111  {
112  fprintf(stdout,"%12.10lf %12.10lf \n",x_c[i],y_c[i]);
113  //cout << x_c[i] << " " << y_c[i] << endl;
114  }
115 
116 }
117 
119  Array<OneD, NekDouble> &xc,
120  Array<OneD, NekDouble> &yc,
121  NekDouble cr,
122  NekDouble trans)
123 {
124  int i;
125  int npts = xc.num_elements();
126 
127  int nq = streak->GetTotPoints();
128  Array<OneD, NekDouble> derstreak(nq);
129  Array<OneD, NekDouble> x(nq);
130  Array<OneD, NekDouble> y(nq);
131  streak->GetCoords(x,y);
132 
133  streak->BwdTrans(streak->GetCoeffs(),streak->UpdatePhys());
134  streak->PhysDeriv(MultiRegions::eY, streak->GetPhys(), derstreak);
135 
136  // set intiial xc to be equispaced over mesh and yc to be zero
137  NekDouble x_max = Vmath::Vmax(nq,x,1);
138  NekDouble x_min = Vmath::Vmin(nq,x,1);
139 
140  for(i = 0; i < npts; ++i)
141  {
142  xc[i] = x_min + (x_max - x_min)*i/((NekDouble)(npts-1));
143  yc[i] = 0.0;
144  }
145 
146 
147  int elmtid, offset,cnt;
148  NekDouble U,dU;
149  NekDouble F;
150  NekDouble ConvTol = 1e-9;
151  NekDouble CoordTol = 1e-5;
152  int maxiter = 100;
153  Array<OneD, NekDouble> coord(2);
154  NekDouble ytmp;
155  // Do Newton iteration on y direction
156  cerr << "[";
157  for(int e=0; e<npts; e++)
158  {
159  coord[0] = xc[e];
160  coord[1] = yc[e];
161 cout<<e<<endl;
162  if(!(e%10))
163  {
164  cerr << ".";
165  }
166 
167  F = 1000;
168  cnt = 0;
169  int its=0;
170  int attempt=0;
171 //cout<<"start guess: x="<<xc[e]<<" y="<<yc[e]<<endl;
172  while( abs(F)> 0.000000001)
173  {
174  ytmp = coord[1];
175  elmtid = streak->GetExpIndex(coord,0.00001);
176  offset = streak->GetPhys_Offset(elmtid);
177  U = streak->GetExp(elmtid)->PhysEvaluate(coord, streak->GetPhys() + offset);
178  dU = streak->GetExp(elmtid)->PhysEvaluate(coord, derstreak + offset);
179  coord[1] = coord[1] - (U-cr)/dU;
180  F = U-cr;
181  ASSERTL0( coord[0]==xc[e], " x coordinate must remain the same");
182  //stvalues[e] = streak->GetExp(elmtid)->PhysEvaluate(coord, streak->GetPhys() +offset );
183 //cout<<"elmtid="<<elmtid<<" x="<<coord[0]<<" y="<<coord[1]<<" stvalue="<<U<<" dU="<<dU<<endl;
184  if(abs(coord[1])>1 )
185  {
186  coord[1] = ytmp +0.01;
187  elmtid = streak->GetExpIndex(coord,0.00001);
188  offset = streak->GetPhys_Offset(elmtid);
189  NekDouble Utmp = streak->GetExp(elmtid)->PhysEvaluate(coord, streak->GetPhys() + offset);
190  NekDouble dUtmp = streak->GetExp(elmtid)->PhysEvaluate(coord, derstreak + offset);
191  coord[1] = coord[1] - (Utmp-cr)/dUtmp;
192 
193  if( (abs(Utmp-cr)>abs(F))||(abs(coord[1])>1) )
194  {
195  coord[1] = ytmp -0.01;
196  }
197 
198  attempt++;
199  }
200  else
201  {
202  ASSERTL0(abs(coord[1])<= 1, " y value out of bound +/-1");
203  }
204 
205  its++;
206  if(its>1000 && abs(F)< 0.0001)
207  {
208  cout<<"warning streak position obtained with precision:"<<F<<endl;
209  break;
210  }
211  else if(its>1000)
212  {
213  ASSERTL0(false, "no convergence after 1000 iterations");
214  }
215  }
216 
217  yc[e] = coord[1];
218  }
219  cerr << "]" << endl;
220 
221  // output to interface file
222  FILE *fp = fopen("interfacedat.geo","w");
223 
224  NekDouble y_max = Vmath::Vmax(nq,y,1);
225  NekDouble y_min = Vmath::Vmin(nq,y,1);
226 
227  cnt = 1;
228  fprintf(fp,"Point(%d)={%12.10lf,%12.10lf,0,1.0}; \n",
229  cnt++,x_min,y_min);
230  fprintf(fp,"Point(%d)={%12.10lf,%12.10lf,0,1.0}; \n",
231  cnt++,x_max,y_min);
232  fprintf(fp,"Point(%d)={%12.10lf,%12.10lf,0,1.0}; \n",
233  cnt++,x_max,y_max);
234  fprintf(fp,"Point(%d)={%12.10lf,%12.10lf,0,1.0}; \n",
235  cnt++,x_min,y_max);
236 
237  for(i = 0; i < npts; ++i)
238  {
239  fprintf(fp,"Point(%d)={%12.10lf,%12.10lf,0,1.0}; \n",
240  cnt++,xc[i],yc[i]);
241  }
242 
243  fclose(fp);
244 
245  // output to interface_up file as bend of vertical shift and 45 degrees shift
246  fp = fopen("interfacedat_up.geo","w");
247 
248 
249  NekDouble nx,ny,norm;
250 
251  fprintf(fp,"Point(%d)={%12.10lf,%12.10lf,0,1.0}; \n",cnt++,xc[0],yc[0]+trans);
252 
253  for(i = 1; i < npts-1; ++i)
254  {
255  norm = sqrt((xc[i+1]-xc[i-1])*(xc[i+1]-xc[i-1])+(yc[i+1]-yc[i-1])*(yc[i+1]-yc[i-1]));
256  nx = (yc[i-1]-yc[i+1])/norm;
257  ny = (xc[i+1]-xc[i-1])/norm;
258 
259  fprintf(fp,"Point(%d)={%12.10lf,%12.10lf,0,1.0}; \n",
260  cnt++,xc[i]+nx*trans,yc[i]+ny*trans);
261  }
262 
263  fprintf(fp,"Point(%d)={%12.10lf,%12.10lf,0,1.0}; \n",cnt++,xc[npts-1],yc[npts-1]+trans);
264 
265 
266  // output to interface_up file as bend of vertical shift and 45 degrees shift
267  fp = fopen("interfacedat_dn.geo","w");
268 
269  trans = -trans;
270 
271  fprintf(fp,"Point(%d)={%12.10lf,%12.10lf,0,1.0}; \n",cnt++,xc[0],yc[0]+trans);
272 
273  for(i = 1; i < npts-1; ++i)
274  {
275  norm = sqrt((xc[i+1]-xc[i-1])*(xc[i+1]-xc[i-1])+(yc[i+1]-yc[i-1])*(yc[i+1]-yc[i-1]));
276  nx = (yc[i-1]-yc[i+1])/norm;
277  ny = (xc[i+1]-xc[i-1])/norm;
278 
279  fprintf(fp,"Point(%d)={%12.10lf,%12.10lf,0,1.0}; \n",
280  cnt++,xc[i]+nx*trans,yc[i]+ny*trans);
281  }
282 
283  fprintf(fp,"Point(%d)={%12.10lf,%12.10lf,0,1.0}; \n",cnt++,xc[npts-1],yc[npts-1]+trans);
284 
285 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:216
std::shared_ptr< MeshGraph > MeshGraphSharedPtr
Definition: MeshGraph.h:163
std::shared_ptr< ExpList > ExpListSharedPtr
Shared pointer to an ExpList object.
T Vmax(int n, const T *x, const int incx)
Return the maximum element in x – called vmax to avoid conflict with max.
Definition: Vmath.cpp:782
T Vmin(int n, const T *x, const int incx)
Return the minimum element in x - called vmin to avoid conflict with min.
Definition: Vmath.cpp:874
void Computestreakpositions(MultiRegions::ExpListSharedPtr &streak, Array< OneD, NekDouble > &xc, Array< OneD, NekDouble > &yc, NekDouble cr, NekDouble trans)
double NekDouble
int main(int argc, char *argv[])
std::shared_ptr< SessionReader > SessionReaderSharedPtr