Пример #1
0
def translate_nodes_ABAQUS_c0(m0,
                              n0,
                              c0,
                              funcnum,
                              model_name,
                              part_name,
                              H_model,
                              semi_angle=0.,
                              scaling_factor=1.,
                              fem_meridian_bot2top=True,
                              ignore_bot_h=None,
                              ignore_top_h=None,
                              T=None):
    r"""Translates the nodes in Abaqus based on a Fourier series

    The Fourier Series can be a half-sine, half-cosine or a complete Fourier
    Series as detailed in :func:`desicos.conecylDB.fit_data.calc_c0`.

    Parameters
    ----------
    m0 : int
        Number of terms along the `x` coordinate.
    n0 : int
        Number of terms along the `\theta` coordinate.
    c0 : numpy.ndarray
        The coefficients that will give the imperfection pattern.
    funcnum : int
        The function type, as detailed in
        :func:`desicos.conecylDB.fit_data.calc_c0`.
    model_name : str
        Must be a valid key in the dictionary ``mdb.models``, in the
        interactive Python inside Abaqus.
    part_name : str
        Must be a valid key in the dictionary
        ``mdb.models[model_name].parts``, in the interactive Python inside
        Abaqus.
    H_model : float
        Total height of the model where the imperfections will be applied to,
        considering also eventual resin rings.
    semi_angle : float, optional
        The cone semi-vertex angle (a null value indicates that a cylinder is
        beeing analyzed).
    scaling_factor : float, optional
        The scaling factor that will multiply ``c0`` when applying the
        imperfections.
    fem_meridian_bot2top : bool, optional
        A boolean indicating if the finite element has the `x` axis starting
        at the bottom or at the top.
    ignore_bot_h : None or float, optional
        Used to ignore nodes from the bottom resin ring.
    ignore_top_h : None or float, optional
        Used to ignore nodes from the top resin ring.
    T : None or np.ndarray, optional
        A transformation matrix (cf. :func:`.transf_matrix`) required when the
        mesh is not in the :ref:`default coordinate system <figure_conecyl>`.

    Returns
    -------
    nodal_translations : numpy.ndarray
        A 2-D array containing the translations ``x, y, z`` for each column.

    Notes
    -----
    Despite the nodal traslations are returned all the nodes belonging to this
    model will be already translated.

    """
    from abaqus import mdb, session

    from desicos.conecylDB import fit_data

    log('Calculating imperfection amplitudes for model {0} ...\n\t'.format(
        model_name) + '(using a scaling factor of {0})'.format(scaling_factor))
    c0 = c0 * scaling_factor
    mod = mdb.models[model_name]
    part = mod.parts[part_name]

    part_nodes = np.array(part.nodes)
    coords = np.array([n.coordinates for n in part_nodes])

    if T is not None:
        tmp = np.vstack((coords.T, np.ones((1, coords.shape[0]))))
        coords = np.dot(T, tmp).T
        del tmp

    if ignore_bot_h is not None:
        if ignore_bot_h <= 0:
            ignore_bot_h = None
        else:
            log('Applying ignore_bot_h: ignoring nodes with z <= {0}'.format(
                ignore_bot_h))
            mask = coords[:, 2] > ignore_bot_h
            coords = coords[mask]
            part_nodes = part_nodes[mask]

    if ignore_top_h is not None:
        if ignore_top_h <= 0:
            ignore_top_h = None
        else:
            log('Applying ignore_top_h: ignoring nodes with z >= {0}'.format(
                H_model - ignore_top_h))
            mask = coords[:, 2] < (H_model - ignore_top_h)
            coords = coords[mask]
            part_nodes = part_nodes[mask]

    if ignore_bot_h is None:
        ignore_bot_h = 0
    if ignore_top_h is None:
        ignore_top_h = 0
    H_eff = H_model - (ignore_bot_h + ignore_top_h)
    if fem_meridian_bot2top:
        xs_norm = (coords[:, 2] - ignore_bot_h) / H_eff
    else:
        xs_norm = (H_eff - (coords[:, 2] - ignore_bot_h)) / H_eff

    thetas = arctan2(coords[:, 1], coords[:, 0])

    alpharad = deg2rad(semi_angle)
    w0 = fit_data.fw0(m0, n0, c0, xs_norm, thetas, funcnum)
    nodal_translations = np.zeros_like(coords)
    nodal_translations[:, 0] = w0 * cos(alpharad) * cos(thetas)
    nodal_translations[:, 1] = w0 * cos(alpharad) * sin(thetas)
    nodal_translations[:, 2] = w0 * sin(alpharad)

    log('Calculation of imperfection amplitudes finished!')

    # applying translations
    viewport = session.viewports[session.currentViewportName]
    log('Applying new nodal positions in ABAQUS CAE to model {0} ...'.format(
        model_name))
    log('    (using a scaling factor of {0})'.format(scaling_factor))

    new_coords = coords + nodal_translations

    if T is not None:
        Tinv = np.zeros_like(T)
        Tinv[:3, :3] = T[:3, :3].T
        Tinv[:, 3] = -T[:, 3]
        tmp = np.vstack((new_coords.T, np.ones((1, new_coords.shape[0]))))
        new_coords = np.dot(Tinv, tmp).T
        del tmp

    meshNodeArray = part.nodes.sequenceFromLabels(
        [n.label for n in part_nodes])
    new_coords = np.ascontiguousarray(new_coords)
    part.editNode(nodes=meshNodeArray, coordinates=new_coords)

    log('Application of new nodal positions finished!')

    ra = mod.rootAssembly
    viewport.setValues(displayedObject=ra)
    ra.regenerate()

    return nodal_translations
