Ejemplo n.º 1
0
def extract_fiber_orientation(self, ply_index, use_elements):
    if use_elements:
        from abaqus import mdb

        if self.model_name in mdb.models.keys():
            part = mdb.models[self.model_name].parts[self.part_name_shell]
        else:
            raise RuntimeError("Cannot obtain element locations, model for '{0}' is not loaded".format(self.model_name))

        elements = part.elements
        coords = utils.vec_calc_elem_cg(elements)
        thetas = np.arctan2(coords[:, 1], coords[:, 0])
        zs = coords[:, 2]
    else:
        thetas = np.linspace(-np.pi, np.pi, self.numel_r + 1)
        thetas = (thetas[:-1] + thetas[1:]) / 2
        mean_circumf = np.pi*(self.rtop + self.rbot)
        # Estimate num elements in vertical direction
        numel_z = int(np.ceil(float(self.L) / mean_circumf * self.numel_r))
        zs = np.linspace(0, self.H, numel_z + 1)
        zs = (zs[:-1] + zs[1:]) / 2
        thetas, zs = np.meshgrid(thetas, zs)
        thetas = thetas.flatten()
        zs = zs.flatten()
        # Determine coords
        rs = self.fr(zs)
        xs = rs*np.cos(thetas)
        ys = rs*np.sin(thetas)
        coords = np.column_stack([xs, ys, zs])
    out = np.array(self.impconf.ppi.fiber_orientation(ply_index, coords))

    return _sort_field_data(thetas, zs, out, self.numel_r)
Ejemplo n.º 2
0
    def _create_orientation_fields(self, mod, elements):
        """Create, for each ply, a discrete field containing the local
        orientation at each element.

        Parameters
        ----------
        mod : Model
            Abaqus model to which the fields should be added
        elements :  MeshElementArray
            Set of elements that should be represented in the discrete field

        Returns
        -------
        fields : list
            List of DiscreteFields, one for each ply.

        .. note:: Must be called from Abaqus.
        """
        from abaqusConstants import SCALAR
        cc = self.impconf.conecyl
        fields = []
        coords = vec_calc_elem_cg(elements)
        el_ids = map(int, coords[:,3])
        for i, angle in enumerate(cc.stack):
            field_name = 'ply_%02d_field' % (i+1)
            values = self.fiber_orientation(i, coords)
            if np.nan in values:
                raise ValueError('Invalid PPI parameters: not all points are covered by ply pieces')
            field = mod.DiscreteField(
                        name=field_name,
                        defaultValues=(angle, ),
                        fieldType=SCALAR,
                        data=[('', 1, el_ids, values)])
            fields.append(field)
        return fields
Ejemplo n.º 3
0
def extract_fiber_orientation(self, ply_index, use_elements):
    if use_elements:
        from abaqus import mdb

        if self.model_name in mdb.models.keys():
            part = mdb.models[self.model_name].parts[self.part_name_shell]
        else:
            raise RuntimeError(
                "Cannot obtain element locations, model for '{0}' is not loaded"
                .format(self.model_name))

        elements = part.elements
        coords = utils.vec_calc_elem_cg(elements)
        thetas = np.arctan2(coords[:, 1], coords[:, 0])
        zs = coords[:, 2]
    else:
        thetas = np.linspace(-np.pi, np.pi, self.numel_r + 1)
        thetas = (thetas[:-1] + thetas[1:]) / 2
        mean_circumf = np.pi * (self.rtop + self.rbot)
        # Estimate num elements in vertical direction
        numel_z = int(np.ceil(float(self.L) / mean_circumf * self.numel_r))
        zs = np.linspace(0, self.H, numel_z + 1)
        zs = (zs[:-1] + zs[1:]) / 2
        thetas, zs = np.meshgrid(thetas, zs)
        thetas = thetas.flatten()
        zs = zs.flatten()
        # Determine coords
        rs = self.fr(zs)
        xs = rs * np.cos(thetas)
        ys = rs * np.sin(thetas)
        coords = np.column_stack([xs, ys, zs])
    out = np.array(self.impconf.ppi.fiber_orientation(ply_index, coords))

    return _sort_field_data(thetas, zs, out, self.numel_r)
