From a9e42d7abc89c6d6bae318b8afc6757767cb19d0 Mon Sep 17 00:00:00 2001 From: acrovato <a.crovato@uliege.be> Date: Mon, 6 Jul 2020 15:30:20 +0200 Subject: [PATCH] Add Problem, lifting and non-lifting Body, Wake. Add basic model + test. --- fpm/_src/fpmw.h | 4 + fpm/_src/fpmw.i | 13 ++- fpm/models/n0012.geo | 254 +++++++++++++++++++++++++++++++++++++++++++ fpm/src/fBody.cpp | 77 +++++++++++++ fpm/src/fBody.h | 55 ++++++++++ fpm/src/fLifting.cpp | 44 ++++++++ fpm/src/fLifting.h | 47 ++++++++ fpm/src/fProblem.cpp | 109 +++++++++++++++++++ fpm/src/fProblem.h | 62 +++++++++++ fpm/src/fWake.cpp | 27 +++++ fpm/src/fWake.h | 43 ++++++++ fpm/src/fpm.h | 10 +- fpm/tests/basic.py | 57 ++++++++++ 13 files changed, 799 insertions(+), 3 deletions(-) create mode 100644 fpm/models/n0012.geo create mode 100644 fpm/src/fBody.cpp create mode 100644 fpm/src/fBody.h create mode 100644 fpm/src/fLifting.cpp create mode 100644 fpm/src/fLifting.h create mode 100644 fpm/src/fProblem.cpp create mode 100644 fpm/src/fProblem.h create mode 100644 fpm/src/fWake.cpp create mode 100644 fpm/src/fWake.h create mode 100644 fpm/tests/basic.py diff --git a/fpm/_src/fpmw.h b/fpm/_src/fpmw.h index ce160ec..53f2b18 100644 --- a/fpm/_src/fpmw.h +++ b/fpm/_src/fpmw.h @@ -14,4 +14,8 @@ * limitations under the License. */ +#include "fBody.h" +#include "fLifting.h" +#include "fProblem.h" #include "fTimers.h" +#include "fWake.h" diff --git a/fpm/_src/fpmw.i b/fpm/_src/fpmw.i index a9bb68b..d3a9efb 100644 --- a/fpm/_src/fpmw.i +++ b/fpm/_src/fpmw.i @@ -65,4 +65,15 @@ def __getitem__(self, name): } }; -//%include <std_shared_ptr.i> +%include <std_shared_ptr.i> + +%shared_ptr(fpm::Body); +%include "fBody.h" +%shared_ptr(fpm::Lifting); +%immutable fpm::Lifting::wake; // avoids the creation of the setter method +%include "fLifting.h" +%include "fWake.h" + +%shared_ptr(fpm::Problem); +%immutable fpm::Problem::msh; // avoids the creation of the setter method +%include "fProblem.h" diff --git a/fpm/models/n0012.geo b/fpm/models/n0012.geo new file mode 100644 index 0000000..4d69a59 --- /dev/null +++ b/fpm/models/n0012.geo @@ -0,0 +1,254 @@ +/* Rectangular NACA0012 wing */ + +// Parameters +// domain and mesh +DefineConstant[ spn = { 2.0, Name "Wing span" } ]; +DefineConstant[ nC = { 80, Name "Number of cells along chord" } ]; +DefineConstant[ nS = { 10, Name "Number of cells along span" } ]; + +//// GEOMETRY + +/// Points + +// Airfoil 1: naca0012, 101 points +Point(1) = {1.000000,0.000000,0.000000}; +Point(2) = {0.999013,0.000000,0.000143}; +Point(3) = {0.996057,0.000000,0.000572}; +Point(4) = {0.991144,0.000000,0.001280}; +Point(5) = {0.984292,0.000000,0.002260}; +Point(6) = {0.975528,0.000000,0.003501}; +Point(7) = {0.964888,0.000000,0.004990}; +Point(8) = {0.952414,0.000000,0.006710}; +Point(9) = {0.938153,0.000000,0.008643}; +Point(10) = {0.922164,0.000000,0.010770}; +Point(11) = {0.904508,0.000000,0.013071}; +Point(12) = {0.885257,0.000000,0.015523}; +Point(13) = {0.864484,0.000000,0.018106}; +Point(14) = {0.842274,0.000000,0.020795}; +Point(15) = {0.818712,0.000000,0.023569}; +Point(16) = {0.793893,0.000000,0.026405}; +Point(17) = {0.767913,0.000000,0.029279}; +Point(18) = {0.740877,0.000000,0.032168}; +Point(19) = {0.712890,0.000000,0.035048}; +Point(20) = {0.684062,0.000000,0.037896}; +Point(21) = {0.654508,0.000000,0.040686}; +Point(22) = {0.624345,0.000000,0.043394}; +Point(23) = {0.593691,0.000000,0.045992}; +Point(24) = {0.562667,0.000000,0.048455}; +Point(25) = {0.531395,0.000000,0.050754}; +Point(26) = {0.500000,0.000000,0.052862}; +Point(27) = {0.468605,0.000000,0.054749}; +Point(28) = {0.437333,0.000000,0.056390}; +Point(29) = {0.406309,0.000000,0.057755}; +Point(30) = {0.375655,0.000000,0.058819}; +Point(31) = {0.345492,0.000000,0.059557}; +Point(32) = {0.315938,0.000000,0.059947}; +Point(33) = {0.287110,0.000000,0.059971}; +Point(34) = {0.259123,0.000000,0.059614}; +Point(35) = {0.232087,0.000000,0.058863}; +Point(36) = {0.206107,0.000000,0.057712}; +Point(37) = {0.181288,0.000000,0.056159}; +Point(38) = {0.157726,0.000000,0.054206}; +Point(39) = {0.135516,0.000000,0.051862}; +Point(40) = {0.114743,0.000000,0.049138}; +Point(41) = {0.095492,0.000000,0.046049}; +Point(42) = {0.077836,0.000000,0.042615}; +Point(43) = {0.061847,0.000000,0.038859}; +Point(44) = {0.047586,0.000000,0.034803}; +Point(45) = {0.035112,0.000000,0.030473}; +Point(46) = {0.024472,0.000000,0.025893}; +Point(47) = {0.015708,0.000000,0.021088}; +Point(48) = {0.008856,0.000000,0.016078}; +Point(49) = {0.003943,0.000000,0.010884}; +Point(50) = {0.000987,0.000000,0.005521}; +Point(51) = {0.000000,0.000000,0.000000}; +Point(52) = {0.000987,0.000000,-0.005521}; +Point(53) = {0.003943,0.000000,-0.010884}; +Point(54) = {0.008856,0.000000,-0.016078}; +Point(55) = {0.015708,0.000000,-0.021088}; +Point(56) = {0.024472,0.000000,-0.025893}; +Point(57) = {0.035112,0.000000,-0.030473}; +Point(58) = {0.047586,0.000000,-0.034803}; +Point(59) = {0.061847,0.000000,-0.038859}; +Point(60) = {0.077836,0.000000,-0.042615}; +Point(61) = {0.095492,0.000000,-0.046049}; +Point(62) = {0.114743,0.000000,-0.049138}; +Point(63) = {0.135516,0.000000,-0.051862}; +Point(64) = {0.157726,0.000000,-0.054206}; +Point(65) = {0.181288,0.000000,-0.056159}; +Point(66) = {0.206107,0.000000,-0.057712}; +Point(67) = {0.232087,0.000000,-0.058863}; +Point(68) = {0.259123,0.000000,-0.059614}; +Point(69) = {0.287110,0.000000,-0.059971}; +Point(70) = {0.315938,0.000000,-0.059947}; +Point(71) = {0.345492,0.000000,-0.059557}; +Point(72) = {0.375655,0.000000,-0.058819}; +Point(73) = {0.406309,0.000000,-0.057755}; +Point(74) = {0.437333,0.000000,-0.056390}; +Point(75) = {0.468605,0.000000,-0.054749}; +Point(76) = {0.500000,0.000000,-0.052862}; +Point(77) = {0.531395,0.000000,-0.050754}; +Point(78) = {0.562667,0.000000,-0.048455}; +Point(79) = {0.593691,0.000000,-0.045992}; +Point(80) = {0.624345,0.000000,-0.043394}; +Point(81) = {0.654508,0.000000,-0.040686}; +Point(82) = {0.684062,0.000000,-0.037896}; +Point(83) = {0.712890,0.000000,-0.035048}; +Point(84) = {0.740877,0.000000,-0.032168}; +Point(85) = {0.767913,0.000000,-0.029279}; +Point(86) = {0.793893,0.000000,-0.026405}; +Point(87) = {0.818712,0.000000,-0.023569}; +Point(88) = {0.842274,0.000000,-0.020795}; +Point(89) = {0.864484,0.000000,-0.018106}; +Point(90) = {0.885257,0.000000,-0.015523}; +Point(91) = {0.904508,0.000000,-0.013071}; +Point(92) = {0.922164,0.000000,-0.010770}; +Point(93) = {0.938153,0.000000,-0.008643}; +Point(94) = {0.952414,0.000000,-0.006710}; +Point(95) = {0.964888,0.000000,-0.004990}; +Point(96) = {0.975528,0.000000,-0.003501}; +Point(97) = {0.984292,0.000000,-0.002260}; +Point(98) = {0.991144,0.000000,-0.001280}; +Point(99) = {0.996057,0.000000,-0.000572}; +Point(100) = {0.999013,0.000000,-0.000143}; + +// Airfoil 2: naca0012, 101 points +Point(102) = {1.000000,spn,0.000000}; +Point(103) = {0.999013,spn,0.000143}; +Point(104) = {0.996057,spn,0.000572}; +Point(105) = {0.991144,spn,0.001280}; +Point(106) = {0.984292,spn,0.002260}; +Point(107) = {0.975528,spn,0.003501}; +Point(108) = {0.964888,spn,0.004990}; +Point(109) = {0.952414,spn,0.006710}; +Point(110) = {0.938153,spn,0.008643}; +Point(111) = {0.922164,spn,0.010770}; +Point(112) = {0.904508,spn,0.013071}; +Point(113) = {0.885257,spn,0.015523}; +Point(114) = {0.864484,spn,0.018106}; +Point(115) = {0.842274,spn,0.020795}; +Point(116) = {0.818712,spn,0.023569}; +Point(117) = {0.793893,spn,0.026405}; +Point(118) = {0.767913,spn,0.029279}; +Point(119) = {0.740877,spn,0.032168}; +Point(120) = {0.712890,spn,0.035048}; +Point(121) = {0.684062,spn,0.037896}; +Point(122) = {0.654508,spn,0.040686}; +Point(123) = {0.624345,spn,0.043394}; +Point(124) = {0.593691,spn,0.045992}; +Point(125) = {0.562667,spn,0.048455}; +Point(126) = {0.531395,spn,0.050754}; +Point(127) = {0.500000,spn,0.052862}; +Point(128) = {0.468605,spn,0.054749}; +Point(129) = {0.437333,spn,0.056390}; +Point(130) = {0.406309,spn,0.057755}; +Point(131) = {0.375655,spn,0.058819}; +Point(132) = {0.345492,spn,0.059557}; +Point(133) = {0.315938,spn,0.059947}; +Point(134) = {0.287110,spn,0.059971}; +Point(135) = {0.259123,spn,0.059614}; +Point(136) = {0.232087,spn,0.058863}; +Point(137) = {0.206107,spn,0.057712}; +Point(138) = {0.181288,spn,0.056159}; +Point(139) = {0.157726,spn,0.054206}; +Point(140) = {0.135516,spn,0.051862}; +Point(141) = {0.114743,spn,0.049138}; +Point(142) = {0.095492,spn,0.046049}; +Point(143) = {0.077836,spn,0.042615}; +Point(144) = {0.061847,spn,0.038859}; +Point(145) = {0.047586,spn,0.034803}; +Point(146) = {0.035112,spn,0.030473}; +Point(147) = {0.024472,spn,0.025893}; +Point(148) = {0.015708,spn,0.021088}; +Point(149) = {0.008856,spn,0.016078}; +Point(150) = {0.003943,spn,0.010884}; +Point(151) = {0.000987,spn,0.005521}; +Point(152) = {0.000000,spn,0.000000}; +Point(153) = {0.000987,spn,-0.005521}; +Point(154) = {0.003943,spn,-0.010884}; +Point(155) = {0.008856,spn,-0.016078}; +Point(156) = {0.015708,spn,-0.021088}; +Point(157) = {0.024472,spn,-0.025893}; +Point(158) = {0.035112,spn,-0.030473}; +Point(159) = {0.047586,spn,-0.034803}; +Point(160) = {0.061847,spn,-0.038859}; +Point(161) = {0.077836,spn,-0.042615}; +Point(162) = {0.095492,spn,-0.046049}; +Point(163) = {0.114743,spn,-0.049138}; +Point(164) = {0.135516,spn,-0.051862}; +Point(165) = {0.157726,spn,-0.054206}; +Point(166) = {0.181288,spn,-0.056159}; +Point(167) = {0.206107,spn,-0.057712}; +Point(168) = {0.232087,spn,-0.058863}; +Point(169) = {0.259123,spn,-0.059614}; +Point(170) = {0.287110,spn,-0.059971}; +Point(171) = {0.315938,spn,-0.059947}; +Point(172) = {0.345492,spn,-0.059557}; +Point(173) = {0.375655,spn,-0.058819}; +Point(174) = {0.406309,spn,-0.057755}; +Point(175) = {0.437333,spn,-0.056390}; +Point(176) = {0.468605,spn,-0.054749}; +Point(177) = {0.500000,spn,-0.052862}; +Point(178) = {0.531395,spn,-0.050754}; +Point(179) = {0.562667,spn,-0.048455}; +Point(180) = {0.593691,spn,-0.045992}; +Point(181) = {0.624345,spn,-0.043394}; +Point(182) = {0.654508,spn,-0.040686}; +Point(183) = {0.684062,spn,-0.037896}; +Point(184) = {0.712890,spn,-0.035048}; +Point(185) = {0.740877,spn,-0.032168}; +Point(186) = {0.767913,spn,-0.029279}; +Point(187) = {0.793893,spn,-0.026405}; +Point(188) = {0.818712,spn,-0.023569}; +Point(189) = {0.842274,spn,-0.020795}; +Point(190) = {0.864484,spn,-0.018106}; +Point(191) = {0.885257,spn,-0.015523}; +Point(192) = {0.904508,spn,-0.013071}; +Point(193) = {0.922164,spn,-0.010770}; +Point(194) = {0.938153,spn,-0.008643}; +Point(195) = {0.952414,spn,-0.006710}; +Point(196) = {0.964888,spn,-0.004990}; +Point(197) = {0.975528,spn,-0.003501}; +Point(198) = {0.984292,spn,-0.002260}; +Point(199) = {0.991144,spn,-0.001280}; +Point(200) = {0.996057,spn,-0.000572}; +Point(201) = {0.999013,spn,-0.000143}; + +/// Lines + +// Airfoil 1: +Spline(1) = {1:51}; +Spline(2) = {51:100,1}; + +// Airfoil 2: +Spline(5) = {102:152}; +Spline(6) = {152:201,102}; + +// Airfoil 1 to airfoil 2: +Line(61) = {1,102}; +Line(62) = {51,152}; + +/// Line loops & Surfaces + +// Wing: +Line Loop(1) = {1,62,-5,-61}; +Line Loop(2) = {2,61,-6,-62}; +Surface(1) = {-1}; +Surface(2) = {-2}; + +//// MESHING + +/// Lines + +// Wing: +Transfinite Line{1, 2, 5, 6} = nC Using Bump 0.05; +Transfinite Line{61, 62} = nS; + +/// Surfaces +Transfinite Surface{1, 2}; +Recombine Surface{1, 2}; + +//// PHYSICAL GROUPS + +// Wing: +Physical Surface("wing") = {1,2}; diff --git a/fpm/src/fBody.cpp b/fpm/src/fBody.cpp new file mode 100644 index 0000000..b890528 --- /dev/null +++ b/fpm/src/fBody.cpp @@ -0,0 +1,77 @@ +/* + * Copyright 2020 University of Liège + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "fBody.h" +#include "wTag.h" +#include <iomanip> +#include <fstream> +using namespace tbox; +using namespace fpm; + +Body::Body(std::shared_ptr<MshData> _msh, int no) : Group(_msh, no), Cl(0), Cd(0), Cs(0), Cm(0) +{ + cLoadX.resize(tag->elems.size()); + cLoadY.resize(tag->elems.size()); + cLoadZ.resize(tag->elems.size()); +} + +Body::Body(std::shared_ptr<MshData> _msh, std::string const &name) : Group(_msh, name), Cl(0), Cd(0), Cs(0), Cm(0) +{ + cLoadX.resize(tag->elems.size()); + cLoadY.resize(tag->elems.size()); + cLoadZ.resize(tag->elems.size()); +} + +/** + * @brief Save global quantities to file + */ +void Body::save(std::string const &name) +{ + // Write to file + std::cout << "writing file: " << name + ".dat" + << "... " << std::flush; + std::ofstream outfile; + outfile.open(name + ".dat"); + // Header + outfile << "$Body - " << tag->name << std::endl; + // Element count + outfile << "$Elements" << std::endl; + outfile << tag->elems.size(); + // Aerodynamic coefficients + outfile << "$Aerodynamic coefficients" << std::endl; + outfile << "#" << std::fixed + << std::setw(14) << "Cl" + << std::setw(15) << "Cd" + << std::setw(15) << "Cs" + << std::setw(15) << "Cm" + << std::endl; + outfile << std::fixed + << std::setw(15) << Cl + << std::setw(15) << Cd + << std::setw(15) << Cs + << std::setw(15) << Cm + << std::endl; + // Footer + outfile << std::endl; + // Close file + outfile.close(); + std::cout << "done!" << std::endl; +} + +void Body::write(std::ostream &out) const +{ + out << "fpm::Body " << *tag << std::endl; +} diff --git a/fpm/src/fBody.h b/fpm/src/fBody.h new file mode 100644 index 0000000..05096ba --- /dev/null +++ b/fpm/src/fBody.h @@ -0,0 +1,55 @@ +/* + * Copyright 2020 University of Liège + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FBODY_H +#define FBODY_H + +#include "fpm.h" +#include "wGroup.h" +#include <vector> + +namespace fpm +{ + +/** + * @brief Manage a body immersed in the fluid + * @authors Adrien Crovato + */ +class FPM_API Body : public tbox::Group +{ +public: + double Cl; ///< lift coefficient + double Cd; ///< drag coefficient + double Cs; ///< sideforce coefficient + double Cm; ///< pitch moment coefficient (positive nose-up) + std::vector<double> cLoadX; ///< x-component of aerodynamic load coefficient on boundary + std::vector<double> cLoadY; ///< y-component of aerodynamic load coefficient on boundary + std::vector<double> cLoadZ; ///< z-component of aerodynamic load coefficient on boundary + + Body(std::shared_ptr<tbox::MshData> _msh, int no); + Body(std::shared_ptr<tbox::MshData> _msh, std::string const &name); + ~Body() { std::cout << "~Body()\n"; } + + virtual void save(std::string const &name); + +#ifndef SWIG + virtual void write(std::ostream &out) const override; +#endif +}; + +} // namespace fpm + +#endif //FBODY_H diff --git a/fpm/src/fLifting.cpp b/fpm/src/fLifting.cpp new file mode 100644 index 0000000..4c018ae --- /dev/null +++ b/fpm/src/fLifting.cpp @@ -0,0 +1,44 @@ +/* + * Copyright 2020 University of Liège + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "fLifting.h" +#include "fWake.h" +#include "wTag.h" +#include <iomanip> +#include <fstream> +using namespace tbox; +using namespace fpm; + +Lifting::Lifting(std::shared_ptr<MshData> _msh, int no) : Body(_msh, no) +{ + wake = new Wake(); +} + +Lifting::Lifting(std::shared_ptr<MshData> _msh, std::string const &name) : Body(_msh, name) +{ + wake = new Wake(); +} + +Lifting::~Lifting() +{ + delete wake; + std::cout << "~Lifting()\n"; +} + +void Lifting::write(std::ostream &out) const +{ + out << "fpm::Lifting " << *tag << std::endl; +} diff --git a/fpm/src/fLifting.h b/fpm/src/fLifting.h new file mode 100644 index 0000000..e8439f0 --- /dev/null +++ b/fpm/src/fLifting.h @@ -0,0 +1,47 @@ +/* + * Copyright 2020 University of Liège + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FLIFTING_H +#define FLIFTING_H + +#include "fpm.h" +#include "fBody.h" +#include "fWake.h" + +namespace fpm +{ + +/** + * @brief Manage a lifting body immersed in the fluid + * @authors Adrien Crovato + */ +class FPM_API Lifting : public Body +{ +public: + Wake *wake; ///< wake attached to the lifting surface + + Lifting(std::shared_ptr<tbox::MshData> _msh, int no); + Lifting(std::shared_ptr<tbox::MshData> _msh, std::string const &name); + ~Lifting(); + +#ifndef SWIG + virtual void write(std::ostream &out) const override; +#endif +}; + +} // namespace fpm + +#endif //FLIFTING_H diff --git a/fpm/src/fProblem.cpp b/fpm/src/fProblem.cpp new file mode 100644 index 0000000..fb67f53 --- /dev/null +++ b/fpm/src/fProblem.cpp @@ -0,0 +1,109 @@ +/* + * Copyright 2020 University of Liège + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "fProblem.h" +#include "fBody.h" +#include "fLifting.h" +#include "wTag.h" +#include "wElement.h" +#include "wMem.h" +using namespace tbox; +using namespace fpm; + +Problem::Problem(std::shared_ptr<MshData> _msh, double aoa, double aos, double sref, double cref, + double xref, double yref, double zref) : msh(_msh), alpha(aoa), beta(aos), + sR(sref), cR(cref) +{ + xR(0) = xref; + xR(1) = yref; + xR(2) = zref; +} + +/** + * @brief Add a non-lifting body + */ +void Problem::add(std::shared_ptr<Body> b) +{ + bodies.push_back(b); +} +/** + * @brief Add a lifting body + */ +void Problem::add(std::shared_ptr<Lifting> l) +{ + liftings.push_back(l); +} + +/** + * @brief Update the elements memory (Jacobian) + */ +void Problem::updateMem() +{ + // Update surface Jacobian + for (auto s : bodies) + for (auto e : s->tag->elems) + e->getVMem().update(false); + for (auto s : liftings) + for (auto e : s->tag->elems) + e->getVMem().update(false); +} + +/** + * @brief Check that Problem is not empty and that elements are supported + */ +void Problem::check() const +{ + // Sanity checks + if (liftings.empty()) + throw std::runtime_error("No lifting bodies provided!\n"); + + // Three-dimension problem + // Surface element type + for (auto b : bodies) + for (auto e : b->tag->elems) + if (e->type() != ELTYPE::QUAD4) + { + std::stringstream err; + err << "FPM solver is only implemented for surface elements of type " + << ELTYPE::QUAD4 << " (" << e->type() << " was given)!\n"; + throw std::runtime_error(err.str()); + } + for (auto l : liftings) + for (auto e : l->tag->elems) + if (e->type() != ELTYPE::QUAD4) + { + std::stringstream err; + err << "FPM solver is only implemented for surface elements of type " + << ELTYPE::QUAD4 << " (" << e->type() << " was given)!\n"; + throw std::runtime_error(err.str()); + } +} + +void Problem::write(std::ostream &out) const +{ + out << "fpm::Problem definition" + << "\n\tAngle of attack: " << alpha + << "\n\tAngle of sideslip: " << beta + << "\n\tReference area: " << sR + << "\n\tReference length: " << cR + << "\n\tReference point: [" << xR.transpose() << "]" + << std::endl; + out << "with"; + for (auto b : bodies) + out << "\n\t" << *b; + for (auto l : liftings) + out << "\n\t" << *l; +} diff --git a/fpm/src/fProblem.h b/fpm/src/fProblem.h new file mode 100644 index 0000000..d34d255 --- /dev/null +++ b/fpm/src/fProblem.h @@ -0,0 +1,62 @@ +/* + * Copyright 2020 University of Liège + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#ifndef FPROBLEM_H +#define FPROBLEM_H + +#include "fpm.h" +#include "wObject.h" +#include <memory> +#include <vector> +#include <Eigen/Dense> + +namespace fpm +{ + +/** + * @brief Manage the problem + * @authors Adrien Crovato + */ +class FPM_API Problem : public fwk::wSharedObject +{ +public: + std::shared_ptr<tbox::MshData> msh; ///< Mesh data structure +#ifndef SWIG + std::vector<std::shared_ptr<Body>> bodies; ///< Non-lifting bodies + std::vector<std::shared_ptr<Lifting>> liftings; ///< Lifting bodies +#endif + // Reference values + double alpha; ///< Angle of attack + double beta; ///< Angle of sideslip + double sR; ///< Reference surface + double cR; ///< Reference chord + Eigen::Vector3d xR; ///< Reference center point (for moment computation) + + Problem(std::shared_ptr<tbox::MshData> _msh, double aoa, double aos, double sref, double cref, double xref, double yref, double zref); + ~Problem() { std::cout << "~Problem()\n"; } + + void add(std::shared_ptr<Body> b); + void add(std::shared_ptr<Lifting> l); + +#ifndef SWIG + void check() const; + void updateMem(); + virtual void write(std::ostream &out) const override; +#endif +}; + +} // namespace fpm + +#endif //FPROBLEM_H diff --git a/fpm/src/fWake.cpp b/fpm/src/fWake.cpp new file mode 100644 index 0000000..02aed26 --- /dev/null +++ b/fpm/src/fWake.cpp @@ -0,0 +1,27 @@ +/* + * Copyright 2020 University of Liège + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "fWake.h" +using namespace fpm; + +Wake::Wake() : fwk::wObject() +{ +} + +void Wake::write(std::ostream &out) const +{ + out << "fpm::Wake " << std::endl; +} diff --git a/fpm/src/fWake.h b/fpm/src/fWake.h new file mode 100644 index 0000000..f32d68e --- /dev/null +++ b/fpm/src/fWake.h @@ -0,0 +1,43 @@ +/* + * Copyright 2020 University of Liège + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FWAKE_H +#define FWAKE_H + +#include "fpm.h" +#include "wObject.h" + +namespace fpm +{ + +/** + * @brief Manage the wake attached to a lifting body + * @authors Adrien Crovato + */ +class FPM_API Wake : public fwk::wObject +{ +public: + Wake(); + ~Wake() {} + +#ifndef SWIG + virtual void write(std::ostream &out) const override; +#endif +}; + +} // namespace fpm + +#endif //FWAKE_H diff --git a/fpm/src/fpm.h b/fpm/src/fpm.h index e408ab5..2eb1d20 100644 --- a/fpm/src/fpm.h +++ b/fpm/src/fpm.h @@ -35,8 +35,14 @@ namespace fpm { // utilities -class fTimer; -class fTimers; +class Timer; +class Timers; + +// problem definition +class Problem; +class Body; +class Lifting; +class Wake; } // namespace fpm diff --git a/fpm/tests/basic.py b/fpm/tests/basic.py new file mode 100644 index 0000000..1a96b37 --- /dev/null +++ b/fpm/tests/basic.py @@ -0,0 +1,57 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +# Copyright 2020 University of Liège +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Dummy test +# Adrien Crovato + +import fpm +import tbox +import tbox.gmsh as gmsh +from fwk.testing import * +from fwk.coloring import ccolors + +def main(): + # timer + tms = fpm.Timers() + tms['total'].start() + # mesh + print(ccolors.ANSI_BLUE + 'PyMeshing...' + ccolors.ANSI_RESET) + pars = {'spn' : 5, 'nC' : 80, 'nS' : 10} + msh = gmsh.MeshLoader('../models/n0012.geo', __file__).execute(**pars) + # problem + pbl = fpm.Problem(msh, 0, 0, 5., 1., 0., 0., 0.) + fuselage = fpm.Body(msh, 'wing') + pbl.add(fuselage) + wing = fpm.Lifting(msh, 'wing') + pbl.add(wing) + print(pbl) + # end timer + tms['total'].stop() + print(ccolors.ANSI_BLUE + 'PyTiming...' + ccolors.ANSI_RESET) + print(tms) + + # test + print(ccolors.ANSI_BLUE + 'PyTesting...' + ccolors.ANSI_RESET) + tests = CTests() + tests.run() + + # eof + print('') + +if __name__ == '__main__': + main() + -- GitLab