42 base_velocity_function(
""),
43 local_vertical_function(
""),
47 area_swept_function(
""),
56 this->set_parameter(base_velocity_function, input,
58 this->zero_vector_function);
60 if (base_velocity_function.expression() == this->zero_vector_function)
61 libmesh_error_msg(
"Error! Zero AveragedFan specified!" <<
64 this->set_parameter(local_vertical_function, input,
66 this->zero_vector_function);
68 if (local_vertical_function.expression() == this->zero_vector_function)
69 libmesh_error_msg(
"Error! Zero LocalVertical specified!" <<
72 this->set_parameter(lift_function, input,
76 if (lift_function.expression() ==
"0")
77 std::cout <<
"Warning! Zero lift function specified!" << std::endl;
79 this->set_parameter(drag_function, input,
83 if (drag_function.expression() ==
"0")
84 std::cout <<
"Warning! Zero drag function specified!" << std::endl;
86 this->set_parameter(chord_function, input,
90 if (chord_function.expression() ==
"0")
91 libmesh_error_msg(
"Error! Zero chord function specified!" <<
94 this->set_parameter(area_swept_function, input,
98 if (area_swept_function.expression() ==
"0")
99 libmesh_error_msg(
"Error! Zero area_swept_function specified!" <<
102 this->set_parameter(aoa_function, input,
106 if (aoa_function.expression() ==
"00000")
107 libmesh_error_msg(
"Error! No angle-of-attack specified!" <<
113 (
const libMesh::Point& point,
114 const libMesh::Real time,
115 const libMesh::NumberVectorValue& U,
116 libMesh::NumberVectorValue& F,
117 libMesh::NumberTensorValue *dFdU)
120 libMesh::DenseVector<libMesh::Number> output_vec(3);
122 base_velocity_function(point, time,
125 const libMesh::NumberVectorValue U_B(output_vec(0),
129 const libMesh::Number U_B_size = U_B.norm();
136 const libMesh::NumberVectorValue N_B =
137 libMesh::NumberVectorValue(U_B/U_B_size);
139 local_vertical_function(point, time,
143 const libMesh::NumberVectorValue N_V(output_vec(0),
149 const libMesh::NumberVectorValue N_R = N_B.cross(N_V);
152 const libMesh::NumberVectorValue U_P = U - (U*N_R)*N_R - U_B;
154 const libMesh::Number U_P_size = U_P.norm();
163 const libMesh::NumberVectorValue N_drag =
164 libMesh::NumberVectorValue(-U_P/U_P_size);
167 const libMesh::NumberVectorValue N_lift = N_drag.cross(N_R);
170 const libMesh::Number u_fwd = -(U_P * N_B);
173 const libMesh::Number u_up = U_P * N_V;
177 libmesh_assert (u_up || u_fwd);
180 const libMesh::Number part_angle = std::atan2(u_up, u_fwd);
183 const libMesh::Number angle = part_angle +
184 aoa_function(point, time);
186 const libMesh::Number C_lift = lift_function(point, angle);
187 const libMesh::Number C_drag = drag_function(point, angle);
189 const libMesh::Number chord = chord_function(point, time);
190 const libMesh::Number area = area_swept_function(point, time);
192 const libMesh::Number v_sq = U_P*U_P;
194 const libMesh::Number LDfactor = 0.5 * this->_rho * v_sq * chord / area;
195 const libMesh::Number lift = C_lift * LDfactor;
196 const libMesh::Number drag = C_drag * LDfactor;
199 F = lift * N_lift + drag * N_drag;
205 const libMesh::NumberVectorValue LDderivfactor =
206 (N_lift*C_lift+N_drag*C_drag) *
207 this->_rho * chord / area;
209 for (
unsigned int i=0; i != 3; ++i)
210 for (
unsigned int j=0; j != 3; ++j)
211 (*dFdU)(i,j) = LDderivfactor(i) * U_P(j);
Physics class for Incompressible Navier-Stokes.
static PhysicsName averaged_fan()
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)
void read_input_options(const GetPot &input)
Read options from GetPot input file.