GRINS-0.6.0
averaged_fan_base.C
Go to the documentation of this file.
1 //-----------------------------------------------------------------------bl-
2 //--------------------------------------------------------------------------
3 //
4 // GRINS - General Reacting Incompressible Navier-Stokes
5 //
6 // Copyright (C) 2014-2015 Paul T. Bauman, Roy H. Stogner
7 // Copyright (C) 2010-2013 The PECOS Development Team
8 //
9 // This library is free software; you can redistribute it and/or
10 // modify it under the terms of the Version 2.1 GNU Lesser General
11 // Public License as published by the Free Software Foundation.
12 //
13 // This library is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 // Lesser General Public License for more details.
17 //
18 // You should have received a copy of the GNU Lesser General Public
19 // License along with this library; if not, write to the Free Software
20 // Foundation, Inc. 51 Franklin Street, Fifth Floor,
21 // Boston, MA 02110-1301 USA
22 //
23 //-----------------------------------------------------------------------el-
24 
25 
26 // This class
28 
29 // GRINS
31 
32 // libMesh
33 #include "libmesh/parsed_function.h"
34 #include "libmesh/zero_function.h"
35 
36 namespace GRINS
37 {
38 
39  template<class Mu>
40  AveragedFanBase<Mu>::AveragedFanBase( const std::string& physics_name, const GetPot& input )
41  : IncompressibleNavierStokesBase<Mu>(physics_name,
42  incompressible_navier_stokes, /* "core" Physics name */
43  input)
44  {
45  this->read_input_options(input);
46 
47  return;
48  }
49 
50  template<class Mu>
52  {
53  return;
54  }
55 
56  template<class Mu>
57  void AveragedFanBase<Mu>::read_input_options( const GetPot& input )
58  {
59  std::string base_function =
60  input("Physics/"+averaged_fan+"/base_velocity",
61  std::string("0"));
62 
63  if (base_function == "0")
64  libmesh_error_msg("Error! Zero AveragedFan specified!" <<
65  std::endl);
66 
67  if (base_function == "0")
68  this->base_velocity_function.reset
69  (new libMesh::ZeroFunction<libMesh::Number>());
70  else
71  this->base_velocity_function.reset
72  (new libMesh::ParsedFunction<libMesh::Number>(base_function));
73 
74  std::string vertical_function =
75  input("Physics/"+averaged_fan+"/local_vertical",
76  std::string("0"));
77 
78  if (vertical_function == "0")
79  libmesh_error_msg("Warning! Zero LocalVertical specified!" <<
80  std::endl);
81 
82  this->local_vertical_function.reset
83  (new libMesh::ParsedFunction<libMesh::Number>(vertical_function));
84 
85  std::string lift_function_string =
86  input("Physics/"+averaged_fan+"/lift",
87  std::string("0"));
88 
89  if (lift_function_string == "0")
90  std::cout << "Warning! Zero lift function specified!" << std::endl;
91 
92  this->lift_function.reset
93  (new libMesh::ParsedFunction<libMesh::Number>(lift_function_string));
94 
95  std::string drag_function_string =
96  input("Physics/"+averaged_fan+"/drag",
97  std::string("0"));
98 
99  if (drag_function_string == "0")
100  std::cout << "Warning! Zero drag function specified!" << std::endl;
101 
102  this->drag_function.reset
103  (new libMesh::ParsedFunction<libMesh::Number>(drag_function_string));
104 
105  std::string chord_function_string =
106  input("Physics/"+averaged_fan+"/chord_length",
107  std::string("0"));
108 
109  if (chord_function_string == "0")
110  libmesh_error_msg("Warning! Zero chord function specified!" <<
111  std::endl);
112 
113  this->chord_function.reset
114  (new libMesh::ParsedFunction<libMesh::Number>(chord_function_string));
115 
116  std::string area_function_string =
117  input("Physics/"+averaged_fan+"/area_swept",
118  std::string("0"));
119 
120  if (area_function_string == "0")
121  libmesh_error_msg("Warning! Zero area_swept_function specified!" <<
122  std::endl);
123 
124  this->area_swept_function.reset
125  (new libMesh::ParsedFunction<libMesh::Number>(area_function_string));
126 
127  std::string aoa_function_string =
128  input("Physics/"+averaged_fan+"/angle_of_attack",
129  std::string("00000"));
130 
131  if (aoa_function_string == "00000")
132  libmesh_error_msg("Warning! No angle-of-attack specified!" <<
133  std::endl);
134 
135  this->aoa_function.reset
136  (new libMesh::ParsedFunction<libMesh::Number>(aoa_function_string));
137  }
138 
139  template<class Mu>
141  ( const libMesh::Point& point,
142  const libMesh::Real time,
143  const libMesh::NumberVectorValue& U,
144  libMesh::NumberVectorValue& F,
145  libMesh::NumberTensorValue *dFdU)
146  {
147  // Find base velocity of moving fan at this point
148  libmesh_assert(base_velocity_function.get());
149 
150  libMesh::DenseVector<libMesh::Number> output_vec(3);
151 
152  (*base_velocity_function)(point, time,
153  output_vec);
154 
155  const libMesh::NumberVectorValue U_B(output_vec(0),
156  output_vec(1),
157  output_vec(2));
158 
159  const libMesh::Number U_B_size = U_B.size();
160 
161  // If there's no base velocity there's no fan
162  if (!U_B_size)
163  return false;
164 
165  // Normal in fan velocity direction
166  const libMesh::NumberVectorValue N_B =
167  libMesh::NumberVectorValue(U_B/U_B_size);
168 
169  (*local_vertical_function)(point, time,
170  output_vec);
171 
172  // Normal in fan vertical direction
173  const libMesh::NumberVectorValue N_V(output_vec(0),
174  output_vec(1),
175  output_vec(2));
176 
177  // Normal in radial direction (or opposite radial direction,
178  // for fans turning clockwise!)
179  const libMesh::NumberVectorValue N_R = N_B.cross(N_V);
180 
181  // Fan-wing-plane component of local relative velocity
182  const libMesh::NumberVectorValue U_P = U - (U*N_R)*N_R - U_B;
183 
184  const libMesh::Number U_P_size = U_P.size();
185 
186  // If there's no flow in the fan's frame of reference, there's no
187  // lift or drag. FIXME - should we account for drag in the
188  // out-of-plane direction?
189  if (!U_P_size)
190  return false;
191 
192  // Direction opposing drag
193  const libMesh::NumberVectorValue N_drag =
194  libMesh::NumberVectorValue(-U_P/U_P_size);
195 
196  // Direction opposing lift
197  const libMesh::NumberVectorValue N_lift = N_drag.cross(N_R);
198 
199  // "Forward" velocity
200  const libMesh::Number u_fwd = -(U_P * N_B);
201 
202  // "Upward" velocity
203  const libMesh::Number u_up = U_P * N_V;
204 
205  // If there's no forward or upward velocity we should have already
206  // returned false
207  libmesh_assert (u_up || u_fwd);
208 
209  // Angle WRT fan velocity direction
210  const libMesh::Number part_angle = std::atan2(u_up, u_fwd);
211 
212  // Angle WRT fan chord
213  const libMesh::Number angle = part_angle +
214  (*aoa_function)(point, time);
215 
216  const libMesh::Number C_lift = (*lift_function)(point, angle);
217  const libMesh::Number C_drag = (*drag_function)(point, angle);
218 
219  const libMesh::Number chord = (*chord_function)(point, time);
220  const libMesh::Number area = (*area_swept_function)(point, time);
221 
222  const libMesh::Number v_sq = U_P*U_P;
223 
224  const libMesh::Number LDfactor = 0.5 * this->_rho * v_sq * chord / area;
225  const libMesh::Number lift = C_lift * LDfactor;
226  const libMesh::Number drag = C_drag * LDfactor;
227 
228  // Force
229  F = lift * N_lift + drag * N_drag;
230 
231  if (dFdU)
232  {
233  // FIXME: Jacobians here are very inexact!
234  // Dropping all AoA dependence on U terms!
235  const libMesh::NumberVectorValue LDderivfactor =
236  (N_lift*C_lift+N_drag*C_drag) *
237  this->_rho * chord / area;
238 
239  for (unsigned int i=0; i != 3; ++i)
240  for (unsigned int j=0; j != 3; ++j)
241  (*dFdU)(i,j) = LDderivfactor(i) * U_P(j);
242  }
243 
244  return true;
245  }
246 
247 } // namespace GRINS
248 
249 // Instantiate
250 INSTANTIATE_INC_NS_SUBCLASS(AveragedFanBase);
const PhysicsName incompressible_navier_stokes
Physics class for Incompressible Navier-Stokes.
bool compute_force(const libMesh::Point &point, const libMesh::Real time, const libMesh::NumberVectorValue &U, libMesh::NumberVectorValue &F, libMesh::NumberTensorValue *dFdU=NULL)
INSTANTIATE_INC_NS_SUBCLASS(AveragedFanBase)
GRINS namespace.
virtual void read_input_options(const GetPot &input)
Read options from GetPot input file.
const PhysicsName averaged_fan

Generated on Mon Jun 22 2015 21:32:20 for GRINS-0.6.0 by  doxygen 1.8.9.1