Source code for opstool.post.eigen_data

import os
import numpy as np
import xarray as xr
from typing import Union
import openseespy.opensees as ops

from ..utils import CONSTANTS, get_random_color
from .model_data import GetFEMData

def _get_modal_properties(mode_tag: int = 1, solver: str = "-genBandArpack"):
    """Get modal properties' data.

    Parameters
    ----------
    mode_tag : int, optional,
        Modal tag, all modal data smaller than this modal tag will be saved, by default 1
    solver : str, optional,
       OpenSees' eigenvalue analysis solver, by default "-genBandArpack".
       See `eigen Command <https://opensees.github.io/OpenSeesDocumentation/user/manual/analysis/eigen.html>`_

    Returns
    --------
    Data: xr.DataArray, modal properties' data.
    """
    ops.wipeAnalysis()
    if mode_tag == 1:
        ops.eigen(solver, 2)
    else:
        ops.eigen(solver, mode_tag)
    modal_props = ops.modalProperties("-return")
    # ------------------------------------------------------------------------
    attrs_names = ["domainSize", "totalMass", "totalFreeMass", "centerOfMass"]
    attrs = {name: tuple(modal_props[name]) for name in attrs_names}
    for key, value in attrs.items():
        if key == "domainSize":
            value = [int(v) for v in value]
        if len(value) == 1:
            value = value[0]
        attrs[key] = value
    # ------------------------------------------------------------------------
    column_names = [name for name in modal_props.keys() if name not in attrs_names]
    columns = [modal_props[name] for name in column_names]
    data = np.vstack(columns).transpose()[:mode_tag]
    data = xr.DataArray(
        data,
        coords={
            "modeTags": np.arange(1, mode_tag + 1),
            "Properties": column_names,
        },
        dims=("modeTags", "Properties"),
        attrs=attrs,
        name="ModalProps",
    )
    return data


def _get_eigen_info(
    mode_tag: int = 1,
    solver: str = "-genBandArpack",
):
    """Get modal properties' data.

    Parameters
    ----------
    mode_tag : int, optional,
        Modal tag, all modal data smaller than this modal tag will be saved, by default 1
    solver : str, optional,
       OpenSees' eigenvalue analysis solver, by default "-genBandArpack".
       See `eigen Command <https://opensees.github.io/OpenSeesDocumentation/user/manual/analysis/eigen.html>`_

    Returns
    --------
    modal_props: xr.DataArray
        Modal properties' data.
    eigenvectors: xr.DataArray
        Eigen vectors data.
    """
    modal_props = _get_modal_properties(mode_tag, solver)
    eigenvectors = []
    node_tags = ops.getNodeTags()
    for mode_tag in range(1, mode_tag + 1):
        eigen_vector = np.zeros((len(node_tags), 6))
        for i, Tag in enumerate(node_tags):
            coord = ops.nodeCoord(Tag)
            eigen = ops.nodeEigenvector(Tag, mode_tag)
            if len(coord) == 1:
                coord.extend([0, 0])
                eigen.extend([0, 0, 0, 0, 0])
            elif len(coord) == 2:
                coord.extend([0])
                if len(eigen) == 3:
                    eigen = [eigen[0], eigen[1], 0, 0, 0, eigen[2]]
                elif len(eigen) == 2:
                    eigen = [eigen[0], eigen[1], 0, 0, 0, 0]
                elif len(eigen) == 1:
                    eigen.extend([0, 0, 0, 0, 0])
            else:
                if len(eigen) == 3:
                    eigen.extend([0, 0, 0])
                elif len(eigen) > 6:
                    eigen = eigen[:6]
            eigen_vector[i] = eigen
        eigenvectors.append(eigen_vector)
    eigenvectors = xr.DataArray(
        eigenvectors,
        dims=["modeTags", "nodeTags", "DOFs"],
        coords={
            "modeTags": np.arange(1, mode_tag + 1),
            "nodeTags": node_tags,
            "DOFs": ["UX", "UY", "UZ", "RX", "RY", "RZ"],
        },
        name="EigenVectors",
    )
    return modal_props, eigenvectors


[docs] def save_eigen_data( odb_tag: Union[str, int] = 1, mode_tag: int = 1, solver: str = "-genBandArpack", ): """Save modal analysis data. Parameters ---------- odb_tag: Union[str, int], default = 1 Output database tag, the data will be saved in ``EigenData-{odb_tag}.nc``. mode_tag : int, optional, Modal tag, all modal data smaller than this modal tag will be saved, by default 1 solver : str, optional, OpenSees' eigenvalue analysis solver, by default "-genBandArpack". See `eigen Command <https://opensees.github.io/OpenSeesDocumentation/user/manual/analysis/eigen.html>`_ """ # ---------------------------------------------------------------------- RESULTS_DIR = CONSTANTS.get_output_dir() CONSOLE = CONSTANTS.get_console() PKG_PREFIX = CONSTANTS.get_pkg_prefix() output_filename = RESULTS_DIR + "/" + f"EigenData-{odb_tag}.nc" # ----------------------------------------------------------------- model_info, _ = GetFEMData().get_model_info() modal_props, eigen_vectors = _get_eigen_info(mode_tag, solver) eigen_data = dict() for key in model_info.keys(): eigen_data[f"ModelInfo/{key}"] = xr.Dataset({key: model_info[key]}) eigen_data["Eigen/ModalProps"] = xr.Dataset({modal_props.name: modal_props}) eigen_data["Eigen/EigenVectors"] = xr.Dataset({eigen_vectors.name: eigen_vectors}) dt = xr.DataTree.from_dict(eigen_data, name="EigenData") dt.to_netcdf(output_filename, mode="w", engine="netcdf4") # ///////////////////////////////////// color = get_random_color() CONSOLE.print( f"{PKG_PREFIX} Eigen data has been saved to [bold {color}]{output_filename}[/]!" )
def load_eigen_data( odb_tag: Union[str, int] = 1, mode_tag: int = 1, solver: str = "-genBandArpack", resave: bool = True, ): """Get the eigenvalue data from the saved file.""" RESULTS_DIR = CONSTANTS.get_output_dir() CONSOLE = CONSTANTS.get_console() PKG_PREFIX = CONSTANTS.get_pkg_prefix() filename = f"{RESULTS_DIR}/" + f"EigenData-{odb_tag}.nc" if not os.path.exists(filename): resave = True if resave: save_eigen_data(odb_tag=odb_tag, mode_tag=mode_tag, solver=solver) else: color = get_random_color() CONSOLE.print( f"{PKG_PREFIX} Loading eigen data from [bold {color}]{filename}[/] ..." ) dt = xr.open_datatree(filename, engine="netcdf4").load() model_info = dict() for key, value in dt["ModelInfo"].items(): model_info[key] = value[key] model_props = dt["Eigen/ModalProps"]["ModalProps"] eigen_vectors = dt["Eigen/EigenVectors"]["EigenVectors"] return model_props, eigen_vectors, model_info
[docs] def get_eigen_data( odb_tag: Union[str, int] = None, ): """Get the eigenvalue data from the saved file. Parameters ---------- odb_tag: Union[int, str], default: None Tag of output databases (ODB) have been saved. Returns -------- modal_props: xr.DataArray Modal properties' data. eigenvectors: xr.DataArray Eigen vectors data. """ model_props, eigen_vectors, _ = load_eigen_data(odb_tag, resave=False) return model_props, eigen_vectors