Ejemplo n.º 4
0
    def _create_orientation_fields(self, mod, elements):
        """Create, for each ply, a discrete field containing the local
        orientation at each element.

        Parameters
        ----------
        mod : Model
            Abaqus model to which the fields should be added
        elements :  MeshElementArray
            Set of elements that should be represented in the discrete field

        Returns
        -------
        fields : list
            List of DiscreteFields, one for each ply.

        .. note:: Must be called from Abaqus.
        """
        from abaqusConstants import SCALAR
        cc = self.impconf.conecyl
        fields = []
        coords = vec_calc_elem_cg(elements)
        el_ids = map(int, coords[:,3])
        for i, angle in enumerate(cc.stack):
            field_name = 'ply_%02d_field' % (i+1)
            values = self.fiber_orientation(i, coords)
            if np.nan in values:
                raise ValueError('Invalid PPI parameters: not all points are covered by ply pieces')
            field = mod.DiscreteField(
                        name=field_name,
                        defaultValues=(angle, ),
                        fieldType=SCALAR,
                        data=[('', 1, el_ids, values)])
            fields.append(field)
        return fields
Ejemplo n.º 5
0
def _nodal_field_S8_add_centroids(elements, node_labels, node_values):
    # For S8 elements and nodal fields, one may want to add values for the
    # centroids as well, to create a regular grid. This is done by
    # interpolation.
    # Values of interpolation functions at centroid: -0.25 for corner
    # nodes, 0.5 for side nodes
    INTERP = np.array([-0.25, -0.25, -0.25, -0.25, 0.5, 0.5, 0.5, 0.5])

    el_coords = utils.vec_calc_elem_cg(elements)
    el_out = np.zeros((el_coords.shape[0], ))
    for i, el in enumerate(elements):
        # el.connectivity can't be used, as it uses node indices, not labels
        mask = np.in1d(node_labels, [n.label for n in el.getNodes()])
        el_out[i] = np.dot(INTERP, node_values[mask])
    # return coords, values for element centroids
    return el_coords[:, :3], el_out
Ejemplo n.º 6
0
def _nodal_field_S8_add_centroids(elements, node_labels, node_values):
    # For S8 elements and nodal fields, one may want to add values for the
    # centroids as well, to create a regular grid. This is done by
    # interpolation.
    # Values of interpolation functions at centroid: -0.25 for corner
    # nodes, 0.5 for side nodes
    INTERP = np.array([-0.25, -0.25, -0.25, -0.25, 0.5, 0.5, 0.5, 0.5])

    el_coords = utils.vec_calc_elem_cg(elements)
    el_out = np.zeros((el_coords.shape[0], ))
    for i, el in enumerate(elements):
        # el.connectivity can't be used, as it uses node indices, not labels
        mask = np.in1d(node_labels, [n.label for n in el.getNodes()])
        el_out[i] = np.dot(INTERP, node_values[mask])
    # return coords, values for element centroids
    return el_coords[:,:3], el_out
Ejemplo n.º 7
0
def extract_thickness_data(self):
    from abaqus import mdb

    if self.model_name in mdb.models.keys():
        part = mdb.models[self.model_name].parts[self.part_name_shell]
    else:
        raise RuntimeError("Cannot obtain element locations, model for '{0}' is not loaded".format(self.model_name))

    elements = part.elements
    coords = utils.vec_calc_elem_cg(elements)
    thetas = np.arctan2(coords[:, 1], coords[:, 0])
    zs = coords[:, 2]
    labels = coords[:, 3]
    thicks = np.zeros_like(zs)
    for layup in part.compositeLayups.values():
        if not layup.suppressed:
            el_set = part.sets[layup.plies[0].region[0]]
            layup_els = np.array([e. label for e in el_set.elements])
            layup_thickness = sum(p.thickness for p in layup.plies.values())
            thicks[np.in1d(labels, layup_els)] = layup_thickness
    return _sort_field_data(thetas, zs, thicks, self.numel_r)
