Nektar++
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
FilterAeroForces.cpp
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 // File FilterAeroForces.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 // License for the specific language governing rights and limitations under
14 // Permission is hereby granted, free of charge, to any person obtaining a
15 // copy of this software and associated documentation files (the "Software"),
16 // to deal in the Software without restriction, including without limitation
17 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
18 // and/or sell copies of the Software, and to permit persons to whom the
19 // Software is furnished to do so, subject to the following conditions:
20 //
21 // The above copyright notice and this permission notice shall be included
22 // in all copies or substantial portions of the Software.
23 //
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
25 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
27 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
29 // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
30 // DEALINGS IN THE SOFTWARE.
31 //
32 // Description: Output values of aerodynamic forces during time-stepping.
33 //
34 ///////////////////////////////////////////////////////////////////////////////
35 
37 #include <iomanip>
38 #include <boost/algorithm/string.hpp>
42 #include <MultiRegions/ExpList2D.h>
43 #include <MultiRegions/ExpList3D.h>
46 
47 using namespace std;
48 
49 namespace Nektar
50 {
51 namespace SolverUtils
52 {
53 std::string FilterAeroForces::className =
55  "AeroForces", FilterAeroForces::create);
56 
57 /**
58  *
59  */
60 FilterAeroForces::FilterAeroForces(
62  const ParamMap &pParams) :
63  Filter(pSession)
64 {
65  ParamMap::const_iterator it;
66 
67  // OutputFile
68  it = pParams.find("OutputFile");
69  if (it == pParams.end())
70  {
71  m_outputFile = m_session->GetSessionName();
72  }
73  else
74  {
75  ASSERTL0(it->second.length() > 0, "Missing parameter 'OutputFile'.");
76  m_outputFile = it->second;
77  }
78  if (!(m_outputFile.length() >= 4
79  && m_outputFile.substr(m_outputFile.length() - 4) == ".fce"))
80  {
81  m_outputFile += ".fce";
82  }
83 
84  // OutputFrequency
85  it = pParams.find("OutputFrequency");
86  if (it == pParams.end())
87  {
89  }
90  else
91  {
92  LibUtilities::Equation equ(m_session, it->second);
93  m_outputFrequency = floor(equ.Evaluate());
94  }
95 
96  // Time after which we need to calculate the forces
97  it = pParams.find("StartTime");
98  if (it == pParams.end())
99  {
100  m_startTime = 0;
101  }
102  else
103  {
104  LibUtilities::Equation equ(m_session, it->second);
105  m_startTime = equ.Evaluate();
106  }
107 
108  // For 3DH1D, OutputAllPlanes or just average forces?
109  m_session->MatchSolverInfo("Homogeneous", "1D",
110  m_isHomogeneous1D, false);
112  {
113  it = pParams.find("OutputAllPlanes");
114  if (it == pParams.end())
115  {
116  m_outputAllPlanes = false;
117  }
118  else
119  {
120  std::string sOption =
121  it->second.c_str();
122  m_outputAllPlanes = ( boost::iequals(sOption,"true")) ||
123  ( boost::iequals(sOption,"yes"));
124  }
125  }
126  else
127  {
128  m_outputAllPlanes = false;
129  }
130 
131  // Boundary (to calculate forces on)
132  it = pParams.find("Boundary");
133  ASSERTL0(it != pParams.end(), "Missing parameter 'Boundary");
134  ASSERTL0(it->second.length() > 0, "Empty parameter 'Boundary'.");
135  m_BoundaryString = it->second;
136 
137  //
138  // Directions (to project forces)
139  //
140 
141  // Allocate m_directions
143  //Initialise directions to default values (ex, ey, ez)
144  for (int i = 0; i < 3; ++i)
145  {
147  m_directions[i][i] = 1.0;
148  }
149  std::stringstream directionStream;
150  std::string directionString;
151  //Override with input from xml file (if defined)
152  for (int i = 0; i < 3; ++i)
153  {
154  std::stringstream tmp;
155  tmp << i+1;
156  std::string dir = "Direction" + tmp.str();
157  it = pParams.find(dir);
158  if ( it != pParams.end() )
159  {
160  ASSERTL0(!(it->second.empty()),
161  "Missing parameter '"+dir+"'.");
162  directionStream.str(it->second);
163  // Guarantee the stream is in its start position
164  // before extracting
165  directionStream.clear();
166  // normalisation factor
167  NekDouble norm = 0.0;
168  for (int j = 0; j < 3; j++)
169  {
170  directionStream >> directionString;
171  if (!directionString.empty())
172  {
173  LibUtilities::Equation equ(m_session, directionString);
174  m_directions[i][j] = equ.Evaluate();
175  norm += m_directions[i][j]*m_directions[i][j];
176  }
177  }
178  // Normalise direction
179  for( int j = 0; j < 3; j++)
180  {
181  m_directions[i][j] /= sqrt(norm);
182  }
183  }
184  }
185 
186 
187 }
188 
189 
190 /**
191  *
192  */
194 {
195 
196 }
197 
198 /**
199  *
200  */
203  const NekDouble &time)
204 {
205  // Load mapping
207 
208  // Parse the boundary regions into a list.
209  std::string::size_type FirstInd =
210  m_BoundaryString.find_first_of('[') + 1;
211  std::string::size_type LastInd =
212  m_BoundaryString.find_last_of(']') - 1;
213 
214  ASSERTL0(FirstInd <= LastInd,
215  (std::string("Error reading boundary region definition:") +
216  m_BoundaryString).c_str());
217 
218  std::string IndString =
219  m_BoundaryString.substr(FirstInd, LastInd - FirstInd + 1);
220  bool parseGood = ParseUtils::GenerateSeqVector(IndString.c_str(),
222  ASSERTL0(parseGood && !m_boundaryRegionsIdList.empty(),
223  (std::string("Unable to read boundary regions index "
224  "range for FilterAeroForces: ") + IndString).c_str());
225 
226  // determine what boundary regions need to be considered
227  int cnt;
228  unsigned int numBoundaryRegions =
229  pFields[0]->GetBndConditions().num_elements();
231  numBoundaryRegions, 0);
232 
234  pFields[0]->GetGraph());
236  bcs.GetBoundaryRegions();
237  SpatialDomains::BoundaryRegionCollection::const_iterator it;
238 
239  for (cnt = 0, it = bregions.begin(); it != bregions.end();
240  ++it, cnt++)
241  {
242  if ( std::find(m_boundaryRegionsIdList.begin(),
243  m_boundaryRegionsIdList.end(), it->first) !=
245  {
246  m_boundaryRegionIsInList[cnt] = 1;
247  }
248  }
249 
250  // Create map for element and edge/face of each boundary expansion
252  {
253  pFields[0]->GetPlane(0)->GetBoundaryToElmtMap
255  }
256  else
257  {
258  pFields[0]->GetBoundaryToElmtMap(m_BCtoElmtID,m_BCtoTraceID);
259  }
260 
261  // Define number of planes to calculate the forces
262  // in the Homogeneous direction ( if m_outputAllPlanes is false,
263  // consider only first plane in wave space)
264  // If flow has no Homogeneous direction, use 1 to make code general
265  if(m_isHomogeneous1D &&(m_outputAllPlanes || m_mapping->IsDefined()))
266  {
267  m_nPlanes = pFields[0]->GetHomogeneousBasis()->
268  GetZ().num_elements();
269  }
270  else
271  {
272  m_nPlanes = 1;
273  }
274 
275  // Create map for Planes ID for Homogeneous direction
276  // If flow has no Homogeneous direction, create trivial map
277  int j;
280  {
281  Array<OneD, const unsigned int> IDs = pFields[0]->GetZIDs();
282  //Loop through all planes
283  for(cnt = 0; cnt < m_nPlanes; cnt++)
284  {
285  for(j = 0; j < IDs.num_elements(); ++j)
286  {
287  //Look for current plane ID in this process
288  if(IDs[j] == cnt)
289  {
290  break;
291  }
292  }
293  // Assign ID to planesID
294  // If plane is not found in this process, leave it with -1
295  if(j != IDs.num_elements())
296  {
297  m_planesID[cnt] = j;
298  }
299  }
300  }
301  else
302  {
303  m_planesID[0] = 0;
304  }
305 
306  LibUtilities::CommSharedPtr vComm = pFields[0]->GetComm();
307 
308  // Write header
309  int expdim = pFields[0]->GetGraph()->GetMeshDimension();
310  if (vComm->GetRank() == 0)
311  {
312  // Open output stream
313  bool adaptive;
314  m_session->MatchSolverInfo("Driver", "Adaptive",
315  adaptive, false);
316  if (adaptive)
317  {
318  m_outputStream.open(m_outputFile.c_str(), ofstream::app);
319  }
320  else
321  {
322  m_outputStream.open(m_outputFile.c_str());
323  }
324  m_outputStream << "# Forces acting on bodies" << endl;
325  for( int i = 0; i < expdim; i++ )
326  {
327  m_outputStream << "#" << " Direction" << i+1 << " = (";
328  m_outputStream.width(8);
329  m_outputStream << setprecision(4) << m_directions[i][0];
330  m_outputStream.width(8);
331  m_outputStream << setprecision(4) << m_directions[i][1];
332  m_outputStream.width(8);
333  m_outputStream << setprecision(4) << m_directions[i][2];
334  m_outputStream << ")" << endl;
335  }
336  m_outputStream << "# Boundary regions: " << IndString.c_str() << endl;
337  m_outputStream << "#";
338  m_outputStream.width(7);
339  m_outputStream << "Time";
340  for( int i = 1; i <= expdim; i++ )
341  {
342  m_outputStream.width(8);
343  m_outputStream << "F" << i << "-press";
344  m_outputStream.width(9);
345  m_outputStream << "F" << i << "-visc";
346  m_outputStream.width(8);
347  m_outputStream << "F" << i << "-total";
348  }
349  if( m_outputAllPlanes )
350  {
351  m_outputStream.width(10);
352  m_outputStream << "Plane";
353  }
354  if (m_session->DefinesSolverInfo("HomoStrip"))
355  {
357  "Output forces on all planes not compatible with HomoStrips");
358  m_outputStream.width(10);
359  m_outputStream << "Strip";
360  }
361 
362  m_outputStream << endl;
363  }
364 
365  m_lastTime = -1;
366  m_index = 0;
367  v_Update(pFields, time);
368 }
369 
370 /**
371  *
372  */
375  const NekDouble &time)
376 {
377  // Only output every m_outputFrequency.
378  if ((m_index++) % m_outputFrequency || (time < m_startTime))
379  {
380  return;
381  }
382  // Calculate the forces
383  CalculateForces(pFields, time);
384 
385  // Calculate forces including all planes
386  int expdim = pFields[0]->GetGraph()->GetMeshDimension();
387  Array<OneD, NekDouble> Fp(expdim,0.0);
388  Array<OneD, NekDouble> Fv(expdim,0.0);
389  Array<OneD, NekDouble> Ft(expdim,0.0);
390  for( int i = 0; i < expdim; i++)
391  {
392  Fp[i] = Vmath::Vsum(m_nPlanes, m_Fpplane[i], 1) / m_nPlanes;
393  Fv[i] = Vmath::Vsum(m_nPlanes, m_Fvplane[i], 1) / m_nPlanes;
394  Ft[i] = Fp[i] + Fv[i];
395  }
396 
397  // Communicators to exchange results
398  LibUtilities::CommSharedPtr vComm = pFields[0]->GetComm();
399 
400  //Write Results
401  if (vComm->GetRank() == 0)
402  {
403  // Write result in each plane
404  if( m_outputAllPlanes)
405  {
406  for( int plane = 0; plane < m_nPlanes; plane++)
407  {
408  // Write time
409  m_outputStream.width(8);
410  m_outputStream << setprecision(6) << time;
411  // Write forces
412  for( int i = 0; i < expdim; i++ )
413  {
414  m_outputStream.width(15);
415  m_outputStream << setprecision(8)
416  << m_Fpplane[i][plane];
417  m_outputStream.width(15);
418  m_outputStream << setprecision(8)
419  << m_Fvplane[i][plane];
420  m_outputStream.width(15);
421  m_outputStream << setprecision(8)
422  << m_Ftplane[i][plane];
423  }
424  m_outputStream.width(10);
425  m_outputStream << plane;
426  m_outputStream << endl;
427  }
428  }
429  // Output average (or total) force
430  m_outputStream.width(8);
431  m_outputStream << setprecision(6) << time;
432  for( int i = 0; i < expdim; i++)
433  {
434  m_outputStream.width(15);
435  m_outputStream << setprecision(8) << Fp[i];
436  m_outputStream.width(15);
437  m_outputStream << setprecision(8) << Fv[i];
438  m_outputStream.width(15);
439  m_outputStream << setprecision(8) << Ft[i];
440  }
441  if( m_outputAllPlanes)
442  {
443  m_outputStream.width(10);
444  m_outputStream << "average";
445  }
446 
447  if( m_session->DefinesSolverInfo("HomoStrip"))
448  {
449  // The result we already wrote is for strip 0
450  m_outputStream.width(10);
451  m_outputStream << 0;
452  m_outputStream << endl;
453 
454  // Now get result from other strips
455  int nstrips;
456  m_session->LoadParameter("Strip_Z", nstrips);
457  for(int i = 1; i<nstrips; i++)
458  {
459  vComm->GetColumnComm()->Recv(i, Fp);
460  vComm->GetColumnComm()->Recv(i, Fv);
461  vComm->GetColumnComm()->Recv(i, Ft);
462 
463  m_outputStream.width(8);
464  m_outputStream << setprecision(6) << time;
465  for( int j = 0; j < expdim; j++)
466  {
467  m_outputStream.width(15);
468  m_outputStream << setprecision(8) << Fp[j];
469  m_outputStream.width(15);
470  m_outputStream << setprecision(8) << Fv[j];
471  m_outputStream.width(15);
472  m_outputStream << setprecision(8) << Ft[j];
473  }
474  m_outputStream.width(10);
475  m_outputStream << i;
476  m_outputStream << endl;
477  }
478  }
479  else
480  {
481  m_outputStream << endl;
482  }
483  }
484  else
485  {
486  // In the homostrips case, we need to send result to root
487  if (m_session->DefinesSolverInfo("HomoStrip") &&
488  (vComm->GetRowComm()->GetRank() == 0) )
489  {
490  vComm->GetColumnComm()->Send(0, Fp);
491  vComm->GetColumnComm()->Send(0, Fv);
492  vComm->GetColumnComm()->Send(0, Ft);
493  }
494  }
495 
496 }
497 
498 
499 /**
500  *
501  */
504  const NekDouble &time)
505 {
506  if (pFields[0]->GetComm()->GetRank() == 0)
507  {
508  m_outputStream.close();
509  }
510 }
511 
512 
513 /**
514  *
515  */
517 {
518  return true;
519 }
520 
521 /**
522  * This function outputs the force on all planes of the current
523  * process, in the format required by ForcingMovingBody
524  */
527  Array<OneD, NekDouble> &Aeroforces,
528  const NekDouble &time)
529 {
530  // Calculate forces if the result we have is not up-to-date
531  if(time > m_lastTime)
532  {
533  CalculateForces(pFields, time);
534  }
535  // Get information to write result
536  Array<OneD, unsigned int> ZIDs = pFields[0]->GetZIDs();
537  int local_planes = ZIDs.num_elements();
538  int expdim = pFields[0]->GetGraph()->GetMeshDimension();
539 
540  // Copy results to Aeroforces
541  if (m_outputAllPlanes)
542  {
543  for(int plane = 0 ; plane < local_planes; plane++)
544  {
545  for(int dir =0; dir < expdim; dir++)
546  {
547  Aeroforces[plane + dir*local_planes] =
548  m_Ftplane[dir][ZIDs[plane]];
549  }
550  }
551  }
552  else
553  {
554  for(int plane = 0 ; plane < local_planes; plane++)
555  {
556  for(int dir =0; dir < expdim; dir++)
557  {
558  Aeroforces[plane + dir*local_planes] =
559  m_Ftplane[dir][0];
560  }
561  }
562  }
563 }
564 
565 /**
566  * This function calculates the forces
567  */
570  const NekDouble &time)
571 {
572  // Store time so we can check if result is up-to-date
573  m_lastTime = time;
574 
575  // If a mapping is defined, call specific function
576  // Note: CalculateForcesMapping should work without a mapping,
577  // but since it is not very efficient the way it is now,
578  // it is only used when actually required
579  if (m_mapping->IsDefined())
580  {
581  CalculateForcesMapping( pFields, time);
582  return;
583  }
584 
585  int i, j, k, n, cnt, elmtid, nq, offset, boundary, plane;
586  // Get number of quadrature points and dimensions
587  int physTot = pFields[0]->GetNpoints();
588  int expdim = pFields[0]->GetGraph()->GetMeshDimension();
589  int nVel = expdim;
590  if( m_isHomogeneous1D )
591  {
592  nVel = nVel + 1;
593  }
594 
596 
597  // Fields used to calculate forces (a single plane for 3DH1D)
599  fields( pFields.num_elements() );
600 
601  // Arrays of variables in the element
602  Array<OneD, Array<OneD, NekDouble> > velocity(expdim);
603  Array<OneD, NekDouble> P(physTot);
604 
605  // Velocity gradient
606  Array<OneD, Array<OneD, NekDouble> > grad( expdim*expdim);
607 
608  // Values at the boundary
610  Array<OneD, Array<OneD, NekDouble> > gradb( expdim*expdim);
611 
612  // Communicators to exchange results
613  LibUtilities::CommSharedPtr vComm = pFields[0]->GetComm();
614  LibUtilities::CommSharedPtr rowComm = vComm->GetRowComm();
615  LibUtilities::CommSharedPtr colComm =
616  m_session->DefinesSolverInfo("HomoStrip") ?
617  vComm->GetColumnComm()->GetColumnComm():
618  vComm->GetColumnComm();
619 
620  // Arrays with forces in each plane
624  for( i = 0; i < expdim; i++)
625  {
627  m_Fvplane[i] = Array<OneD, NekDouble>(m_nPlanes,0.0);
628  m_Ftplane[i] = Array<OneD, NekDouble>(m_nPlanes,0.0);
629  }
630 
631  // Forces per element length in a boundary
632  Array<OneD, Array<OneD, NekDouble> > fp( expdim );
633  Array<OneD, Array<OneD, NekDouble> > fv( expdim );
634 
635  // Get viscosity
636  NekDouble rho = (m_session->DefinesParameter("rho"))
637  ? (m_session->GetParameter("rho"))
638  : 1;
639  NekDouble mu = rho*m_session->GetParameter("Kinvis");
640 
641  // Perform BwdTrans: when we only want the mean force in a 3DH1D
642  // we work in wavespace, otherwise we use physical space
643  for(i = 0; i < pFields.num_elements(); ++i)
644  {
646  {
647  pFields[i]->SetWaveSpace(false);
648  }
649  pFields[i]->BwdTrans(pFields[i]->GetCoeffs(),
650  pFields[i]->UpdatePhys());
651  pFields[i]->SetPhysState(true);
652  }
653 
654  // Define boundary expansions
658  {
659  BndConds = pFields[0]->GetPlane(0)->GetBndConditions();
660  BndExp = pFields[0]->GetPlane(0)->GetBndCondExpansions();
661  }
662  else
663  {
664  BndConds = pFields[0]->GetBndConditions();
665  BndExp = pFields[0]->GetBndCondExpansions();
666  }
667 
668  // For Homogeneous, calculate force on each 2D plane
669  // Otherwise, m_nPlanes = 1, and loop only runs once
670  for(plane = 0; plane < m_nPlanes; plane++ )
671  {
672  // Check if plane is in this proc
673  if( m_planesID[plane] != -1 )
674  {
675  // For Homogeneous, consider the 2D expansion
676  // on the current plane
678  {
679  for(n = 0; n < pFields.num_elements(); n++)
680  {
681  fields[n] = pFields[n]->GetPlane(m_planesID[plane]);
682  }
683  }
684  else
685  {
686  for(n = 0; n < pFields.num_elements(); n++)
687  {
688  fields[n] = pFields[n];
689  }
690  }
691 
692  //Loop all the Boundary Regions
693  for( cnt = n = 0; n < BndConds.num_elements(); n++)
694  {
695  if(m_boundaryRegionIsInList[n] == 1)
696  {
697  for (i=0; i < BndExp[n]->GetExpSize(); ++i,cnt++)
698  {
699  elmtid = m_BCtoElmtID[cnt];
700  elmt = fields[0]->GetExp(elmtid);
701  nq = elmt->GetTotPoints();
702  offset = fields[0]->GetPhys_Offset(elmtid);
703 
704  // Extract fields on this element
705  for( j=0; j<expdim; j++)
706  {
707  velocity[j] = fields[j]->GetPhys() + offset;
708  }
709  P = fields[nVel]->GetPhys() + offset;
710 
711  // Compute the velocity gradients
712  for (j=0; j<expdim; j++)
713  {
714  for (k=0; k<expdim; k++)
715  {
716  grad[j*expdim+k] =
717  Array<OneD, NekDouble>(nq,0.0);
718  elmt->PhysDeriv(k,velocity[j],
719  grad[j*expdim+k]);
720  }
721  }
722 
723  // identify boundary of element
724  boundary = m_BCtoTraceID[cnt];
725 
726  // Dimension specific part for obtaining values
727  // at boundary and normal vector
729  int nbc;
730  switch(expdim)
731  {
732  case 2:
733  {
734  // Get expansion on boundary
736  bc = BndExp[n]->GetExp(i)->
737  as<LocalRegions::Expansion1D> ();
738 
739  // Get number of points on the boundary
740  nbc = bc->GetTotPoints();
741 
742  // Get normals
743  normals = elmt->GetEdgeNormal(boundary);
744 
745  // Extract values at boundary
746  Pb = Array<OneD, NekDouble>(nbc,0.0);
747  elmt->GetEdgePhysVals(boundary,bc,P,Pb);
748  for(int j = 0; j < expdim*expdim; ++j)
749  {
750  gradb[j] = Array<OneD, NekDouble>
751  (nbc,0.0);
752  elmt->GetEdgePhysVals(boundary,
753  bc,grad[j],gradb[j]);
754  }
755  }
756  break;
757 
758  case 3:
759  {
760  // Get expansion on boundary
762  bc = BndExp[n]->GetExp(i)->
763  as<LocalRegions::Expansion2D> ();
764 
765  // Get number of points on the boundary
766  nbc = bc->GetTotPoints();
767 
768  // Get normals
769  normals = elmt->GetFaceNormal(boundary);
770 
771  // Extract values at boundary
772  Pb = Array<OneD, NekDouble>(nbc,0.0);
773  elmt->GetFacePhysVals(boundary,bc,P,Pb);
774  for(int j = 0; j < expdim*expdim; ++j)
775  {
776  gradb[j] = Array<OneD, NekDouble>
777  (nbc,0.0);
778  elmt->GetFacePhysVals(boundary,
779  bc,grad[j],gradb[j]);
780  }
781  }
782  break;
783 
784  default:
785  ASSERTL0(false,
786  "Expansion not supported by FilterForces");
787  break;
788  }
789 
790  // Calculate forces per unit length
791 
792  // Pressure component: fp[j] = p*n[j]
793  for ( j = 0; j < expdim; j++)
794  {
795  fp[j] = Array<OneD, NekDouble> (nbc,0.0);
796  Vmath::Vmul (nbc, Pb, 1,
797  normals[j], 1,
798  fp[j], 1);
799  }
800 
801  // Viscous component:
802  // fv[j] = -mu*{(grad[k,j]+grad[j,k]) *n[k]}
803  for ( j = 0; j < expdim; j++ )
804  {
805  fv[j] = Array<OneD, NekDouble> (nbc,0.0);
806  for ( k = 0; k < expdim; k++ )
807  {
808  Vmath::Vvtvp (nbc, gradb[k*expdim+j], 1,
809  normals[k], 1,
810  fv[j], 1,
811  fv[j], 1);
812  Vmath::Vvtvp (nbc, gradb[j*expdim+k], 1,
813  normals[k], 1,
814  fv[j], 1,
815  fv[j], 1);
816  }
817  Vmath::Smul(nbc, -mu, fv[j], 1, fv[j], 1);
818  }
819 
820  // Integrate to obtain force
821  for ( j = 0; j < expdim; j++)
822  {
823  m_Fpplane[j][plane] += BndExp[n]->GetExp(i)->
824  Integral(fp[j]);
825  m_Fvplane[j][plane] += BndExp[n]->GetExp(i)->
826  Integral(fv[j]);
827  }
828  }
829  }
830  else
831  {
832  cnt += BndExp[n]->GetExpSize();
833  }
834  }
835  }
836  }
837 
838  // Combine contributions from different processes
839  // this is split between row and col comm because of
840  // homostrips case, which only keeps its own strip
841  for( i = 0; i < expdim; i++)
842  {
843  rowComm->AllReduce(m_Fpplane[i], LibUtilities::ReduceSum);
844  colComm->AllReduce(m_Fpplane[i], LibUtilities::ReduceSum);
845 
846  rowComm->AllReduce(m_Fvplane[i], LibUtilities::ReduceSum);
847  colComm->AllReduce(m_Fvplane[i], LibUtilities::ReduceSum);
848  }
849 
850  // Project results to new directions
851  for(plane = 0; plane < m_nPlanes; plane++)
852  {
853  Array< OneD, NekDouble> tmpP(expdim, 0.0);
854  Array< OneD, NekDouble> tmpV(expdim, 0.0);
855  for( i = 0; i < expdim; i++)
856  {
857  for( j = 0; j < expdim; j++ )
858  {
859  tmpP[i] += m_Fpplane[j][plane]*m_directions[i][j];
860  tmpV[i] += m_Fvplane[j][plane]*m_directions[i][j];
861  }
862  }
863  // Copy result
864  for( i = 0; i < expdim; i++)
865  {
866  m_Fpplane[i][plane] = tmpP[i];
867  m_Fvplane[i][plane] = tmpV[i];
868  }
869  }
870 
871  // Sum viscous and pressure components
872  for(plane = 0; plane < m_nPlanes; plane++)
873  {
874  for( i = 0; i < expdim; i++)
875  {
876  m_Ftplane[i][plane] = m_Fpplane[i][plane] + m_Fvplane[i][plane];
877  }
878  }
879 
880  // Put results back to wavespace, if necessary
882  {
883  for (i = 0; i < pFields.num_elements(); ++i)
884  {
885  pFields[i]->SetWaveSpace(true);
886  pFields[i]->HomogeneousFwdTrans(pFields[i]->GetPhys(),
887  pFields[i]->UpdatePhys());
888  }
889  }
890 }
891 
892 /**
893  * This function calculates the forces when we have a mapping
894  * defining a coordinate system transformation
895  */
898  const NekDouble &time)
899 {
900  int i, j, k, n, cnt, elmtid, offset, boundary, plane;
901  // Get number of quadrature points and dimensions
902  int physTot = pFields[0]->GetNpoints();
903  int expdim = pFields[0]->GetGraph()->GetMeshDimension();
904  int nVel = expdim;
905  if( m_isHomogeneous1D )
906  {
907  nVel = nVel + 1;
908  }
909 
911 
912  // Pressure stress tensor
913  // (global, in a plane, in element and boundary)
916  Array<OneD, Array<OneD, NekDouble> > PElmt ( nVel*nVel);
917  Array<OneD, Array<OneD, NekDouble> > PBnd ( nVel*nVel);
918  // Velocity gradient
920  Array<OneD, MultiRegions::ExpListSharedPtr> gradPlane( nVel*nVel);
921  Array<OneD, Array<OneD, NekDouble> > gradElmt ( nVel*nVel);
922  Array<OneD, Array<OneD, NekDouble> > gradBnd ( nVel*nVel);
923 
924  // Transformation to cartesian system
927  Array<OneD, Array<OneD, NekDouble> > CElmt ( nVel*nVel);
928  Array<OneD, Array<OneD, NekDouble> > CBnd ( nVel*nVel);
929 
930  // Jacobian
933  Array<OneD, NekDouble> JacElmt;
934  Array<OneD, NekDouble> JacBnd;
935 
936  // Communicators to exchange results
937  LibUtilities::CommSharedPtr vComm = pFields[0]->GetComm();
938  LibUtilities::CommSharedPtr rowComm = vComm->GetRowComm();
939  LibUtilities::CommSharedPtr colComm =
940  m_session->DefinesSolverInfo("HomoStrip") ?
941  vComm->GetColumnComm()->GetColumnComm():
942  vComm->GetColumnComm();
943 
944  // Arrays with forces in each plane
948  for( i = 0; i < expdim; i++)
949  {
951  m_Fvplane[i] = Array<OneD, NekDouble>(m_nPlanes,0.0);
952  m_Ftplane[i] = Array<OneD, NekDouble>(m_nPlanes,0.0);
953  }
954 
955  // Forces per element length in a boundary
958 
959  // Get viscosity
960  NekDouble rho = (m_session->DefinesParameter("rho"))
961  ? (m_session->GetParameter("rho"))
962  : 1;
963  NekDouble mu = rho*m_session->GetParameter("Kinvis");
964 
965  // Perform BwdTrans: for case with mapping, we can never work
966  // in wavespace
967  for(i = 0; i < pFields.num_elements(); ++i)
968  {
969  if (m_isHomogeneous1D)
970  {
971  pFields[i]->SetWaveSpace(false);
972  }
973  pFields[i]->BwdTrans(pFields[i]->GetCoeffs(),
974  pFields[i]->UpdatePhys());
975  pFields[i]->SetPhysState(true);
976  }
977 
978  // Define boundary expansions
982  {
983  BndConds = pFields[0]->GetPlane(0)->GetBndConditions();
984  BndExp = pFields[0]->GetPlane(0)->GetBndCondExpansions();
985  }
986  else
987  {
988  BndConds = pFields[0]->GetBndConditions();
989  BndExp = pFields[0]->GetBndCondExpansions();
990  }
991 
992  //
993  // Calculate pressure stress tensor, velocity gradient
994  // and get informations about the mapping
995 
996  // Initialise variables
997  switch (expdim)
998  {
999  case 2:
1000  {
1001  if (m_isHomogeneous1D)
1002  {
1004  Exp3DH1 = boost::dynamic_pointer_cast
1006  (pFields[0]);
1007  for(i = 0; i < nVel*nVel; i++)
1008  {
1010  AllocateSharedPtr(*Exp3DH1);
1011 
1013  AllocateSharedPtr(*Exp3DH1);
1014 
1016  AllocateSharedPtr(*Exp3DH1);
1017  }
1019  AllocateSharedPtr(*Exp3DH1);
1020  }
1021  else
1022  {
1024  Exp2D = boost::dynamic_pointer_cast
1026  (pFields[0]);
1027  for(i = 0; i < nVel*nVel; i++)
1028  {
1030  AllocateSharedPtr(*Exp2D);
1031 
1033  AllocateSharedPtr(*Exp2D);
1034 
1036  AllocateSharedPtr(*Exp2D);
1037  }
1039  AllocateSharedPtr(*Exp2D);
1040  }
1041  break;
1042  }
1043  case 3:
1044  {
1046  Exp3D = boost::dynamic_pointer_cast
1048  (pFields[0]);
1049  for(i = 0; i < nVel*nVel; i++)
1050  {
1052  AllocateSharedPtr(*Exp3D);
1053 
1055  AllocateSharedPtr(*Exp3D);
1056 
1058  AllocateSharedPtr(*Exp3D);
1059  }
1061  AllocateSharedPtr(*Exp3D);
1062 
1063  break;
1064  }
1065  default:
1066  ASSERTL0(false,"Expansion dimension not supported by FilterAeroForces");
1067  break;
1068  }
1069 
1070 
1071  // Get g^ij
1072  Array<OneD, Array<OneD, NekDouble> > tmp( nVel*nVel );
1073  m_mapping->GetInvMetricTensor(tmp);
1074 
1075  // Calculate P^ij = g^ij*p
1076  for (i = 0; i < nVel*nVel; i++)
1077  {
1078  Vmath::Vmul(physTot, tmp[i], 1,
1079  pFields[nVel]->GetPhys(), 1,
1080  P[i]->UpdatePhys(), 1);
1081  }
1082 
1083  // Calculate covariant derivatives of U = u^i_,k
1085  for (i=0; i<nVel; i++)
1086  {
1087  wk[i] = Array<OneD, NekDouble>(physTot, 0.0);
1088  Vmath::Vcopy(physTot, pFields[i]->GetPhys(), 1,
1089  wk[i], 1);
1090  }
1091  m_mapping->ApplyChristoffelContravar(wk, tmp);
1092  for (i=0; i< nVel; i++)
1093  {
1094  for (k=0; k< nVel; k++)
1095  {
1096  pFields[0]->PhysDeriv(MultiRegions::DirCartesianMap[k],
1097  wk[i], grad[i*nVel+k]->UpdatePhys());
1098 
1099  Vmath::Vadd(physTot,tmp[i*nVel+k],1,
1100  grad[i*nVel+k]->UpdatePhys(), 1,
1101  grad[i*nVel+k]->UpdatePhys(), 1);
1102  }
1103  }
1104  // Raise index to obtain Grad^ij = g^jk u^i_,k
1105  for (i=0; i< nVel; i++)
1106  {
1107  for (k=0; k< nVel; k++)
1108  {
1109  Vmath::Vcopy(physTot, grad[i*nVel+k]->GetPhys(), 1,
1110  wk[k], 1);
1111  }
1112  m_mapping->RaiseIndex(wk, wk);
1113  for (j=0; j<nVel; j++)
1114  {
1115  Vmath::Vcopy(physTot, wk[j], 1,
1116  grad[i*nVel+j]->UpdatePhys(), 1);
1117  }
1118  }
1119 
1120  // Get Jacobian
1121  m_mapping->GetJacobian( Jac->UpdatePhys());
1122 
1123  // Get transformation to Cartesian system
1124  for (i=0; i< nVel; i++)
1125  {
1126  // Zero wk storage
1127  for (k=0; k< nVel; k++)
1128  {
1129  wk[k] = Array<OneD, NekDouble>(physTot, 0.0);
1130  }
1131  // Make wk[i] = 1
1132  wk[i] = Array<OneD, NekDouble>(physTot, 1.0);
1133  // Transform wk to Cartesian
1134  m_mapping->ContravarToCartesian(wk,wk);
1135  // Copy result to a column in C
1136  for (k=0; k< nVel; k++)
1137  {
1138  Vmath::Vcopy(physTot, wk[k], 1,
1139  C[k*nVel+i]->UpdatePhys(), 1);
1140  }
1141  }
1142 
1143  //
1144  // Calculate forces
1145  //
1146 
1147  // For Homogeneous, calculate force on each 2D plane
1148  // Otherwise, m_nPlanes = 1, and loop only runs once
1149  for(plane = 0; plane < m_nPlanes; plane++ )
1150  {
1151  // Check if plane is in this proc
1152  if( m_planesID[plane] != -1 )
1153  {
1154  // For Homogeneous, consider the 2D expansion
1155  // on the current plane
1156  if(m_isHomogeneous1D)
1157  {
1158  for(n = 0; n < nVel*nVel; n++)
1159  {
1160  PPlane[n] = P[n]->GetPlane(m_planesID[plane]);
1161  gradPlane[n] = grad[n]->GetPlane(m_planesID[plane]);
1162  CPlane[n] = C[n]->GetPlane(m_planesID[plane]);
1163  }
1164  JacPlane = Jac->GetPlane(m_planesID[plane]);
1165  }
1166  else
1167  {
1168  for(n = 0; n < nVel*nVel; n++)
1169  {
1170  PPlane[n] = P[n];
1171  gradPlane[n] = grad[n];
1172  CPlane[n] = C[n];
1173  }
1174  JacPlane = Jac;
1175  }
1176 
1177  //Loop all the Boundary Regions
1178  for( cnt = n = 0; n < BndConds.num_elements(); n++)
1179  {
1180  if(m_boundaryRegionIsInList[n] == 1)
1181  {
1182  for (i=0; i < BndExp[n]->GetExpSize(); ++i,cnt++)
1183  {
1184  elmtid = m_BCtoElmtID[cnt];
1185  elmt = PPlane[0]->GetExp(elmtid);
1186  offset = PPlane[0]->GetPhys_Offset(elmtid);
1187 
1188  // Extract fields on this element
1189  for( j=0; j<nVel*nVel; j++)
1190  {
1191  PElmt[j] = PPlane[j]->GetPhys()
1192  + offset;
1193  gradElmt[j] = gradPlane[j]->GetPhys()
1194  + offset;
1195  CElmt[j] = CPlane[j]->GetPhys()
1196  + offset;
1197  }
1198  JacElmt = JacPlane->GetPhys() + offset;
1199 
1200  // identify boundary of element
1201  boundary = m_BCtoTraceID[cnt];
1202 
1203  // Dimension specific part for obtaining values
1204  // at boundary and normal vector
1206  int nbc;
1207  switch(expdim)
1208  {
1209  case 2:
1210  {
1211  // Get expansion on boundary
1213  bc = BndExp[n]->GetExp(i)->
1214  as<LocalRegions::Expansion1D> ();
1215 
1216  // Get number of points on the boundary
1217  nbc = bc->GetTotPoints();
1218 
1219  // Get normals
1220  normals = elmt->GetEdgeNormal(boundary);
1221 
1222  // Extract values at boundary
1223  for(int j = 0; j < nVel*nVel; ++j)
1224  {
1225  gradBnd[j] = Array<OneD, NekDouble>
1226  (nbc,0.0);
1227  elmt->GetEdgePhysVals(boundary,
1228  bc,gradElmt[j],
1229  gradBnd[j]);
1230 
1231  PBnd[j] = Array<OneD, NekDouble>
1232  (nbc,0.0);
1233  elmt->GetEdgePhysVals(boundary,
1234  bc,PElmt[j],
1235  PBnd[j]);
1236  CBnd[j] = Array<OneD, NekDouble>
1237  (nbc,0.0);
1238  elmt->GetEdgePhysVals(boundary,
1239  bc,CElmt[j],
1240  CBnd[j]);
1241  }
1242  JacBnd = Array<OneD, NekDouble>
1243  (nbc,0.0);
1244  elmt->GetEdgePhysVals(boundary,
1245  bc,JacElmt,
1246  JacBnd);
1247  }
1248  break;
1249 
1250  case 3:
1251  {
1252  // Get expansion on boundary
1254  bc = BndExp[n]->GetExp(i)->
1255  as<LocalRegions::Expansion2D> ();
1256 
1257  // Get number of points on the boundary
1258  nbc = bc->GetTotPoints();
1259 
1260  // Get normals
1261  normals = elmt->GetFaceNormal(boundary);
1262 
1263  // Extract values at boundary
1264  for(int j = 0; j < nVel*nVel; ++j)
1265  {
1266  gradBnd[j] = Array<OneD, NekDouble>
1267  (nbc,0.0);
1268  elmt->GetFacePhysVals(boundary,
1269  bc,gradElmt[j],
1270  gradBnd[j]);
1271 
1272  PBnd[j] = Array<OneD, NekDouble>
1273  (nbc,0.0);
1274  elmt->GetFacePhysVals(boundary,
1275  bc,PElmt[j],
1276  PBnd[j]);
1277 
1278  CBnd[j] = Array<OneD, NekDouble>
1279  (nbc,0.0);
1280  elmt->GetFacePhysVals(boundary,
1281  bc,CElmt[j],
1282  CBnd[j]);
1283  }
1284  JacBnd = Array<OneD, NekDouble>
1285  (nbc,0.0);
1286  elmt->GetFacePhysVals(boundary,
1287  bc,JacElmt,
1288  JacBnd);
1289  }
1290  break;
1291 
1292  default:
1293  ASSERTL0(false,
1294  "Expansion not supported by FilterForces");
1295  break;
1296  }
1297 
1298  // Calculate forces per unit length
1299 
1300  // Pressure component: fp[j] = P[j,k]*n[k]
1301  for ( j = 0; j < nVel; j++)
1302  {
1303  fp[j] = Array<OneD, NekDouble> (nbc,0.0);
1304  // Normals only has expdim elements
1305  for ( k = 0; k < expdim; k++)
1306  {
1307  Vmath::Vvtvp (nbc, PBnd[ j*nVel + k], 1,
1308  normals[k], 1,
1309  fp[j], 1,
1310  fp[j], 1);
1311  }
1312  }
1313 
1314  // Viscous component:
1315  // fv[j] = -mu*{(grad[k,j]+grad[j,k]) *n[k]}
1316  for ( j = 0; j < nVel; j++ )
1317  {
1318  fv[j] = Array<OneD, NekDouble> (nbc,0.0);
1319  for ( k = 0; k < expdim; k++ )
1320  {
1321  Vmath::Vvtvp (nbc,gradBnd[k*nVel+j],1,
1322  normals[k], 1,
1323  fv[j], 1,
1324  fv[j], 1);
1325  Vmath::Vvtvp (nbc,gradBnd[j*nVel+k],1,
1326  normals[k], 1,
1327  fv[j], 1,
1328  fv[j], 1);
1329  }
1330  Vmath::Smul(nbc, -mu, fv[j], 1, fv[j], 1);
1331  }
1332 
1333  // Multiply by Jacobian
1334  for ( k = 0; k < nVel; k++ )
1335  {
1336  Vmath::Vmul(nbc, JacBnd, 1, fp[k], 1,
1337  fp[k], 1);
1338  Vmath::Vmul(nbc, JacBnd, 1, fv[k], 1,
1339  fv[k], 1);
1340  }
1341 
1342  // Convert to cartesian system
1343  for ( k = 0; k < nVel; k++ )
1344  {
1345  wk[k] = Array<OneD, NekDouble>(physTot,0.0);
1346  for ( j = 0; j < nVel; j++ )
1347  {
1348  Vmath::Vvtvp(nbc, CBnd[k*nVel+j], 1,
1349  fp[j], 1,
1350  wk[k], 1,
1351  wk[k], 1);
1352  }
1353  }
1354  for ( k = 0; k < nVel; k++ )
1355  {
1356  Vmath::Vcopy(nbc, wk[k], 1, fp[k], 1);
1357  }
1358 
1359  for ( k = 0; k < nVel; k++ )
1360  {
1361  wk[k] = Array<OneD, NekDouble>(physTot,0.0);
1362  for ( j = 0; j < nVel; j++ )
1363  {
1364  Vmath::Vvtvp(nbc, CBnd[k*nVel+j], 1,
1365  fv[j], 1,
1366  wk[k], 1,
1367  wk[k], 1);
1368  }
1369  }
1370  for ( k = 0; k < nVel; k++ )
1371  {
1372  Vmath::Vcopy(nbc, wk[k], 1, fv[k], 1);
1373  }
1374 
1375  // Integrate to obtain force
1376  for ( j = 0; j < expdim; j++)
1377  {
1378  m_Fpplane[j][plane] += BndExp[n]->GetExp(i)->
1379  Integral(fp[j]);
1380  m_Fvplane[j][plane] += BndExp[n]->GetExp(i)->
1381  Integral(fv[j]);
1382  }
1383  }
1384  }
1385  else
1386  {
1387  cnt += BndExp[n]->GetExpSize();
1388  }
1389  }
1390  }
1391  }
1392 
1393  // Combine contributions from different processes
1394  // this is split between row and col comm because of
1395  // homostrips case, which only keeps its own strip
1396  for( i = 0; i < expdim; i++)
1397  {
1398  rowComm->AllReduce(m_Fpplane[i], LibUtilities::ReduceSum);
1399  colComm->AllReduce(m_Fpplane[i], LibUtilities::ReduceSum);
1400 
1401  rowComm->AllReduce(m_Fvplane[i], LibUtilities::ReduceSum);
1402  colComm->AllReduce(m_Fvplane[i], LibUtilities::ReduceSum);
1403  }
1404 
1405  // Project results to new directions
1406  for(plane = 0; plane < m_nPlanes; plane++)
1407  {
1408  Array< OneD, NekDouble> tmpP(expdim, 0.0);
1409  Array< OneD, NekDouble> tmpV(expdim, 0.0);
1410  for( i = 0; i < expdim; i++)
1411  {
1412  for( j = 0; j < expdim; j++ )
1413  {
1414  tmpP[i] += m_Fpplane[j][plane]*m_directions[i][j];
1415  tmpV[i] += m_Fvplane[j][plane]*m_directions[i][j];
1416  }
1417  }
1418  // Copy result
1419  for( i = 0; i < expdim; i++)
1420  {
1421  m_Fpplane[i][plane] = tmpP[i];
1422  m_Fvplane[i][plane] = tmpV[i];
1423  }
1424  }
1425 
1426  // Sum viscous and pressure components
1427  for(plane = 0; plane < m_nPlanes; plane++)
1428  {
1429  for( i = 0; i < expdim; i++)
1430  {
1431  m_Ftplane[i][plane] = m_Fpplane[i][plane] + m_Fvplane[i][plane];
1432  }
1433  }
1434 
1435  // Put results back to wavespace, if necessary
1436  if( m_isHomogeneous1D)
1437  {
1438  for (i = 0; i < pFields.num_elements(); ++i)
1439  {
1440  pFields[i]->SetWaveSpace(true);
1441  pFields[i]->HomogeneousFwdTrans(pFields[i]->GetPhys(),
1442  pFields[i]->UpdatePhys());
1443  }
1444  }
1445 }
1446 
1447 }
1448 }
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:188
static boost::shared_ptr< DataType > AllocateSharedPtr()
Allocate a shared pointer from the memory pool.
virtual SOLVER_UTILS_EXPORT ~FilterAeroForces()
void Vvtvp(int n, const T *w, const int incw, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
vvtvp (vector times vector plus vector): z = w*x + y
Definition: Vmath.cpp:428
virtual void v_Update(const Array< OneD, const MultiRegions::ExpListSharedPtr > &pFields, const NekDouble &time)
STL namespace.
virtual void v_Finalise(const Array< OneD, const MultiRegions::ExpListSharedPtr > &pFields, const NekDouble &time)
boost::shared_ptr< SessionReader > SessionReaderSharedPtr
Definition: MeshPartition.h:51
static bool GenerateSeqVector(const char *const str, std::vector< unsigned int > &vec)
Definition: ParseUtils.hpp:79
std::vector< bool > m_boundaryRegionIsInList
Determines if a given Boundary Region is in m_boundaryRegionsIdList.
boost::shared_ptr< Comm > CommSharedPtr
Pointer to a Communicator object.
Definition: Comm.h:53
void Smul(int n, const T alpha, const T *x, const int incx, T *y, const int incy)
Scalar multiply y = alpha*y.
Definition: Vmath.cpp:199
std::vector< unsigned int > m_boundaryRegionsIdList
ID's of boundary regions where we want the forces.
GlobalMapping::MappingSharedPtr m_mapping
Array< OneD, Array< OneD, NekDouble > > m_directions
SOLVER_UTILS_EXPORT void GetForces(const Array< OneD, const MultiRegions::ExpListSharedPtr > &pFields, Array< OneD, NekDouble > &Aeroforces, const NekDouble &time)
NekDouble Evaluate() const
Definition: Equation.h:102
std::map< int, BoundaryRegionShPtr > BoundaryRegionCollection
Definition: Conditions.h:206
boost::shared_ptr< ExpList > ExpListSharedPtr
Shared pointer to an ExpList object.
void CalculateForces(const Array< OneD, const MultiRegions::ExpListSharedPtr > &pFields, const NekDouble &time)
double NekDouble
boost::shared_ptr< ExpList2D > ExpList2DSharedPtr
Shared pointer to an ExpList2D object.
Definition: ExpList2D.h:49
std::map< std::string, std::string > ParamMap
Definition: Filter.h:67
LibUtilities::SessionReaderSharedPtr m_session
Definition: Filter.h:84
virtual void v_Initialise(const Array< OneD, const MultiRegions::ExpListSharedPtr > &pFields, const NekDouble &time)
int m_nPlanes
number of planes for homogeneous1D expansion
boost::shared_ptr< ExpList3D > ExpList3DSharedPtr
Shared pointer to an ExpList3D object.
Definition: ExpList3D.h:114
MultiRegions::Direction const DirCartesianMap[]
Definition: ExpList.h:86
Array< OneD, Array< OneD, NekDouble > > m_Ftplane
Abstraction of a two-dimensional multi-elemental expansion which is merely a collection of local expa...
Definition: ExpList2D.h:60
Array< OneD, Array< OneD, NekDouble > > m_Fpplane
Abstraction of a three-dimensional multi-elemental expansion which is merely a collection of local ex...
Definition: ExpList3D.h:49
InputIterator find(InputIterator first, InputIterator last, InputIterator startingpoint, const EqualityComparable &value)
Definition: StdRegions.hpp:315
FilterFactory & GetFilterFactory()
Definition: Filter.cpp:42
const BoundaryRegionCollection & GetBoundaryRegions(void) const
Definition: Conditions.h:227
boost::shared_ptr< ExpList3DHomogeneous1D > ExpList3DHomogeneous1DSharedPtr
Shared pointer to an ExpList3DHomogeneous1D object.
T Vsum(int n, const T *x, const int incx)
Subtract return sum(x)
Definition: Vmath.cpp:723
boost::shared_ptr< StdExpansion > StdExpansionSharedPtr
Array< OneD, Array< OneD, NekDouble > > m_Fvplane
boost::shared_ptr< Expansion1D > Expansion1DSharedPtr
Definition: Expansion1D.h:53
bool m_outputAllPlanes
if using a homogeneous1D expansion, determine if should output all planes or just the average ...
void Vcopy(int n, const T *x, const int incx, T *y, const int incy)
Definition: Vmath.cpp:1047
static GLOBAL_MAPPING_EXPORT MappingSharedPtr Load(const LibUtilities::SessionReaderSharedPtr &pSession, const Array< OneD, MultiRegions::ExpListSharedPtr > &pFields)
Return a pointer to the mapping, creating it on first call.
Definition: Mapping.cpp:266
Abstraction of a two-dimensional multi-elemental expansion which is merely a collection of local expa...
void CalculateForcesMapping(const Array< OneD, const MultiRegions::ExpListSharedPtr > &pFields, const NekDouble &time)
void Vadd(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Add vector z = x+y.
Definition: Vmath.cpp:285
void Vmul(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Multiply vector z = x*y.
Definition: Vmath.cpp:169
boost::shared_ptr< Expansion2D > Expansion2DSharedPtr
Definition: Expansion1D.h:49
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, tDescription pDesc="")
Register a class with the factory.
Definition: NekFactory.hpp:215