Ejemplo n.º 1
0
    def create_prop_around_cutout(self):
        if self.prop_around_cutout is not None:
            from abaqus import mdb
            from abaqusConstants import CYLINDRICAL

            cc = self.impconf.conecyl
            mod = mdb.models[cc.model_name]
            p = mod.parts[cc.part_name_shell]

            if not isinstance(self.prop_around_cutout, dict):
                raise ValueError('prop_around_cutout must be a dictionary')
            mode = self.prop_around_cutout['mode']
            stack = self.prop_around_cutout['stack']
            plyts = self.prop_around_cutout['plyts']
            mat_names = self.prop_around_cutout['mat_names']

            if mode == 'radius':
                radius = self.prop_around_cutout['radius']
                elem_set = p.Set(name='elems_around_cutout_%02d' % self.index,
                                 elements=p.elements.getByBoundingCylinder(
                                     center1=self.p0coord,
                                     center2=self.p2coord,
                                     radius=radius))
            elif mode == 'partition':
                selection_radius = (
                    1 + self.clearance_factor) * self.d * 1.05 * 2**0.5
                elem_set = p.Set(name='elems_around_cutout_%02d' % self.index,
                                 faces=p.faces.getByBoundingCylinder(
                                     center1=self.p0coord,
                                     center2=self.p2coord,
                                     radius=selection_radius))
            else:
                raise ValueError('%s is an invalid options for "mode"' % mode)

            #TODO could get the Csys that already exists...
            part_csys = p.DatumCsysByThreePoints(name='part_cyl_csys',
                                                 coordSysType=CYLINDRICAL,
                                                 origin=(0.0, 0.0, 0.0),
                                                 point1=(1.0, 0.0, 0.0),
                                                 point2=(0.0, 1.0, 0.0))

            #FIXME create a circular boundary region around the cutout to
            #      guarantee a better mesh for these cases with a new property
            #      around the cutout
            part_csys = p.datums[part_csys.id]

            abaqus_functions.create_composite_layup(
                name='prop_around_cutout_%02d' % self.index,
                stack=stack,
                plyts=plyts,
                mat_names=mat_names,
                part=p,
                part_csys=part_csys,
                region=elem_set)
        else:
            raise RuntimeError('prop_around_cutout not defined!')
Ejemplo n.º 2
0
    def create_prop_around_cutout(self):
        if self.prop_around_cutout is not None:
            from abaqus import mdb
            from abaqusConstants import CYLINDRICAL

            cc = self.impconf.conecyl
            mod = mdb.models[cc.model_name]
            p = mod.parts[cc.part_name_shell]

            if not isinstance(self.prop_around_cutout, dict):
                raise ValueError('prop_around_cutout must be a dictionary')
            mode = self.prop_around_cutout['mode']
            stack = self.prop_around_cutout['stack']
            plyts = self.prop_around_cutout['plyts']
            mat_names = self.prop_around_cutout['mat_names']

            if mode == 'radius':
                radius = self.prop_around_cutout['radius']
                elem_set = p.Set(name='elems_around_cutout_%02d' % self.index,
                                 elements=p.elements.getByBoundingCylinder(
                                 center1=self.p0coord, center2=self.p2coord,
                                 radius=radius))
            elif mode == 'partition':
                selection_radius = (1+self.clearance_factor)*self.d*1.05*2**0.5
                elem_set = p.Set(name='elems_around_cutout_%02d' % self.index,
                                 faces=p.faces.getByBoundingCylinder(
                                 center1=self.p0coord, center2=self.p2coord,
                                 radius=selection_radius))
            else:
                raise ValueError('%s is an invalid options for "mode"' % mode)

            #TODO could get the Csys that already exists...
            part_csys = p.DatumCsysByThreePoints(name='part_cyl_csys',
                                                 coordSysType=CYLINDRICAL,
                                                 origin=(0.0, 0.0, 0.0),
                                                 point1=(1.0, 0.0, 0.0),
                                                 point2=(0.0, 1.0, 0.0))

            #FIXME create a circular boundary region around the cutout to
            #      guarantee a better mesh for these cases with a new property
            #      around the cutout
            part_csys = p.datums[part_csys.id]

            abaqus_functions.create_composite_layup(
                    name='prop_around_cutout_%02d' % self.index,
                    stack=stack, plyts=plyts, mat_names=mat_names,
                    part=p, part_csys=part_csys,
                    region=elem_set)
        else:
            raise RuntimeError('prop_around_cutout not defined!')