from desicos.conecylDB.fit_data import fw0

ntheta = 420
nz = 180
funcnum = 2
path = 'degenhardt_2010_z25_msi_theta_z_imp.txt'

theta = linspace(-pi, pi, ntheta)
z = linspace(0., 1., nz)
theta, z = meshgrid(theta, z, copy=False)

for m0, n0 in [[20, 30], [30, 45], [40, 60], [50, 75]]:
    c, residues = calc_c0(path, m0=m0, n0=n0, sample_size=(10*2*m*n),
                          funcnum=funcnum)

    w0 = fw0(m0, n0, z.ravel(), theta.ravel(), funcnum=funcnum)

    plt.figure(figsize=(3.5, 2))

    levels = np.linspace(w0.min(), w0.max(), 400)
    plt.contourf(theta, z*H_measured, w0.reshape(theta.shape),
                 levels=levels)

    ax = plt.gca()
    ax.xaxis.set_ticks_position('bottom')
    ax.yaxis.set_ticks_position('left')
    ax.spines['top'].set_visible(False)
    ax.spines['right'].set_visible(False)

    ax.xaxis.set_ticks([-pi, pi])
    ax.xaxis.set_ticklabels([r'$-\pi$', r'$\pi$'])
Пример #3
0
def translate_nodes_ABAQUS_c0(m0, n0, c0, funcnum,
                              model_name,
                              part_name,
                              H_model,
                              semi_angle=0.,
                              scaling_factor=1.,
                              fem_meridian_bot2top=True,
                              ignore_bot_h=None,
                              ignore_top_h=None,
                              T=None):
    r"""Translates the nodes in Abaqus based on a Fourier series

    The Fourier Series can be a half-sine, half-cosine or a complete Fourier
    Series as detailed in :func:`desicos.conecylDB.fit_data.calc_c0`.

    Parameters
    ----------
    m0 : int
        Number of terms along the `x` coordinate.
    n0 : int
        Number of terms along the `\theta` coordinate.
    c0 : numpy.ndarray
        The coefficients that will give the imperfection pattern.
    funcnum : int
        The function type, as detailed in
        :func:`desicos.conecylDB.fit_data.calc_c0`.
    model_name : str
        Must be a valid key in the dictionary ``mdb.models``, in the
        interactive Python inside Abaqus.
    part_name : str
        Must be a valid key in the dictionary
        ``mdb.models[model_name].parts``, in the interactive Python inside
        Abaqus.
    H_model : float
        Total height of the model where the imperfections will be applied to,
        considering also eventual resin rings.
    semi_angle : float, optional
        The cone semi-vertex angle (a null value indicates that a cylinder is
        beeing analyzed).
    scaling_factor : float, optional
        The scaling factor that will multiply ``c0`` when applying the
        imperfections.
    fem_meridian_bot2top : bool, optional
        A boolean indicating if the finite element has the `x` axis starting
        at the bottom or at the top.
    ignore_bot_h : None or float, optional
        Used to ignore nodes from the bottom resin ring.
    ignore_top_h : None or float, optional
        Used to ignore nodes from the top resin ring.
    T : None or np.ndarray, optional
        A transformation matrix (cf. :func:`.transf_matrix`) required when the
        mesh is not in the :ref:`default coordinate system <figure_conecyl>`.

    Returns
    -------
    nodal_translations : numpy.ndarray
        A 2-D array containing the translations ``x, y, z`` for each column.

    Notes
    -----
    Despite the nodal traslations are returned all the nodes belonging to this
    model will be already translated.

    """
    from abaqus import mdb, session

    from desicos.conecylDB import fit_data

    log('Calculating imperfection amplitudes for model {0} ...\n\t'.
        format(model_name) +
        '(using a scaling factor of {0})'.format(scaling_factor))
    c0 = c0*scaling_factor
    mod = mdb.models[model_name]
    part = mod.parts[part_name]

    part_nodes = np.array(part.nodes)
    coords = np.array([n.coordinates for n in part_nodes])

    if T is not None:
        tmp = np.vstack((coords.T, np.ones((1, coords.shape[0]))))
        coords = np.dot(T, tmp).T
        del tmp

    if ignore_bot_h is not None:
        if ignore_bot_h <= 0:
            ignore_bot_h = None
        else:
            log('Applying ignore_bot_h: ignoring nodes with z <= {0}'.format(
                ignore_bot_h))
            mask = coords[:, 2] > ignore_bot_h
            coords = coords[mask]
            part_nodes = part_nodes[mask]

    if ignore_top_h is not None:
        if ignore_top_h <= 0:
            ignore_top_h = None
        else:
            log('Applying ignore_top_h: ignoring nodes with z >= {0}'.format(
                H_model - ignore_top_h))
            mask = coords[:, 2] < (H_model - ignore_top_h)
            coords = coords[mask]
            part_nodes = part_nodes[mask]

    if ignore_bot_h is None:
        ignore_bot_h = 0
    if ignore_top_h is None:
        ignore_top_h = 0
    H_eff = H_model - (ignore_bot_h + ignore_top_h)
    if fem_meridian_bot2top:
        xs_norm = (coords[:, 2]-ignore_bot_h)/H_eff
    else:
        xs_norm = (H_eff-(coords[:, 2]-ignore_bot_h))/H_eff

    thetas = arctan2(coords[:, 1], coords[:, 0])

    alpharad = deg2rad(semi_angle)
    w0 = fit_data.fw0(m0, n0, c0, xs_norm, thetas, funcnum)
    nodal_translations = np.zeros_like(coords)
    nodal_translations[:, 0] = w0*cos(alpharad)*cos(thetas)
    nodal_translations[:, 1] = w0*cos(alpharad)*sin(thetas)
    nodal_translations[:, 2] = w0*sin(alpharad)

    log('Calculation of imperfection amplitudes finished!')

    # applying translations
    viewport = session.viewports[session.currentViewportName]
    log('Applying new nodal positions in ABAQUS CAE to model {0} ...'.
        format(model_name))
    log('    (using a scaling factor of {0})'.format(scaling_factor))

    new_coords = coords + nodal_translations

    if T is not None:
        Tinv = np.zeros_like(T)
        Tinv[:3, :3] = T[:3, :3].T
        Tinv[:, 3] = -T[:, 3]
        tmp = np.vstack((new_coords.T, np.ones((1, new_coords.shape[0]))))
        new_coords = np.dot(Tinv, tmp).T
        del tmp

    meshNodeArray = part.nodes.sequenceFromLabels(
                        [n.label for n in part_nodes])
    new_coords = np.ascontiguousarray(new_coords)
    part.editNode(nodes=meshNodeArray, coordinates=new_coords)

    log('Application of new nodal positions finished!')

    ra = mod.rootAssembly
    viewport.setValues(displayedObject=ra)
    ra.regenerate()

    return nodal_translations
nz = 180
funcnum = 2
path = 'degenhardt_2010_z25_msi_theta_z_imp.txt'

theta = linspace(-pi, pi, ntheta)
z = linspace(0., 1., nz)
theta, z = meshgrid(theta, z, copy=False)

for m0, n0 in [[20, 30], [30, 45], [40, 60], [50, 75]]:
    c, residues = calc_c0(path,
                          m0=m0,
                          n0=n0,
                          sample_size=(10 * 2 * m * n),
                          funcnum=funcnum)

    w0 = fw0(m0, n0, z.ravel(), theta.ravel(), funcnum=funcnum)

    plt.figure(figsize=(3.5, 2))

    levels = np.linspace(w0.min(), w0.max(), 400)
    plt.contourf(theta, z * H_measured, w0.reshape(theta.shape), levels=levels)

    ax = plt.gca()
    ax.xaxis.set_ticks_position('bottom')
    ax.yaxis.set_ticks_position('left')
    ax.spines['top'].set_visible(False)
    ax.spines['right'].set_visible(False)

    ax.xaxis.set_ticks([-pi, pi])
    ax.xaxis.set_ticklabels([r'$-\pi$', r'$\pi$'])
    ax.set_xlabel('Circumferential Position, $rad$')