예제 #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 _mirror_aero(model, nid_offset, plane):
    """
    Mirrors the aero elements

    Considers:
     - AEROS
      - doesn't consider sideslip
     - CAERO1
      - doesn't consider sideslip
      - doesn't consider lspan/lchord
     - SPLINE1
     - SET1
    """
    if model.aeros is not None:
        aeros = model.aeros
        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):
        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':
                assert caero.lspan == 0, caero
                assert caero.lchord == 0, caero
                lchord = caero.lchord
                nchord = caero.nchord
                lspan = caero.lspan
                nspan = caero.nspan
                p1 = caero.p1.copy()
                p1[1] *= -1.
                x12 = caero.x12
                p4 = caero.p4.copy()
                p4[1] *= -1.
                x43 = caero.x43
                eid2 = caero.eid + caero_id_offset
                caero_new = CAERO1(eid2,
                                   caero.pid,
                                   caero.igroup,
                                   p1,
                                   x12,
                                   p4,
                                   x43,
                                   cp=caero.cp,
                                   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)
                #print(caero)
            else:  # pragma: no cover
                model.log.error('skipping (only support 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:
        splines = []
        spline_sets_to_duplicate = []
        spline_max = max(model.splines)
        for unused_spline_id, spline in model.splines.items():
            if spline.type == 'SPLINE1':
                #spline = SPLINE1(eid, caero, box1, box2, setg)

                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)

    model.pop_parse_errors()