예제 #1
0
def disturb_my_model(imperfection_file_name,
                     nodes_file_name,
                     output_file_name,
                     H_model,
                     H_measured,
                     R_model,
                     R_best_fit=None,
                     semi_angle=0.,
                     stretch_H=False,
                     z_offset_bot=None,
                     rotatedeg=0.,
                     scaling_factor=1.,
                     r_TOL=1.,
                     num_closest_points=5,
                     power_parameter=2,
                     num_sec_z=25,
                     sample_size=None):
    # reading nodes data
    log('Reading nodes data from {0} ...'.format(nodes_file_name))
    nodes = get_nodes_from_txt_file(nodes_file_name)
    # calling translate_nodes function
    nodal_translations = calc_nodal_translations(
                                     imperfection_file_name,
                                     nodes = nodes,
                                     H_model = H_model,
                                     H_measured = H_measured,
                                     R_model = R_model,
                                     R_best_fit = R_best_fit,
                                     semi_angle = semi_angle,
                                     stretch_H = stretch_H,
                                     z_offset_bot = z_offset_bot,
                                     rotatedeg = rotatedeg,
                                     r_TOL = r_TOL,
                                     num_closest_points = num_closest_points,
                                     power_parameter = power_parameter,
                                     num_sec_z = num_sec_z,
                                     sample_size=sample_size)
    # writing output file
    log('Writing output file "{0}" ...'.format(output_file_name))
    outfile = open(output_file_name, 'w')
    for i, node in enumerate(nodal_translations):
        original_coords = node[0:3]
        translations = nodal_translations[k]
        new_coords = original_coords + translations * scaling_factor
        outfile.write('{0:d} {1:f} {2:f} {3:f}\n'.format(k, coords[0],
                      coords[1], coords[2]))
    outfile.close()
    return True
예제 #2
0
def disturb_my_model(imperfection_file_name,
                     nodes_file_name,
                     output_file_name,
                     H_model,
                     H_measured,
                     R_model,
                     R_best_fit=None,
                     semi_angle=0.,
                     stretch_H=False,
                     z_offset_bot=None,
                     rotatedeg=0.,
                     scaling_factor=1.,
                     r_TOL=1.,
                     num_closest_points=5,
                     power_parameter=2,
                     num_sec_z=25,
                     sample_size=None):
    # reading nodes data
    log('Reading nodes data from {0} ...'.format(nodes_file_name))
    nodes = get_nodes_from_txt_file(nodes_file_name)
    # calling translate_nodes function
    nodal_translations = calc_nodal_translations(
        imperfection_file_name,
        nodes=nodes,
        H_model=H_model,
        H_measured=H_measured,
        R_model=R_model,
        R_best_fit=R_best_fit,
        semi_angle=semi_angle,
        stretch_H=stretch_H,
        z_offset_bot=z_offset_bot,
        rotatedeg=rotatedeg,
        r_TOL=r_TOL,
        num_closest_points=num_closest_points,
        power_parameter=power_parameter,
        num_sec_z=num_sec_z,
        sample_size=sample_size)
    # writing output file
    log('Writing output file "{0}" ...'.format(output_file_name))
    outfile = open(output_file_name, 'w')
    for i, node in enumerate(nodal_translations):
        original_coords = node[0:3]
        translations = nodal_translations[k]
        new_coords = original_coords + translations * scaling_factor
        outfile.write('{0:d} {1:f} {2:f} {3:f}\n'.format(
            k, coords[0], coords[1], coords[2]))
    outfile.close()
    return True
예제 #3
0
    def check_completed(self, wait=False, print_found=False):
        if not self.rebuilt:
            self.rebuild()
        tmp = os.path.join(self.output_dir, self.model_name + '.log')
        if wait == True:
            log('Waiting for job completion...')
        #TODO a general function to check the log file
        while True:
            if os.path.isfile(tmp):
                tmpfile = open(tmp, 'r')
                lines = tmpfile.readlines()
                tmpfile.close()
                if len(lines) == 0:
                    continue
                if len(lines) < 2:
                    continue
                if lines[-2].find('End Abaqus/Standard Analysis') > -1:
                    if print_found:
                        log('RUN COMPLETED for model {0}'.format(
                            self.model_name))
                    return True
                elif lines[-1].find('Abaqus/Analysis exited with errors') > -1:
                    if print_found:
                        log('RUN COMPLETED WITH ERRORS for model {0}'.format(
                            self.model_name))
                    return True

                else:
                    if not wait:
                        warn('RUN NOT COMPLETED for model {0}'.format(
                            self.model_name))
                        return False
            else:
                if not wait:
                    warn('RUN NOT STARTED for model {0}'.format(
                        self.model_name))
                    return False
            if wait:
                import time
                time.sleep(5)
예제 #4
0
    def check_completed(self, wait=False, print_found=False):
        if not self.rebuilt:
            self.rebuild()
        tmp = os.path.join(self.output_dir, self.model_name + '.log')
        if wait == True:
            log('Waiting for job completion...')
        #TODO a general function to check the log file
        while True:
            if os.path.isfile(tmp):
                tmpfile = open(tmp, 'r')
                lines = tmpfile.readlines()
                tmpfile.close()
                if len(lines) == 0:
                    continue
                if len(lines) < 2:
                    continue
                if lines[-2].find('End Abaqus/Standard Analysis') > -1:
                    if print_found:
                        log('RUN COMPLETED for model {0}'.format(
                            self.model_name))
                    return True
                elif lines[-1].find('Abaqus/Analysis exited with errors') > -1:
                    if print_found:
                        log('RUN COMPLETED WITH ERRORS for model {0}'.format(
                            self.model_name))
                    return True

                else:
                    if not wait:
                        warn('RUN NOT COMPLETED for model {0}'.format(
                             self.model_name))
                        return False
            else:
                if not wait:
                    warn('RUN NOT STARTED for model {0}'.format(
                         self.model_name))
                    return False
            if wait:
                import time
                time.sleep(5)
예제 #5
0
    cc.created_model = False
    cc.create_model()
    part_nodes = mdb.models[cc.model_name].parts[cc.part_name_shell].nodes
    coords = np.array([n.coordinates for n in part_nodes])

    sf = 100

    path = r'C:\clones\desicos\desicos\conecylDB\files\dlr\degenhardt_2010_z20\degenhardt_2010_z20_msi_theta_z_imp.txt'
    H_measured = 510.
    H_model = 510.
    d, d, data = read_theta_z_imp(path=path,
                                  H_measured=H_measured,
                                  stretch_H=False,
                                  z_offset_bot=None)

    log('init sample')
    data = np.array(sample(data, 10000))
    log('end sample')
    data = data[np.argsort(data[:, 0])]
    data = np.vstack((data[-3000:], data[:], data[:3000]))
    data[:, 0] /= data[:, 0].max()

    mesh = np.zeros((coords.shape[0], 2), dtype=FLOAT)
    mesh[:, 0] = arctan2(coords[:, 1], coords[:, 0])
    mesh[:, 1] = coords[:, 2]
    mesh_norm = mesh.copy()
    mesh_norm[:, 0] /= mesh_norm[:, 0].max()
    mesh_norm[:, 1] /= mesh_norm[:, 1].max()

    import desicos.conecylDB.interpolate
    reload(desicos.conecylDB.interpolate)
예제 #6
0
def read_file(file_name,
              frequency=1,
              forced_average_radius=None,
              H_measured=None,
              R_best_fit=None,
              stretch_H=False,
              z_offset_bot=None,
              r_TOL=1.):
    log('Reading imperfection file: {0} ...'.format(file_name))
    # user warnings
    if stretch_H:
        if z_offset_bot:
            warn('Because of the stretch_H option, ' +
                 'consider setting z_offset_bot to None')
    # reading the imperfection file
    ignore = False
    mps = np.loadtxt(file_name, dtype=FLOAT)
    r = np.sqrt(mps[:, 0]**2 + mps[:, 1]**2)
    # measuring model dimensions
    if R_best_fit is None:
        R_best_fit = np.average(r)
        warn('The cylinder average radius of the measured points ' +
             'assumed to be {0:1.2f}'.format(R_best_fit))
    z_min = mps[:, 2].min()
    z_max = mps[:, 2].max()
    z_center = (z_max + z_min) / 2.
    H_points = (z_max - z_min)
    log('R_best_fit     : {0}'.format(R_best_fit))
    # applying user inputs
    R = R_best_fit
    if forced_average_radius:
        R = forced_average_radius
        log('Forced measured radius: {0}'.format(forced_average_radius))
    H_model = H_points
    if not H_measured:
        H_measured = H_points
        warn('The cylinder height of the measured points assumed ' +
             'to be {0:1.2f}'.format(H_measured))
    # calculating default z_offset_bot
    if not z_offset_bot:
        if stretch_H:
            z_offset_bot = 0.
        else:
            z_offset_bot = (H_measured - H_points) / 2.
    offset_z = z_offset_bot - z_min
    log('H_points       : {0}'.format(H_points))
    log('H_measured     : {0}'.format(H_measured))
    log('z_min          : {0}'.format(z_min))
    log('z_max          : {0}'.format(z_max))
    log('offset_z       : {0}'.format(offset_z))
    r_TOL_min = (R * (1 - r_TOL / 100.))
    r_TOL_max = (R * (1 + r_TOL / 100.))
    cond = np.all(np.array((r > r_TOL_max, r < r_TOL_min)), axis=0)
    skept = mps[cond]
    log('Skipping {0} points'.format(len(skept)))
    mps = mps[np.logical_not(cond)]
    offset_mps = mps.copy()
    offset_mps[:, 2] += offset_z
    norm_mps = offset_mps.copy()
    norm_mps[:, 0] /= R
    norm_mps[:, 1] /= R
    if stretch_H:
        norm_mps[:, 2] /= H_points
    else:
        norm_mps[:, 2] /= H_measured
    return mps, offset_mps, norm_mps