Ejemplo n.º 8
0
def extract_thickness_data(self):
    from abaqus import mdb

    if self.model_name in mdb.models.keys():
        part = mdb.models[self.model_name].parts[self.part_name_shell]
    else:
        raise RuntimeError(
            "Cannot obtain element locations, model for '{0}' is not loaded".
            format(self.model_name))

    elements = part.elements
    coords = utils.vec_calc_elem_cg(elements)
    thetas = np.arctan2(coords[:, 1], coords[:, 0])
    zs = coords[:, 2]
    labels = coords[:, 3]
    thicks = np.zeros_like(zs)
    for layup in part.compositeLayups.values():
        if not layup.suppressed:
            el_set = part.sets[layup.plies[0].region[0]]
            layup_els = np.array([e.label for e in el_set.elements])
            layup_thickness = sum(p.thickness for p in layup.plies.values())
            thicks[np.in1d(labels, layup_els)] = layup_thickness
    return _sort_field_data(thetas, zs, thicks, self.numel_r)
Ejemplo n.º 9
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
Ejemplo n.º 10
0
def extract_field_output(self, ignore):
    from abaqus import mdb
    from abaqusConstants import NODAL
    import desicos.abaqus.abaqus_functions as abaqus_functions

    if self.model_name in mdb.models.keys():
        part = mdb.models[self.model_name].parts[self.part_name_shell]
    else:
        text = 'The model corresponding to the active odb must be loaded'
        raise RuntimeError(text)

    elements = part.elements
    nodes = part.nodes
    sina = np.sin(self.alpharad)
    cosa = np.cos(self.alpharad)

    odb = abaqus_functions.get_current_odb()
    odbDisplay = abaqus_functions.get_current_odbdisplay()
    frame = abaqus_functions.get_current_frame()
    fieldOutputKey = odbDisplay.primaryVariable[0]
    sub_vector = odbDisplay.primaryVariable[5]

    frame_num = int(frame.frameValue)
    field = frame.fieldOutputs[fieldOutputKey]
    nodal_out = False
    if field.values[0].position == NODAL:
        nodal_out = True

    if nodal_out:
        odbSet = odb.rootAssembly.nodeSets['SHELL_FACES']
        coords = np.array([n.coordinates for n in nodes])
        labels = np.array([n.label for n in nodes])
        if ignore:
            mask = np.in1d(labels, ignore)
            labels = labels[mask]
            coords = coords[mask]
        thetas = np.arctan2(coords[:, 1], coords[:, 0])
    else:
        odbSet = odb.rootAssembly.elementSets['SHELL_FACES']
        coords = utils.vec_calc_elem_cg(elements)
        thetas = np.arctan2(coords[:, 1], coords[:, 0])

    field = field.getSubset(region=odbSet)

    attributes = {
        'Magnitude': 'magnitude',
        'Mises': 'mises',
        'Min. In-Plane Principal': 'minInPlanePrincipal',
        'Max. In-Plane Principal': 'maxInPlanePrincipal',
        'Min. Principal': 'minPrincipal',
        'Mid. Principal': 'midPrincipal',
        'Max. Principal': 'maxPrincipal',
        'Out-of-Plane Principal': 'outOfPlanePrincipal',
        'Tresca': 'tresca',
        'Third Invariant': 'inv3',
    }
    components = {
        'S11': 0,
        'S22': 1,
        'S33': 2,
        'S12': 3,
        'SF1': 0,
        'SF2': 1,
        'SF3': 3,
        'SM2': 0,
        'SM1': 1,
        'SM3': 2,
    }

    if sub_vector == '':
        out = np.array([val.data for val in field.values])

    elif sub_vector in attributes.keys():
        attr = attributes.get(sub_vector)
        out = np.array([getattr(v, attr) for v in field.values])

    elif sub_vector in components.keys():
        pos = components[sub_vector]
        out = np.array([v.data[pos] for v in field.values])

    elif sub_vector in ('U1', 'UT1', 'U2', 'UT2', 'U3', 'UT3'):
        uvw_rec = np.array([val.data for val in field.values])

        u1_rec = uvw_rec[:, 0]
        u2_rec = uvw_rec[:, 1]
        u3_rec = uvw_rec[:, 2]

        u3_cyl = u3_rec
        u2_cyl = u2_rec * np.cos(thetas) - u1_rec * np.sin(thetas)
        u1_cyl = u2_rec * np.sin(thetas) + u1_rec * np.cos(thetas)

        u1_cone = u1_cyl * cosa + u3_cyl * sina
        u2_cone = u2_cyl
        u3_cone = u3_cyl * cosa - u1_cyl * sina

        displ_vecs = {
            'U1': u1_cone,
            'U2': u2_cone,
            'U3': u3_cone,
            'UT1': u1_cone,
            'UT2': u2_cone,
            'UT3': u3_cone
        }
        out = displ_vecs[sub_vector]

    else:
        raise NotImplementedError('{0} cannot be used!'.format(sub_vector))

    if not nodal_out:
        firstElement = None
        numIntPts = 0
        for v in field.values:
            if firstElement is None:
                firstElement = v.elementLabel
            if v.elementLabel == firstElement:
                numIntPts += 1
            else:
                break
        out = out.reshape(-1, numIntPts).mean(axis=1)

    if 'S8' in self.elem_type and nodal_out:
        el_coords, el_out = _nodal_field_S8_add_centroids(
            elements, labels, out)
        el_thetas = np.arctan2(el_coords[:, 1], el_coords[:, 0])
        coords = np.vstack((coords, el_coords))
        thetas = np.hstack((thetas, el_thetas))
        out = np.hstack((out, el_out))
        num_thetas = 2 * self.numel_r
    else:
        num_thetas = self.numel_r

    zs = coords[:, 2]
    return _sort_field_data(thetas, zs, out, num_thetas)
