예제 #1
0
파일: abaqus.py 프로젝트: jz20170904/mapy
#line to be revoluted
s1.Line( point1=(R,-H/2.), point2=(R,H/2.) )

#CREATING A LOCAL COORDINATE SYSTEM TO USE IN THE BOUNDARY CONDITIONS
csysCyl = partCyl.DatumCsysByThreePoints( name='CSYSCylinder',
                                          coordSysType=CYLINDRICAL,
                                          origin=(0,0,0),
                                          point1=(1,0,0),
                                          point2=(1,0,-1) )
#CREATING THE CYLINDER SHELL GEOMETRY
myCyl = partCyl.BaseShellRevolve( sketch=s1,
                                  angle=360.0,
                                  flipRevolveDirection=OFF )
#PROPERTY - assigning the property to the corresponding faces
partCyl.SectionAssignment( 
    region=Region( faces=partCyl.faces.findAt(((-R,0,0),)) ),
    sectionName='AluminumPlate' )

#DEFINING THE MESH SEEDS ALONG ALL EDGES
partCyl.PartitionEdgeByParam( edges=partCyl.edges.findAt( ((R,0,0),) ),
                              parameter=PLpoint )
partCyl.seedEdgeBySize(edges= partCyl.edges.findAt( ((R,-H/2,0),) ),
                       size=ELSIZE,
                       deviationFactor=0.1,
                       constraint=FINER)
partCyl.seedEdgeBySize(edges= partCyl.edges.findAt( ((R, H/2,0),) ),
                       size=ELSIZE,
                       deviationFactor=0.1,
                       constraint=FINER)
