Nektar++
Loading...
Searching...
No Matches
ProcessForceDecomposeBnd.cpp
Go to the documentation of this file.
1////////////////////////////////////////////////////////////////////////////////
2//
3// File: ProcessForceDecomposeBnd.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// Permission is hereby granted, free of charge, to any person obtaining a
14// copy of this software and associated documentation files (the "Software"),
15// to deal in the Software without restriction, including without limitation
16// the rights to use, copy, modify, merge, publish, distribute, sublicense,
17// and/or sell copies of the Software, and to permit persons to whom the
18// Software is furnished to do so, subject to the following conditions:
19//
20// The above copyright notice and this permission notice shall be included
21// in all copies or substantial portions of the Software.
22//
23// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29// DEALINGS IN THE SOFTWARE.
30//
31// Description: Computes boundary force elements using weighted pressure source
32// theory.
33//
34////////////////////////////////////////////////////////////////////////////////
35
36#include <iostream>
37#include <string>
38
41
43
44using namespace std;
45
46namespace Nektar::FieldUtils
47{
48
51 ModuleKey(eProcessModule, "FDecomposeBnd"),
52 ProcessForceDecomposeBnd::create, "Computes boundary force elements.");
53
56{
57 f->m_declareExpansionAsContField = true;
58 f->m_requireBoundaryExpansion = true;
59}
60
64
65void ProcessForceDecomposeBnd::v_Process(po::variables_map &vm)
66{
67 m_f->SetUpExp(vm);
68
69 if (m_f->m_exp[0]->GetNumElmts() != 0)
70 {
71 for (size_t i = 0; i < m_f->m_exp.size(); ++i)
72 {
73 m_f->m_exp[i]->FillBndCondFromField(m_f->m_exp[i]->GetCoeffs());
74 }
75 }
76
77 int nfields = m_f->m_variables.size();
78 m_expdim = m_f->m_graph->GetSpaceDimension();
79 m_spacedim = m_expdim + m_f->m_numHomogeneousDir;
80 if (m_f->m_exp[0]->GetNumElmts() == 0)
81 {
82 return;
83 }
84 if (m_spacedim == 1)
85 {
88 "Error: Force decomposition for a 1D problem cannot be computed");
89 }
90
91 // Create map of boundary ids for partitioned domains
92 int nBnds = 0, cnt = 0, Nphi = 0;
93 map<int, int> BndRegionMap;
95 m_f->m_exp[0]->GetGraph());
98 for (auto &breg_it : bregions)
99 {
100 nBnds = max(nBnds, breg_it.first);
101 BndRegionMap[breg_it.first] = cnt++;
102 }
103 // assuming all boundary regions are consecutive number if
104 // regions is one more than maximum id
105 nBnds++;
106 // not all partitions in parallel touch all boundaries so
107 // find maximum number of boundaries
108 m_f->m_comm->GetSpaceComm()->AllReduce(nBnds, LibUtilities::ReduceMax);
109
110 std::map<int, std::string> Infophi;
111 GetInfoPhi(Infophi);
112 Nphi = Infophi.size();
113
114 // Declare arrays
117
118 Array<OneD, NekDouble> friction(nBnds * m_spacedim,
119 std::numeric_limits<NekDouble>::lowest());
120 Array<OneD, NekDouble> vispress(nBnds * Nphi,
121 std::numeric_limits<NekDouble>::lowest());
122 Array<OneD, NekDouble> acceleration(
123 nBnds * Nphi, std::numeric_limits<NekDouble>::lowest());
124
125 // Loop over boundaries to Write, boundary integral
126 for (const auto &bit : bregions)
127 {
128 int b = BndRegionMap[bit.first];
129 // Get expansion list for boundary and for elements containing this bnd
130 for (int i = 0; i < nfields; i++)
131 {
132 BndExp[i] = m_f->m_exp[i]->UpdateBndCondExpansion(b);
133 }
134 for (int i = 0; i < nfields; i++)
135 {
136 m_f->m_exp[i]->GetBndElmtExpansion(b, BndElmtExp[i]);
137 }
138
139 // Get number of points in expansions
140 int nqb = BndExp[0]->GetTotPoints();
141
142 // Initialise local arrays for the velocity gradients, and
143 // stress components size of total number of quadrature
144 // points for elements in this bnd
145 Array<OneD, Array<OneD, NekDouble>> gradp, stress, lapvel, phi;
146 GetPhi(BndElmtExp, phi, Infophi);
147 GetGradPressure(BndElmtExp, gradp);
148 GetStressTensor(BndElmtExp, stress);
149 GetLaplaceVelocity(BndElmtExp, lapvel);
150
151 // Get boundary values.
153 Array<OneD, NekDouble> normLapVel(nqb, 0.), normp(nqb, 0.),
154 norma(nqb, 0.), tmp(nqb, 0.);
155 Array<OneD, Array<OneD, NekDouble>> bndphi(phi.size());
157 for (size_t i = 0; i < bndvalue.size(); ++i)
158 {
159 bndvalue[i] = Array<OneD, NekDouble>(nqb);
160 }
161 for (size_t i = 0; i < bndphi.size(); ++i)
162 {
163 bndphi[i] = Array<OneD, NekDouble>(nqb);
164 }
165 // Reverse normals, to get correct orientation for the body
166 m_f->m_exp[0]->GetBoundaryNormals(b, normals);
167 for (int i = 0; i < m_spacedim; ++i)
168 {
169 Vmath::Neg(nqb, normals[i], 1);
170 }
171 // phi on boundary
172 for (size_t i = 0; i < phi.size(); ++i)
173 {
174 m_f->m_exp[0]->ExtractElmtToBndPhys(b, phi[i], bndphi[i]);
175 }
176 // wall shear stress
177 for (size_t i = 0; i < stress.size(); ++i)
178 {
179 m_f->m_exp[0]->ExtractElmtToBndPhys(b, stress[i], bndvalue[i]);
180 }
181 for (int i = 0; i < m_spacedim; ++i)
182 {
183 Vmath::Zero(nqb, tmp, 1);
184 for (int j = 0; j < m_expdim; ++j)
185 {
186 Vmath::Vvtvp(nqb, normals[j], 1, bndvalue[i * m_spacedim + j],
187 1, tmp, 1, tmp, 1);
188 }
189 friction[i + bit.first * m_spacedim] = BndExp[i]->Integral(tmp);
190 }
191 // wall pressure viscous
192 for (int i = 0; i < m_expdim; ++i)
193 {
194 m_f->m_exp[0]->ExtractElmtToBndPhys(b, lapvel[i], bndvalue[i]);
195 Vmath::Vvtvp(nqb, normals[i], 1, bndvalue[i], 1, normLapVel, 1,
196 normLapVel, 1);
197 }
198 Vmath::Smul(nqb, GetViscosity(), normLapVel, 1, normLapVel, 1);
199 for (int i = 0; i < Nphi; ++i)
200 {
201 Vmath::Vmul(nqb, bndphi[i], 1, normLapVel, 1, tmp, 1);
202 vispress[i + bit.first * Nphi] = BndExp[i]->Integral(tmp);
203 }
204 // wall acceleration
205 for (int i = 0; i < m_expdim; ++i)
206 {
207 m_f->m_exp[0]->ExtractElmtToBndPhys(b, gradp[i], bndvalue[i]);
208 Vmath::Vvtvp(nqb, normals[i], 1, bndvalue[i], 1, normp, 1, normp,
209 1);
210 }
211 Vmath::Vsub(nqb, normLapVel, 1, normp, 1, norma, 1);
212 for (int i = 0; i < Nphi; ++i)
213 {
214 Vmath::Vmul(nqb, bndphi[i], 1, norma, 1, tmp, 1);
215 acceleration[i + bit.first * Nphi] = -BndExp[i]->Integral(tmp);
216 }
217 }
218
219 m_f->m_comm->AllReduce(friction, LibUtilities::ReduceMax);
220 m_f->m_comm->AllReduce(vispress, LibUtilities::ReduceMax);
221 m_f->m_comm->AllReduce(acceleration, LibUtilities::ReduceMax);
222
223 if (m_f->m_comm->TreatAsRankZero())
224 {
225 cout << "Force decomposition results\n";
226 cout << "number of boundaries " << nBnds << "\n";
227 cout << "space dimension " << m_spacedim << "\n";
228 cout << "number of phi " << Nphi << "\n";
229 cout << "Friction force (x, y, ...)[" + std::to_string(m_spacedim) +
230 "] on all boundaries \n FRIC ";
231 for (const auto f : friction)
232 {
233 cout << f << " ";
234 }
235 cout << "\n";
236 cout << "Visouce pressure force (phi0, phi1, ...)[" +
237 std::to_string(Nphi) +
238 "] on all "
239 "boundaries \n VISP ";
240 for (const auto f : vispress)
241 {
242 cout << f << " ";
243 }
244 cout << "\n";
245 cout << "Wall acceleratrion (phi0, phi1, ...)[" + std::to_string(Nphi) +
246 "] on all boundaries "
247 "\n ACCF ";
248 for (const auto f : acceleration)
249 {
250 cout << f << " ";
251 }
252 cout << "\n";
253 }
254}
255
256} // namespace Nektar::FieldUtils
#define NEKERROR(type, msg)
Assert Level 0 – Fundamental assert which is used whether in FULLDEBUG, DEBUG or OPT compilation mode...
FieldSharedPtr m_f
Field object.
Definition Module.h:239
static std::shared_ptr< Module > create(FieldSharedPtr f)
Creates an instance of this class.
void v_Process(po::variables_map &vm) override
Write mesh to output file.
This processing module calculates the Q Criterion and adds it as an extra-field to the output file.
void GetGradPressure(const Array< OneD, MultiRegions::ExpListSharedPtr > exp, Array< OneD, Array< OneD, NekDouble > > &gradp)
void GetLaplaceVelocity(const Array< OneD, MultiRegions::ExpListSharedPtr > exp, Array< OneD, Array< OneD, NekDouble > > &lapvel)
void GetInfoPhi(std::map< int, std::string > &Iphi)
void GetStressTensor(const Array< OneD, MultiRegions::ExpListSharedPtr > exp, Array< OneD, Array< OneD, NekDouble > > &shear)
void GetPhi(const Array< OneD, MultiRegions::ExpListSharedPtr > exp, Array< OneD, Array< OneD, NekDouble > > &phi, std::map< int, std::string > &Iphi)
tKey RegisterCreatorFunction(tKey idKey, CreatorFunction classCreator, std::string pDesc="")
Register a class with the factory.
const BoundaryRegionCollection & GetBoundaryRegions(void) const
Definition Conditions.h:273
std::shared_ptr< Field > FieldSharedPtr
Definition Field.hpp:1026
std::pair< ModuleType, std::string > ModuleKey
Definition Module.h:180
ModuleFactory & GetModuleFactory()
Definition Module.cpp:47
std::map< int, BoundaryRegionShPtr > BoundaryRegionCollection
Definition Conditions.h:249
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.hpp:72
void Neg(int n, T *x, const int incx)
Negate x = -x.
Definition Vmath.hpp:292
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.hpp:366
void Smul(int n, const T alpha, const T *x, const int incx, T *y, const int incy)
Scalar multiply y = alpha*x.
Definition Vmath.hpp:100
void Zero(int n, T *x, const int incx)
Zero vector.
Definition Vmath.hpp:273
void Vsub(int n, const T *x, const int incx, const T *y, const int incy, T *z, const int incz)
Subtract vector z = x-y.
Definition Vmath.hpp:220
STL namespace.
scalarT< T > max(scalarT< T > lhs, scalarT< T > rhs)
Definition scalar.hpp:305