15#ifndef B2EIDW_MESH_DEFORMATION_H_ 
   16#define B2EIDW_MESH_DEFORMATION_H_ 
   23#include "utils/b2database.H" 
   24#include "utils/b2finite_rotation.H" 
   25#include "utils/b2linear_algebra.H" 
   30class EIDW_Mesh_deformation {
 
   32    EIDW_Mesh_deformation() : power_disp(0), power_rot(0), power_rot_dist(0), boundary_size(0) {}
 
   35          int power_disp_, 
int power_rot_, 
int power_rot_dist_, 
double boundary_size_) {
 
   36        power_disp = power_disp_;
 
   37        power_rot = power_rot_;
 
   38        power_rot_dist = power_rot_dist_;
 
   39        boundary_size = boundary_size_;
 
   43    void compute_deformation(
 
   44          const b2linalg::Matrix<double>& node_coor, b2linalg::Matrix<double>& node_disp,
 
   45          const b2linalg::Index& imposed_node_id, 
const b2linalg::Vector<double>& node_area,
 
   46          const b2linalg::Matrix<double>& node_normal,
 
   47          const b2linalg::Matrix<double>& node_rotation) {
 
   48        size_t imposed_node_ptr = 0;
 
   49        for (
size_t i = 0; i != node_disp.size2(); ++i) {
 
   50            if (i == imposed_node_id[imposed_node_ptr]) {
 
   53                double min_dist = 1e50;
 
   57                std::fill_n(disp, ndim, 0);
 
   59                std::fill_n(disp_r, ndim, 0);
 
   60                for (
size_t j = 0; j != imposed_node_id.size(); ++j) {
 
   61                    const size_t jj = imposed_node_id[j];
 
   64                    for (
int k = 0; k != ndim; ++k) {
 
   65                        const double tmp = node_coor(k, i) - node_coor(k, jj);
 
   70                    min_dist = std::min(min_dist, nv);
 
   72                    std::fill_n(vr, ndim, 0);
 
   74                        const double* rotator = &node_rotation(0, j);
 
   75                        for (
int lj = 0; lj != ndim; ++lj) {
 
   76                            for (
int li = 0; li != ndim; ++li, ++rotator) {
 
   77                                vr[li] += *rotator * v[lj];
 
   81                    const double omega = node_area[j] * std::pow(nv, -power_disp);
 
   82                    const double omega_r = node_area[j] * std::pow(nv, -power_rot);
 
   85                    for (
int k = 0; k != ndim; ++k) {
 
   86                        disp[k] += omega * node_disp(k, jj);
 
   87                        disp_r[k] += omega_r * (vr[k] - v[k]);
 
   91                pr = std::pow(std::max(1.0, min_dist - boundary_size + 1), -power_rot_dist) / pr;
 
   92                for (
int k = 0; k != ndim; ++k) { node_disp(k, i) = disp[k] * p + disp_r[k] * pr; }
 
  101    double boundary_size;
 
  104class EIDW_Mesh_deformationDB : 
public EIDW_Mesh_deformation {
 
  106    EIDW_Mesh_deformationDB() : database(nullptr) {}
 
  108    void init(DataBase& db) { database = &db; }
 
  110    void compute_deformation(
const int ndim) {
 
  111        b2linalg::Matrix<double> node_coor;
 
  112        database->get(SetName(
"COOR", 1), node_coor);
 
  114        b2linalg::Matrix<double> node_disp(ndim, node_coor.size2());
 
  115        b2linalg::Index imposed_node_id;
 
  117            std::set<size_t> imposed_node_id_set;
 
  118            b2linalg::Matrix<double> ebc;
 
  119            database->get(SetName(
"EBC", 1, 0, 0, 1), ebc);
 
  120            for (
size_t i = 0; i != ebc.size2(); ++i) {
 
  121                const size_t n = int(ebc(0, i)) - 1;
 
  122                imposed_node_id_set.insert(n);
 
  123                node_disp(
int(ebc(1, i)) - 1, n) = ebc(2, i);
 
  125            imposed_node_id.assign(imposed_node_id_set.begin(), imposed_node_id_set.end());
 
  128        b2linalg::Vector<double> node_area(imposed_node_id.size());
 
  129        b2linalg::Matrix<double> node_normal(ndim, imposed_node_id.size());
 
  130        b2linalg::Matrix<double> node_rotation(ndim * ndim, imposed_node_id.size());
 
  134                compute_surface_node_2(
 
  135                      node_coor, node_disp, imposed_node_id, node_area, node_normal, node_rotation);
 
  136                EIDW_Mesh_deformation::compute_deformation<2>(
 
  137                      node_coor, node_disp, imposed_node_id, node_area, node_normal, node_rotation);
 
  140                compute_surface_node_3(
 
  141                      node_coor, node_disp, imposed_node_id, node_area, node_normal, node_rotation);
 
  142                EIDW_Mesh_deformation::compute_deformation<3>(
 
  143                      node_coor, node_disp, imposed_node_id, node_area, node_normal, node_rotation);
 
  146                Exception() << 
THROW;
 
  150        database->set(SetName(
"DISP", 1, 0, 0, 1), node_disp);
 
  156    void compute_surface_node_2(
 
  157          const b2linalg::Matrix<double>& node_coor, 
const b2linalg::Matrix<double>& node_disp,
 
  158          const b2linalg::Index& imposed_node_id, b2linalg::Vector<double>& node_area,
 
  159          b2linalg::Matrix<double>& node_normal, b2linalg::Matrix<double>& node_rotation) {
 
  161        database->get(SetName(
"ETAB", 1), etab);
 
  162        std::vector<int> nb_contrib(imposed_node_id.size());
 
  163        for (
size_t j = 0; j != etab.size(); ++j) {
 
  164            const RTable& rtable = etab[j];
 
  165            if (rtable.get_int(
"ITYP", -1) != 266) { 
continue; }
 
  166            std::vector<int> nodes;
 
  167            rtable.get(
"NODES", nodes);
 
  168            if (nodes.size() != 2) { Exception() << 
THROW; }
 
  175            for (
int i = 0; i != 2; ++i) {
 
  176                double tmp = node_coor(i, nodes[1]) - node_coor(i, nodes[0]);
 
  179                tmp += node_disp(i, nodes[1]) - node_disp(i, nodes[0]);
 
  184            ndv = std::sqrt(ndv);
 
  185            const double n[2] = {v[1] / nv, -v[0] / nv};
 
  186            const double omega = (v[0] * dv[1] - v[1] * dv[0]) / (nv * ndv);
 
  188            for (
int i = 0; i != 2; ++i) {
 
  189                const size_t node_id =
 
  191                            imposed_node_id.begin(), imposed_node_id.end(), 
size_t(nodes[i]))
 
  192                      - imposed_node_id.begin();
 
  193                ++nb_contrib[node_id];
 
  194                node_area[node_id] += nv;
 
  195                for (
int k = 0; k != 2; ++k) { node_normal(k, node_id) += n[k]; }
 
  196                node_rotation(0, node_id) += omega;
 
  199        for (
size_t j = 0; j != imposed_node_id.size(); ++j) {
 
  200            const double omega = node_rotation(0, j) / nb_contrib[j];
 
  201            const double c = std::cos(omega);
 
  202            const double s = std::sin(omega);
 
  203            node_rotation(0, j) = c;
 
  204            node_rotation(1, j) = s;
 
  205            node_rotation(2, j) = -s;
 
  206            node_rotation(3, j) = c;
 
  211    void compute_surface_node_3(
 
  212          const b2linalg::Matrix<double>& node_coor, 
const b2linalg::Matrix<double>& node_disp,
 
  213          const b2linalg::Index& imposed_node_id, b2linalg::Vector<double>& node_area,
 
  214          b2linalg::Matrix<double>& node_normal, b2linalg::Matrix<double>& node_rotation) {
 
  216        database->get(SetName(
"ETAB", 1), etab);
 
  217        std::vector<int> nb_contrib(imposed_node_id.size());
 
  218        for (
size_t j = 0; j != etab.size(); ++j) {
 
  219            const RTable& rtable = etab[j];
 
  220            switch (rtable.get_int(
"ITYP", -1)) {
 
  223                    std::vector<int> nodes;
 
  224                    rtable.get(
"NODES", nodes);
 
  225                    if (nodes.size() != 3) { Exception() << 
THROW; }
 
  226                    for (
int k = 0; k != 3; ++k) { nodes[k] -= 1; }
 
  229                    for (
int k = 0; k != 2; ++k) {
 
  230                        for (
int i = 0; i != 3; ++i) {
 
  231                            const double tmp = node_coor(i, nodes[k + 1]) - node_coor(i, nodes[0]);
 
  233                            dv[k][i] = tmp + node_disp(i, nodes[k + 1]) - node_disp(i, nodes[0]);
 
  244                    for (
int k = 0; k != 3; ++k) {
 
  245                        const size_t node_id = std::lower_bound(
 
  246                                                     imposed_node_id.begin(), imposed_node_id.end(),
 
  248                                               - imposed_node_id.begin();
 
  249                        ++nb_contrib[node_id];
 
  250                        node_area[node_id] += s;
 
  251                        for (
int i = 0; i != 3; ++i) {
 
  252                            node_normal(i, node_id) += n[i];
 
  253                            node_rotation(i, node_id) += rot[i];
 
  260                    std::vector<int> nodesq;
 
  261                    rtable.get(
"NODES", nodesq);
 
  262                    if (nodesq.size() != 4) { Exception() << 
THROW; }
 
  263                    for (
int k = 0; k != 4; ++k) { nodesq[k] -= 1; }
 
  264                    for (
int kk = 0; kk != 4; ++kk) {
 
  265                        const int nodes[3] = {
 
  266                              nodesq[kk], nodesq[(kk + 1) % 4], nodesq[(kk + 2) % 4]};
 
  269                        for (
int k = 0; k != 2; ++k) {
 
  270                            for (
int i = 0; i != 3; ++i) {
 
  272                                      node_coor(i, nodes[k + 1]) - node_coor(i, nodes[0]);
 
  275                                      tmp + node_disp(i, nodes[k + 1]) - node_disp(i, nodes[0]);
 
  286                        const size_t node_id =
 
  288                                    imposed_node_id.begin(), imposed_node_id.end(), nodes[1])
 
  289                              - imposed_node_id.begin();
 
  290                        ++nb_contrib[node_id];
 
  291                        node_area[node_id] += s;
 
  292                        for (
int i = 0; i != 3; ++i) {
 
  293                            node_normal(i, node_id) += n[i];
 
  294                            node_rotation(i, node_id) += rot[i];
 
  302        for (
size_t j = 0; j != imposed_node_id.size(); ++j) {
 
  304            for (
int i = 0; i != 3; ++i) { omega[i] = node_rotation(i, j) / nb_contrib[j]; }
 
  305            FiniteRotation<double>(omega).get_rotator(
 
  306                  reinterpret_cast<double(*)[3]
>(&node_rotation(0, j)));
 
#define THROW
Definition b2exception.H:198
 
Contains the base classes for implementing Finite Elements.
Definition b2boundary_condition.H:32
 
T normalise_3(T a[3])
Definition b2tensor_calculus.H:418
 
void outer_product_3(const T1 a[3], const T2 b[3], T3 c[3])
Definition b2tensor_calculus.H:389
 
T normalise_2(T a[2])
Definition b2tensor_calculus.H:460