Ejemplo n.º 3
0
    def create_prop_around_hole(self):
        if self.prop_around_hole is not None:
            if not isinstance(self.prop_around_hole, dict):
                raise ValueError("prop_around_hole must be a dictionary")
            radius = self.prop_around_hole["radius"]
            stack = self.prop_around_hole["stack"]
            plyts = self.prop_around_hole["plyts"]
            mat_names = self.prop_around_hole["mat_names"]

            p = self.part
            print self.p0coord
            print self.p2coord
            print radius
            elem_set = p.Set(
                name="elems_around_cutout_%02d" % self.index,
                elements=p.elements.getByBoundingCylinder(center1=self.p0coord, center2=self.p2coord, radius=radius),
            )

            # TODO could get the Csys that already exists...
            part_csys = p.DatumCsysByThreePoints(
                name="part_cyl_csys",
                coordSysType=CYLINDRICAL,
                origin=(0.0, 0.0, 0.0),
                point1=(1.0, 0.0, 0.0),
                point2=(0.0, 1.0, 0.0),
            )
            part_csys = p.datums[part_csys.id]
            # FIXME create a circular boundary region around the cutout to
            #      guarantee a better mesh for these cases with a new property
            #      around the cutout
            abaqus_functions.create_composite_layup(
                name="prop_around_cutout_%02d" % self.index,
                stack=stack,
                plyts=plyts,
                mat_names=mat_names,
                part=p,
                part_csys=part_csys,
                region=elem_set,
            )
        else:
            raise RuntimeError("prop_around_hole not defined!")
