예제 #1
0
def _mirror_aero(model: BDF, nid_offset: int, plane: str = 'xz'):
    """
    Mirrors the aero cards

    Considers:
     - AEROS
      - doesn't consider sideslip
     - CAERO1
      - doesn't consider sideslip
      - considers Cp
      - considers lchord/lspan/nchord/nspan
     - SPLINE1
       - handle boxes
     - SET1
       - handle nodes
     - AELIST
       - handle boxes
     - AESURF
       - only supports names of length 7 or less (appends an M to the name)
       - handles AELIST
       - doesn't handle coords well
       - doesn't handle second AESURF

    Doesnt consider:
     - AERO
     - AEFORCE
     - AEPRES
     - CAERO2/3/4/5
     - PAERO1/2/3/4/5
     - AESURFS

    """
    is_aero = False
    aero_cids_set = set([])
    if model.aeros is not None:
        is_aero = True
        aeros = model.aeros
        # The ACSID must be a rectangular coordinate system.
        # Flow is in the positive x-direction (T1).
        if aeros.acsid > 0:
            model.log.error(
                'Sideslip coordinate system (ACSID) mirroring is not supported'
            )

        # REFB should be full span, even on half-span models
        # REFS should be half area on half-span models
        aeros.sref *= 2.
        if plane == 'xz':
            aeros.sym_xz = 0
        elif plane == 'yz':
            aeros.sym_yz = 0
        else:
            model.log.error('not mirroring plane %r; only xz, yz' % plane)

    caero_id_offset = 0
    if len(model.caeros):
        is_aero = True
        caero_id_max = max(model.caero_ids)
        caero_id_offset = np.max(model.caeros[caero_id_max].box_ids.flat)

        caeros = []
        for unused_caero_id, caero in model.caeros.items():
            if caero.type == 'CAERO1':
                # the AEFACTs are assumed to be the same on the left and right side
                # I think the spanwise direction will be fine
                lchord = caero.lchord
                nchord = caero.nchord
                lspan = caero.lspan
                nspan = caero.nspan
                p1, p4 = caero.get_leading_edge_points()
                p1 = p1.copy()
                p4 = p4.copy()
                x12 = caero.x12
                x43 = caero.x43
                if plane == 'xz':  # flip the y
                    p1[1] *= -1.
                    p4[1] *= -1.
                elif plane == 'xy':
                    p1[2] *= -1.
                    p4[2] *= -1.
                else:  # pragma: no cover
                    raise NotImplementedError(
                        'plane=%r not supported in CAERO1' % plane)
                eid2 = caero.eid + caero_id_offset
                caero_new = CAERO1(eid2,
                                   caero.pid,
                                   caero.igroup,
                                   p1,
                                   x12,
                                   p4,
                                   x43,
                                   cp=0,
                                   nspan=nspan,
                                   lspan=lspan,
                                   nchord=nchord,
                                   lchord=lchord,
                                   comment='')

                # we flip the normal so if we ever use W2GJ it's going to be consistent
                caero_new.flip_normal()
                caeros.append(caero_new)
            else:  # pragma: no cover
                model.log.error('skipping (only supports CAERO1):\n%s' %
                                caero.rstrip())

        for caero in caeros:
            model._add_caero_object(caero)

    nsplines = len(model.splines)
    sets_max = max(model.sets) if len(model.sets) else 0
    if caero_id_offset == 0 and nsplines:
        model.log.error("cant mirror splines because CAEROs don't exist...")
    elif nsplines and sets_max == 0:
        model.log.error("cant mirror splines because SET1/3 don't exist...")
    elif nsplines:
        is_aero = True
        splines = []
        spline_sets_to_duplicate = []
        spline_max = max(model.splines)
        for unused_spline_id, spline in model.splines.items():
            if spline.type == 'SPLINE1':
                eid = spline.eid + spline_max
                caero = spline.caero + caero_id_offset
                method = spline.method
                usage = spline.usage
                box1 = spline.box1 + caero_id_offset
                box2 = spline.box2 + caero_id_offset
                setg = spline.setg + sets_max
                dz = spline.dz
                melements = spline.melements
                nelements = spline.nelements
                spline_new = SPLINE1(eid,
                                     caero,
                                     box1,
                                     box2,
                                     setg,
                                     dz=dz,
                                     method=method,
                                     usage=usage,
                                     nelements=nelements,
                                     melements=melements,
                                     comment='')
                splines.append(spline_new)
                spline_sets_to_duplicate.append(spline.setg)
            else:  # pragma: no cover
                model.log.error('skipping (only support SPLINE1):\n%s' %
                                spline.rstrip())

        #print("spline_sets_to_duplicate =", spline_sets_to_duplicate)
        msg = ', which is required to mirror:\n%s' % spline.rstrip()

        sets_to_add = []
        for set_id in spline_sets_to_duplicate:
            set_card = model.Set(set_id, msg=msg)
            if set_card.type == 'SET1':
                sid = set_card.sid + sets_max
                ids = [nid + nid_offset for nid in set_card.ids]
                is_skin = set_card.is_skin
                set_card = SET1(sid, ids, is_skin=is_skin, comment='')
                sets_to_add.append(set_card)
            else:  # pragma: no cover
                model.log.error('skipping (only support SET1):\n%s' %
                                set_card.rstrip())

        for spline in splines:
            model._add_spline_object(spline)
        for set_card in sets_to_add:
            model._add_set_object(set_card)

    aelist_id_offset = 0
    if len(model.aelists):
        is_aero = True
        aelist_id_offset = max(model.aelists)

    cid_offset = max(model.coords) if len(model.coords) > 1 else 0
    if len(model.aesurf):
        is_aero = True
        aesurf_id_offset = max(model.aesurf)
        for aelist_id, aelist in sorted(model.aelists.items()):
            aelist_id_new = aelist_id + aelist_id_offset
            elements = [eid + caero_id_offset for eid in aelist.elements]
            model.add_aelist(aelist_id_new, elements, comment='')

        for aesurf_id, aesurf in sorted(model.aesurf.items()):
            # TODO: doesn't handle cid2/aelist2
            aesurf_id_new = aesurf_id + aesurf_id_offset
            label = aesurf.label + 'M'
            cid1 = aesurf.cid1 + cid_offset
            alid1 = aesurf.alid1 + aelist_id_offset
            if cid_offset > 0:
                aero_cids_set.add(aesurf.cid1)

            cid2 = None
            alid2 = None
            if aesurf.cid2:
                model.log.warning(
                    "skipping aesurf='{aesurf.label}' second cid/aelist")
                # combine this into the first coordinate system
                #
                #  don't mirror the coordinate system because it's antisymmetric?
                #cid2 = aesurf.cid1 + cid_offset * 2
                # how is the second coord and aelist made?
                #aero_cids_set.add(aesurf.cid1)
                #alid2 = aesurf.alid1 + aelist_id_offset * 2

            model.add_aesurf(aesurf_id_new,
                             label,
                             cid1,
                             alid1,
                             cid2=None,
                             alid2=None,
                             eff=aesurf.eff,
                             ldw=aesurf.ldw,
                             crefc=aesurf.crefc,
                             crefs=aesurf.crefs,
                             pllim=aesurf.pllim,
                             pulim=aesurf.pulim,
                             hmllim=aesurf.hmllim,
                             hmulim=aesurf.hmulim,
                             tqllim=aesurf.tqllim,
                             tqulim=aesurf.tqulim,
                             comment='')

    if is_aero:
        _asymmetrically_mirror_aero_coords(model, aero_cids_set, cid_offset,
                                           plane)
    model.pop_parse_errors()