예제 #7
0
def calc_nodal_translations(imperfection_file_name, nodes, H_model, H_measured,
                            R_model, R_best_fit, semi_angle, stretch_H,
                            z_offset_bot, rotatedeg, r_TOL, num_closest_points,
                            power_parameter, num_sec_z, sample_size):
    # reading imperfection file
    m, o, mps = read_file(file_name=imperfection_file_name,
                          H_measured=H_measured,
                          R_best_fit=R_best_fit,
                          forced_average_radius=R_best_fit,
                          stretch_H=stretch_H,
                          z_offset_bot=z_offset_bot,
                          r_TOL=r_TOL)

    log('Calculating nodal translations!')
    if sample_size:
        num = mps.shape[0]
        if sample_size < num:
            log('Using sample_size={0}'.format(sample_size), level=1)
            mps = mps[sample(range(num), int(sample_size)), :]
    num_nodes = nodes.shape[0]
    R_top = R_model - np.tan(np.deg2rad(semi_angle)) * H_model
    semi_angle = abs(semi_angle)

    def local_radius(z):
        return R_model + (R_top - R_model) * z / H_model

    mps[:, 2] *= H_model
    if semi_angle < 1.e-6:
        R_local = R_model
    else:
        R_local = local_radius(mps[:, 2])
    thetarads = np.arctan2(mps[:, 1], mps[:, 0])
    if rotatedeg:
        thetarads += np.deg2rad(rotatedeg)
    mps[:, 0] = R_local * np.cos(thetarads)
    mps[:, 1] = R_local * np.sin(thetarads)
    num_sec_z = int(num_sec_z)
    mem_limit = 1024 * 1024 * 1024 * 8 * 2  # 2 GB
    mem_entries = int(mem_limit / 64)  # if float64 is used
    sec_size = int(num_nodes / num_sec_z)
    #TODO better memory control...
    if sec_size**2 * 10 > mem_entries:
        while True:
            num_sec_z += 1
            sec_size = int(num_nodes / num_sec_z)
            if sec_size**2 * 10 <= mem_entries:
                warn('New sec_size {0}'.format(sec_size))
                break
    ncp = num_closest_points
    nodes = nodes[np.argsort(nodes[:, 2])]
    mps = mps[np.argsort(mps[:, 2])]
    nodal_t = np.zeros(nodes.shape, dtype=nodes.dtype)
    limit = int(num_sec_z / 5)
    for i in xrange(num_sec_z + 1):
        i_inf = sec_size * i
        i_sup = sec_size * (i + 1)
        if i % limit == 0:
            log('processed {0:7d} out of {1:7d} entries'.format(
                min(i_sup, num_nodes), num_nodes),
                level=1)
        sub_nodes = nodes[i_inf:i_sup]
        if not np.any(sub_nodes):
            continue
        inf_z = sub_nodes[:, 2].min()
        sup_z = sub_nodes[:, 2].max()
        tol = 0.01
        if i == 0 or i == num_sec_z:
            tol = 0.05
        while True:
            cond1 = mps[:, 2] >= inf_z - tol * H_model
            cond2 = mps[:, 2] <= sup_z + tol * H_model
            cond = np.all(np.array((cond1, cond2)), axis=0)
            sub_mps = mps[cond]
            if not np.any(sub_mps):
                tol += 0.01
            else:
                break
        dist = np.subtract.outer(sub_nodes[:, 0], sub_mps[:, 0])**2
        dist += np.subtract.outer(sub_nodes[:, 1], sub_mps[:, 1])**2
        dist += np.subtract.outer(sub_nodes[:, 2], sub_mps[:, 2])**2
        asort = np.argsort(dist, axis=1)
        lenn = sub_nodes.shape[0]
        lenp = sub_mps.shape[0]
        asort_mesh = asort + np.meshgrid(
            np.arange(lenn) * lenp, np.arange(lenp))[0].transpose()
        # getting the z coordinate of the closest points
        sub_mps_z = np.take(sub_mps[:, 2], asort[:, :ncp])
        # getting the distance of the closest points
        dist_ncp = np.take(dist, asort_mesh[:, :ncp])
        # avoiding division by zero
        dist_ncp[(dist_ncp == 0)] == 1.e-12
        # calculating the radius of the sub-group of measured points
        radius = np.sqrt(sub_mps[:, 0]**2 + sub_mps[:, 1]**2)
        # taking only the radius of the closest points
        radius_ncp = np.take(radius, asort[:, :ncp])
        # weight calculation
        total_weight = np.sum(1. / (dist_ncp**power_parameter), axis=1)
        weight = 1. / (dist_ncp**power_parameter)
        # calculating the local radius for the closest points
        r_local_ncp = local_radius(sub_mps_z)
        # computing the new radius
        r_new = np.sum(radius_ncp * weight / r_local_ncp,
                       axis=1) / total_weight
        r_new *= local_radius(sub_nodes[:, 2])
        #NOTE modified after Regina, Mariano and Saullo decided to use
        #     the imperfection amplitude constant along the whole cone
        #     surface, which represents better the real manufacturing
        #     conditions. In that case the amplitude will be re-scaled
        #     using only  the bottom radius
        # calculating the local radius for the nodes for the new assumption
        r_local_nodes = np.sqrt(sub_nodes[:, 0]**2 + sub_nodes[:, 1]**2)
        # calculating the scaling factor required for the new assumption
        sf = R_model / r_local_nodes
        theta = np.arctan2(sub_nodes[:, 1], sub_nodes[:, 0])
        nodal_t[i_inf : i_sup][:, 0] = \
                (r_new*np.cos(theta) - sub_nodes[:, 0])*sf
        nodal_t[i_inf : i_sup][:, 1] = \
                (r_new*np.sin(theta) - sub_nodes[:, 1])*sf
        nodal_t[i_inf:i_sup][:, 3] = sub_nodes[:, 3]
    nodal_t = nodal_t[np.argsort(nodal_t[:, 3])]
    log('Nodal translations calculated!')

    return nodal_t
예제 #8
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
예제 #9
0
def read_file(file_name,
               frequency             = 1,
               forced_average_radius = None,
               H_measured            = None,
               R_best_fit            = None,
               stretch_H             = False,
               z_offset_bot            = None,
               r_TOL                 = 1.):
    log('Reading imperfection file: {0} ...'.format(file_name))
    # user warnings
    if stretch_H:
        if z_offset_bot:
            warn('Because of the stretch_H option, '+
                 'consider setting z_offset_bot to None')
    # reading the imperfection file
    ignore = False
    mps = np.loadtxt(file_name, dtype=FLOAT)
    r = np.sqrt(mps[:, 0]**2 + mps[:, 1]**2)
    # measuring model dimensions
    if R_best_fit is None:
        R_best_fit   = np.average(r)
        warn('The cylinder average radius of the measured points ' +
             'assumed to be {0:1.2f}'.format(R_best_fit))
    z_min = mps[:, 2].min()
    z_max = mps[:, 2].max()
    z_center  = (z_max + z_min)/2.
    H_points  = (z_max - z_min)
    log('R_best_fit     : {0}'.format(R_best_fit))
    # applying user inputs
    R = R_best_fit
    if forced_average_radius:
        R = forced_average_radius
        log('Forced measured radius: {0}'.format(forced_average_radius))
    H_model = H_points
    if not H_measured:
        H_measured = H_points
        warn('The cylinder height of the measured points assumed ' +
             'to be {0:1.2f}'.format(H_measured))
    # calculating default z_offset_bot
    if not z_offset_bot:
        if stretch_H:
            z_offset_bot = 0.
        else:
            z_offset_bot = (H_measured - H_points) / 2.
    offset_z = z_offset_bot - z_min
    log('H_points       : {0}'.format(H_points))
    log('H_measured     : {0}'.format(H_measured))
    log('z_min          : {0}'.format(z_min))
    log('z_max          : {0}'.format(z_max))
    log('offset_z       : {0}'.format(offset_z))
    r_TOL_min = (R * (1-r_TOL/100.))
    r_TOL_max = (R * (1+r_TOL/100.))
    cond = np.all(np.array((r > r_TOL_max,
                            r < r_TOL_min)), axis=0)
    skept = mps[cond]
    log('Skipping {0} points'.format(len(skept)))
    mps = mps[np.logical_not(cond)]
    offset_mps = mps.copy()
    offset_mps[:, 2] += offset_z
    norm_mps = offset_mps.copy()
    norm_mps[:, 0] /= R
    norm_mps[:, 1] /= R
    if stretch_H:
        norm_mps[:, 2] /= H_points
    else:
        norm_mps[:, 2] /= H_measured
    return mps, offset_mps, norm_mps
