FlightGear next
WakeMesh.cxx
Go to the documentation of this file.
1// WakeMesh.cxx -- Mesh for the computation of a wing wake.
2//
3// Written by Bertrand Coconnier, started March 2017.
4//
5// Copyright (C) 2017 Bertrand Coconnier - bcoconni@users.sf.net
6//
7// This program is free software; you can redistribute it and/or modify it under
8// the terms of the GNU General Public License as published by the Free Software
9// Foundation; either version 2 of the License, or (at your option) any later
10// version.
11//
12// This program is distributed in the hope that it will be useful, but WITHOUT
13// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
15// details.
16//
17// You should have received a copy of the GNU General Public License along with
18// this program; if not, write to the Free Software Foundation, Inc., 51
19// Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20//
21// $Id$
22
23#include <vector>
24#include <cmath>
25
26#include <simgear/structure/SGSharedPtr.hxx>
27#include <simgear/math/SGVec3.hxx>
28#include <simgear/debug/logstream.hxx>
29
30#include "WakeMesh.hxx"
31
32extern "C" {
33 #include "FDM/ls_matrix.h"
34}
35
36WakeMesh::WakeMesh(double _span, double _chord, const std::string& aircraft_name)
37 : nelm(10), span(_span), chord(_chord)
38{
39 double y1 = -0.5*span;
40 double ds = span / nelm;
41
42 for(int i=0; i<nelm; i++) {
43 double y2 = y1 + ds;
44 elements.push_back(new AeroElement(SGVec3d(-chord, y1, 0.),
45 SGVec3d(0., y1, 0.),
46 SGVec3d(0., y2, 0.),
47 SGVec3d(-chord, y2, 0.)));
48 y1 = y2;
49 }
50
52 Gamma = nr_matrix(1, nelm, 1, 1);
53
54 for (int i=0; i < nelm; ++i) {
55 SGVec3d normal = elements[i]->getNormal();
56 SGVec3d collPt = elements[i]->getCollocationPoint();
57
58 for (int j=0; j < nelm; ++j)
59 influenceMtx[i+1][j+1] = dot(elements[j]->getInducedVelocity(collPt),
60 normal);
61 }
62
63 // Compute the inverse matrix with the Gauss-Jordan algorithm
64 int ret = nr_gaussj(influenceMtx, nelm, nullptr, 0);
65 if (ret) {
66 // Something went wrong with the matrix inversion.
67
68 // 1. Nullify the influence matrix to disable the current aircraft wake.
69 for (int i=0; i < nelm; ++i) {
70 for (int j=0; j < nelm; ++j)
71 influenceMtx[i+1][j+1] = 0.0;
72 }
73 // 2. Report the issue in the log.
74 SG_LOG(SG_FLIGHT, SG_WARN,
75 "Failed to build wake mesh. " << aircraft_name << " ( span:"
76 << _span << ", chord:" << _chord << ") wake will be ignored.");
77 }
78}
79
85
86double WakeMesh::computeAoA(double vel, double rho, double weight)
87{
88 for (int i=1; i<=nelm; ++i) {
89 Gamma[i][1] = 0.0;
90 for (int k=1; k<=nelm; ++k)
91 Gamma[i][1] -= influenceMtx[i][k];
92 Gamma[i][1] *= vel;
93 }
94
95 // Compute the lift only. Velocities in the z direction are discarded
96 // because they only produce drag. This include the vertical component
97 // vel*sin(alpha) and the induced velocities on the bound vortex.
98 // This assumption is only valid for small angles.
99 SGVec3d f(0.,0.,0.);
100 SGVec3d v(-vel, 0.0, 0.0);
101
102 for (int i=0; i<nelm; ++i)
103 f += rho*Gamma[i+1][1]*cross(v, elements[i]->getBoundVortex());
104
105 double sinAlpha = -weight/f[2];
106
107 for (int i=1; i<=nelm; ++i)
108 Gamma[i][1] *= sinAlpha;
109
110 return asin(sinAlpha);
111}
112
113SGVec3d WakeMesh::getInducedVelocityAt(const SGVec3d& at) const
114{
115 SGVec3d v(0., 0., 0.);
116
117 for (int i=0; i<nelm; ++i)
118 v += Gamma[i+1][1] * elements[i]->getInducedVelocity(at);
119
120 return v;
121}
#define i(x)
std::vector< AeroElement_ptr > elements
Definition WakeMesh.hxx:45
double ** influenceMtx
Definition WakeMesh.hxx:46
double ** Gamma
Definition WakeMesh.hxx:46
virtual ~WakeMesh()
Definition WakeMesh.cxx:80
double computeAoA(double vel, double rho, double weight)
Definition WakeMesh.cxx:86
SGVec3d getInducedVelocityAt(const SGVec3d &at) const
Definition WakeMesh.cxx:113
WakeMesh(double _span, double _chord, const std::string &aircraft_name)
Definition WakeMesh.cxx:36
double span
Definition WakeMesh.hxx:44
double chord
Definition WakeMesh.hxx:44
double ** nr_matrix(long nrl, long nrh, long ncl, long nch)
Definition ls_matrix.c:122
int nr_gaussj(double **a, int n, double **b, int m)
Definition ls_matrix.c:172
void nr_free_matrix(double **m, long nrl, long nrh, long ncl, long nch)
Definition ls_matrix.c:164