Ejemplo n.º 4
0
    def create(self):
        #TODO
        # for each stringer create a method that will create its part and
        # translate at the Assembly level already. The part name should be the
        # stringer name added by an identification number
        # probably it will be easier to handle the identification number by
        # creating a StringerConfiguration class, analogously to the
        # imperfection configuration class

        from desicos.abaqus import abaqus_functions
        from regionToolset import Region
        from abaqus import mdb, session
        from abaqusConstants import (STANDALONE, THREE_D, DEFORMABLE_BODY,
                                     FIXED, QUAD, STRUCTURED, ON, XZPLANE,
                                     CARTESIAN, LAMINA, COMPUTED,
                                     SURFACE_TO_SURFACE, OFF)

        cc = self.stringerconf.conecyl
        mod = mdb.models[cc.model_name]
        vp = session.viewports[session.currentViewportName]
        count = 1
        for part_name in mod.parts.keys():
            if 'Stringer' in part_name:
                count += 1
        self.name = 'StringerBladeComposite_{0:02d}'.format(count)

        thetarad = np.deg2rad(self.thetadeg)
        L = cc.L
        sina = sin(cc.alpharad)
        cosa = cos(cc.alpharad)
        rbot = cc.rbot
        rtop = cc.rtop
        wbot = self.wbot
        wtop = self.wtop

        point1 = (0, 0)
        point2 = (-wbot, 0)
        point3 = (-L*sina - wtop, L*cosa)
        point4 = (-L*sina, L*cosa)

        # creating part
        s = mod.ConstrainedSketch(name='__profile__', sheetSize=L)
        g, v, d, c = s.geometry, s.vertices, s.dimensions, s.constraints
        s.setPrimaryObject(option=STANDALONE)
        s.Line(point1=point1, point2=point2)
        s.Line(point1=point2, point2=point3)
        s.Line(point1=point3, point2=point4)
        s.Line(point1=point4, point2=point1)
        part = mod.Part(name=self.name, dimensionality=THREE_D,
                        type=DEFORMABLE_BODY)
        part.BaseShell(sketch=s)
        s.unsetPrimaryObject()
        vp.setValues(displayedObject=part)
        del mod.sketches['__profile__']

        # partitioning along the meridian
        for pt in cc.pts:
            plane = part.DatumPlaneByPrincipalPlane(
                            principalPlane=XZPLANE, offset=pt*cc.H)
            part.PartitionFaceByDatumPlane(datumPlane=part.datums[plane.id],
                        faces=part.faces)

        # material properties
        same_laminaprop = True
        for laminaprop in self.laminaprops:
            if laminaprop != self.laminaprops[0]:
                same_lamiaprop = False
                break
        material_type = LAMINA
        if same_laminaprop:
            mat_name = 'MatStringer_{0:02d}'.format(count)
            mat_names = [mat_name for _ in self.laminaprops]
            myMat = mod.Material(name=mat_name)
            myMat.Elastic(table=(laminaprop,), type=material_type)
        else:
            mat_names = []
            for i, laminaprop in enumerate(self.laminaprops):
                mat_name = 'MatStringer_{0:02d}_ply_{0:02d}'.format(count, i+1)
                mat_names.append(mat_name)
                myMat = mod.Material(name=mat_name)
                myMat.Elastic(table=(laminaprop,), type=material_type)
        csys_name = 'CsysStringer_{0:02d}'.format(count)
        csys = part.DatumCsysByThreePoints(point1=(-L*sina, L*cosa, 0),
                point2=(-wbot, 0, 0), name=csys_name, coordSysType=CARTESIAN,
                origin=(0.0, 0.0, 0.0))
        csys_datum = part.datums[csys.id]
        abaqus_functions.create_composite_layup(
                name='LayupStringer_{0:02d}'.format(count),
                stack=self.stack, plyts=self.plyts, mat_names=mat_names,
                part=part, part_csys=csys_datum,
                region=Region(faces=part.faces), axis_normal=3)

        # meshing part
        # flange
        edge = part.edges.findAt((-wbot/2., 0., 0.))
        part.seedEdgeByNumber(edges=(edge,), number=self.numel_flange,
                              constraint=FIXED)
        # meridian
        coords = []
        for f in np.linspace(0.01, 0.99, 100):
            Li = f*L
            coords.append(((-Li*sina, Li*cosa, 0.),))
        edges = part.edges.findAt(*coords)
        part.seedEdgeBySize(edges=edges, size=cc.mesh_size,
                            constraint=FIXED)
        part.setMeshControls(regions=part.faces, elemShape=QUAD,
                             technique=STRUCTURED)
        part.generateMesh()

        # assemblying part
        ra = mod.rootAssembly
        ra.Instance(name=self.name, part=part, dependent=ON)
        ra.rotate(instanceList=(self.name,),
                  axisPoint=(0.0, 0.0, 0.0),
                  axisDirection=(1.0, 0.0, 0.0),
                  angle=90.0)
        if self.thetadeg > 0:
            ra.rotate(instanceList=(self.name,),
                      axisPoint=(0.0, 0.0, 0.0),
                      axisDirection=(0.0, 0.0, 1.0),
                      angle=self.thetadeg)
        ra.translate(instanceList=(self.name,),
                     vector=(rbot*cos(thetarad), rbot*sin(thetarad), 0.))
        vp.setValues(displayedObject=ra)

        # tieing stringer to the shell surface
        inst_shell = ra.instances['INST_SHELL']
        side2Faces1 = inst_shell.faces
        region1 = Region(side2Faces=side2Faces1)
        inst_stringer_faces = ra.instances[self.name].faces
        region2 = Region(side2Faces=inst_stringer_faces)
        tie_name = 'TieStringer_{0:02d}'.format(count)
        mod.Tie(name=tie_name, master=region1, slave=region2,
                positionToleranceMethod=COMPUTED, adjust=OFF,
                tieRotations=ON, constraintEnforcement=SURFACE_TO_SURFACE,
                thickness=ON)

        # output request
        hist_name = 'HistoryOutStringer_{0:02d}'.format(count)
        mod.FieldOutputRequest(name=hist_name, createStepName=cc.step1Name,
                               variables=('U',))
Ejemplo n.º 5
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:
        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']
    plyts = [ply.thickness for ply in original_layup.plies.values()]
    mat_names = [ply.material for ply in original_layup.plies.values()]
    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)
        sufix = 'measured_imp_t_{0:03d}'.format(i)
        set_name = 'Set_' + sufix
        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_' + sufix
        t_diff = (float(t_list[i]) - t_model) * scaling_factor
        t_scaling_factor = (t_model + t_diff) / t_model
        abaqus_functions.create_composite_layup(
            name=layup_name,
            stack=stack,
            plyts=plyts,
            mat_names=mat_names,
            region=region,
            part=part,
            part_csys=part_cyl_csys,
            scaling_factor=t_scaling_factor)
    # suppress needed to put the new properties to the input file
    original_layup.suppress()

    return elems_t, t_set