예제 #10
0
def calc_nodal_translations(imperfection_file_name,
                            nodes,
                            H_model,
                            H_measured,
                            R_model,
                            R_best_fit,
                            semi_angle,
                            stretch_H,
                            z_offset_bot,
                            rotatedeg,
                            r_TOL,
                            num_closest_points,
                            power_parameter,
                            num_sec_z,
                            sample_size):
    # reading imperfection file
    m, o, mps = read_file(file_name = imperfection_file_name,
                          H_measured = H_measured,
                          R_best_fit = R_best_fit,
                          forced_average_radius = R_best_fit,
                          stretch_H = stretch_H,
                          z_offset_bot = z_offset_bot,
                          r_TOL = r_TOL)

    log('Calculating nodal translations!')
    if sample_size:
        num = mps.shape[0]
        if sample_size < num:
            log('Using sample_size={0}'.format(sample_size), level=1)
            mps = mps[sample(range(num), int(sample_size)), :]
    num_nodes = nodes.shape[0]
    R_top = R_model - np.tan(np.deg2rad(semi_angle)) * H_model
    semi_angle = abs(semi_angle)
    def local_radius(z):
        return R_model + (R_top - R_model) * z / H_model
    mps[:, 2] *= H_model
    if semi_angle < 1.e-6:
        R_local = R_model
    else:
        R_local = local_radius(mps[:, 2])
    thetarads = np.arctan2(mps[:, 1], mps[:, 0])
    if rotatedeg:
        thetarads += np.deg2rad(rotatedeg)
    mps[:, 0] = R_local*np.cos(thetarads)
    mps[:, 1] = R_local*np.sin(thetarads)
    num_sec_z = int(num_sec_z)
    mem_limit = 1024*1024*1024*8*2    # 2 GB
    mem_entries = int(mem_limit / 64) # if float64 is used
    sec_size = int(num_nodes/num_sec_z)
    #TODO better memory control...
    if sec_size**2*10 > mem_entries:
        while True:
            num_sec_z +=1
            sec_size = int(num_nodes/num_sec_z)
            if sec_size**2*10 <= mem_entries:
                warn('New sec_size {0}'.format(sec_size))
                break
    ncp = num_closest_points
    nodes = nodes[np.argsort(nodes[:, 2])]
    mps = mps[np.argsort(mps[:, 2])]
    nodal_t = np.zeros(nodes.shape, dtype=nodes.dtype)
    limit = int(num_sec_z/5)
    for i in xrange(num_sec_z+1):
        i_inf = sec_size*i
        i_sup = sec_size*(i+1)
        if i % limit == 0:
            log('processed {0:7d} out of {1:7d} entries'.format(
                min(i_sup, num_nodes), num_nodes), level=1)
        sub_nodes = nodes[i_inf : i_sup]
        if not np.any(sub_nodes):
            continue
        inf_z = sub_nodes[:, 2].min()
        sup_z = sub_nodes[:, 2].max()
        tol = 0.01
        if i == 0 or i == num_sec_z:
            tol = 0.05
        while True:
            cond1 = mps[:, 2] >= inf_z - tol*H_model
            cond2 = mps[:, 2] <= sup_z + tol*H_model
            cond = np.all(np.array((cond1, cond2)), axis=0)
            sub_mps = mps[cond]
            if not np.any(sub_mps):
                tol += 0.01
            else:
                break
        dist  = np.subtract.outer(sub_nodes[:, 0], sub_mps[:, 0])**2
        dist += np.subtract.outer(sub_nodes[:, 1], sub_mps[:, 1])**2
        dist += np.subtract.outer(sub_nodes[:, 2], sub_mps[:, 2])**2
        asort = np.argsort(dist, axis=1)
        lenn = sub_nodes.shape[0]
        lenp = sub_mps.shape[0]
        asort_mesh = asort + np.meshgrid(np.arange(lenn)*lenp,
                                         np.arange(lenp))[0].transpose()
        # getting the z coordinate of the closest points
        sub_mps_z = np.take(sub_mps[:, 2], asort[:, :ncp])
        # getting the distance of the closest points
        dist_ncp = np.take(dist, asort_mesh[:, :ncp])
        # avoiding division by zero
        dist_ncp[(dist_ncp==0)] == 1.e-12
        # calculating the radius of the sub-group of measured points
        radius = np.sqrt(sub_mps[:, 0]**2 + sub_mps[:, 1]**2)
        # taking only the radius of the closest points
        radius_ncp = np.take(radius, asort[:, :ncp])
        # weight calculation
        total_weight = np.sum(1./(dist_ncp**power_parameter), axis=1)
        weight = 1./(dist_ncp**power_parameter)
        # calculating the local radius for the closest points
        r_local_ncp = local_radius(sub_mps_z)
        # computing the new radius
        r_new = np.sum(radius_ncp*weight/r_local_ncp, axis=1)/total_weight
        r_new *= local_radius(sub_nodes[:, 2])
        #NOTE modified after Regina, Mariano and Saullo decided to use
        #     the imperfection amplitude constant along the whole cone
        #     surface, which represents better the real manufacturing
        #     conditions. In that case the amplitude will be re-scaled
        #     using only  the bottom radius
        # calculating the local radius for the nodes for the new assumption
        r_local_nodes = np.sqrt(sub_nodes[:,0]**2 + sub_nodes[:, 1]**2)
        # calculating the scaling factor required for the new assumption
        sf = R_model/r_local_nodes
        theta = np.arctan2(sub_nodes[:, 1], sub_nodes[:, 0])
        nodal_t[i_inf : i_sup][:, 0] = \
                (r_new*np.cos(theta) - sub_nodes[:, 0])*sf
        nodal_t[i_inf : i_sup][:, 1] = \
                (r_new*np.sin(theta) - sub_nodes[:, 1])*sf
        nodal_t[i_inf : i_sup][:, 3] = sub_nodes[:, 3]
    nodal_t = nodal_t[np.argsort(nodal_t[:, 3])]
    log('Nodal translations calculated!')

    return nodal_t