Ejemplo n.º 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
Ejemplo n.º 12
0
def extract_field_output(self, ignore):
    from abaqus import mdb
    from abaqusConstants import NODAL
    import desicos.abaqus.abaqus_functions as abaqus_functions

    if self.model_name in mdb.models.keys():
        part = mdb.models[self.model_name].parts[self.part_name_shell]
    else:
        text = 'The model corresponding to the active odb must be loaded'
        raise RuntimeError(text)

    elements = part.elements
    nodes = part.nodes
    sina = np.sin(self.alpharad)
    cosa = np.cos(self.alpharad)

    odb = abaqus_functions.get_current_odb()
    odbDisplay = abaqus_functions.get_current_odbdisplay()
    frame = abaqus_functions.get_current_frame()
    fieldOutputKey = odbDisplay.primaryVariable[0]
    sub_vector = odbDisplay.primaryVariable[5]

    frame_num = int(frame.frameValue)
    field = frame.fieldOutputs[fieldOutputKey]
    nodal_out = False
    if field.values[0].position == NODAL:
        nodal_out = True

    if nodal_out:
        odbSet = odb.rootAssembly.nodeSets['SHELL_FACES']
        coords = np.array([n.coordinates for n in nodes])
        labels = np.array([n.label for n in nodes])
        if ignore:
            mask = np.in1d(labels, ignore)
            labels = labels[mask]
            coords = coords[mask]
        thetas = np.arctan2(coords[:, 1], coords[:, 0])
    else:
        odbSet = odb.rootAssembly.elementSets['SHELL_FACES']
        coords = utils.vec_calc_elem_cg(elements)
        thetas = np.arctan2(coords[:, 1], coords[:, 0])

    field = field.getSubset(region=odbSet)

    attributes = {
                  'Magnitude': 'magnitude',
                  'Mises': 'mises',
                  'Min. In-Plane Principal': 'minInPlanePrincipal',
                  'Max. In-Plane Principal': 'maxInPlanePrincipal',
                  'Min. Principal': 'minPrincipal',
                  'Mid. Principal': 'midPrincipal',
                  'Max. Principal': 'maxPrincipal',
                  'Out-of-Plane Principal': 'outOfPlanePrincipal',
                  'Tresca': 'tresca',
                  'Third Invariant': 'inv3',
                 }
    components = {
                  'S11': 0,
                  'S22': 1,
                  'S33': 2,
                  'S12': 3,
                  'SF1': 0,
                  'SF2': 1,
                  'SF3': 3,
                  'SM2': 0,
                  'SM1': 1,
                  'SM3': 2,
                 }

    if sub_vector == '':
        out = np.array([val.data for val in field.values])

    elif sub_vector in attributes.keys():
        attr = attributes.get(sub_vector)
        out = np.array([getattr(v, attr) for v in field.values])

    elif sub_vector in components.keys():
        pos = components[sub_vector]
        out = np.array([v.data[pos] for v in field.values])

    elif sub_vector in ('U1', 'UT1', 'U2', 'UT2', 'U3', 'UT3'):
        uvw_rec = np.array([val.data for val in field.values])

        u1_rec = uvw_rec[:,0]
        u2_rec = uvw_rec[:,1]
        u3_rec = uvw_rec[:,2]

        u3_cyl = u3_rec
        u2_cyl = u2_rec*np.cos(thetas) - u1_rec*np.sin(thetas)
        u1_cyl = u2_rec*np.sin(thetas) + u1_rec*np.cos(thetas)

        u1_cone = u1_cyl*cosa + u3_cyl*sina
        u2_cone = u2_cyl
        u3_cone = u3_cyl*cosa - u1_cyl*sina

        displ_vecs = {'U1':u1_cone, 'U2':u2_cone, 'U3':u3_cone,
                      'UT1':u1_cone, 'UT2':u2_cone, 'UT3':u3_cone}
        out = displ_vecs[sub_vector]

    else:
        raise NotImplementedError('{0} cannot be used!'.format(
            sub_vector))

    if not nodal_out:
        firstElement = None
        numIntPts = 0
        for v in field.values:
            if firstElement is None:
                firstElement = v.elementLabel
            if v.elementLabel == firstElement:
                numIntPts += 1
            else:
                break
        out = out.reshape(-1, numIntPts).mean(axis=1)

    if 'S8' in self.elem_type and nodal_out:
        el_coords, el_out = _nodal_field_S8_add_centroids(elements, labels, out)
        el_thetas = np.arctan2(el_coords[:, 1], el_coords[:, 0])
        coords = np.vstack((coords, el_coords))
        thetas = np.hstack((thetas, el_thetas))
        out = np.hstack((out, el_out))
        num_thetas = 2*self.numel_r
    else:
        num_thetas = self.numel_r

    zs = coords[:, 2]
    return _sort_field_data(thetas, zs, out, num_thetas)