partCyl.seedEdgeBySize(edges= partCyl.edges.findAt( ((R,-H/4,0),) ),
                       size=ELSIZE,
예제 #2
0
파일: cutout.py 프로젝트: sovsep/desicos
    def create(self):
        from abaqus import mdb
        from abaqusConstants import (SIDE1, SUPERIMPOSE, COPLANAR_EDGES,
                                     MIDDLE, XZPLANE, SWEEP, FIXED)
        from regionToolset import Region

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

        ra = mod.rootAssembly
        datums = p.datums
        d = self.d
        r, z = cc.r_z_from_pt(self.pt)
        x, y, z = self.x, self.y, self.z
        alpharad = cc.alpharad
        drill_offset_rad = np.deg2rad(self.drill_offset_deg)
        thetarad = np.deg2rad(self.thetadeg)
        thetadeg = self.thetadeg
        thetadeg1 = self.thetadeg1
        thetadeg2 = self.thetadeg2

        # line defining the z axis
        _p1 = p.DatumPointByCoordinate(coords=(0, 0, 0))
        _p2 = p.DatumPointByCoordinate(coords=(0, 0, 1))
        zaxis = p.DatumAxisByTwoPoint(point1=datums[_p1.id],
                                      point2=datums[_p2.id])

        # line defining the cutting axis
        self.p1coord = np.array((x, y, z))
        dx = d * cos(alpharad - drill_offset_rad) * cos(thetarad)
        dy = d * cos(alpharad - drill_offset_rad) * sin(thetarad)
        dz = d * sin(alpharad - drill_offset_rad)
        self.p0coord = np.array((x - dx, y - dy, z - dz))
        self.p2coord = np.array((x + dx, y + dy, z + dz))
        p1 = p.DatumPointByCoordinate(coords=self.p1coord)
        p2 = p.DatumPointByCoordinate(coords=self.p2coord)
        drillaxis = p.DatumAxisByTwoPoint(point1=datums[p1.id],
                                          point2=datums[p2.id])

        #TODO get vertices where to pass the cutting plane
        plow = self.p1coord.copy()
        pup = self.p1coord.copy()
        rlow, zlow = cc.r_z_from_pt(self.ptlow)
        plow[2] = zlow
        rup, zup = cc.r_z_from_pt(self.ptup)
        pup[2] = zup

        diag1pt = p.DatumPointByCoordinate(coords=cyl2rec(rup, thetadeg2, zup))
        diag2pt = p.DatumPointByCoordinate(coords=cyl2rec(rup, thetadeg1, zup))
        diag3pt = p.DatumPointByCoordinate(
            coords=cyl2rec(rlow, thetadeg1, zlow))
        diag4pt = p.DatumPointByCoordinate(
            coords=cyl2rec(rlow, thetadeg2, zlow))
        diag1 = p.DatumPlaneByThreePoints(point1=datums[p1.id],
                                          point2=datums[p2.id],
                                          point3=datums[diag1pt.id])
        diag2 = p.DatumPlaneByThreePoints(point1=datums[p1.id],
                                          point2=datums[p2.id],
                                          point3=datums[diag2pt.id])
        diag3 = p.DatumPlaneByThreePoints(point1=datums[p1.id],
                                          point2=datums[p2.id],
                                          point3=datums[diag3pt.id])
        diag4 = p.DatumPlaneByThreePoints(point1=datums[p1.id],
                                          point2=datums[p2.id],
                                          point3=datums[diag4pt.id])

        c1 = cyl2rec(0.5 * (rup + r), thetadeg + 0.5 * self.offsetdeg,
                     0.5 * (z + zup))
        c2 = cyl2rec(0.5 * (rup + r), thetadeg - 0.5 * self.offsetdeg,
                     0.5 * (z + zup))
        c3 = cyl2rec(0.5 * (rlow + r), thetadeg - 0.5 * self.offsetdeg,
                     0.5 * (z + zlow))
        c4 = cyl2rec(0.5 * (rlow + r), thetadeg + 0.5 * self.offsetdeg,
                     0.5 * (z + zlow))

        #TODO try / except blocks needed due to an Abaqus bug
        try:
            face1 = p.faces.findAt(c1)
            p.PartitionFaceByDatumPlane(datumPlane=datums[diag1.id],
                                        faces=face1)
        except:
            pass

        try:
            face2 = p.faces.findAt(c2)
            p.PartitionFaceByDatumPlane(datumPlane=datums[diag2.id],
                                        faces=face2)
        except:
            pass

        try:
            face3 = p.faces.findAt(c3)
            p.PartitionFaceByDatumPlane(datumPlane=datums[diag3.id],
                                        faces=face3)
        except:
            pass

        try:
            face4 = p.faces.findAt(c4)
            p.PartitionFaceByDatumPlane(datumPlane=datums[diag4.id],
                                        faces=face4)
        except:
            pass

        sketchplane = p.DatumPlaneByPointNormal(point=datums[p2.id],
                                                normal=datums[drillaxis.id])

        sketchstrans = p.MakeSketchTransform(
            sketchPlane=datums[sketchplane.id],
            sketchUpEdge=datums[zaxis.id],
            sketchPlaneSide=SIDE1,
            origin=self.p2coord)

        sketch = mod.ConstrainedSketch(name='__profile__',
                                       sheetSize=10. * d,
                                       gridSpacing=d / 10.,
                                       transform=sketchstrans)
        sketch.setPrimaryObject(option=SUPERIMPOSE)
        p.projectReferencesOntoSketch(sketch=sketch, filter=COPLANAR_EDGES)
        sketch.CircleByCenterPerimeter(center=(0.0, 0), point1=(0.0, d / 2.))

        #TODO try / except blocks needed due to an Abaqus bug
        try:
            p.PartitionFaceBySketchDistance(sketchPlane=datums[sketchplane.id],
                                            sketchUpEdge=datums[zaxis.id],
                                            faces=p.faces,
                                            sketchPlaneSide=SIDE1,
                                            sketch=sketch,
                                            distance=1.5 * d)
        except:
            pass

        sketch.unsetPrimaryObject()
        del mod.sketches['__profile__']

        while True:
            faceList = [
                f[0]
                for f in p.faces.getClosest(coordinates=((x, y, z), ),
                                            searchTolerance=(d / 2. -
                                                             0.5)).values()
            ]
            if not faceList:
                break
            #TODO try / except blocks needed due to an Abaqus bug
            try:
                p.RemoveFaces(faceList=faceList, deleteCells=False)
            except:
                pass

        # Seed edges around cutout area
        numel_per_edge = int(np.ceil(self.offsetdeg / 360.0 * cc.numel_r))
        edge_coords = [
            (rup, 0.5 * (thetadeg1 + thetadeg), zup),
            (rup, 0.5 * (thetadeg2 + thetadeg), zup),
            (rlow, 0.5 * (thetadeg1 + thetadeg), zlow),
            (rlow, 0.5 * (thetadeg2 + thetadeg), zlow),
            (0.5 * (rlow + r), thetadeg1, 0.5 * (zlow + z)),
            (0.5 * (rup + r), thetadeg1, 0.5 * (zup + z)),
            (0.5 * (rlow + r), thetadeg2, 0.5 * (zlow + z)),
            (0.5 * (rup + r), thetadeg2, 0.5 * (zup + z)),
        ]
        edge_coords = [cyl2rec(*c) for c in edge_coords]
        edgeList = [
            e[0] for e in p.edges.getClosest(coordinates=edge_coords,
                                             searchTolerance=1.).values()
        ]
        p.seedEdgeByNumber(edges=edgeList,
                           number=numel_per_edge,
                           constraint=FIXED)

        # Seed radial edges about the cutout
        edge_coords = [
            (r, 0.5 * (thetadeg2 + thetadeg), z),
            (0.5 * (rup + r), 0.5 * (thetadeg2 + thetadeg), 0.5 * (zup + z)),
            (0.5 * (rup + r), thetadeg, 0.5 * (zup + z)),
            (0.5 * (rup + r), 0.5 * (thetadeg1 + thetadeg), 0.5 * (zup + z)),
            (r, 0.5 * (thetadeg1 + thetadeg), z),
            (0.5 * (rlow + r), 0.5 * (thetadeg1 + thetadeg), 0.5 * (zlow + z)),
            (0.5 * (rlow + r), thetadeg, 0.5 * (zlow + z)),
            (0.5 * (rlow + r), 0.5 * (thetadeg2 + thetadeg), 0.5 * (zlow + z)),
        ]
        edge_coords = [cyl2rec(*c) for c in edge_coords]
        edgeList = [
            e[0] for e in p.edges.getClosest(coordinates=edge_coords,
                                             searchTolerance=1.).values()
        ]
        p.seedEdgeByNumber(edges=edgeList,
                           number=self.numel_radial_edge,
                           constraint=FIXED)

        # Mesh control for cutout faces
        try:
            p.setMeshControls(regions=p.faces, technique=SWEEP)
        except:
            warn(
                "Unable to set mesh control to 'SWEEP', please check the mesh around your cutout(s)"
            )
        p.generateMesh()
        for pload in cc.impconf.ploads:
            if (pload.pt == self.pt and pload.thetadeg == self.thetadeg
                    and pload.name in mod.loads.keys()):
                warn(
                    "Cutout is in the same location as perturbation load, moving PL to cutout edge"
                )
                inst_shell = ra.instances['INST_SHELL']
                coords = cyl2rec(r, thetadeg + np.rad2deg(self.d / 2. / r), z)
                new_vertex = inst_shell.vertices.getClosest(
                    coordinates=[coords], searchTolerance=1.).values()[0][0]
                #TODO Unfortunately you cannot simply pass a vertex or list of vertices
                # It has to be some internal abaqus sequence type... work around that:
                index = inst_shell.vertices.index(new_vertex)
                region = Region(vertices=inst_shell.vertices[index:index + 1])
                mod.loads[pload.name].setValues(region=region)

        if self.prop_around_cutout is not None:
            self.create_prop_around_cutout()
예제 #3
0
    def create(self):
        r"""Creates the uneven top edge imperfections

        The uneven top edge will be represented by many GAP elements created
        in such a way to consider all the imperfections contained in the
        current :class:`.UnevenTopEdge` object.

        The output file ``cc.model_name + '_top_edge.gaps'`` will be created,
        where ``cc`` is the :class:`.ConeCyl` object that contains this
        :class:`.UnevenTopEdge` object.

        The following steps are executed:

        - get the `\theta` coordinate of the top nodes from the shell and top
          resin rings

        - get imperfection from the ``shims`` attribute

        - get any additional imperfection of the top edge represented by
          ``measured_u3s``

        - include effect of the misalignment angle ``betadeg``

        Assumptions:

        - for a given `\theta` coordinate the uneven displacement is the same
          for all the shell and resin ring nodes, but the load asymmetry angle
          ``self.betadeg`` may change this equality. The contribution due to
          `\beta` is given by:

          .. math::
              \Delta u_3 = R_{top} tan(\beta) cos(\theta-\omega)

        .. note:: Must be called from Abaqus

        """
        from abaqus import mdb
        from abaqusConstants import (PIN_MPC, DOF_MODE_MPC)
        from regionToolset import Region

        from desicos.abaqus.abaqus_functions import edit_keywords

        cc = self.impconf.conecyl
        mod = mdb.models[cc.model_name]
        ra = mod.rootAssembly

        def calc_gaps(nodes, yx=True):
            # calculating gaps

            # theta according to the assembly coordinate system
            coords = np.array([n.coordinates for n in nodes])
            if yx:
                theta_nodes = np.arctan2(coords[:, 1], coords[:, 0])
            else:
                theta_nodes = np.arctan2(-coords[:, 2], coords[:, 0])

            # contributions from measured edge imperfection
            if self.measured_u3s is not None:
                measured_u3s = np.asarray(self.measured_u3s)
            else:
                measured_u3s = np.zeros((2, 100))
                measured_u3s[0, :] = np.linspace(0, 360, 100)

            # calculating u3 for each node
            u3_nodes = interp(rad2deg(theta_nodes),
                              measured_u3s[0, :],
                              measured_u3s[1, :],
                              period=360)

            # applying load asymmetry according to cc.betarad and omega
            betadeg = self.betadeg if self.betadeg is not None else 0.
            betarad = deg2rad(betadeg)
            omegadeg = self.omegadeg if self.omegadeg is not None else 0.
            omegarad = deg2rad(omegadeg)
            u3_nodes -= cc.rtop * np.tan(betarad) * np.cos(theta_nodes -
                                                           omegarad)

            # contributions from shims
            hs = np.zeros_like(theta_nodes)
            for s in self.shims:
                trad1 = deg2rad(s.thetadeg)
                trad2 = deg2rad(s.thetadeg + 360 * s.width /
                                (2 * pi * cc.rtop))
                thetarads = [trad1 - 0.001, trad1, trad2, trad2 + 0.001]
                u3s = [0, s.thick, s.thick, 0]
                tmp = interp(theta_nodes, thetarads, u3s, period=2 * pi)
                hs += tmp
            u3_nodes -= hs

            # applying scaling_factor
            u3_nodes *= self.scaling_factor

            # calculating gap values
            gaps = u3_nodes - u3_nodes.min()

            return gaps

        if not self.uneven_plate:
            # shell
            part = mod.parts[cc.part_name_shell]
            wdw = 2 * cc.rtop
            zmin = cc.H - cc.resin_top_h * 1.001
            zmax = 1.001 * cc.H
            nodes = part.nodes.getByBoundingBox(-wdw, -wdw, zmin, +wdw, +wdw,
                                                zmax)
            coords = np.array([n.coordinates for n in nodes])
            coords[:, 2] -= calc_gaps(nodes)
            labels = [n.label for n in nodes]
            meshNodeArray = nodes.sequenceFromLabels(labels)
            part.editNode(nodes=meshNodeArray, coordinates=coords)

            # top inner ring
            if cc.resin_add_TIR:
                mesh_arrays = []
                coords_list = []
                part = mod.parts['Top_IR']
                coords = np.array([n.coordinates for n in part.nodes])
                gaps = calc_gaps(part.nodes, yx=False)
                coords[:, 1] -= gaps
                part.editNode(nodes=part.nodes, coordinates=coords)

            # top outer ring
            if cc.resin_add_TOR:
                mesh_arrays = []
                coords_list = []
                part = mod.parts['Top_OR']
                coords = np.array([n.coordinates for n in part.nodes])
                gaps = calc_gaps(part.nodes, yx=False)
                coords[:, 1] -= gaps
                part.editNode(nodes=part.nodes, coordinates=coords)

        nodes_shell = np.array(ra.sets['shell_top_edges'].nodes)
        nodes_all = nodes_shell
        tshell = sum(cc.plyts)
        cosa = np.cos(cc.alpharad)

        if cc.resin_add_TIR:
            nodes_TIR_assembly = np.array(ra.sets['Top_IR_faces'].nodes)
            coords = np.array([n.coordinates for n in nodes_TIR_assembly])
            r_nodes = np.sqrt(coords[:, 0]**2 + coords[:, 1]**2)
            # taking nodes that are not pinned to the shell
            check = (r_nodes < (cc.rtop - cosa * 0.51 * tshell))
            nodes_all = np.hstack((nodes_all, nodes_TIR_assembly[check]))
            if cc.bc_fix_top_side_u3:
                tmp = np.array(ra.sets['Top_IR_faces_side'].nodes)
                coords = np.array([n.coordinates for n in tmp])
                # taking nodes that are not on the top edge
                check = (coords[:, 2] < (cc.H - 0.1))
                nodes_all = np.hstack((nodes_all, tmp[check]))

        if cc.resin_add_TOR:
            nodes_TOR_assembly = np.array(ra.sets['Top_OR_faces'].nodes)
            coords = np.array([n.coordinates for n in nodes_TOR_assembly])
            r_nodes = np.sqrt(coords[:, 0]**2 + coords[:, 1]**2)
            # taking nodes that are not pinned to the shell
            check = (r_nodes > (cc.rtop + cosa * 0.51 * tshell))
            nodes_all = np.hstack((nodes_all, nodes_TOR_assembly[check]))
            if cc.bc_fix_top_side_u3:
                tmp = np.array(ra.sets['Top_OR_faces_side'].nodes)
                coords = np.array([n.coordinates for n in tmp])
                # taking nodes that are not on the top edge
                check = (coords[:, 2] < (cc.H - 0.1))
                nodes_all = np.hstack((nodes_all, tmp[check]))

        # creating GAP elements
        rps_gap = []
        text = ''
        gaps = calc_gaps(nodes_all)
        for node, gap in zip(nodes_all, gaps):
            coord = list(node.coordinates)

            coord[2] += gap

            rp = ra.ReferencePoint(point=coord)
            inst_name = node.instanceName
            #TODO really bad approach, but couldn' find any other way to
            #     get the actual node id that is printed in the .inp
            #     file
            rp_id = int(rp.name.split('-')[1]) + 2
            #
            rps_gap.append(rp)
            gap_name = 'gap_{0}_{1:d}'.format(inst_name, 2000000 + node.label)
            inst_node = '{0}.{1:d}'.format(inst_name, node.label)
            text += ('\n*Element, type=GAPUNI, elset={0}'.format(gap_name))
            text += ('\n{0:d},{1:d},{2}'.format(2000000 + node.label, rp_id,
                                                inst_node))
            text += '\n*GAP, elset={0}'.format(gap_name)
            text += '\n{0:f},0,0,-1\n'.format(gap)

        top_name_gaps = '{0}_top_edge.gaps'.format(cc.model_name)
        with open(top_name_gaps, 'w') as f:
            f.write(text)

        pattern = '*Instance'
        if self.impconf.uneven_bottom_edge:
            bottom_name_gaps = '{0}_bottom_edge.gaps'.format(cc.model_name)
            text = '*INCLUDE, INPUT={0}'.format(bottom_name_gaps)
            text += '\n**\n*INCLUDE, INPUT={0}'.format(top_name_gaps)
        else:
            text = '*INCLUDE, INPUT={0}'.format(top_name_gaps)
        edit_keywords(mod=mod, text=text, before_pattern=pattern, insert=True)

        set_RP_top = ra.sets['RP_top']
        rps = ra.referencePoints
        rps_gap_datums = [rps[rp.id] for rp in rps_gap]
        region = Region(referencePoints=rps_gap_datums)
        ra_cyl_csys = ra.features['ra_cyl_csys']
        ra_cyl_csys = ra.datums[ra_cyl_csys.id]
        mod.MultipointConstraint(name='MPC_RP_GAPs_top_edge',
                                 controlPoint=set_RP_top,
                                 surface=region,
                                 mpcType=PIN_MPC,
                                 userMode=DOF_MODE_MPC,
                                 userType=0,
                                 csys=ra_cyl_csys)
예제 #4
0
    def mesh_part(self, mesh_params):
        """Mesh the model.
        
        The following functions are used in succession:
        
        + **seedPart()**: *deviationFactor* and *minSizeFactor* are
          set to 0.1 and *constraint* is not supported.
        + **setMeshControls()**: The following parameters are not supported:
          *technique*, *algorithm*, *minTransition*, *sizeGrowth*, *allowMapped*.
        + **setElementType()**: The following constraints exist:
          
          - *region* is set to all faces/cells of the structure.
          - The *elemTypes* tuple is determined by *mesh_params.elem_code*
            and *mesh_params.elem_library*.
        
        Args:
            mesh_params(MeshParams): Special namedtuple describing the mesh applied to the model.
                                     See class for full description of options.
        
        Raises:
            ValueError:      If *mesh_params.elem_shape* is invalid.
            ValueError:      If *mesh_params.elem_shape* does not correspond to
                             the structure's dimensionality.
            ValueError:      If *mesh_params.elem_library* is invalid.
            ValueError:      If *mesh_params.elem_code is invalid.
            KeyError:        If *mesh_params.elem_code* does not correspond to a SymbolicConstant.
            ValueError:      If *mesh_params.elem_code* does not correspond to an element.
            AbaqusException: Various exceptions raised by the Abaqus API.
        """

        logger.debug('Meshing the part.')
        import abaqusConstants as abqConst  # So as no to pollute the namespace.
        abaqusConstants_vars = vars(abqConst)

        # Validate and set mesh_params.elem_shape.
        elem_shape_str = mesh_params.elem_shape
        if elem_shape_str.upper(
        ) in auxetic_structure_params.all_elem_shape_list:
            elem_shape = abaqusConstants_vars[elem_shape_str.upper()]
        else:
            raise ValueError("invalid value '%s' for mesh_params.elem_shape." %
                             elem_shape_str)
        # Make sure element shape is consistant with the structure's dimensionality.
        if self.is_solid and (elem_shape in [QUAD, QUAD_DOMINATED, TRI]):
            raise ValueError("Structure is a solid," +
                             " but mesh_params.elem_shape is set to '%s'." %
                             elem_shape)
        if self.is_shell and (elem_shape in [HEX, HEX_DOMINATED, TET, WEDGE]):
            raise ValueError("Structure is a shell," +
                             " but mesh_params.elem_shape is set to '%s'." %
                             elem_shape)

        # Validate and set mesh_params.elem_library.
        if mesh_params.elem_library.upper(
        ) in auxetic_structure_params.all_elem_library_list:
            elem_library = abaqusConstants_vars[
                mesh_params.elem_library.upper()]

        # Validate and set mesh_params.elem_code.
        ## If it's not an iterable, convert into one.
        if isinstance(mesh_params.elem_code, str):
            elem_code_iter = (mesh_params.elem_code, )
        elif isinstance(mesh_params.elem_code, Iterable):
            elem_code_iter = mesh_params.elem_code
        else:
            raise ValueError('Invalid value for mesh_params.elem_code.')
        ## Validate over a loop.
        elem_type_list = []
        for elem_code_str in elem_code_iter:
            # Raises KeyError if elem_code_str is not a SymbolicConstant.
            # Does not actually check if it's a valid element code.
            code = abaqusConstants_vars[elem_code_str.upper()]
            # Create ElemType objects.
            new_elem_type = ElemType(elemCode=code, elemLibrary=elem_library)
            if str(type(new_elem_type)) == "<type 'ElemType'>":
                elem_type_list.append(new_elem_type)
            else:  #Should be None, but I'm not completely sure.
                raise ValueError(
                    "Invalid value '%s' in mesh_params.elem_code." % code)

        # Seed the part.
        part = self.part_main
        if mesh_params.seed_size is None:
            raise ValueError('mesh_params.seed_size has not been specified.')
        part.seedPart(size=mesh_params.seed_size,
                      deviationFactor=0.1,
                      minSizeFactor=0.1)
        logger.debug('Seed generated.')

        # Set mesh controls and element type(s).
        if self.is_shell:
            part.setMeshControls(regions=part.faces, elemShape=elem_shape)
            part.setElementType(regions=Region(faces=part.faces),
                                elemTypes=elem_type_list)
        elif self.is_solid:
            part.setMeshControls(regions=part.cells, elemShape=elem_shape)
            part.setElementType(regions=Region(cells=part.cells),
                                elemTypes=elem_type_list)
        else:
            raise RuntimeError(
                'Both self.is_shell and self.is_solid are False.' +
                ' This should not happen.')

        part.generateMesh()
        logger.debug('Mesh generated.')

        # Get text stats of element codes and types for logging.
        # This is a possible bottleneck. #TODO: test for 500K+ elements.
        elem_stats = dict()
        for elem in part.elements:
            elem_type_name = elem.type.name
            if elem_type_name in elem_stats.keys():
                elem_stats[elem_type_name] += 1
            else:
                elem_stats[elem_type_name] = 1
        elem_stats_str = elem_stats.__repr__().replace(': ', ':').replace(
            '{', '').replace('}', '')

        logger.info("Mesh generation completed with" +
                    " the following number of Abaqus/%s elements: %s." %
                    (elem_library.name.capitalize(), elem_stats_str))
예제 #5
0
    def assign_material(self, material_params):
        """Assign material properties to the auxetic structure.
        
        Note that *material_params.material_data* is not validated.
        Duck-Typing is used for calling the API and some errors are
        caught by the API itself, but ultimately any bad values are
        carried to the CAE model.
        
        Args:
            material_params(MaterialParams): Special namedtuple describing the material
                                             used for modeling and analysis.
                                             See class for full description of options.
        
        Raises:
            ValueError:      If *material_params.hyperelastic* is invalid.
            ValueError:      If *material_params.hyperelastic* is invalid.
            AbaqusException: Various exceptions raised by the Abaqus API.
        """

        logger.debug('Defining material properties for the structure.')
        model = self.model
        part = self.part_main

        logger.debug('Defining material properties.')
        material = model.Material(name='material')

        # Define Elastic property.
        if material_params.elastic is None:
            pass
        elif len(material_params.elastic) == 2:
            material.Elastic(table=(material_params.elastic, ))
            logger.debug('Defined elastic property.')
        else:
            raise ValueError(
                'material_params.elastic must be a Tuple containing two floats.'
            )

        # Define material Density.
        if material_params.density is not None:
            material.Density(table=((material_params.density, ), ))
            logger.debug('Defined material density.')

        # Define Hyperelastic property.
        if material_params.hyperelastic is not None:
            if len(material_params.hyperelastic) == 2:
                type = material_params.hyperelastic[0]
                data = material_params.hyperelastic[1]
            else:
                raise ValueError(
                    'material_params.hyperelastic must be a Tuple.')

            if type == 'ogden':
                material.Hyperelastic(materialType=ISOTROPIC,
                                      type=OGDEN,
                                      volumetricResponse=VOLUMETRIC_DATA,
                                      table=())
                material.hyperelastic.UniaxialTestData(table=data)
            elif type == 'marlow':
                material.Hyperelastic(materialType=ISOTROPIC,
                                      type=MARLOW,
                                      table=())
                material.hyperelastic.UniaxialTestData(table=data)
            else:
                raise ValueError(
                    'Invalid value for material_params.hyperelastic[0]')
            logger.debug(
                'Defined hyperelastic property based on the %s material model.',
                type)

        logger.debug('Assigning section to the structure.')
        section = model.HomogeneousSolidSection(name='section',
                                                material=material.name,
                                                thickness=1.0)

        region = Region(faces=part.faces, cells=part.cells)
        part.SectionAssignment(region=region,
                               sectionName=section.name,
                               offset=0.0,
                               offsetType=MIDDLE_SURFACE,
                               offsetField='',
                               thicknessAssignment=FROM_SECTION)
        logger.debug('Assigned section to the structure.')
        logger.info('Defined material properties for the structure.')
예제 #6
0
def periodicBC(modelName, xmin, ymin, xmax, ymax, dispVector):

    activeModel = mdb.models[modelName]
    assembly = activeModel.rootAssembly
    part = activeModel.parts['Specimen']
    partEdges = part.edges
    partInstance = assembly.instances['Specimen']

    xmid = ymid = (abs(xmin)+abs(xmax))/2.0 + xmin

    # Creating faces
    tol = 0.001
    face1Edges = partEdges.getByBoundingBox(xmax-tol, ymin-tol, -1.0, xmax+tol,
                                            ymax+tol, 1.0)
    face1 = part.Set(edges=face1Edges, name='Face 1')
    face2Edges = partEdges.getByBoundingBox(xmin-tol, ymax-tol, -1.0, xmax+tol,
                                            ymax+tol, 1.0)
    face2 = part.Set(edges=face2Edges, name='Face 2')
    face3Edges = partEdges.getByBoundingBox(xmin-tol, ymin-tol, -1.0, xmin+tol,
                                            ymax+tol, 1.0)
    face3 = part.Set(edges=face3Edges, name='Face 3')
    face4Edges = partEdges.getByBoundingBox(xmin-tol, ymin-tol, -1.0, xmax+tol,
                                            ymin+tol, 1.0)
    face4 = part.Set(edges=face4Edges, name='Face 4')

    # Creating vertices
    partVertices = part.vertices
    vertex1 = part.Set(vertices=partVertices.findAt(((xmax, ymax, 0.0), ), ),
                       name='Vertex 1')
    vertex2 = part.Set(vertices=partVertices.findAt(((xmin, ymax, 0.0), ), ),
                       name='Vertex 2')
    vertex3 = part.Set(vertices=partVertices.findAt(((xmin, ymin, 0.0), ), ),
                       name='Vertex 3')
    vertex4 = part.Set(vertices=partVertices.findAt(((xmax, ymin, 0.0), ), ),
                       name='Vertex 4')

    masterNode1ID = assembly.ReferencePoint(point=(xmid, ymid, 1.0)).id
    masterNode2ID = assembly.ReferencePoint(point=(xmid, ymid, 2.0)).id
    masterNode1 = assembly.referencePoints[masterNode1ID]
    masterNode2 = assembly.referencePoints[masterNode2ID]
    masterNodeSet1 = assembly.Set(referencePoints=(masterNode1, ),
                                      name='MasterNode1')
    masterNodeSet2 = assembly.Set(referencePoints=(masterNode2, ),
                                      name='MasterNode2')
    masterNodeRegion1 = Region(
        referencePoints=(assembly.referencePoints[masterNode1ID], ))
    masterNodeRegion2 = Region(
        referencePoints=(assembly.referencePoints[masterNode1ID], ))

    # Construction Pairs of nodes
    # Face 1 and 3 (right-left)
    face13Paired = []
    face13Paired.append(SortListOfNodes(face1, 1))
    face13Paired.append(SortListOfNodes(face3, 1))
    # Face 2 and 4 (top-bottom)
    face24Paired = []
    face24Paired.append(TakeVertexOut(SortListOfNodes(face2, 0)))
    face24Paired.append(TakeVertexOut(SortListOfNodes(face4, 0)))

    # Top and Bottom faces (2 & 4)
    for i in range(len(face24Paired[0])):
        part.Set(name='MasterFace24-'+str(i),
                 nodes=(part.nodes[face24Paired[0][i]:face24Paired[0][i]+1],))
        part.Set(name='SlaveFace24-'+str(i),
                 nodes=(part.nodes[face24Paired[1][i]:face24Paired[1][i]+1],))
        # (6.14, i=1)
        activeModel.Equation(name='Constraint24-1-'+str(i),
                             terms=((1.0, 'Specimen.MasterFace24-'+str(i), 1),
                                    (-1.0, 'Specimen.SlaveFace24-'+str(i), 1),
                                    (1.0, 'MasterNode2', 1)))
        # (6.14, i=2)
        activeModel.Equation(name='Constraint24-2-'+str(i),
                             terms=((1.0, 'Specimen.MasterFace24-'+str(i), 2),
                                    (-1.0, 'Specimen.SlaveFace24-'+str(i), 2),
                                    (1.0, 'MasterNode2', 1)))

    # Left and Right faces (1 & 3)
    for j in range(len(face13Paired[0])):
        part.Set(name='MasterFace13-'+str(j),
                 nodes=(part.nodes[face13Paired[0][j]:face13Paired[0][j]+1],))
        part.Set(name='SlaveFace13-'+str(j),
                 nodes=(part.nodes[face13Paired[1][j]:face13Paired[1][j]+1],))
        # (6.13, i=1)
        activeModel.Equation(name='Constraint13-1-'+str(j),
                             terms=((1.0, 'Specimen.MasterFace13-'+str(j), 1),
                                    (-1.0, 'Specimen.SlaveFace13-'+str(j), 1),
                                    (1.0, 'MasterNode1', 1)))
        # (6.13, i=2)
        activeModel.Equation(name='Constraint13-2-'+str(j),
                             terms=((1.0, 'Specimen.MasterFace13-'+str(j), 2),
                                    (-1.0, 'Specimen.SlaveFace13-'+str(j), 2),
                                    (1.0, 'MasterNode1', 2)))
    # Apply BCs to master nodes
    if dispVector[0]:
        activeModel.DisplacementBC(amplitude=UNSET,
                                   createStepName='Loading Step',
                                   distributionType=UNIFORM, fieldName='',
                                   fixed=OFF, localCsys=None, name='BC-13',
                                   region=masterNodeRegion1, u1=dispVector[0],
                                   u2=UNSET, ur3=UNSET)
    if dispVector[1]:
        activeModel.DisplacementBC(amplitude=UNSET,
                                   createStepName='Loading Step',
                                   distributionType=UNIFORM, fieldName='',
                                   fixed=OFF, localCsys=None, name='BC-24',
                                   region=masterNodeRegion2, u1=UNSET,
                                   u2=dispVector[1], ur3=UNSET)

    activeModel.rootAssembly.regenerate()
예제 #7
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',))
예제 #8
0
def periodicBC(modelName, xmin, ymin, xmax, ymax, strain):

    activeModel = mdb.models[modelName]
    assembly = activeModel.rootAssembly
    part = activeModel.parts['Specimen']
    partEdges = part.edges
    partInstance = assembly.instances['Specimen']

    xmid = ymid = (abs(xmin) + abs(xmax)) / 2.0 + xmin

    # Creating faces
    tol = 0.001
    face1Edges = partEdges.getByBoundingBox(xmax - tol, ymin - tol, -1.0,
                                            xmax + tol, ymax + tol, 1.0)
    face1 = part.Set(edges=face1Edges, name='Face 1')
    face2Edges = partEdges.getByBoundingBox(xmin - tol, ymax - tol, -1.0,
                                            xmax + tol, ymax + tol, 1.0)
    face2 = part.Set(edges=face2Edges, name='Face 2')
    face3Edges = partEdges.getByBoundingBox(xmin - tol, ymin - tol, -1.0,
                                            xmin + tol, ymax + tol, 1.0)
    face3 = part.Set(edges=face3Edges, name='Face 3')
    face4Edges = partEdges.getByBoundingBox(xmin - tol, ymin - tol, -1.0,
                                            xmax + tol, ymin + tol, 1.0)
    face4 = part.Set(edges=face4Edges, name='Face 4')

    # Creating vertices
    partVertices = part.vertices
    vertex1 = part.Set(vertices=partVertices.findAt(((xmax, ymax, 0.0), ), ),
                       name='Vertex 1')
    vertex2 = part.Set(vertices=partVertices.findAt(((xmin, ymax, 0.0), ), ),
                       name='Vertex 2')
    vertex3 = part.Set(vertices=partVertices.findAt(((xmin, ymin, 0.0), ), ),
                       name='Vertex 3')
    vertex4 = part.Set(vertices=partVertices.findAt(((xmax, ymin, 0.0), ), ),
                       name='Vertex 4')

    masterNodeID = part.ReferencePoint(point=(xmid, ymid, 0.0)).id
    masterNode = part.referencePoints[masterNodeID]
    masterNodeSet = part.Set(referencePoints=(masterNode, ), name='MasterNode')
    masterNodeRegion = Region(
        referencePoints=(partInstance.referencePoints[masterNodeID], ))

    activeModel.DisplacementBC(amplitude=UNSET,
                               createStepName='Loading Step',
                               distributionType=UNIFORM,
                               fieldName='',
                               fixed=OFF,
                               localCsys=None,
                               name='BC-1',
                               region=masterNodeRegion,
                               u1=1.0,
                               u2=UNSET,
                               ur3=UNSET)

    # Construction Pairs of nodes
    # Face 1 and 3 (right-left)
    face13Paired = []
    face13Paired.append(TakeVertexOut(SortListOfNodes(face1, 1)))
    face13Paired.append(TakeVertexOut(SortListOfNodes(face3, 1)))
    # Face 2 and 4 (top-bottom)
    face24Paired = []
    face24Paired.append(TakeVertexOut(SortListOfNodes(face2, 0)))
    face24Paired.append(TakeVertexOut(SortListOfNodes(face4, 0)))

    # Create constraint equations
    # Vertices

    # Master V1 (Contained in 1 and 3)
    activeModel.Equation(
        name='ConstraintV1-V3-1',
        terms=((1.0, 'Specimen.Vertex 1', 1), (-1.0, 'Specimen.Vertex 3', 1),
               (-strain[0] * (vertex1.nodes[-1].coordinates[0] -
                              vertex3.nodes[-1].coordinates[0]) +
                -strain[2] / 2. * (vertex1.nodes[-1].coordinates[1] -
                                   vertex3.nodes[-1].coordinates[1]),
                'Specimen.MasterNode', 1)))
    activeModel.Equation(
        name='ConstraintV1-V3-2',
        terms=((1.0, 'Specimen.Vertex 1', 2), (-1.0, 'Specimen.Vertex 3', 2),
               (-strain[2] / 2. * (vertex1.nodes[-1].coordinates[0] -
                                   vertex3.nodes[-1].coordinates[0]) +
                -strain[1] * (vertex1.nodes[-1].coordinates[1] -
                              vertex3.nodes[-1].coordinates[1]),
                'Specimen.MasterNode', 1)))

    # Master V2 (Contained in 2 and 4)
    activeModel.Equation(
        name='ConstraintV2-V4-1',
        terms=((1.0, 'Specimen.Vertex 2', 1), (-1.0, 'Specimen.Vertex 4', 1),
               (strain[2] / 2. * (vertex4.nodes[-1].coordinates[1] -
                                  vertex2.nodes[-1].coordinates[1]) +
                strain[0] * (vertex4.nodes[-1].coordinates[0] -
                             vertex2.nodes[-1].coordinates[0]),
                'Specimen.MasterNode', 1)))
    activeModel.Equation(
        name='ConstraintV2-V4-2',
        terms=((1.0, 'Specimen.Vertex 2', 2), (-1.0, 'Specimen.Vertex 4', 2),
               (-strain[1] * (vertex2.nodes[-1].coordinates[1] -
                              vertex4.nodes[-1].coordinates[1]) -
                strain[2] / 2. * (vertex2.nodes[-1].coordinates[0] -
                                  vertex4.nodes[-1].coordinates[0]),
                'Specimen.MasterNode', 1)))

    # For the edges
    for ii in range(len(face13Paired[0])):
        part.Set(name='MasterFace13-' + str(ii),
                 nodes=(part.nodes[face13Paired[0][ii]:face13Paired[0][ii] +
                                   1], ))
        part.Set(name='SlaveFace13-' + str(ii),
                 nodes=(part.nodes[face13Paired[1][ii]:face13Paired[1][ii] +
                                   1], ))
        # (6.13, i=1)
        activeModel.Equation(
            name='Constraint13-1-' + str(ii),
            terms=((1.0, 'Specimen.MasterFace13-' + str(ii),
                    1), (-1.0, 'Specimen.SlaveFace13-' + str(ii), 1),
                   (-strain[0] *
                    (part.nodes[face13Paired[0][ii]].coordinates[0] -
                     part.nodes[face13Paired[1][ii]].coordinates[0]),
                    'Specimen.MasterNode', 1)))
        # (6.13, i=2)
        activeModel.Equation(
            name='Constraint13-2-' + str(ii),
            terms=((1.0, 'Specimen.MasterFace13-' + str(ii),
                    2), (-1.0, 'Specimen.SlaveFace13-' + str(ii), 2),
                   (-strain[2] / 2. *
                    (part.nodes[face13Paired[0][ii]].coordinates[0] -
                     part.nodes[face13Paired[1][ii]].coordinates[0]),
                    'Specimen.MasterNode', 1)))

    for ii in range(len(face24Paired[0])):
        part.Set(name='MasterFace24-' + str(ii),
                 nodes=(part.nodes[face24Paired[0][ii]:face24Paired[0][ii] +
                                   1], ))
        part.Set(name='SlaveFace24-' + str(ii),
                 nodes=(part.nodes[face24Paired[1][ii]:face24Paired[1][ii] +
                                   1], ))
        # (6.14, i=1)
        activeModel.Equation(
            name='Constraint24-1-' + str(ii),
            terms=((1.0, 'Specimen.MasterFace24-' + str(ii),
                    1), (-1.0, 'Specimen.SlaveFace24-' + str(ii), 1),
                   (-strain[2] / 2. *
                    (part.nodes[face24Paired[0][ii]].coordinates[1] -
                     part.nodes[face24Paired[1][ii]].coordinates[1]),
                    'Specimen.MasterNode', 1)))
        # (6.14, i=2)
        activeModel.Equation(
            name='Constraint24-2-' + str(ii),
            terms=((1.0, 'Specimen.MasterFace24-' + str(ii),
                    2), (-1.0, 'Specimen.SlaveFace24-' + str(ii), 2),
                   (-strain[1] *
                    (part.nodes[face24Paired[0][ii]].coordinates[1] -
                     part.nodes[face24Paired[1][ii]].coordinates[1]),
                    'Specimen.MasterNode', 1)))

    activeModel.rootAssembly.regenerate()