예제 #11
0
def change_thickness_ABAQUS(imperfection_file_name,
                            model_name,
                            part_name,
                            stack,
                            t_model,
                            t_measured,
                            H_model,
                            H_measured,
                            R_model,
                            R_best_fit = None,
                            number_of_sets = None,
                            semi_angle = 0.,
                            stretch_H = False,
                            z_offset_bot = None,
                            scaling_factor = 1.,
                            num_closest_points = 5,
                            power_parameter = 2,
                            num_sec_z = 100,
                            elems_t = None,
                            t_set = None,
                            use_theta_z_format = False):
    r"""Applies a given thickness imperfection to the finite element model

    Assumes that a percentage variation of the laminate thickness can be
    represented by the same percentage veriation of each ply, i.e., each
    ply thickness is varied in order to reflect a given measured thickness
    imperfection field.

    Parameters
    ----------

    imperfection_file_name : str
        Full path to the imperfection file.
    model_name : str
        Model name.
    part_name : str
        Part name.
    stack : list
        The stacking sequence of the current model with each angle given in
        degrees.
    t_model : float
        The nominal shell thickness of the current model.
    t_measured : float
        The nominal thickness of the measured specimen.
    H_model : float
        Total height of the model where the imperfections will be applied to,
        considering also eventual resin rings.
    H_measured : float
        The total height of the measured test specimen, including eventual
        resin rings at the edges.
    R_model : float
        Radius **at the bottom edge** of the model where the imperfections
        will be applied to.
    R_best_fit : float, optional
        Best fit radius obtained with functions :func:`.best_fit_cylinder`
        or :func:`.best_fit_cone`.
    number_of_sets : int, optional
        Defines in how many levels the thicknesses should be divided. If
        ``None`` it will be based on the input file, and if the threshold
        of ``100`` is exceeded, ``10`` sections are used.
    semi_angle : float, optional
        Cone semi-vertex angle in degrees, when applicable.
    stretch_H : bool, optional
        If the measured imperfection data should be stretched to the current
        model (which may happen when ``H_model!=H_measured``.
    z_offset_bot : float, optional
        It is common to have the measured data not covering the whole test
        specimen, and therefore it will be centralized, if a non-centralized
        position is desired this parameter can be used for the adjustment.
    scaling_factor : float, optional
        A scaling factor that can be used to study the imperfection
        sensitivity.
    num_closest_points : int, optional
        See :func:`the inverse-weighted interpolation algorithm
        <.inv_weighted>`.
    power_parameter : float, optional
        See :func:`the inverse-weighted interpolation algorithm
        <.inv_weighted>`.
    num_sec_z : int, optional
        Number of spatial sections used to classify the measured data in order
        to accelerate the searching algorithms
    elems_t : np.ndarray, optional
        Interpolated thickness for each element. Can be used to avoid the same
        interpolation to be performed twice.
    t_set : set, optional
        A ``set`` object containing the unique thicknesses that will be used
        to create the new properties.
    use_theta_z_format : bool, optional
        If the new format `\theta, Z, imp` should be used instead of the old
        `X, Y, Z`.

    """
    from abaqus import mdb

    import desicos.abaqus.abaqus_functions as abaqus_functions

    mod = mdb.models[model_name]
    part = mod.parts[part_name]
    part_cyl_csys = part.features['part_cyl_csys']
    part_cyl_csys = part.datums[part_cyl_csys.id]

    if use_theta_z_format:
        if elems_t is None or t_set is None:
            log('Reading coordinates for elements...')
            elements = vec_calc_elem_cg(part.elements)

            log('Coordinates for elements read!')
            d, d, data = read_theta_z_imp(path = imperfection_file_name,
                                          H_measured = H_measured,
                                          stretch_H = stretch_H,
                                          z_offset_bot = z_offset_bot)

            data3D = np.zeros((data.shape[0], 4), dtype=FLOAT)
            z = data[:, 1]
            z *= H_model

            alpharad = deg2rad(semi_angle)
            tana = tan(alpharad)
            def r_local(z):
                return R_model - z*tana
            data3D[:, 0] = r_local(z)*cos(data[:, 0])
            data3D[:, 1] = r_local(z)*sin(data[:, 0])
            data3D[:, 2] = z
            data3D[:, 3] = data[:, 2]

            ans = inv_weighted(data3D, elements[:, :3],
                               num_sub = num_sec_z,
                               col = 2,
                               ncp = num_closest_points,
                               power_parameter = power_parameter)

            t_set = set(ans)
            t_set.discard(0.) #TODO why inv_weighted returns an array with 0.
            elems_t = np.zeros((elements.shape[0], 2), dtype=FLOAT)
            elems_t[:, 0] = elements[:, 3]
            elems_t[:, 1] = ans

        else:
            log('Thickness differences already calculated!')

    else:
        if elems_t is None or t_set is None:
            # reading elements data
            log('Reading coordinates for elements...')
            elements = vec_calc_elem_cg(part.elements)
            log('Coordinates for elements read!')
            # calling translate_nodes function
            elems_t, t_set = calc_elems_t(
                                imperfection_file_name,
                                nodes = elements,
                                t_model = t_model,
                                t_measured = t_measured,
                                H_model = H_model,
                                H_measured = H_measured,
                                R_model = R_model,
                                R_best_fit = R_best_fit,
                                semi_angle = semi_angle,
                                stretch_H = stretch_H,
                                z_offset_bot = z_offset_bot,
                                num_closest_points = num_closest_points,
                                power_parameter = power_parameter,
                                num_sec_z = num_sec_z)
        else:
            log('Thickness differences already calculated!')
    # creating sets
    t_list = []
    max_len_t_set = 100
    if len(t_set) >= max_len_t_set and number_of_sets in (None, 0):
        number_of_sets = 10
        log('More than {0:d} different thicknesses measured!'.format(
            max_len_t_set))
        log('Forcing a number_of_sets = {0:d}'.format(number_of_sets))
    if number_of_sets is None or number_of_sets == 0:
        number_of_sets = len(t_set)
        t_list = list(t_set)
        t_list.sort()
    else:
        t_min = min(t_set)
        t_max = max(t_set)
        t_list = list(np.linspace(t_min, t_max, number_of_sets+1))

    # grouping elements
    sets_ids = [[] for i in range(len(t_list))]
    for entry in elems_t:
        elem_id, t = entry
        index = index_within_linspace(t_list, t)
        sets_ids[index].append(int(elem_id))
    # putting elements in sets
    original_layup = part.compositeLayups['CompositePlate']
    for i, set_ids in enumerate(sets_ids):
        if len(set_ids) == 0:
            # since t_set_norm * t_model <> t_set originally measured
            # there may be empty set_ids at the end
            continue
        elements = part.elements.sequenceFromLabels(labels=set_ids)
        suffix = 'measured_imp_t_{0:03d}'.format(i)
        set_name = 'Set_' + suffix
        log('Creating set ({0: 7d} elements): {1}'.format(
            len(set_ids), set_name))
        part.Set(name = set_name, elements = elements)
        region = part.sets[set_name]
        layup_name = 'CLayup_' + suffix
        t_diff = (float(t_list[i]) - t_model) * scaling_factor
        t_scaling_factor = (t_model + t_diff)/t_model

        def modify_ply(index, kwargs):
            kwargs['thickness'] *= t_scaling_factor
            kwargs['region'] = region
            return kwargs

        layup = part.CompositeLayup(name=layup_name,
                                    objectToCopy=original_layup)
        layup.resume()
        abaqus_functions.modify_composite_layup(part=part,
            layup_name=layup_name, modify_func=modify_ply)
    # suppress needed to put the new properties to the input file
    original_layup.suppress()

    return elems_t, t_set
예제 #12
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
예제 #13
0
def calc_translations_ABAQUS(imperfection_file_name,
                             model_name,
                             part_name,
                             H_model,
                             H_measured,
                             R_model,
                             R_best_fit=None,
                             semi_angle=0.,
                             stretch_H=False,
                             z_offset_bot=None,
                             rotatedeg=0.,
                             scaling_factor=1.,
                             r_TOL=1.,
                             num_closest_points=5,
                             power_parameter=2,
                             num_sec_z=50,
                             use_theta_z_format=True,
                             ignore_bot_h=None,
                             ignore_top_h=None,
                             sample_size=None,
                             T=None):
    r"""Reads an imperfection file and calculates the nodal translations

    Parameters
    ----------
    imperfection_file_name : str
        Full path to the imperfection file.
    model_name : str
        Model name.
    part_name : str
        Part name.
    H_model : float
        Total height of the model where the imperfections will be applied to,
        considering also eventual resin rings.
    H_measured : float
        The total height of the measured test specimen, including eventual
        resin rings at the edges.
    R_model : float
        Radius **at the bottom edge** of the model where the imperfections
        will be applied to.
    R_best_fit : float, optional
        Best fit radius obtained with functions :func:`.best_fit_cylinder`
        or :func:`.best_fit_cone`.
    semi_angle : float, optional
        Cone semi-vertex angle in degrees, when applicable.
    stretch_H : bool, optional
        If the measured imperfection data should be stretched to the current
        model (which may happen when ``H_model!=H_measured``.
    z_offset_bot : float, optional
        It is common to have the measured data not covering the whole test
        specimen, and therefore it will be centralized, if a non-centralized
        position is desired this parameter can be used for the adjustment.
    rotatedeg : float, optional
        Rotation angle in degrees telling how much the imperfection pattern
        should be rotated about the `X_3` (or `Z`) axis.
    scaling_factor : float, optional
        A scaling factor that can be used to study the imperfection
        sensitivity.
    r_TOL : float, optional
        Percentage tolerance to ignore noisy data from the measurements.
    num_closest_points : int, optional
        See :func:`the inverse-weighted interpolation algorithm
        <.inv_weighted>`.
    power_parameter : float, optional
        See :func:`the inverse-weighted interpolation algorithm
        <.inv_weighted>`.
    num_sec_z : int, optional
        Number of spatial sections used to classify the measured data in order
        to accelerate the searching algorithms
    use_theta_z_format : bool, optional
        If the new format `\theta, Z, imp` should be used instead of the old
        `X, Y, Z`.
    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.
    sample_size : int, optional
        If the input file containing the measured data is too large it may be
        required to limit the sample size in order to avoid memory errors.
    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>`.

    """
    import abaqus

    import desicos.abaqus.abaqus_functions as abaqus_functions

    mod = abaqus.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], dtype=FLOAT)

    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:
            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:
            mask = coords[:, 2] < (H_model - ignore_top_h)
            coords = coords[mask]
            part_nodes = part_nodes[mask]

    if use_theta_z_format:
        d, d, data = read_theta_z_imp(path=imperfection_file_name,
                                      H_measured=H_measured,
                                      stretch_H=stretch_H,
                                      z_offset_bot=z_offset_bot)
        if sample_size:
            num = data.shape[0]
            if sample_size < num:
                log('Using sample_size={0}'.format(sample_size), level=1)
                data = data[sample(range(num), int(sample_size)), :]

        if r_TOL:
            max_imp = R_model * r_TOL / 100.
            imp = data[:, 2]
            cond = np.any(np.array((imp > max_imp, imp < (-max_imp))), axis=0)
            log('Skipping {0} points'.format(len(imp[cond])))
            data = data[np.logical_not(cond), :]

        data3D = np.zeros((data.shape[0], 4), dtype=FLOAT)
        if rotatedeg:
            data[:, 0] += deg2rad(rotatedeg)
        z = data[:, 1]
        z *= H_model

        alpharad = deg2rad(semi_angle)
        tana = tan(alpharad)
        def r_local(z):
            return R_model - z*tana
        data3D[:, 0] = r_local(z)*cos(data[:, 0])
        data3D[:, 1] = r_local(z)*sin(data[:, 0])
        data3D[:, 2] = z
        data3D[:, 3] = data[:, 2]

        w0 = inv_weighted(data3D, coords,
                          num_sub = num_sec_z,
                          col = 2,
                          ncp = num_closest_points,
                          power_parameter = power_parameter)

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

        trans = np.zeros_like(coords)
        trans[:, 0] = w0*cos(alpharad)*cos(thetas)
        trans[:, 1] = w0*cos(alpharad)*sin(thetas)
        trans[:, 2] = w0*sin(alpharad)

    else:
        #NOTE perhaps remove this in the future, when the imperfection files
        #     are stored as theta, z, amplitude only
        nodes = np.array([[n.coordinates[0],
                           n.coordinates[1],
                           n.coordinates[2],
                           n.label] for n in part_nodes], dtype=FLOAT)

        # calling translate_nodes function
        trans = calc_nodal_translations(
                                imperfection_file_name,
                                nodes = nodes,
                                H_model = H_model,
                                H_measured = H_measured,
                                R_model = R_model,
                                R_best_fit = R_best_fit,
                                semi_angle = semi_angle,
                                stretch_H = stretch_H,
                                z_offset_bot = z_offset_bot,
                                rotatedeg = rotatedeg,
                                r_TOL = r_TOL,
                                num_closest_points = num_closest_points,
                                power_parameter = power_parameter,
                                num_sec_z = num_sec_z,
                                sample_size = sample_size)
        trans = trans[:, :3]

    return trans
