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