예제 #2
0
    def test_spline2(self):
        """checks the SPLINE2 card"""
        #| SPLINE2 | EID  | CAERO |  ID1  |  ID2  | SETG | DZ | DTOR | CID |
        #|         | DTHX | DTHY  | None  | USAGE |      |    |      |     |
        #+---------+------+-------+-------+-------+------+----+------+-----+
        #| SPLINE2 |   5  |   8   |  12   | 24    | 60   | 0. | 1.0  |  3  |
        #|         |  1.  |       |       |       |      |    |      |     |

        cid = 3
        origin = [0., 0., 0.]
        xaxis = [1., 0., 0.]
        xyplane = [0., 1., 0.]
        coord = CORD2R.add_axes(cid, rid=0, origin=origin,
                                xaxis=xaxis, yaxis=None, zaxis=None,
                                xyplane=xyplane, yzplane=None, xzplane=None,
                                comment='comment')
        eid = 8
        pid = 10
        cp = 0
        nsb = 4
        nint = 2
        lsb = None
        lint = None
        p1 = [0., 0., 0.]
        x12 = 42.
        igid = None
        caero2 = CAERO2(eid, pid, igid, p1, x12,
                        cp=cp, nsb=nsb, nint=nint, lsb=lsb, lint=lint,
                        comment='this is a caero')
        #caero = CAERO2(eid, pid, cp, nsb, nint, lsb, lint, igid, p1, x12)

        sid = 60
        ids = [7, 13]
        set_obj = SET1(sid, ids, is_skin=False, comment='set card')
        grid7 = GRID(nid=7, cp=0, xyz=[7., 0., 0.], cd=0, ps='', seid=0, comment='')
        grid13 = GRID(nid=13, cp=0, xyz=[13., 0., 0.], cd=0, ps='', seid=0, comment='')

        model = BDF(log=None)
        model._add_coord_object(coord)
        model._add_caero_object(caero2)
        model._add_set_object(set_obj)
        model._add_node_object(grid7)
        model._add_node_object(grid13)

        eid = 5
        caero = 8
        id1 = 12
        id2 = 24
        setg = 60
        dz = 0.
        dtor = 1.0
        cid = 3
        dthx = 1.
        dthy = None
        usage = None
        card = ['SPLINE2', eid, caero, id1, id2, setg, dz, dtor, cid,
                dthx, dthy, None, usage]

        bdf_card = BDFCard(card, has_none=True)
        spline_a = SPLINE2.add_card(bdf_card, comment='spline2_a')
        spline_a.write_card()

        spline_b = SPLINE2(eid, caero, id1, id2, setg, dz, dtor, cid, dthx,
                           dthy, usage, comment='spline2_b')
        spline_b.validate()
        spline_b.write_card()
        spline_b.cross_reference(model)
        spline_b.write_card()