예제 #14
0
def translate_nodes_ABAQUS(imperfection_file_name,
                           model_name,
                           part_name,
                           H_model,
                           H_measured,
                           R_model,
                           R_best_fit=None,
                           semi_angle=0.,
                           stretch_H=False,
                           z_offset_bot=None,
                           rotatedeg=0.,
                           scaling_factor=1.,
                           r_TOL=1.,
                           num_closest_points=5,
                           power_parameter=2,
                           num_sec_z=50,
                           nodal_translations=None,
                           use_theta_z_format=False,
                           ignore_bot_h=None,
                           ignore_top_h=None,
                           sample_size=None,
                           T=None):
    r"""Translates the nodes in Abaqus based on imperfection data

    The imperfection amplitude for each node is calculated using an inversed
    weight function (see :func:`desicos.conecylDB.interpolate.inv_weighted`).

    Parameters
    ----------
    imperfection_file_name : str
        The full path to the imperfection file, which must be a file with
        three columns containing the ``x, y, z`` coordinates when
        ``use_theta_z_format=False`` or containing ``x, theta, amplitude``
        when ``use_theta_z_format=True``.
    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.
    H_measured : float
        The total height of the measured test specimen, including eventual
        resin rings at the edges.
    R_model : float
        The radius of the current model. In case of cones this should be the
        bottom radius.
    R_best_fit : float, optional
        Best fit radius obtained with functions :func:`.best_fit_cylinder`
        or :func:`.best_fit_cone`.
    semi_angle : float, optional
        The cone semi-vertex angle (a null value indicates that a cylinder is
        beeing analyzed).
    stretch_H : float, optional
        A boolean indicating if the imperfection pattern should be stretched
        when applied to the model. The measurement systems usually cannot
        obtain data for the whole surface, making it an option to stretch the
        data to fit the whole surface. In case ``stretch_H=False`` the
        measured data of the extremities will be extruded up to the end of the
        domain.
    z_offset_bot : float, optional
        This parameter allows the analyst to adjust the height of the measured
        data about the model, when the measured data is not available for the
        whole domain.
    rotatedeg : float, optional
        Rotation angle in degrees telling how much the imperfection pattern
        should be rotated about the `X_3` (or `Z`) axis.
    scaling_factor : float, optional
        The scaling factor that will multiply the calculated imperfection
        amplitude.
    r_TOL : float, optional
        Parameter to ignore noisy data in the imperfection file, the points
        with a radius higher than `r=r_{model} \times (1 + r_{TOL})` will not
        be considered in the interpolation.
    num_closest_points : int, optional
        See :func:`the inverse-weighted interpolation algorithm
        <.inv_weighted>`.
    power_parameter : int, optional
        See :func:`the inverse-weighted interpolation algorithm
        <.inv_weighted>`.
    num_sec_z : int, optional
        Number of cross sections that will be used to classify the points
        spatially in the inverse-weighted algorithm.
    nodal_translations : None or numpy.ndarray, optional
        An array containing the interpolated traslations, which is passed to
        avoid repeated calls to the interpolation functions.
    use_theta_z_format : bool, optional
        A boolean to indicate whether the imperfection file contains ``x, y,
        z`` positions or ``theta, z, amplitude``.
    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.
    sample_size : int, optional
        If the input file containing the measured data is too large it may be
        required to limit the sample size in order to avoid memory errors.
    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 already be translated.

    """
    from abaqus import mdb, session

    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 use_theta_z_format:
        if nodal_translations is None:
            trans = calc_translations_ABAQUS(
                        imperfection_file_name = imperfection_file_name,
                        model_name = model_name,
                        part_name = part_name,
                        H_model = H_model,
                        H_measured = H_measured,
                        R_model = R_model,
                        R_best_fit = R_best_fit,
                        semi_angle = semi_angle,
                        stretch_H = stretch_H,
                        z_offset_bot = z_offset_bot,
                        rotatedeg = rotatedeg,
                        scaling_factor = scaling_factor,
                        r_TOL = r_TOL,
                        num_closest_points = num_closest_points,
                        power_parameter = power_parameter,
                        num_sec_z = num_sec_z,
                        use_theta_z_format = use_theta_z_format,
                        ignore_bot_h = ignore_bot_h,
                        ignore_top_h = ignore_top_h,
                        sample_size = sample_size,
                        T = T)

        else:
            trans = nodal_translations

        # 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 + trans*scaling_factor

        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=part_nodes.tolist(), coordinates=new_coords)

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

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

        return trans

    else:
        nodes = np.array([[n.coordinates[0],
                           n.coordinates[1],
                           n.coordinates[2],
                           n.label] for n in part_nodes], dtype=FLOAT)

        # calling translate_nodes function
        if nodal_translations is None:
            nodal_translations = calc_translations_ABAQUS(
                         imperfection_file_name = imperfection_file_name,
                         model_name = model_name,
                         part_name = part_name,
                         H_model = H_model,
                         H_measured = H_measured,
                         R_model = R_model,
                         R_best_fit = R_best_fit,
                         semi_angle = semi_angle,
                         stretch_H = stretch_H,
                         z_offset_bot = z_offset_bot,
                         rotatedeg = rotatedeg,
                         scaling_factor = scaling_factor,
                         r_TOL = r_TOL,
                         num_closest_points = num_closest_points,
                         power_parameter = power_parameter,
                         num_sec_z = num_sec_z,
                         use_theta_z_format = use_theta_z_format,
                         ignore_bot_h = ignore_bot_h,
                         ignore_top_h = ignore_top_h,
                         sample_size = sample_size,
                         T = T)

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

        trans = nodal_translations

        new_coords = coords + trans*scaling_factor

        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!')
        # regenerating ra
        ra = mod.rootAssembly
        viewport.setValues(displayedObject=ra)
        ra.regenerate()

        return nodal_translations
예제 #15
0
    cc.created_model = False
    cc.create_model()
    part_nodes = mdb.models[cc.model_name].parts[cc.part_name_shell].nodes
    coords = np.array([n.coordinates for n in part_nodes])

    sf = 100

    path = r'C:\clones\desicos\desicos\conecylDB\files\dlr\degenhardt_2010_z20\degenhardt_2010_z20_msi_theta_z_imp.txt'
    H_measured = 510.
    H_model = 510.
    d, d, data = read_theta_z_imp(path=path,
                                  H_measured=H_measured,
                                  stretch_H=False,
                                  z_offset_bot=None)

    log('init sample')
    data = np.array(sample(data, 10000))
    log('end sample')
    data = data[np.argsort(data[:, 0])]
    data = np.vstack((data[-3000:], data[:], data[:3000]))
    data[:, 0] /= data[:, 0].max()


    mesh = np.zeros((coords.shape[0], 2), dtype=FLOAT)
    mesh[:, 0] = arctan2(coords[:, 1], coords[:, 0])
    mesh[:, 1] = coords[:, 2]
    mesh_norm = mesh.copy()
    mesh_norm[:, 0] /= mesh_norm[:, 0].max()
    mesh_norm[:, 1] /= mesh_norm[:, 1].max()

    import desicos.conecylDB.interpolate
