| 274 | } |
| 275 | |
| 276 | bool |
| 277 | DomainModalProperties::compute() |
| 278 | { |
| 279 | /* |
| 280 | Notes: |
| 281 | 1 - we assemble the global mass matrix and eigenvectors with our own (plain) numbering |
| 282 | 2 - we make room for rotational DOFs even if some nodes are translational only, because we |
| 283 | also include the rotational effect given by the translational masses gyrating about the |
| 284 | center of mass |
| 285 | 3 - the mass matrix may be consistent. however we need also a diagonalized version of it |
| 286 | to compute the center of mass, the total mass of the structure, and the rotational masses |
| 287 | due to the translational masses gyrating about the center of mass |
| 288 | */ |
| 289 | |
| 290 | Domain* domain = m_domain; |
| 291 | |
| 292 | // number of eigen-modes |
| 293 | int num_eigen = domain->getEigenvalues().Size(); |
| 294 | if (num_eigen < 1) |
| 295 | DMP_ERR("No Eigenvalue provided.\n"); |
| 296 | |
| 297 | // eigenvalues |
| 298 | m_eigenvalues = domain->getEigenvalues(); |
| 299 | // number of dimensions |
| 300 | int ndm = domainSize(domain); |
| 301 | // max number of DOFs per node, translational and rotational only |
| 302 | int ndf = ndm == 2 ? 3 : 6; |
| 303 | // number of nodes |
| 304 | int num_nodes = domain->getNumNodes(); |
| 305 | // number of equations (not the real one, include rotational dofs even if not present) |
| 306 | int num_eq = num_nodes * ndf; |
| 307 | |
| 308 | // initialize members |
| 309 | m_center_of_mass.resize(ndm); |
| 310 | m_total_mass.resize(ndf); |
| 311 | m_total_free_mass.resize(ndf); |
| 312 | m_generalized_mass_matrix.resize(num_eigen); |
| 313 | m_modal_participation_factors.resize(num_eigen, ndf); |
| 314 | m_modal_participation_masses.resize(num_eigen, ndf); |
| 315 | m_modal_participation_masses_cumulative.resize(num_eigen, ndf); |
| 316 | m_modal_participation_mass_ratios.resize(num_eigen, ndf); |
| 317 | m_modal_participation_mass_ratios_cumulative.resize(num_eigen, ndf); |
| 318 | |
| 319 | // map all nodes |
| 320 | node_map_t nodemap(domain, ndm, ndf); |
| 321 | |
| 322 | // map all elements |
| 323 | ele_map_t elemap(domain, nodemap); |
| 324 | |
| 325 | // the sparse mass matrix |
| 326 | SparseMatrix M; |
| 327 | // the equivalent diagonalized masses for each node (total) |
| 328 | Matrix ML(num_nodes, ndf); |
| 329 | // the equivalent diagonalized masses for each node (only at free DOFs) |
| 330 | Matrix MLfree(num_nodes, ndf); |
| 331 | // the array of eigenvectors |
| 332 | std::vector<Vector> V(num_eigen); |
| 333 | for (auto& iV : V) { |
no test coverage detected