21#ifndef B2_ELEMENT_AEROACOUSTIC_H_
22#define B2_ELEMENT_AEROACOUSTIC_H_
26#include "elements/properties/b2aeroacoustic.H"
27#include "model/b2element.H"
28#include "model_imp/b2hnode.H"
30#include "utils/b2linear_algebra.H"
34#define NB_POINT_IN_CONSTRAINT 4
38template <
int NB_NODES,
int NB_GAUSS,
int NB_GAUSS_FACE>
39class GenericVolumeInterpolation {
41 static const int nb_nodes;
42 static const int nb_gauss;
45 double NodeCoor[NB_NODES][3];
48 double IntCoor[NB_GAUSS][3];
51 double weight[NB_GAUSS];
54 double N[NB_GAUSS][NB_NODES];
57 double dN[NB_GAUSS][NB_NODES][3];
59 static const int nb_gauss_face;
62 double IntCoor_face1[NB_GAUSS_FACE][3];
65 double weight_face1[NB_GAUSS_FACE];
68 double N_face1[NB_GAUSS_FACE][NB_NODES];
71 double dN_face1[NB_GAUSS_FACE][NB_NODES][3];
74 double IntCoor_face1_c[3];
77 double N_face1_c[NB_NODES];
78 double dN_face1_c[NB_NODES][3];
81template <
int NB_NODES,
int NB_GAUSS,
int NB_GAUSS_FACE>
82const int GenericVolumeInterpolation<NB_NODES, NB_GAUSS, NB_GAUSS_FACE>::nb_nodes = NB_NODES;
84template <
int NB_NODES,
int NB_GAUSS,
int NB_GAUSS_FACE>
85const int GenericVolumeInterpolation<NB_NODES, NB_GAUSS, NB_GAUSS_FACE>::nb_gauss = NB_GAUSS;
87template <
int NB_NODES,
int NB_GAUSS,
int NB_GAUSS_FACE>
88const int GenericVolumeInterpolation<NB_NODES, NB_GAUSS, NB_GAUSS_FACE>::nb_gauss_face =
91template <
typename INTERPOLATION>
94 using node_type = node::HNode<
95 coordof::Coor<coordof::Trans<coordof::X, coordof::Y, coordof::Z>>,
97 coordof::Density, coordof::DTrans<coordof::VX, coordof::VY, coordof::VZ>,
98 coordof::Temperature>>;
100 using type_t = ObjectTypeComplete<
101 ElementAeroAcoustic,
typename TypedElement<std::complex<double>>::type_t>;
103 int get_number_of_dof()
const override {
return INTERPOLATION::nb_nodes; }
105 void set_nodes(std::pair<int, Node* const*> nodes_)
override {
106 if (nodes_.first != INTERPOLATION::nb_nodes) {
107 Exception() <<
"This element has " << INTERPOLATION::nb_nodes <<
" nodes." <<
THROW;
109 for (
int i = 0; i != INTERPOLATION::nb_nodes; ++i) { nodes[i] = nodes_.second[i]; }
112 std::pair<int, Node* const*> get_nodes()
const override {
113 return std::pair<int, Node* const*>(INTERPOLATION::nb_nodes, nodes);
116 void set_property(ElementProperty* property_)
override {
117 property =
dynamic_cast<AeroAcousticPropertiesInterface*
>(property_);
118 if (property ==
nullptr) {
119 TypeError() <<
"Bad or missing element property type for aeroacoustic element "
124 const ElementProperty* get_property()
const override {
return property; }
126 void get_dof_numbering(b2linalg::Index& dof_numbering)
override {
127 dof_numbering.resize(5 * INTERPOLATION::nb_nodes);
128 size_t* ptr = &dof_numbering[0];
129 for (
int k = 0; k != INTERPOLATION::nb_nodes; ++k) {
130 ptr = nodes[k]->get_global_dof_numbering(ptr);
134 const std::vector<VariableInfo> get_value_info()
const override {
138 void get_static_linear_value(
139 Model& model, b2linalg::Vector<std::complex<double>, b2linalg::Vdense>& value,
140 b2linalg::Matrix<std::complex<double>, b2linalg::Mrectangle>& d_value_d_dof);
143 Model& model,
const bool linear,
const EquilibriumSolution equilibrium_solution,
144 const double time,
const double delta_time,
145 const b2linalg::Matrix<std::complex<double>, b2linalg::Mrectangle_constref>& dof,
146 GradientContainer* gradient_container, SolverHints* solver_hints,
147 b2linalg::Vector<std::complex<double>, b2linalg::Vdense>& value,
148 std::vector<b2linalg::Matrix<std::complex<double>, b2linalg::Mrectangle>>& d_value_d_dof,
149 b2linalg::Vector<std::complex<double>, b2linalg::Vdense>& d_value_d_time) {
150 get_static_linear_value(
152 d_value_d_dof.size() == 0 || d_value_d_dof[0].size1() == 0
153 ? b2linalg::Matrix<std::complex<double>, b2linalg::Mrectangle>::null
161 Node* nodes[INTERPOLATION::nb_nodes];
164 AeroAcousticPropertiesInterface* property;
166 static const INTERPOLATION N;
168 const bool symmetric{
false};
171template <
typename INTERPOLATION>
172const INTERPOLATION ElementAeroAcoustic<INTERPOLATION>::N;
174template <
typename INTERPOLATION>
175class ElementAeroAcousticRadiation :
public ElementAeroAcoustic<INTERPOLATION> {
177 using parent = ElementAeroAcoustic<INTERPOLATION>;
179 using type_t = ObjectTypeComplete<
180 ElementAeroAcousticRadiation,
typename TypedElement<std::complex<double>>::type_t>;
182 std::pair<int, Element::VariableInfo> get_constraint_info() {
183 return std::pair<int, Element::VariableInfo>(5 * NB_POINT_IN_CONSTRAINT,
Element::linear);
187 Model& model,
const bool linear,
double time,
188 const b2linalg::Matrix<std::complex<double>, b2linalg::Mrectangle_constref>& dof,
189 b2linalg::Vector<std::complex<double>, b2linalg::Vdense>& constraint,
190 b2linalg::Matrix<std::complex<double>, b2linalg::Mcompressed_col>& d_constraint_d_dof,
191 b2linalg::Vector<std::complex<double>, b2linalg::Vdense>& d_constraint_d_time);
193 void get_static_linear_value(
194 Model& model, b2linalg::Vector<std::complex<double>, b2linalg::Vdense>& value,
195 b2linalg::Matrix<std::complex<double>, b2linalg::Mrectangle>& d_value_d_dof);
200template <
typename INTERPOLATION>
201class ElementAeroAcousticContacte :
public ElementAeroAcoustic<INTERPOLATION> {
203 using parent = ElementAeroAcoustic<INTERPOLATION>;
205 using type_t = ObjectTypeComplete<
206 ElementAeroAcousticContacte,
typename TypedElement<std::complex<double>>::type_t>;
210 return std::pair<int, Element::VariableInfo>(3 * NB_POINT_IN_CONSTRAINT,
Element::linear);
212 return std::pair<int, Element::VariableInfo>(2 * NB_POINT_IN_CONSTRAINT,
Element::linear);
217 Model& model,
const bool linear,
double time,
218 const b2linalg::Matrix<std::complex<double>, b2linalg::Mrectangle_constref>& dof,
219 b2linalg::Vector<std::complex<double>, b2linalg::Vdense>& constraint,
220 b2linalg::Matrix<std::complex<double>, b2linalg::Mcompressed_col>& d_constraint_d_dof,
221 b2linalg::Vector<std::complex<double>, b2linalg::Vdense>& d_constraint_d_time);
223 void get_static_linear_value(
224 Model& model, b2linalg::Vector<std::complex<double>, b2linalg::Vdense>& value,
225 b2linalg::Matrix<std::complex<double>, b2linalg::Mrectangle>& d_value_d_dof) {
226 const size_t s = INTERPOLATION::nb_nodes * 5;
229 d_value_d_dof.resize(s, s);
230 d_value_d_dof.set_zero();
236template <
typename INTERPOLATION>
237class ElementAeroAcousticSymmetry :
public ElementAeroAcoustic<INTERPOLATION> {
239 using parent = ElementAeroAcoustic<INTERPOLATION>;
241 using type_t = ObjectTypeComplete<
242 ElementAeroAcousticSymmetry,
typename TypedElement<std::complex<double>>::type_t>;
246 return std::pair<int, Element::VariableInfo>(5 * NB_POINT_IN_CONSTRAINT,
Element::linear);
248 return std::pair<int, Element::VariableInfo>(4 * NB_POINT_IN_CONSTRAINT,
Element::linear);
253 Model& model,
const bool linear,
double time,
254 const b2linalg::Matrix<std::complex<double>, b2linalg::Mrectangle_constref>& dof,
255 b2linalg::Vector<std::complex<double>, b2linalg::Vdense>& constraint,
256 b2linalg::Matrix<std::complex<double>, b2linalg::Mcompressed_col>& d_constraint_d_dof,
257 b2linalg::Vector<std::complex<double>, b2linalg::Vdense>& d_constraint_d_time);
259 void get_static_linear_value(
260 Model& model, b2linalg::Vector<std::complex<double>, b2linalg::Vdense>& value,
261 b2linalg::Matrix<std::complex<double>, b2linalg::Mrectangle>& d_value_d_dof) {
262 const size_t s = INTERPOLATION::nb_nodes * 5;
265 d_value_d_dof.resize(s, s);
266 d_value_d_dof.set_zero();
274template <
typename INTERPOLATION>
275void b2000::ElementAeroAcoustic<INTERPOLATION>::get_static_linear_value(
276 Model& model, b2linalg::Vector<std::complex<double>, b2linalg::Vdense>& value,
277 b2linalg::Matrix<std::complex<double>, b2linalg::Mrectangle>& d_value_d_dof) {
278 const int number_of_dof = INTERPOLATION::nb_nodes * 5;
279 value.resize(number_of_dof);
281 d_value_d_dof.resize(number_of_dof, number_of_dof);
282 d_value_d_dof.set_zero();
285 double NodeCoor[INTERPOLATION::nb_nodes][3];
286 for (
int k = 0; k != INTERPOLATION::nb_nodes; ++k) {
287 node_type::get_coor_s(NodeCoor[k], nodes[k]);
293 std::complex<double> omega;
299 property->get_constant(c_K, c_R, c_r, c_omega);
300 omega = std::complex<double>(0, c_omega);
306 std::complex<double> omega;
310 property->get_constant(c_K, c_R, c_r, c_omega);
311 omega = std::complex<double>(0, c_omega);
312 c_cv = c_R / (c_K - 1);
317 for (
int ng = 0; ng != INTERPOLATION::nb_gauss; ++ng) {
321 for (
int j = 0; j != 3; ++j) {
322 for (
int i = 0; i != 3; ++i) {
324 for (
int n = 0; n != INTERPOLATION::nb_nodes; ++n) {
325 v += N.dN[ng][n][i] * NodeCoor[n][j];
333 const double weight =
invert_3_3(J, inv_J) * N.weight[ng];
337 double B[INTERPOLATION::nb_nodes][3];
339 'N',
'N', 3, INTERPOLATION::nb_nodes, 3, 1.0, inv_J[0], 3, N.dN[ng][0], 3, 0.0, B[0],
345 property->get_cfd_value_and_gradient(
346 model, INTERPOLATION::nb_nodes, nodes, N.N[ng], B, W0, d_W0);
350 const double Bg[5][5] = {
351 {d_W0[1][0] + d_W0[2][1] + d_W0[3][2], d_W0[0][0], d_W0[0][1], d_W0[0][2], 0},
352 {(W0[1] * d_W0[1][0] + W0[2] * d_W0[1][1] + W0[3] * d_W0[1][2]) / W0[0],
353 d_W0[1][0], d_W0[1][1], d_W0[1][2], 0},
354 {(W0[1] * d_W0[2][0] + W0[2] * d_W0[2][1] + W0[3] * d_W0[2][2]) / W0[0],
355 d_W0[2][0], d_W0[2][1], d_W0[2][2], 0},
356 {(W0[1] * d_W0[3][0] + W0[2] * d_W0[3][1] + W0[3] * d_W0[3][2]) / W0[0],
357 d_W0[3][0], d_W0[3][1], d_W0[3][2], 0},
358 {0, d_W0[4][0], d_W0[4][1], d_W0[4][2],
359 hcr * (d_W0[1][0] + d_W0[2][1] + d_W0[3][2])}};
361 const double A2 = hcr * W0[4];
362 const double inv_dense = 1 / W0[0];
363 for (
int nj = 0; nj != INTERPOLATION::nb_nodes; ++nj) {
364 const int nnj = nj * 5;
365 for (
int ni = 0; ni != INTERPOLATION::nb_nodes; ++ni) {
366 const int nni = ni * 5;
368 const double v = weight * N.N[ng][ni];
369 const double vx = v * B[nj][0];
370 const double vy = v * B[nj][1];
371 const double vz = v * B[nj][2];
372 const double A3 = W0[1] * vx + W0[2] * vy + W0[3] * vz;
373 d_value_d_dof(nni, nnj) += A3;
374 d_value_d_dof(nni + 1, nnj + 1) += A3;
375 d_value_d_dof(nni + 2, nnj + 2) += A3;
376 d_value_d_dof(nni + 3, nnj + 3) += A3;
377 d_value_d_dof(nni + 4, nnj + 4) += A3;
378 d_value_d_dof(nni + 4, nnj + 1) += A2 * vx;
379 d_value_d_dof(nni + 4, nnj + 2) += A2 * vy;
380 d_value_d_dof(nni + 4, nnj + 3) += A2 * vz;
381 d_value_d_dof(nni, nnj + 1) += W0[0] * vx;
382 d_value_d_dof(nni, nnj + 2) += W0[0] * vy;
383 d_value_d_dof(nni, nnj + 3) += W0[0] * vz;
384 d_value_d_dof(nni + 1, nnj + 4) += inv_dense * vx;
385 d_value_d_dof(nni + 2, nnj + 4) += inv_dense * vy;
386 d_value_d_dof(nni + 3, nnj + 4) += inv_dense * vz;
389 const double v = weight * N.N[ng][ni] * N.N[ng][nj];
390 for (
int j = 0; j != 5; ++j) {
391 d_value_d_dof(nni + j, nnj + j) += omega * v;
392 for (
int i = 0; i != 5; ++i) {
393 d_value_d_dof(nni + i, nnj + j) += v * Bg[i][j];
407 const double Bg[5][5] = {
408 {d_W0[1][0] + d_W0[2][1] + d_W0[3][2], d_W0[0][0], d_W0[0][1], d_W0[0][2], 0},
409 {(c_R * d_W0[4][0] + W0[1] * d_W0[1][0] + W0[2] * d_W0[1][1] + W0[3] * d_W0[1][2])
411 d_W0[1][0], d_W0[1][1], d_W0[1][2], c_R / W0[0] * d_W0[0][0]},
412 {(c_R * d_W0[4][1] + W0[1] * d_W0[2][0] + W0[2] * d_W0[2][1] + W0[3] * d_W0[2][2])
414 d_W0[2][0], d_W0[2][1], d_W0[2][2], c_R / W0[0] * d_W0[0][1]},
415 {(c_R * d_W0[4][2] + W0[1] * d_W0[3][0] + W0[2] * d_W0[3][1] + W0[3] * d_W0[3][2])
417 d_W0[3][0], d_W0[3][1], d_W0[3][2], c_R / W0[0] * d_W0[0][2]},
418 {c_R * W0[4] / (c_cv * W0[0]) * (d_W0[1][0] + d_W0[2][1] + d_W0[3][2])
419 - (W0[1] * d_W0[4][0] + W0[2] * d_W0[4][1] + W0[3] * d_W0[4][2]) / W0[0],
420 d_W0[4][0], d_W0[4][1], d_W0[4][2],
421 c_R / c_cv * (d_W0[1][0] + d_W0[2][1] + d_W0[3][2])}};
423 const double L = -weight * c_K / (c_cv * W0[0]);
424 const double dL = -weight * c_K / (c_cv * W0[0] * W0[0]);
425 const double dL_dx = dL * d_W0[0][0];
426 const double dL_dy = dL * d_W0[0][1];
427 const double dL_dz = dL * d_W0[0][2];
428 const double A1 = c_R * W0[4] / W0[0];
429 const double A2 = c_R * c_cv / W0[4];
430 for (
int nj = 0; nj != INTERPOLATION::nb_nodes; ++nj) {
431 const int nnj = nj * 5;
432 for (
int ni = 0; ni != INTERPOLATION::nb_nodes; ++ni) {
433 const int nni = ni * 5;
434 d_value_d_dof(nni + 4, nnj + 4) +=
435 N.N[ng][ni] * (dL_dx * B[nj][0] + dL_dy * B[nj][1] + dL_dz * B[nj][2])
436 + L * (B[ni][0] * B[nj][0] + B[ni][1] * B[nj][1] + B[ni][2] * B[nj][2]);
438 const double v = weight * N.N[ng][ni];
439 const double vx = v * B[nj][0];
440 const double vy = v * B[nj][1];
441 const double vz = v * B[nj][2];
442 const double A3 = W0[1] * vx + W0[2] * vy + W0[3] * vz;
443 d_value_d_dof(nni, nnj) += A3;
444 d_value_d_dof(nni + 1, nnj + 1) += A3;
445 d_value_d_dof(nni + 2, nnj + 2) += A3;
446 d_value_d_dof(nni + 3, nnj + 3) += A3;
447 d_value_d_dof(nni + 4, nnj + 4) += A3;
448 d_value_d_dof(nni + 1, nnj) += A1 * vx;
449 d_value_d_dof(nni + 2, nnj) += A1 * vy;
450 d_value_d_dof(nni + 3, nnj) += A1 * vz;
451 d_value_d_dof(nni + 4, nnj + 1) += A2 * vx;
452 d_value_d_dof(nni + 4, nnj + 2) += A2 * vy;
453 d_value_d_dof(nni + 4, nnj + 3) += A2 * vz;
454 d_value_d_dof(nni, nnj + 1) += W0[0] * vx;
455 d_value_d_dof(nni, nnj + 2) += W0[0] * vy;
456 d_value_d_dof(nni, nnj + 3) += W0[0] * vz;
457 d_value_d_dof(nni + 1, nnj + 4) += c_R * vx;
458 d_value_d_dof(nni + 2, nnj + 4) += c_R * vy;
459 d_value_d_dof(nni + 3, nnj + 4) += c_R * vz;
462 const double v = weight * N.N[ng][ni] * N.N[ng][nj];
463 for (
int j = 0; j != 5; ++j) {
464 d_value_d_dof(nni + j, nnj + j) += omega * v;
465 for (
int i = 0; i != 5; ++i) {
466 d_value_d_dof(nni + i, nnj + j) += v * Bg[i][j];
477template <
typename INTERPOLATION>
478void b2000::ElementAeroAcousticRadiation<INTERPOLATION>::get_static_linear_value(
479 Model& model, b2linalg::Vector<std::complex<double>, b2linalg::Vdense>& value,
480 b2linalg::Matrix<std::complex<double>, b2linalg::Mrectangle>& d_value_d_dof) {
482 const size_t s = INTERPOLATION::nb_nodes * 5;
485 d_value_d_dof.resize(s, s);
486 d_value_d_dof.set_zero();
488 const int number_of_dof = INTERPOLATION::nb_nodes * 5;
489 value.resize(number_of_dof);
491 d_value_d_dof.resize(number_of_dof, number_of_dof);
492 d_value_d_dof.set_zero();
495 double NodeCoor[INTERPOLATION::nb_nodes][3];
496 for (
int k = 0; k != INTERPOLATION::nb_nodes; ++k) {
497 parent::node_type::get_coor_s(NodeCoor[k], parent::nodes[k]);
507 parent::property->get_constant(c_K, c_R, c_r, c_omega);
508 c_cv = c_R / (c_K - 1);
512 for (
int ng = 0; ng != INTERPOLATION::nb_gauss_face; ++ng) {
516 for (
int j = 0; j != 3; ++j) {
517 for (
int i = 0; i != 3; ++i) {
519 for (
int n = 0; n != INTERPOLATION::nb_nodes; ++n) {
520 v += parent::N.dN_face1[ng][n][i] * NodeCoor[n][j];
528 const double weight =
invert_3_3(J, inv_J) * parent::N.weight_face1[ng];
532 double B[INTERPOLATION::nb_nodes][3];
534 'N',
'N', 3, INTERPOLATION::nb_nodes, 3, 1.0, inv_J[0], 3, parent::N.dN_face1[ng][0],
539 J[1][1] * J[2][0] - J[2][1] * J[1][0], J[2][1] * J[0][0] - J[0][1] * J[2][0],
540 J[0][1] * J[1][0] - J[1][1] * J[0][0]};
544 double Bnorm[INTERPOLATION::nb_nodes];
545 for (
int n = 0; n != INTERPOLATION::nb_nodes; ++n) {
546 Bnorm[n] = B[n][0] * Nface[0] + B[n][1] * Nface[1] + B[n][2] * Nface[2];
551 parent::property->get_cfd_value(
552 model, INTERPOLATION::nb_nodes, parent::nodes, parent::N.N_face1[ng], W0);
554 const double L = weight * c_K / (c_cv * W0[0]);
556 for (
int nj = 0; nj != INTERPOLATION::nb_nodes; ++nj) {
557 const int nnj = nj + 5;
558 for (
int ni = 0; ni != INTERPOLATION::nb_nodes; ++ni) {
559 d_value_d_dof(ni * 5 + 4, nnj + 4) += parent::N.N_face1[ng][ni] * L * Bnorm[nj];
566template <
typename INTERPOLATION>
567void b2000::ElementAeroAcousticRadiation<INTERPOLATION>::get_constraint(
568 Model& model,
const bool linear,
double time,
569 const b2linalg::Matrix<std::complex<double>, b2linalg::Mrectangle_constref>& dof,
570 b2linalg::Vector<std::complex<double>, b2linalg::Vdense>& constraint,
571 b2linalg::Matrix<std::complex<double>, b2linalg::Mcompressed_col>& trans_d_constraint_d_dof,
572 b2linalg::Vector<std::complex<double>, b2linalg::Vdense>& d_constraint_d_time) {
573#if NB_POINT_IN_CONSTRAINT == 1
575 double NodeCoor[INTERPOLATION::nb_nodes][3];
576 double face_coor[3] = {};
577 for (
int k = 0; k != INTERPOLATION::nb_nodes; ++k) {
578 parent::node_type::get_coor_s(NodeCoor[k], parent::nodes[k]);
579 face_coor[0] += parent::N.N_face1_c[k] * NodeCoor[k][0];
580 face_coor[1] += parent::N.N_face1_c[k] * NodeCoor[k][1];
581 face_coor[2] += parent::N.N_face1_c[k] * NodeCoor[k][2];
593 parent::property->get_constant(c_K, c_R, c_r, c_omega);
597 parent::property->get_cfd_value(
598 model, INTERPOLATION::nb_nodes, parent::nodes, parent::N.N_face1_c, W0);
599 double mean_sound_speed = std::sqrt(c_K * c_r * W0[4]);
600 double noise_source_pos[3];
601 parent::property->get_radiation_value(noise_source_pos);
603 r[0] = face_coor[0] - noise_source_pos[0];
604 r[1] = face_coor[1] - noise_source_pos[1];
605 r[2] = face_coor[2] - noise_source_pos[2];
606 rayon = std::sqrt(r[0] * r[0] + r[1] * r[1] + r[2] * r[2]);
607 const double inv_r = 1 / rayon;
611 const double u_er = r[0] * W0[1] + r[0] * W0[2] + r[0] * W0[3];
614 mean_sound_speed * mean_sound_speed - W0[1] * W0[1] - W0[2] * W0[2]
615 - W0[3] * W0[3] + u_er * u_er);
621 for (
int j = 0; j != 3; ++j) {
622 for (
int i = 0; i != 3; ++i) {
624 for (
int n = 0; n != INTERPOLATION::nb_nodes; ++n) {
625 v += parent::N.dN_face1_c[n][i] * NodeCoor[n][j];
637 double B[INTERPOLATION::nb_nodes][3];
639 'N',
'N', 3, INTERPOLATION::nb_nodes, 3, 1.0, inv_J[0], 3, parent::N.dN_face1_c[0], 3,
643 double Bnorm[INTERPOLATION::nb_nodes];
644 for (
int n = 0; n != INTERPOLATION::nb_nodes; ++n) {
645 Bnorm[n] = B[n][0] * r[0] + B[n][1] * r[1] + B[n][2] * r[2];
648 constraint.resize(5);
649 constraint.set_zero();
652 trans_d_constraint_d_dof.resize(INTERPOLATION::nb_nodes * 5, 5, INTERPOLATION::nb_nodes * 5);
655 std::complex<double>* value;
656 trans_d_constraint_d_dof.get_values(colind, rowind, value);
658 for (
int i = 0; i != 5; ++i) { colind[i + 1] = INTERPOLATION::nb_nodes * i; }
659 for (
int ni = 0; ni != INTERPOLATION::nb_nodes; ++ni) {
660 const int nni = ni * 5;
661 const std::complex<double> v(
662 vg * (Bnorm[ni] + parent::N.N_face1_c[ni] / rayon),
663 c_omega * parent::N.N_face1_c[ni]);
664 for (
int i = 0; i != 5; ++i) {
665 const size_t ptr = colind[i + 1]++;
666 rowind[ptr] = nni + i;
671 double noise_source_pos[3];
672 parent::property->get_radiation_value(noise_source_pos);
678 parent::property->get_constant(c_K, c_R, c_r, c_omega);
682 double NodeCoor[INTERPOLATION::nb_nodes][3];
683 for (
int k = 0; k != INTERPOLATION::nb_nodes; ++k) {
684 parent::node_type::get_coor_s(NodeCoor[k], parent::nodes[k]);
687 constraint.resize(5 * NB_POINT_IN_CONSTRAINT);
688 constraint.set_zero();
691 trans_d_constraint_d_dof.resize(
692 INTERPOLATION::nb_nodes * 5, 5 * NB_POINT_IN_CONSTRAINT,
693 INTERPOLATION::nb_nodes * 5 * NB_POINT_IN_CONSTRAINT);
696 std::complex<double>* value;
697 trans_d_constraint_d_dof.get_values(colind, rowind, value);
699 for (
int i = 0; i != 5 * NB_POINT_IN_CONSTRAINT; ++i) {
700 colind[i + 1] = INTERPOLATION::nb_nodes * i;
703 for (
int ng = 0; ng != INTERPOLATION::nb_gauss_face; ++ng) {
705 double face_coor[3] = {};
706 for (
int k = 0; k != INTERPOLATION::nb_nodes; ++k) {
707 face_coor[0] += parent::N.N_face1[ng][k] * NodeCoor[k][0];
708 face_coor[1] += parent::N.N_face1[ng][k] * NodeCoor[k][1];
709 face_coor[2] += parent::N.N_face1[ng][k] * NodeCoor[k][2];
719 parent::property->get_cfd_value(
720 model, INTERPOLATION::nb_nodes, parent::nodes, parent::N.N_face1[ng], W0);
721 double mean_sound_speed = std::sqrt(c_K * c_r * W0[4]);
723 r[0] = face_coor[0] - noise_source_pos[0];
724 r[1] = face_coor[1] - noise_source_pos[1];
725 r[2] = face_coor[2] - noise_source_pos[2];
726 rayon = std::sqrt(r[0] * r[0] + r[1] * r[1] + r[2] * r[2]);
727 const double inv_r = 1 / rayon;
731 const double u_er = r[0] * W0[1] + r[0] * W0[2] + r[0] * W0[3];
734 mean_sound_speed * mean_sound_speed - W0[1] * W0[1] - W0[2] * W0[2]
735 - W0[3] * W0[3] + u_er * u_er);
741 for (
int j = 0; j != 3; ++j) {
742 for (
int i = 0; i != 3; ++i) {
744 for (
int n = 0; n != INTERPOLATION::nb_nodes; ++n) {
745 v += parent::N.dN_face1[ng][n][i] * NodeCoor[n][j];
757 double B[INTERPOLATION::nb_nodes][3];
759 'N',
'N', 3, INTERPOLATION::nb_nodes, 3, 1.0, inv_J[0], 3, parent::N.dN_face1[ng][0],
763 double Bnorm[INTERPOLATION::nb_nodes];
764 for (
int n = 0; n != INTERPOLATION::nb_nodes; ++n) {
765 Bnorm[n] = B[n][0] * r[0] + B[n][1] * r[1] + B[n][2] * r[2];
768 for (
int ni = 0; ni != INTERPOLATION::nb_nodes; ++ni) {
769 const int nni = ni * 5;
770 const std::complex<double> v(
771 vg * (Bnorm[ni] + parent::N.N_face1_c[ni] / rayon),
772 c_omega * parent::N.N_face1[ng][ni]);
773 for (
int i = 0; i != 5; ++i) {
774 const size_t ptr = colind[5 * ng + i + 1]++;
775 rowind[ptr] = nni + i;
783template <
typename INTERPOLATION>
784void b2000::ElementAeroAcousticContacte<INTERPOLATION>::get_constraint(
785 Model& model,
const bool linear,
double time,
786 const b2linalg::Matrix<std::complex<double>, b2linalg::Mrectangle_constref>& dof,
787 b2linalg::Vector<std::complex<double>, b2linalg::Vdense>& constraint,
788 b2linalg::Matrix<std::complex<double>, b2linalg::Mcompressed_col>& trans_d_constraint_d_dof,
789 b2linalg::Vector<std::complex<double>, b2linalg::Vdense>& d_constraint_d_time) {
790#if NB_POINT_IN_CONSTRAINT == 1
792 double NodeCoor[INTERPOLATION::nb_nodes][3];
793 for (
int k = 0; k != INTERPOLATION::nb_nodes; ++k) {
794 parent::node_type::get_coor_s(NodeCoor[k], parent::nodes[k]);
800 for (
int j = 0; j != 3; ++j) {
801 for (
int i = 0; i != 3; ++i) {
803 for (
int n = 0; n != INTERPOLATION::nb_nodes; ++n) {
804 v += parent::N.dN_face1_c[n][i] * NodeCoor[n][j];
812 J[1][1] * J[2][0] - J[2][1] * J[1][0], J[2][1] * J[0][0] - J[0][1] * J[2][0],
813 J[0][1] * J[1][0] - J[1][1] * J[0][0]};
822 double B[INTERPOLATION::nb_nodes][3];
824 'N',
'N', 3, INTERPOLATION::nb_nodes, 3, 1.0, inv_J[0], 3, parent::N.dN_face1_c[0], 3,
828 double Bnorm[INTERPOLATION::nb_nodes];
829 for (
int n = 0; n != INTERPOLATION::nb_nodes; ++n) {
830 Bnorm[n] = B[n][0] * Nface[0] + B[n][1] * Nface[1] + B[n][2] * Nface[2];
834 constraint.resize(3);
835 constraint.set_zero();
836 trans_d_constraint_d_dof.resize(INTERPOLATION::nb_nodes * 5, 3, INTERPOLATION::nb_nodes * 5);
839 std::complex<double>* value;
840 trans_d_constraint_d_dof.get_values(colind, rowind, value);
843 for (
int ni = 0; ni != INTERPOLATION::nb_nodes; ++ni) {
846 value[ptr++] = Bnorm[ni];
849 for (
int ni = 0; ni != INTERPOLATION::nb_nodes; ++ni) {
852 value[ptr++] = Nface[0] * parent::N.N_face1_c[ni];
855 value[ptr++] = Nface[1] * parent::N.N_face1_c[ni];
858 value[ptr++] = Nface[2] * parent::N.N_face1_c[ni];
861 for (
int ni = 0; ni != INTERPOLATION::nb_nodes; ++ni) {
863 rowind[ptr] = nni + 4;
864 value[ptr++] = Bnorm[ni];
869 constraint.resize(2);
870 constraint.set_zero();
872 trans_d_constraint_d_dof.resize(INTERPOLATION::nb_nodes * 5, 2, INTERPOLATION::nb_nodes * 4);
875 std::complex<double>* value;
876 trans_d_constraint_d_dof.get_values(colind, rowind, value);
879 for (
int ni = 0; ni != INTERPOLATION::nb_nodes; ++ni) {
882 value[ptr++] = Bnorm[ni];
885 for (
int ni = 0; ni != INTERPOLATION::nb_nodes; ++ni) {
888 value[ptr++] = Nface[0] * parent::N.N_face1_c[ni];
891 value[ptr++] = Nface[1] * parent::N.N_face1_c[ni];
894 value[ptr++] = Nface[2] * parent::N.N_face1_c[ni];
901 double NodeCoor[INTERPOLATION::nb_nodes][3];
902 for (
int k = 0; k != INTERPOLATION::nb_nodes; ++k) {
903 parent::node_type::get_coor_s(NodeCoor[k], parent::nodes[k]);
906 constraint.resize(3 * NB_POINT_IN_CONSTRAINT);
907 constraint.set_zero();
909 trans_d_constraint_d_dof.resize(
910 INTERPOLATION::nb_nodes * 5, 3 * NB_POINT_IN_CONSTRAINT,
911 INTERPOLATION::nb_nodes * 5 * NB_POINT_IN_CONSTRAINT);
914 std::complex<double>* value;
915 trans_d_constraint_d_dof.get_values(colind, rowind, value);
919 for (
int ng = 0; ng != INTERPOLATION::nb_gauss_face; ++ng) {
923 for (
int j = 0; j != 3; ++j) {
924 for (
int i = 0; i != 3; ++i) {
926 for (
int n = 0; n != INTERPOLATION::nb_nodes; ++n) {
927 v += parent::N.dN_face1[ng][n][i] * NodeCoor[n][j];
935 J[1][1] * J[2][0] - J[2][1] * J[1][0], J[2][1] * J[0][0] - J[0][1] * J[2][0],
936 J[0][1] * J[1][0] - J[1][1] * J[0][0]};
945 double B[INTERPOLATION::nb_nodes][3];
947 'N',
'N', 3, INTERPOLATION::nb_nodes, 3, 1.0, inv_J[0], 3, parent::N.dN_face1[ng][0],
951 double Bnorm[INTERPOLATION::nb_nodes];
952 for (
int n = 0; n != INTERPOLATION::nb_nodes; ++n) {
953 Bnorm[n] = B[n][0] * Nface[0] + B[n][1] * Nface[1] + B[n][2] * Nface[2];
957 for (
int ni = 0; ni != INTERPOLATION::nb_nodes; ++ni) {
960 value[ptr++] = Bnorm[ni];
963 for (
int ni = 0; ni != INTERPOLATION::nb_nodes; ++ni) {
966 value[ptr++] = Nface[0] * parent::N.N_face1[ng][ni];
969 value[ptr++] = Nface[1] * parent::N.N_face1[ng][ni];
972 value[ptr++] = Nface[2] * parent::N.N_face1[ng][ni];
975 for (
int ni = 0; ni != INTERPOLATION::nb_nodes; ++ni) {
977 rowind[ptr] = nni + 4;
978 value[ptr++] = Bnorm[ni];
985template <
typename INTERPOLATION>
986void b2000::ElementAeroAcousticSymmetry<INTERPOLATION>::get_constraint(
987 Model& model,
const bool linear,
double time,
988 const b2linalg::Matrix<std::complex<double>, b2linalg::Mrectangle_constref>& dof,
989 b2linalg::Vector<std::complex<double>, b2linalg::Vdense>& constraint,
990 b2linalg::Matrix<std::complex<double>, b2linalg::Mcompressed_col>& trans_d_constraint_d_dof,
991 b2linalg::Vector<std::complex<double>, b2linalg::Vdense>& d_constraint_d_time) {
992#if NB_POINT_IN_CONSTRAINT == 1
994 double NodeCoor[INTERPOLATION::nb_nodes][3];
995 for (
int k = 0; k != INTERPOLATION::nb_nodes; ++k) {
996 parent::node_type::get_coor_s(NodeCoor[k], parent::nodes[k]);
1002 for (
int j = 0; j != 3; ++j) {
1003 for (
int i = 0; i != 3; ++i) {
1005 for (
int n = 0; n != INTERPOLATION::nb_nodes; ++n) {
1006 v += parent::N.dN_face1_c[n][i] * NodeCoor[n][j];
1014 J[1][1] * J[2][0] - J[2][1] * J[1][0], J[2][1] * J[0][0] - J[0][1] * J[2][0],
1015 J[0][1] * J[1][0] - J[1][1] * J[0][0]};
1024 double B[INTERPOLATION::nb_nodes][3];
1026 'N',
'N', 3, INTERPOLATION::nb_nodes, 3, 1.0, inv_J[0], 3, parent::N.dN_face1_c[0], 3,
1030 double Bnorm[INTERPOLATION::nb_nodes];
1031 for (
int n = 0; n != INTERPOLATION::nb_nodes; ++n) {
1032 Bnorm[n] = B[n][0] * Nface[0] + B[n][1] * Nface[1] + B[n][2] * Nface[2];
1036 constraint.resize(5);
1037 constraint.set_zero();
1040 trans_d_constraint_d_dof.resize(INTERPOLATION::nb_nodes * 5, 5, INTERPOLATION::nb_nodes * 5);
1043 std::complex<double>* value;
1044 trans_d_constraint_d_dof.get_values(colind, rowind, value);
1046 for (
int i = 0; i != 5; ++i) {
1048 for (
int ni = 0; ni != INTERPOLATION::nb_nodes; ++ni, ++ptr) {
1049 rowind[ptr] = ni * 5 + i;
1050 value[ptr] = Bnorm[ni];
1055 constraint.resize(4);
1056 constraint.set_zero();
1059 trans_d_constraint_d_dof.resize(INTERPOLATION::nb_nodes * 5, 4, INTERPOLATION::nb_nodes * 4);
1062 std::complex<double>* value;
1063 trans_d_constraint_d_dof.get_values(colind, rowind, value);
1065 for (
int i = 0; i != 4; ++i) {
1067 for (
int ni = 0; ni != INTERPOLATION::nb_nodes; ++ni, ++ptr) {
1068 rowind[ptr] = ni * 5 + i;
1069 value[ptr] = Bnorm[ni];
1077 double NodeCoor[INTERPOLATION::nb_nodes][3];
1078 for (
int k = 0; k != INTERPOLATION::nb_nodes; ++k) {
1079 parent::node_type::get_coor_s(NodeCoor[k], parent::nodes[k]);
1082 constraint.resize(5 * NB_POINT_IN_CONSTRAINT);
1083 constraint.set_zero();
1086 trans_d_constraint_d_dof.resize(
1087 INTERPOLATION::nb_nodes * 5, 5 * NB_POINT_IN_CONSTRAINT,
1088 INTERPOLATION::nb_nodes * 5 * NB_POINT_IN_CONSTRAINT);
1091 std::complex<double>* value;
1092 trans_d_constraint_d_dof.get_values(colind, rowind, value);
1097 for (
int ng = 0; ng != INTERPOLATION::nb_gauss_face; ++ng) {
1101 for (
int j = 0; j != 3; ++j) {
1102 for (
int i = 0; i != 3; ++i) {
1104 for (
int n = 0; n != INTERPOLATION::nb_nodes; ++n) {
1105 v += parent::N.dN_face1[ng][n][i] * NodeCoor[n][j];
1113 J[1][1] * J[2][0] - J[2][1] * J[1][0], J[2][1] * J[0][0] - J[0][1] * J[2][0],
1114 J[0][1] * J[1][0] - J[1][1] * J[0][0]};
1123 double B[INTERPOLATION::nb_nodes][3];
1125 'N',
'N', 3, INTERPOLATION::nb_nodes, 3, 1.0, inv_J[0], 3, parent::N.dN_face1[ng][0],
1129 double Bnorm[INTERPOLATION::nb_nodes];
1130 for (
int n = 0; n != INTERPOLATION::nb_nodes; ++n) {
1131 Bnorm[n] = B[n][0] * Nface[0] + B[n][1] * Nface[1] + B[n][2] * Nface[2];
1134 for (
int i = 0; i != 5; ++i) {
1135 for (
int ni = 0; ni != INTERPOLATION::nb_nodes; ++ni, ++ptr) {
1136 rowind[ptr] = ni * 5 + i;
1137 value[ptr] = Bnorm[ni];
#define THROW
Definition b2exception.H:198
@ nonlinear
Definition b2element.H:619
@ linear
Definition b2element.H:615
const std::string & get_object_name() const override
Definition b2element.H:220
virtual std::pair< int, VariableInfo > get_constraint_info()
Definition b2element.H:688
Definition b2element.H:1054
virtual void get_value(Model &model, const bool linear, const EquilibriumSolution equilibrium_solution, const double time, const double delta_time, const b2linalg::Matrix< std::complex< double >, b2linalg::Mrectangle_constref > &dof, GradientContainer *gradient_container, SolverHints *solver_hints, b2linalg::Index &dof_numbering, b2linalg::Vector< std::complex< double >, b2linalg::Vdense > &value, const std::vector< bool > &d_value_d_dof_flags, std::vector< b2linalg::Matrix< std::complex< double >, b2linalg::Mrectangle > > &d_value_d_dof, b2linalg::Vector< std::complex< double >, b2linalg::Vdense > &d_value_d_time)
Compute the internal forces and their derivatives of the element.
Definition b2element.H:1619
virtual void get_constraint(Model &model, const bool linear, const double time, const b2linalg::Matrix< std::complex< double >, b2linalg::Mrectangle_constref > &dof, b2linalg::Index &dof_numbering, b2linalg::Vector< std::complex< double >, b2linalg::Vdense > &constraint, b2linalg::Matrix< std::complex< double >, b2linalg::Mcompressed_col > &trans_d_constraint_d_dof, b2linalg::Vector< std::complex< double >, b2linalg::Vdense > &d_constraint_d_time)
Definition b2element.H:1096
Contains the base classes for implementing Finite Elements.
Definition b2boundary_condition.H:32
T normalise_3(T a[3])
Definition b2tensor_calculus.H:418
GenericException< TypeError_name > TypeError
Definition b2exception.H:325
T invert_3_3(const T a[3][3], T b[3][3])
Definition b2tensor_calculus.H:699