예제 #16
0
def translate_nodes_ABAQUS(imperfection_file_name,
                           model_name,
                           part_name,
                           H_model,
                           H_measured,
                           R_model,
                           R_best_fit=None,
                           semi_angle=0.,
                           stretch_H=False,
                           z_offset_bot=None,
                           rotatedeg=0.,
                           scaling_factor=1.,
                           r_TOL=1.,
                           num_closest_points=5,
                           power_parameter=2,
                           nodal_translations=None,
                           use_theta_z_format=False,
                           ignore_bot_h=None,
                           ignore_top_h=None,
                           sample_size=None,
                           T=None):
    r"""Translates the nodes in Abaqus based on imperfection data

    The imperfection amplitude for each node is calculated using an inversed
    weight function (see :func:`desicos.conecylDB.interpolate.inv_weighted`).

    Parameters
    ----------
    imperfection_file_name : str
        The full path to the imperfection file, which must be a file with
        three columns containing the ``x, y, z`` coordinates when
        ``use_theta_z_format=False`` or containing ``x, theta, amplitude``
        when ``use_theta_z_format=True``.
    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.
    H_measured : float
        The total height of the measured test specimen, including eventual
        resin rings at the edges.
    R_model : float
        The radius of the current model. In case of cones this should be the
        bottom radius.
    R_best_fit : float, optional
        Best fit radius obtained with functions :func:`.best_fit_cylinder`
        or :func:`.best_fit_cone`.
    semi_angle : float, optional
        The cone semi-vertex angle (a null value indicates that a cylinder is
        beeing analyzed).
    stretch_H : float, optional
        A boolean indicating if the imperfection pattern should be stretched
        when applied to the model. The measurement systems usually cannot
        obtain data for the whole surface, making it an option to stretch the
        data to fit the whole surface. In case ``stretch_H=False`` the
        measured data of the extremities will be extruded up to the end of the
        domain.
    z_offset_bot : float, optional
        This parameter allows the analyst to adjust the height of the measured
        data about the model, when the measured data is not available for the
        whole domain.
    rotatedeg : float, optional
        Rotation angle in degrees telling how much the imperfection pattern
        should be rotated about the `X_3` (or `Z`) axis.
    scaling_factor : float, optional
        The scaling factor that will multiply the calculated imperfection
        amplitude.
    r_TOL : float, optional
        Parameter to ignore noisy data in the imperfection file, the points
        with a radius higher than `r=r_{model} \times (1 + r_{TOL})` will not
        be considered in the interpolation.
    num_closest_points : int, optional
        See :func:`the inverse-weighted interpolation algorithm
        <.inv_weighted>`.
    power_parameter : int, optional
        See :func:`the inverse-weighted interpolation algorithm
        <.inv_weighted>`.
    nodal_translations : None or numpy.ndarray, optional
        An array containing the interpolated traslations, which is passed to
        avoid repeated calls to the interpolation functions.
    use_theta_z_format : bool, optional
        A boolean to indicate whether the imperfection file contains ``x, y,
        z`` positions or ``theta, z, amplitude``.
    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.
    sample_size : int, optional
        If the input file containing the measured data is too large it may be
        required to limit the sample size in order to avoid memory errors.
    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 already be translated.

    """
    from abaqus import mdb, session

    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 use_theta_z_format:
        if nodal_translations is None:
            trans = calc_translations_ABAQUS(
                imperfection_file_name=imperfection_file_name,
                model_name=model_name,
                part_name=part_name,
                H_model=H_model,
                H_measured=H_measured,
                R_model=R_model,
                R_best_fit=R_best_fit,
                semi_angle=semi_angle,
                stretch_H=stretch_H,
                z_offset_bot=z_offset_bot,
                rotatedeg=rotatedeg,
                scaling_factor=scaling_factor,
                r_TOL=r_TOL,
                num_closest_points=num_closest_points,
                power_parameter=power_parameter,
                use_theta_z_format=use_theta_z_format,
                ignore_bot_h=ignore_bot_h,
                ignore_top_h=ignore_top_h,
                sample_size=sample_size,
                T=T)

        else:
            trans = nodal_translations

        # 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 + trans * scaling_factor

        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=part_nodes.tolist(), coordinates=new_coords)

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

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

        return trans

    else:
        nodes = np.array(
            [[n.coordinates[0], n.coordinates[1], n.coordinates[2], n.label]
             for n in part_nodes],
            dtype=FLOAT)

        # calling translate_nodes function
        if nodal_translations is None:
            nodal_translations = calc_translations_ABAQUS(
                imperfection_file_name=imperfection_file_name,
                model_name=model_name,
                part_name=part_name,
                H_model=H_model,
                H_measured=H_measured,
                R_model=R_model,
                R_best_fit=R_best_fit,
                semi_angle=semi_angle,
                stretch_H=stretch_H,
                z_offset_bot=z_offset_bot,
                rotatedeg=rotatedeg,
                scaling_factor=scaling_factor,
                r_TOL=r_TOL,
                num_closest_points=num_closest_points,
                power_parameter=power_parameter,
                use_theta_z_format=use_theta_z_format,
                ignore_bot_h=ignore_bot_h,
                ignore_top_h=ignore_top_h,
                sample_size=sample_size,
                T=T)

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

        trans = nodal_translations

        new_coords = coords + trans * scaling_factor

        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!')
        # regenerating ra
        ra = mod.rootAssembly
        viewport.setValues(displayedObject=ra)
        ra.regenerate()

        return nodal_translations
예제 #17
0
def calc_translations_ABAQUS(imperfection_file_name,
                             model_name,
                             part_name,
                             H_model,
                             H_measured,
                             R_model,
                             R_best_fit=None,
                             semi_angle=0.,
                             stretch_H=False,
                             z_offset_bot=None,
                             rotatedeg=0.,
                             scaling_factor=1.,
                             r_TOL=1.,
                             num_closest_points=5,
                             power_parameter=2,
                             use_theta_z_format=True,
                             ignore_bot_h=None,
                             ignore_top_h=None,
                             sample_size=None,
                             T=None):
    r"""Reads an imperfection file and calculates the nodal translations

    Parameters
    ----------
    imperfection_file_name : str
        Full path to the imperfection file.
    model_name : str
        Model name.
    part_name : str
        Part name.
    H_model : float
        Total height of the model where the imperfections will be applied to,
        considering also eventual resin rings.
    H_measured : float
        The total height of the measured test specimen, including eventual
        resin rings at the edges.
    R_model : float
        Radius **at the bottom edge** of the model where the imperfections
        will be applied to.
    R_best_fit : float, optional
        Best fit radius obtained with functions :func:`.best_fit_cylinder`
        or :func:`.best_fit_cone`.
    semi_angle : float, optional
        Cone semi-vertex angle in degrees, when applicable.
    stretch_H : bool, optional
        If the measured imperfection data should be stretched to the current
        model (which may happen when ``H_model!=H_measured``.
    z_offset_bot : float, optional
        It is common to have the measured data not covering the whole test
        specimen, and therefore it will be centralized, if a non-centralized
        position is desired this parameter can be used for the adjustment.
    rotatedeg : float, optional
        Rotation angle in degrees telling how much the imperfection pattern
        should be rotated about the `X_3` (or `Z`) axis.
    scaling_factor : float, optional
        A scaling factor that can be used to study the imperfection
        sensitivity.
    r_TOL : float, optional
        Percentage tolerance to ignore noisy data from the measurements.
    num_closest_points : int, optional
        See :func:`the inverse-weighted interpolation algorithm
        <.inv_weighted>`.
    power_parameter : float, optional
        See :func:`the inverse-weighted interpolation algorithm
        <.inv_weighted>`.
    use_theta_z_format : bool, optional
        If the new format `\theta, Z, imp` should be used instead of the old
        `X, Y, Z`.
    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.
    sample_size : int, optional
        If the input file containing the measured data is too large it may be
        required to limit the sample size in order to avoid memory errors.
    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>`.

    """
    import abaqus

    import desicos.abaqus.abaqus_functions as abaqus_functions

    mod = abaqus.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], dtype=FLOAT)

    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:
            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:
            mask = coords[:, 2] < (H_model - ignore_top_h)
            coords = coords[mask]
            part_nodes = part_nodes[mask]

    if use_theta_z_format:
        d, d, data = read_theta_z_imp(path=imperfection_file_name,
                                      H_measured=H_measured,
                                      stretch_H=stretch_H,
                                      z_offset_bot=z_offset_bot)
        if sample_size:
            num = data.shape[0]
            if sample_size < num:
                log('Using sample_size={0}'.format(sample_size), level=1)
                data = data[sample(range(num), int(sample_size)), :]

        if r_TOL:
            max_imp = R_model * r_TOL / 100.
            imp = data[:, 2]
            cond = np.any(np.array((imp > max_imp, imp < (-max_imp))), axis=0)
            log('Skipping {0} points'.format(len(imp[cond])))
            data = data[np.logical_not(cond), :]

        data3D = np.zeros((data.shape[0], 4), dtype=FLOAT)
        if rotatedeg:
            data[:, 0] += deg2rad(rotatedeg)
        z = data[:, 1]
        z *= H_model

        alpharad = deg2rad(semi_angle)
        tana = tan(alpharad)

        def r_local(z):
            return R_model - z * tana

        data3D[:, 0] = r_local(z) * cos(data[:, 0])
        data3D[:, 1] = r_local(z) * sin(data[:, 0])
        data3D[:, 2] = z
        data3D[:, 3] = data[:, 2]

        dist, w0 = inv_weighted(data3D,
                                coords,
                                ncp=num_closest_points,
                                power_parameter=power_parameter)

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

        trans = np.zeros_like(coords)
        trans[:, 0] = w0 * cos(alpharad) * cos(thetas)
        trans[:, 1] = w0 * cos(alpharad) * sin(thetas)
        trans[:, 2] = w0 * sin(alpharad)

    else:
        #NOTE perhaps remove this in the future, when the imperfection files
        #     are stored as theta, z, amplitude only
        nodes = np.array(
            [[n.coordinates[0], n.coordinates[1], n.coordinates[2], n.label]
             for n in part_nodes],
            dtype=FLOAT)

        # calling translate_nodes function
        trans = calc_nodal_translations(imperfection_file_name,
                                        nodes=nodes,
                                        H_model=H_model,
                                        H_measured=H_measured,
                                        R_model=R_model,
                                        R_best_fit=R_best_fit,
                                        semi_angle=semi_angle,
                                        stretch_H=stretch_H,
                                        z_offset_bot=z_offset_bot,
                                        rotatedeg=rotatedeg,
                                        r_TOL=r_TOL,
                                        num_closest_points=num_closest_points,
                                        power_parameter=power_parameter,
                                        sample_size=sample_size)
        trans = trans[:, :3]

    return trans