Ejemplo n.º 13
0
import numpy as np
from numpy.linalg import lstsq
from numpy import sin, cos
from regionToolset import Region

from desicos.abaqus.utils import vec_calc_elem_cg

elem_cgs = vec_calc_elem_cg( cc.part.elements )
ce = elem_cgs[ np.all( (elem_cgs[:,2] > 0.95*cc.h/2,
                                      elem_cgs[:,2] <   1.*cc.h/2),axis=0 ) ]
ce = ce[ np.argsort(ce[:,3]) ]
elem_ids = np.int_(ce[:,3])
odb = cc.attach_results()
inst = odb.rootAssembly.instances['INSTANCECYLINDER']
odb_mesh_elem_array = inst.ElementSetFromElementLabels(
                                 name='ce',
                                 elementLabels=elem_ids  )
frames = odb.steps[cc.step2Name].frames
#def get_outputs(frame, key='SF'):
def calc_sfs(frame):
    key = 'SF'
    fieldOutput = frame.fieldOutputs[key]
    output = fieldOutput.getSubset(region=odb_mesh_elem_array)
    sfs =np.array([[v.data[0], v.data[1], v.data[2], v.elementLabel] \
                      for v in output.values], dtype='float32')
    sfs = np.average(np.array([sfs[i:i+4] for i in range(0,len(elem_ids)*4,4)]),
                     axis=1)
    return sfs

vec_calc_sfs = np.vectorize(calc_sfs, otypes=[object])