Exemple #1
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)
Exemple #2
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
          ``cc.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
            betarad = deg2rad(cc.betadeg)
            omegarad = deg2rad(cc.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)