예제 #18
0
def plot_field_data(self, x, y, field, create_npz_only, ax, figsize, save_png,
                    aspect, clean, outpath, pngname, npzname, pyname,
                    num_levels, show_colorbar, lines):
    npzname = npzname.split('.npz')[0] + '.npz'
    pyname = pyname.split('.py')[0] + '.py'
    pngname = pngname.split('.png')[0] + '.png'

    npzname = os.path.join(outpath, npzname)
    pyname = os.path.join(outpath, pyname)
    pngname = os.path.join(outpath, pngname)

    if lines:  # not empty or None
        # Concatenate all lines into a single matrix, separated by 'sep'
        sep = np.array([[float('NaN')], [float('NaN')]])
        all_lines = (2 * len(lines) - 1) * [sep]
        all_lines[::2] = [np.array(l, copy=False) for l in lines]
        line = np.hstack(all_lines)
    else:
        line = np.empty((2, 0))

    if not create_npz_only:
        try:
            import matplotlib.pyplot as plt
            import matplotlib
        except:
            create_npz_only = True

    if not create_npz_only:
        levels = np.linspace(field.min(), field.max(), num_levels)
        if ax is None:
            fig = plt.figure(figsize=figsize)
            ax = fig.add_subplot(111)
        else:
            if isinstance(ax, matplotlib.axes.Axes):
                ax = ax
                fig = ax.figure
                save_png = False
            else:
                raise ValueError('"ax" must be an Axes object')
        contours = ax.contourf(x, y, field, levels=levels)
        if show_colorbar:
            plt.colorbar(contours,
                         ax=ax,
                         shrink=0.5,
                         format='%.4g',
                         use_gridspec=True)
        ax.plot(line[0, :], line[1, :], 'k-', linewidth=0.5)
        ax.grid(False)
        ax.set_aspect(aspect)
        #ax.set_title(
        #r'$PL=20 N$, $F_{{C}}=50 kN$, $w_{{PL}}=\beta$, $mm$')
        if clean:
            ax.xaxis.set_ticks_position('none')
            ax.yaxis.set_ticks_position('none')
            ax.xaxis.set_ticklabels([])
            ax.yaxis.set_ticklabels([])
            ax.set_frame_on(False)
        else:
            ax.xaxis.set_ticks_position('bottom')
            ax.yaxis.set_ticks_position('left')
            ax.xaxis.set_ticks([-self.rbot * np.pi, 0, self.rbot * np.pi])
            ax.xaxis.set_ticklabels([r'$-\pi$', '$0$', r'$+\pi$'])
        if save_png:
            log('')
            log('Plot saved at: {0}'.format(pngname))
            plt.tight_layout()
            plt.savefig(pngname,
                        transparent=True,
                        bbox_inches='tight',
                        pad_inches=0.05,
                        dpi=400)

    else:
        log('Matplotlib cannot be imported from Abaqus')
    np.savez(npzname, x=x, y=y, field=field, line=line)
    with open(pyname, 'w') as f:
        f.write("import os\n")
        f.write("\n")
        f.write("import numpy as np\n")
        f.write("import matplotlib\n")
        f.write("matplotlib.use('TkAgg')\n")
        f.write("from matplotlib import cm\n")
        f.write("import matplotlib.pyplot as plt\n")
        f.write("from mpl_toolkits.axes_grid1 import make_axes_locatable\n")
        f.write("\n")
        f.write("add_title = False\n")
        f.write("tmp = np.load(r'{0}')\n".format(basename(npzname)))
        f.write("pngname = r'{0}'\n".format(basename(pngname)))
        f.write("x = tmp['x']\n")
        f.write("y = tmp['y']\n")
        f.write("field = tmp['field']\n")
        f.write("line = tmp['line']\n")
        f.write("clean = {0}\n".format(clean))
        f.write("show_colorbar = {0}\n".format(show_colorbar))
        f.write("plt.figure(figsize={0})\n".format(figsize))
        f.write("ax = plt.gca()\n")
        f.write("levels = np.linspace(field.min(), field.max(), {0})\n".format(
            num_levels))
        f.write(
            "contours = ax.contourf(x, y, field, levels=levels, cmap=cm.jet)\n"
        )
        f.write("if show_colorbar:\n")
        f.write("    divider = make_axes_locatable(ax)\n")
        f.write(
            "    cax = divider.append_axes('right', size='5%', pad=0.05)\n")
        f.write(
            "    cbar = plt.colorbar(contours, cax=cax, format='%.2f', use_gridspec=True,\n"
        )
        f.write("                        ticks=[field.min(), field.max()])\n")
        f.write("    cbar.outline.remove()\n")
        f.write(
            "    cbar.ax.tick_params(labelsize=14, pad=0., tick2On=False)\n")
        f.write("ax.plot(line[0,:], line[1,:], 'k-', linewidth=0.5)\n")
        f.write("ax.grid(False)\n")
        f.write("ax.set_aspect('{0}')\n".format(aspect))
        f.write("if add_title:\n")
        f.write(
            "    ax.set_title(r'Abaqus, $PL=20 N$, $F_{{C}}=50 kN$, $w_{{PL}}=\\beta$, $mm$')\n"
        )
        f.write("if clean:\n")
        f.write("    ax.xaxis.set_ticks_position('none')\n")
        f.write("    ax.yaxis.set_ticks_position('none')\n")
        f.write("    ax.xaxis.set_ticklabels([])\n")
        f.write("    ax.yaxis.set_ticklabels([])\n")
        f.write("    ax.set_frame_on(False)\n")
        f.write("else:\n")
        f.write("    ax.xaxis.set_ticks_position('bottom')\n")
        f.write("    ax.yaxis.set_ticks_position('left')\n")
        f.write("    ax.xaxis.set_ticks([{0}, 0, {1}])\n".format(
            -self.rbot * np.pi, self.rbot * np.pi))
        f.write(
            "    ax.xaxis.set_ticklabels([r'$-\\pi$', '$0$', r'$+\\pi$'])\n")
        f.write("plt.savefig(pngname, transparent=True,\n")
        f.write("            bbox_inches='tight', pad_inches=0.05, dpi=400)\n")
        f.write("plt.show()\n")
    log('')
    log('Output exported to "{0}"'.format(npzname))
    log('Please run the file "{0}" to plot the output'.format(pyname))
    log('')
예제 #19
0
def change_thickness_ABAQUS(imperfection_file_name,
                            model_name,
                            part_name,
                            stack,
                            t_model,
                            t_measured,
                            H_model,
                            H_measured,
                            R_model,
                            R_best_fit=None,
                            number_of_sets=None,
                            semi_angle=0.,
                            stretch_H=False,
                            z_offset_bot=None,
                            scaling_factor=1.,
                            num_closest_points=5,
                            power_parameter=2,
                            elems_t=None,
                            t_set=None,
                            use_theta_z_format=False):
    r"""Applies a given thickness imperfection to the finite element model

    Assumes that a percentage variation of the laminate thickness can be
    represented by the same percentage veriation of each ply, i.e., each
    ply thickness is varied in order to reflect a given measured thickness
    imperfection field.

    Parameters
    ----------

    imperfection_file_name : str
        Full path to the imperfection file.
    model_name : str
        Model name.
    part_name : str
        Part name.
    stack : list
        The stacking sequence of the current model with each angle given in
        degrees.
    t_model : float
        The nominal shell thickness of the current model.
    t_measured : float
        The nominal thickness of the measured specimen.
    H_model : float
        Total height of the model where the imperfections will be applied to,
        considering also eventual resin rings.
    H_measured : float
        The total height of the measured test specimen, including eventual
        resin rings at the edges.
    R_model : float
        Radius **at the bottom edge** of the model where the imperfections
        will be applied to.
    R_best_fit : float, optional
        Best fit radius obtained with functions :func:`.best_fit_cylinder`
        or :func:`.best_fit_cone`.
    number_of_sets : int, optional
        Defines in how many levels the thicknesses should be divided. If
        ``None`` it will be based on the input file, and if the threshold
        of ``100`` is exceeded, ``10`` sections are used.
    semi_angle : float, optional
        Cone semi-vertex angle in degrees, when applicable.
    stretch_H : bool, optional
        If the measured imperfection data should be stretched to the current
        model (which may happen when ``H_model!=H_measured``.
    z_offset_bot : float, optional
        It is common to have the measured data not covering the whole test
        specimen, and therefore it will be centralized, if a non-centralized
        position is desired this parameter can be used for the adjustment.
    scaling_factor : float, optional
        A scaling factor that can be used to study the imperfection
        sensitivity.
    num_closest_points : int, optional
        See :func:`the inverse-weighted interpolation algorithm
        <.inv_weighted>`.
    power_parameter : float, optional
        See :func:`the inverse-weighted interpolation algorithm
        <.inv_weighted>`.
    elems_t : np.ndarray, optional
        Interpolated thickness for each element. Can be used to avoid the same
        interpolation to be performed twice.
    t_set : set, optional
        A ``set`` object containing the unique thicknesses that will be used
        to create the new properties.
    use_theta_z_format : bool, optional
        If the new format `\theta, Z, imp` should be used instead of the old
        `X, Y, Z`.

    """
    from abaqus import mdb

    import desicos.abaqus.abaqus_functions as abaqus_functions

    mod = mdb.models[model_name]
    part = mod.parts[part_name]
    part_cyl_csys = part.features['part_cyl_csys']
    part_cyl_csys = part.datums[part_cyl_csys.id]

    if use_theta_z_format:
        if elems_t is None or t_set is None:
            log('Reading coordinates for elements...')
            elements = vec_calc_elem_cg(part.elements)

            log('Coordinates for elements read!')
            d, d, data = read_theta_z_imp(path=imperfection_file_name,
                                          H_measured=H_measured,
                                          stretch_H=stretch_H,
                                          z_offset_bot=z_offset_bot)

            data3D = np.zeros((data.shape[0], 4), dtype=FLOAT)
            z = data[:, 1]
            z *= H_model

            alpharad = deg2rad(semi_angle)
            tana = tan(alpharad)

            def r_local(z):
                return R_model - z * tana

            data3D[:, 0] = r_local(z) * cos(data[:, 0])
            data3D[:, 1] = r_local(z) * sin(data[:, 0])
            data3D[:, 2] = z
            data3D[:, 3] = data[:, 2]

            dist, ans = inv_weighted(data3D,
                                     elements[:, :3],
                                     ncp=num_closest_points,
                                     power_parameter=power_parameter)

            t_set = set(ans)
            t_set.discard(0.)  #TODO why inv_weighted returns an array with 0.
            elems_t = np.zeros((elements.shape[0], 2), dtype=FLOAT)
            elems_t[:, 0] = elements[:, 3]
            elems_t[:, 1] = ans

        else:
            log('Thickness differences already calculated!')

    else:
        if elems_t is None or t_set is None:
            # reading elements data
            log('Reading coordinates for elements...')
            elements = vec_calc_elem_cg(part.elements)
            log('Coordinates for elements read!')
            # calling translate_nodes function
            elems_t, t_set = calc_elems_t(
                imperfection_file_name,
                nodes=elements,
                t_model=t_model,
                t_measured=t_measured,
                H_model=H_model,
                H_measured=H_measured,
                R_model=R_model,
                R_best_fit=R_best_fit,
                semi_angle=semi_angle,
                stretch_H=stretch_H,
                z_offset_bot=z_offset_bot,
                num_closest_points=num_closest_points,
                power_parameter=power_parameter)
        else:
            log('Thickness differences already calculated!')
    # creating sets
    t_list = []
    max_len_t_set = 100
    if len(t_set) >= max_len_t_set and number_of_sets in (None, 0):
        number_of_sets = 10
        log('More than {0:d} different thicknesses measured!'.format(
            max_len_t_set))
        log('Forcing a number_of_sets = {0:d}'.format(number_of_sets))
    if number_of_sets is None or number_of_sets == 0:
        number_of_sets = len(t_set)
        t_list = list(t_set)
        t_list.sort()
    else:
        t_min = min(t_set)
        t_max = max(t_set)
        t_list = list(np.linspace(t_min, t_max, number_of_sets + 1))

    # grouping elements
    sets_ids = [[] for i in range(len(t_list))]
    for entry in elems_t:
        elem_id, t = entry
        index = index_within_linspace(t_list, t)
        sets_ids[index].append(int(elem_id))
    # putting elements in sets
    original_layup = part.compositeLayups['CompositePlate']
    for i, set_ids in enumerate(sets_ids):
        if len(set_ids) == 0:
            # since t_set_norm * t_model <> t_set originally measured
            # there may be empty set_ids at the end
            continue
        elements = part.elements.sequenceFromLabels(labels=set_ids)
        suffix = 'measured_imp_t_{0:03d}'.format(i)
        set_name = 'Set_' + suffix
        log('Creating set ({0: 7d} elements): {1}'.format(
            len(set_ids), set_name))
        part.Set(name=set_name, elements=elements)
        region = part.sets[set_name]
        layup_name = 'CLayup_' + suffix
        t_diff = (float(t_list[i]) - t_model) * scaling_factor
        t_scaling_factor = (t_model + t_diff) / t_model

        def modify_ply(index, kwargs):
            kwargs['thickness'] *= t_scaling_factor
            kwargs['region'] = region
            return kwargs

        layup = part.CompositeLayup(name=layup_name,
                                    objectToCopy=original_layup)
        layup.resume()
        abaqus_functions.modify_composite_layup(part=part,
                                                layup_name=layup_name,
                                                modify_func=modify_ply)
    # suppress needed to put the new properties to the input file
    original_layup.suppress()

    return elems_t, t_set
예제 #20
0
파일: _plot.py 프로젝트: desicos/desicos
def plot_field_data(self, x, y, field, create_npz_only, ax, figsize, save_png,
        aspect, clean, outpath, pngname, npzname, pyname, num_levels,
        show_colorbar, lines):
    npzname = npzname.split('.npz')[0] + '.npz'
    pyname = pyname.split('.py')[0] + '.py'
    pngname = pngname.split('.png')[0] + '.png'

    npzname = os.path.join(outpath, npzname)
    pyname = os.path.join(outpath, pyname)
    pngname = os.path.join(outpath, pngname)

    if lines: # not empty or None
        # Concatenate all lines into a single matrix, separated by 'sep'
        sep = np.array([[float('NaN')], [float('NaN')]])
        all_lines = (2*len(lines) - 1)*[sep]
        all_lines[::2] = [np.array(l, copy=False) for l in lines]
        line = np.hstack(all_lines)
    else:
        line = np.empty((2, 0))

    if not create_npz_only:
        try:
            import matplotlib.pyplot as plt
            import matplotlib
        except:
            create_npz_only = True

    if not create_npz_only:
        levels = np.linspace(field.min(), field.max(), num_levels)
        if ax is None:
            fig = plt.figure(figsize=figsize)
            ax = fig.add_subplot(111)
        else:
            if isinstance(ax, matplotlib.axes.Axes):
                ax = ax
                fig = ax.figure
                save_png = False
            else:
                raise ValueError('"ax" must be an Axes object')
        contours = ax.contourf(x, y, field, levels=levels)
        if show_colorbar:
            plt.colorbar(contours, ax=ax, shrink=0.5, format='%.4g', use_gridspec=True)
        ax.plot(line[0,:], line[1,:], 'k-', linewidth=0.5)
        ax.grid(False)
        ax.set_aspect(aspect)
        #ax.set_title(
            #r'$PL=20 N$, $F_{{C}}=50 kN$, $w_{{PL}}=\beta$, $mm$')
        if clean:
            ax.xaxis.set_ticks_position('none')
            ax.yaxis.set_ticks_position('none')
            ax.xaxis.set_ticklabels([])
            ax.yaxis.set_ticklabels([])
            ax.set_frame_on(False)
        else:
            ax.xaxis.set_ticks_position('bottom')
            ax.yaxis.set_ticks_position('left')
            ax.xaxis.set_ticks([-self.rbot*np.pi, 0, self.rbot*np.pi])
            ax.xaxis.set_ticklabels([r'$-\pi$', '$0$', r'$+\pi$'])
        if save_png:
            log('')
            log('Plot saved at: {0}'.format(pngname))
            plt.tight_layout()
            plt.savefig(pngname, transparent=True,
                        bbox_inches='tight', pad_inches=0.05,
                        dpi=400)

    else:
        log('Matplotlib cannot be imported from Abaqus')
    np.savez(npzname, x=x, y=y, field=field, line=line)
    with open(pyname, 'w') as f:
        f.write("import os\n")
        f.write("\n")
        f.write("import numpy as np\n")
        f.write("import matplotlib.pyplot as plt\n")
        f.write("from mpl_toolkits.axes_grid1 import make_axes_locatable\n")
        f.write("\n")
        f.write("add_title = False\n")
        f.write("tmp = np.load(r'{0}')\n".format(basename(npzname)))
        f.write("pngname = r'{0}'\n".format(basename(pngname)))
        f.write("x = tmp['x']\n")
        f.write("y = tmp['y']\n")
        f.write("field = tmp['field']\n")
        f.write("line = tmp['line']\n")
        f.write("clean = {0}\n".format(clean))
        f.write("show_colorbar = {0}\n".format(show_colorbar))
        f.write("plt.figure(figsize={0})\n".format(figsize))
        f.write("ax = plt.gca()\n")
        f.write("levels = np.linspace(field.min(), field.max(), {0})\n".format(
                num_levels))
        f.write("contours = ax.contourf(x, y, field, levels=levels)\n")
        f.write("if show_colorbar:\n")
        f.write("    divider = make_axes_locatable(ax)\n")
        f.write("    cax = divider.append_axes('right', size='5%', pad=0.05)\n")
        f.write("    cbar = plt.colorbar(contours, cax=cax, format='%.2f', use_gridspec=True,\n")
        f.write("                        ticks=[field.min(), field.max()])\n")
        f.write("    cbar.outline.remove()\n")
        f.write("    cbar.ax.tick_params(labelsize=14, pad=0., tick2On=False)\n")
        f.write("ax.plot(line[0,:], line[1,:], 'k-', linewidth=0.5)\n")
        f.write("ax.grid(False)\n")
        f.write("ax.set_aspect('{0}')\n".format(aspect))
        f.write("if add_title:\n")
        f.write("    ax.set_title(r'Abaqus, $PL=20 N$, $F_{{C}}=50 kN$, $w_{{PL}}=\\beta$, $mm$')\n")
        f.write("if clean:\n")
        f.write("    ax.xaxis.set_ticks_position('none')\n")
        f.write("    ax.yaxis.set_ticks_position('none')\n")
        f.write("    ax.xaxis.set_ticklabels([])\n")
        f.write("    ax.yaxis.set_ticklabels([])\n")
        f.write("    ax.set_frame_on(False)\n")
        f.write("else:\n")
        f.write("    ax.xaxis.set_ticks_position('bottom')\n")
        f.write("    ax.yaxis.set_ticks_position('left')\n")
        f.write("    ax.xaxis.set_ticks([{0}, 0, {1}])\n".format(
                -self.rbot*np.pi, self.rbot*np.pi))
        f.write("    ax.xaxis.set_ticklabels([r'$-\\pi$', '$0$', r'$+\\pi$'])\n")
        f.write("plt.savefig(pngname, transparent=True,\n")
        f.write("            bbox_inches='tight', pad_inches=0.05, dpi=400)\n")
        f.write("plt.show()\n")
    log('')
    log('Output exported to "{0}"'.format(npzname))
    log('Please run the file "{0}" to plot the output'.format(
          pyname))
    log('')