예제 #1
0
    def __init__(self, model):
        """
        Defines the ShellProperties object.

        :param self: the ShellProperties object
        :param model: the BDF object
        """
        self.model = model
        self.pshell = PSHELL(self.model)
        self.pcomp = PCOMP(self.model)
        self.pcompg = PCOMPG(self.model)
        self.n = 0
    def __init__(self, model):
        """
        Defines the ShellProperties object.

        :param model: the BDF object
        """
        self.model = model
        self.pshell = PSHELL(self.model)
        self.pcomp = PCOMP(self.model)
        self.pcompg = PCOMPG(self.model)
        self.n = 0
예제 #3
0
class PropertiesShell(object):
    def __init__(self, model):
        """
        Defines the ShellProperties object.

        :param self: the ShellProperties object
        :param model: the BDF object
        """
        self.model = model
        self.pshell = PSHELL(self.model)
        self.pcomp = PCOMP(self.model)
        self.pcompg = PCOMPG(self.model)
        self.n = 0

    def allocate(self, card_count):
        ptypes = self._get_types(nlimit=False)
        self.model.log.debug('card_count = %s' % card_count)
        for ptype in ptypes:
            if ptype.type in card_count:
                self.model.log.debug('    allocate %s' % ptype.type)
                ptype.allocate(card_count[ptype.type])
                del card_count[ptype.type]
            #else:
                #assert hasattr(etype, 'allocate'), '%s doesnt support allocate' % ptype.type

    def build(self):
        for prop in [self.pshell, self.pcomp, self.pcompg]:
            if hasattr(prop, 'n'):
                self.model.log.debug('    building %s' % prop.__class__.__name__)
            prop.build()
            self.n += prop.n

        npshell = self.pshell.n
        npcomp  = self.pcomp.n
        npcompg = self.pcompg.n

        self.n = npshell + npcomp + npcompg
        pid = hstack([self.pshell.property_id, self.pcomp.property_id, self.pcompg.property_id])
        unique_pids = unique(pid)
        #print unique_pids
        if len(unique_pids) != len(pid):
            raise RuntimeError('There are duplicate PSHELL/PCOMP IDs...')

    def rebuild(self):
        raise NotImplementedError()

    #=========================================================================
    def add_pshell(self, card, comment):
        self.pshell.add(card, comment)

    def add_pcomp(self, card, comment):
        self.pcomp.add(card, comment)

    def add_pcompg(self, card, comment):
        raise NotImplementedError(card)
        self.pcompg.add(card, comment)

    #=========================================================================
    def get_material_id_by_property_id(self, property_id):
        types = self._get_types(nlimit=True)
        _property_id = concatenate([ptype.property_id for ptype in types])
        #print _property_id
        return _property_id

    def get_nonstructural_mass_by_property_id(self, property_id=None):
        return self._getmethod(property_id, 'get_nonstructural_mass_by_property_id')

    def get_mass_per_area_by_property_id(self, property_id=None):
        return self._getmethod(property_id, 'get_mass_per_area_by_property_id')

    def get_thickness_by_property_id(self, property_id=None):
        """
        Gets the thickness of the PSHELLs/PCOMPs.

        :param self: the ShellProperties object
        :param property_id: the property IDs to consider (default=None -> all)
        """
        return self._getmethod(property_id, 'get_thickness_by_property_id')

    def get_density_by_property_id(self, property_id=None):
        """
        Gets the density of the PSHELLs/PCOMPs.

        :param self: the ShellProperties object
        :param property_ids: the property IDs to consider (default=None -> all)
        """
        return self._getmethod(property_id, 'get_density_by_property_id')

    def _getattr(self, property_id, method):
        TypeMap = {
            'PSHELL': (self.pshell, self.pshell.property_id),
            'PCOMP' : (self.pcomp, self.pcomp.property_id),
            'PCOMPG': (self.pcompg, self.pcompg.property_id),
        }
        out = array([])
        for Type, (ptype, pids) in sorted(iteritems(TypeMap)):
            for pid in pids:
                if pid in property_id:
                    value = getattr(ptype, method)
                    #assert len(value) == 1, value
                    #print('pid =', pid, value)
                    out = hstack([out, value])
        #print("out = %s" % out)
        return out

    def _getmethod(self, property_id, method):
        #types = self._get_types(nlimit=True)
        #data = hstack([getattr(ptype, method)() for ptype in types] )
        #if property_ids is None:
            #return data

        TypeMap = {
            'PSHELL': (self.pshell, self.pshell.property_id),
            'PCOMP' : (self.pcomp, self.pcomp.property_id),
            'PCOMPG': (self.pcompg, self.pcompg.property_id),
        }
        #self.model.log.debug('property_id = %s' % property_id)
        n = len(property_id)
        out = full(n, nan, dtype='float64')
        for Type, (ptype, pids) in sorted(iteritems(TypeMap)):
            #self.model.log.debug('Type=%s pids=%s' % (Type, pids))
            for pid in pids:
                if pid in property_id:
                    value = getattr(ptype, method)([pid])
                    j = where(pid == property_id)[0]
                    #assert len(value) == 1, value
                    #self.model.log.debug('pid = %s %s' % (pid, value))
                    out[j] = value
        #self.model.log.debug("out = %s" % out)
        assert out.shape == (n, ), out.shape
        assert isnan(out) == False, out
        return out
        #_property_ids = hstack([ptype.property_id for ptype in types])
        #assert isinstance(property_ids, ndarray), type(property_ids)
        #i = argsort(_property_ids)
        #j = searchsorted(property_ids, _property_ids[i])
        #data_short = data[j]
        #return data_short

    #=========================================================================
    def _get_types(self, nlimit=True):
        types = [self.pshell, self.pcomp, self.pcompg]
        if nlimit:
            types2 = []
            for ptype in types:
                if ptype.n:
                    types2.append(ptype)
            types = types2
        else:
            #self.model.log.debug('ptypes=%s' % types)
            pass
        return types

    def get_stats(self):
        msg = []
        types = self._get_types()
        for prop in types:
            nprop = prop.n
            if nprop:
                msg.append('  %-8s: %i' % (prop.type, nprop))
        return msg

    def write_bdf(self, f, size=8, property_id=None):
        f.write('$PROPERTIES_SHELL\n')
        types = self._get_types()
        for prop in types:
            #print('*SHELL', prop.type)
            prop.write_bdf(f, size=size, property_id=property_id)
예제 #4
0
class PropertiesShell(object):
    def __init__(self, model):
        """
        Defines the ShellProperties object.

        :param self: the ShellProperties object
        :param model: the BDF object
        """
        self.model = model
        self.pshell = PSHELL(self.model)
        self.pcomp = PCOMP(self.model)
        self.pcompg = PCOMPG(self.model)
        self.n = 0

    def allocate(self, card_count):
        ptypes = self._get_types(nlimit=False)
        self.model.log.debug('card_count = %s' % card_count)
        for ptype in ptypes:
            if ptype.type in card_count:
                self.model.log.debug('    allocate %s' % ptype.type)
                ptype.allocate(card_count[ptype.type])
                del card_count[ptype.type]
            #else:
            #assert hasattr(etype, 'allocate'), '%s doesnt support allocate' % ptype.type

    def build(self):
        for prop in [self.pshell, self.pcomp, self.pcompg]:
            if hasattr(prop, 'n'):
                self.model.log.debug('    building %s' %
                                     prop.__class__.__name__)
            prop.build()
            self.n += prop.n

        npshell = self.pshell.n
        npcomp = self.pcomp.n
        npcompg = self.pcompg.n

        self.n = npshell + npcomp + npcompg
        pid = hstack([
            self.pshell.property_id, self.pcomp.property_id,
            self.pcompg.property_id
        ])
        unique_pids = unique(pid)
        #print unique_pids
        if len(unique_pids) != len(pid):
            raise RuntimeError('There are duplicate PSHELL/PCOMP IDs...')

    def rebuild(self):
        raise NotImplementedError()

    #=========================================================================
    def add_pshell(self, card, comment):
        self.pshell.add(card, comment)

    def add_pcomp(self, card, comment):
        self.pcomp.add(card, comment)

    def add_pcompg(self, card, comment):
        raise NotImplementedError(card)
        self.pcompg.add(card, comment)

    #=========================================================================
    def get_material_id_by_property_id(self, property_id):
        types = self._get_types(nlimit=True)
        _property_id = concatenate([ptype.property_id for ptype in types])
        #print _property_id
        return _property_id

    def get_nonstructural_mass_by_property_id(self, property_id=None):
        return self._getmethod(property_id,
                               'get_nonstructural_mass_by_property_id')

    def get_mass_per_area_by_property_id(self, property_id=None):
        return self._getmethod(property_id, 'get_mass_per_area_by_property_id')

    def get_thickness_by_property_id(self, property_id=None):
        """
        Gets the thickness of the PSHELLs/PCOMPs.

        :param self: the ShellProperties object
        :param property_id: the property IDs to consider (default=None -> all)
        """
        return self._getmethod(property_id, 'get_thickness_by_property_id')

    def get_density_by_property_id(self, property_id=None):
        """
        Gets the density of the PSHELLs/PCOMPs.

        :param self: the ShellProperties object
        :param property_ids: the property IDs to consider (default=None -> all)
        """
        return self._getmethod(property_id, 'get_density_by_property_id')

    def _getattr(self, property_id, method):
        TypeMap = {
            'PSHELL': (self.pshell, self.pshell.property_id),
            'PCOMP': (self.pcomp, self.pcomp.property_id),
            'PCOMPG': (self.pcompg, self.pcompg.property_id),
        }
        out = array([])
        for Type, (ptype, pids) in sorted(iteritems(TypeMap)):
            for pid in pids:
                if pid in property_id:
                    value = getattr(ptype, method)
                    #assert len(value) == 1, value
                    #print('pid =', pid, value)
                    out = hstack([out, value])
        #print("out = %s" % out)
        return out

    def _getmethod(self, property_id, method):
        #types = self._get_types(nlimit=True)
        #data = hstack([getattr(ptype, method)() for ptype in types] )
        #if property_ids is None:
        #return data

        TypeMap = {
            'PSHELL': (self.pshell, self.pshell.property_id),
            'PCOMP': (self.pcomp, self.pcomp.property_id),
            'PCOMPG': (self.pcompg, self.pcompg.property_id),
        }
        #self.model.log.debug('property_id = %s' % property_id)
        n = len(property_id)
        out = full(n, nan, dtype='float64')
        for Type, (ptype, pids) in sorted(iteritems(TypeMap)):
            #self.model.log.debug('Type=%s pids=%s' % (Type, pids))
            for pid in pids:
                if pid in property_id:
                    value = getattr(ptype, method)([pid])
                    j = where(pid == property_id)[0]
                    #assert len(value) == 1, value
                    #self.model.log.debug('pid = %s %s' % (pid, value))
                    out[j] = value
        #self.model.log.debug("out = %s" % out)
        assert out.shape == (n, ), out.shape
        assert isnan(out) == False, out
        return out
        #_property_ids = hstack([ptype.property_id for ptype in types])
        #assert isinstance(property_ids, ndarray), type(property_ids)
        #i = argsort(_property_ids)
        #j = searchsorted(property_ids, _property_ids[i])
        #data_short = data[j]
        #return data_short

    #=========================================================================
    def _get_types(self, nlimit=True):
        types = [self.pshell, self.pcomp, self.pcompg]
        if nlimit:
            types2 = []
            for ptype in types:
                if ptype.n:
                    types2.append(ptype)
            types = types2
        else:
            #self.model.log.debug('ptypes=%s' % types)
            pass
        return types

    def get_stats(self):
        msg = []
        types = self._get_types()
        for prop in types:
            nprop = prop.n
            if nprop:
                msg.append('  %-8s: %i' % (prop.type, nprop))
        return msg

    def write_bdf(self, f, size=8, property_id=None):
        f.write('$PROPERTIES_SHELL\n')
        types = self._get_types()
        for prop in types:
            #print('*SHELL', prop.type)
            prop.write_bdf(f, size=size, property_id=property_id)
예제 #5
0
    def __init__(self):
        """creates the attributes for the BDF"""
        self._nastran_format = 'msc'
        self.is_nx = False
        self.is_msc = True
        self.max_int = 100000000

        #----------------------------------------
        self._is_cards_dict = True
        self.punch = None
        self.reject_lines = []

        self.set_precision()
        #----------------------------------------
        self.grid = GRID(self)
        self.grdset = GRDSET(self)
        self.point = POINT(self)
        self.grdset = GRDSET(self)
        self.spoint = SPOINT(self)
        self.epoint = EPOINT(self)
        self.pointax = POINTAX(self)
        self.coords = Coord(self)
        #----------------------------------------

        # springs
        self.pelas = PELAS(self)
        self.celas1 = CELAS1(self)
        self.celas2 = CELAS2(self)
        self.celas3 = CELAS3(self)
        self.celas4 = CELAS4(self)
        self.elements_spring = ElementsSpring(self)

        # rods/tubes
        self.prod = PROD(self)
        self.crod = CROD(self)
        self.conrod = CONROD(self)
        self.ptube = PTUBE(self)
        self.ctube = CTUBE(self)

        # bars
        self.cbar = CBAR(self)
        #self.cbaror = CBAROR(self)
        self.pbar = PBAR(self)
        self.pbarl = PBARL(self)
        self.properties_bar = PropertiesBar(self)

        # beams
        self.cbeam = CBEAM(self)
        self.pbeam = PBEAM(self)
        self.pbeaml = PBEAML(self)
        #: stores PBEAM, PBEAML
        self.properties_beam = PropertiesBeam(self)

        # shear
        #: stores CSHEAR
        self.cshear = CSHEAR(self)
        #: stores PSHEAR
        self.pshear = PSHEAR(self)

        # shells
        self.pshell = PSHELL(self)
        self.pcomp = PCOMP(self)
        self.pcompg = PCOMPG(self)
        self.cquad4 = CQUAD4(self)
        self.ctria3 = CTRIA3(self)
        self.ctria6 = CTRIA6(self)
        self.cquad8 = CQUAD8(self)
        self.ctriax6 = CTRIAX6(self)
        #self.cquad = CQUAD(self)
        #: stores PSHELL, PCOMP, PCOMPG
        self.properties_shell = PropertiesShell(self)
        #: stores CTRIA3, CTRIA6, CQUAD4, CQUAD8
        self.elements_shell = ElementsShell(self)

        # solids
        self.psolid = PSOLID(self)
        self.plsolid = PLSOLID(self)
        self.ctetra4 = CTETRA4(self)
        self.ctetra10 = CTETRA10(self)
        self.cpyram5 = None
        self.cpyram13 = None
        self.cpenta6 = CPENTA6(self)
        self.cpenta15 = CPENTA15(self)
        self.chexa8 = CHEXA8(self)
        self.chexa20 = CHEXA20(self)
        #: stores CTETRA4, CPENTA6, CHEXA8, CTETRA10, CPENTA15, CHEXA20
        self.elements_solid = ElementsSolid(self)
        #: stores PSOLID, PLSOLID
        self.properties_solid = PropertiesSolid(self)

        #----------------------------------------
        # mass
        self.conm1 = CONM1(self)
        self.conm2 = CONM2(self)
        #self.pmass = PMASS(self)
        #self.cmass1 = CMASS1(self)
        #self.cmass2 = CMASS2(self)
        #self.cmass3 = CMASS3(self)
        #self.cmass4 = CMASS4(self)
        #self.cmass5 = CMASS5(self)
        self.pmass = None
        self.cmass1 = None
        self.cmass2 = None
        self.cmass3 = None
        self.cmass4 = None
        self.cmass5 = None
        self.mass = Mass(self)
        #----------------------------------------
        # b-list elements
        #self.rbe2 = None
        #self.rbe3 = None
        self.cbush = CBUSH(self)
        self.pbush = PBUSH(self)
        self.cbush1d = None
        self.pbush1d = None
        self.cbush2d = None
        self.pbush2d = None

        #----------------------------------------
        # control structure
        self.elements = Elements(self)
        self.properties = Properties(self)
        #----------------------------------------

        self.mat1 = MAT1(self)
        self.mats1 = MATS1(self)
        #self.mat2 = MAT2(self)
        #self.mat2 = MAT2(self)
        #self.mat4 = MAT4(self)
        #self.mat5 = MAT5(self)
        self.mat8 = MAT8(self)
        #self.mat10 = MAT10(self)
        #self.mat11 = MAT11(self)
        self.mathp = MATHP(self)

        self.materials = Materials(self)

        # ----------------------------------------------------------------

        self.load = LOADs(self)
        self.dload = LOADs(self)
        #self.dload = defaultdict(list)
        #self.loadset = LOADSET(model)

        self.force = FORCE(self)
        self.force1 = FORCE1(self)
        self.force2 = FORCE2(self)
        self.moment = MOMENT(self)
        self.moment1 = MOMENT1(self)
        self.moment2 = MOMENT2(self)
        self.grav = GRAV(self)
        self.rforce = RFORCE(self)

        self.pload = PLOAD(self)
        self.pload1 = PLOAD1(self)
        self.pload2 = PLOAD2(self)
        #self.pload3 = PLOAD3(self)
        self.pload4 = PLOAD4(self)
        self.ploadx1 = PLOADX1(self)

        self.tload1 = TLOAD1(self)
        self.tload2 = TLOAD2(self)
        self.delay = DELAY(self)

        self.rload1 = RLOAD1(self)
        #self.rload2 = RLOAD2(self)
        self.dphase = DPHASE(self)

        self.darea = DAREA(self)

        #: stores LOAD, FORCE, MOMENT, etc.
        self.loads = Loads(self)
        # ----------------------------------------------------------------
        self.tempp1 = TEMPP1(self)
        self.temp = TEMP(self)
        self.temps = TEMPs(self)

        # ----------------------------------------------------------------
        #self.spc1 = SPC1(self)
        #self.spcadd = SPCADD(self)
        self.spc = {} #class_obj_defaultdict(SPC, model)
        self.spcd = {} #class_obj_defaultdict(SPCD, model)
        self.spc1 = {} #class_obj_defaultdict(SPC1, model)
        self.spcadd = {}
        self.mpc = {}  # the new form, not added...
        self.mpcadd = {}

        # ----------------------------------------------------------------
        #: stores PARAMs
        self.params = {}

        #: stores rigid elements (RBE2, RBE3, RJOINT, etc.)
        self.rigid_elements = {}
        #: stores PLOTELs
        self.plotels = {}

        # --------------------------- dynamic ----------------------------
        #: stores DAREA
        #self.dareas = {}
        #self.dphases = {}

        self.pbusht = {}
        self.pdampt = {}
        self.pelast = {}

        #: frequencies
        self.frequencies = {}

        # ----------------------------------------------------------------
        #: direct matrix input - DMIG
        self.dmis = {}
        self.dmigs = {}
        self.dmijs = {}
        self.dmijis = {}
        self.dmiks = {}
        self._dmig_temp = defaultdict(list)

        # ----------------------------------------------------------------
        #: SETy
        self.sets = {} # SET1, SET3
        self.asets = []
        self.bsets = []
        self.csets = []
        self.qsets = []
        self.usets = {}

        #: SExSETy
        self.se_bsets = []
        self.se_csets = []
        self.se_qsets = []
        self.se_usets = {}
        self.se_sets = {}

        # ----------------------------------------------------------------
        #: tables
        self.tables = {}
        #: random_tables
        self.random_tables = {}
        #: TABDMP1
        self.tables_sdamping = {}

        # ----------------------------------------------------------------
        #: EIGB, EIGR, EIGRL methods
        self.methods = {}
        # EIGC, EIGP methods
        self.cMethods = {}

        # ---------------------------- optimization --------------------------
        # optimization
        self.dconadds = {}
        self.dconstrs = {}
        self.desvars = {}
        self.ddvals = {}
        self.dlinks = {}
        self.dresps = {}

        self.dtable = None
        self.dequations = {}

        #: stores DVPREL1, DVPREL2...might change to DVxRel
        self.dvprels = {}
        self.dvmrels = {}
        self.dvcrels = {}
        self.dvgrids = {}
        self.doptprm = None
        self.dscreen = {}

        # ------------------------- nonlinear defaults -----------------------
        #: stores NLPCI
        self.nlpcis = {}
        #: stores NLPARM
        self.nlparms = {}
        #: stores TSTEPs
        self.tsteps = {}
        #: stores TSTEPNL
        self.tstepnls = {}
        #: stores TF
        self.transfer_functions = {}
        #: stores DELAY
        self.delays = {}

        # --------------------------- aero defaults --------------------------
        # aero cards
        #: stores CAEROx
        self.caeros = {}
        #: stores PAEROx
        self.paeros = {}
        # stores MONPNT1
        self.monitor_points = []

        #: stores AECOMP
        self.aecomps = {}
        #: stores AEFACT
        self.aefacts = {}
        #: stores AELINK
        self.aelinks = {}
        #: stores AELIST
        self.aelists = {}
        #: stores AEPARAM
        self.aeparams = {}
        #: stores AESURF
        self.aesurf = {}
        #: stores AESURFS
        self.aesurfs = {}
        #: stores AESTAT
        self.aestats = {}
        #: stores CSSCHD
        self.csschds = {}

        #: store SPLINE1,SPLINE2,SPLINE4,SPLINE5
        self.splines = {}

        # ------ SOL 144 ------
        #: stores AEROS
        self.aeros = None

        #: stores TRIM
        self.trims = {}

        #: stores DIVERG
        self.divergs = {}

        # ------ SOL 145 ------
        #: stores AERO
        self.aero = None

        #: stores FLFACT
        self.flfacts = {}  #: .. todo:: can this be simplified ???
        #: stores FLUTTER
        self.flutters = {}
        #: mkaeros
        self.mkaeros = []

        # ------ SOL 146 ------
        #: stores GUST cards
        self.gusts = {}
        # ------------------------- thermal defaults -------------------------
        # BCs
        #: stores thermal boundary conditions - CONV,RADBC
        self.bcs = {}  # e.g. RADBC

        #: stores PHBDY
        self.phbdys = {}
        #: stores convection properties - PCONV, PCONVM ???
        self.convection_properties = {}
        #: stores TEMPD
        self.tempds = {}

        # -------------------------contact cards-------------------------------
        self.bcrparas = {}
        self.bctadds = {}
        self.bctparas = {}
        self.bctsets = {}
        self.bsurf = {}
        self.bsurfs = {}

        # ---------------------------------------------------------------------

        self._type_to_id_map = defaultdict(list)
        self._solmap_to_value = {
            'NONLIN': 101,  # 66 -> 101 per Reference 1
            'SESTATIC': 101,
            'SESTATICS': 101,
            'SEMODES': 103,
            'BUCKLING': 105,
            'SEBUCKL': 105,
            'NLSTATIC': 106,
            'SEDCEIG': 107,
            'SEDFREQ': 108,
            'SEDTRAN': 109,
            'SEMCEIG': 110,
            'SEMFREQ': 111,
            'SEMTRAN': 112,
            'CYCSTATX': 114,
            'CYCMODE': 115,
            'CYCBUCKL': 116,
            'CYCFREQ': 118,
            'NLTRAN': 129,
            'AESTAT': 144,
            'FLUTTR': 145,
            'SEAERO': 146,
            'NLSCSH': 153,
            'NLTCSH': 159,
            'DBTRANS': 190,
            'DESOPT': 200,

            # guessing
            #'CTRAN' : 115,
            'CFREQ' : 118,

            # solution 200 names
            'STATICS': 101,
            'MODES': 103,
            'BUCK': 105,
            'DFREQ': 108,
            'MFREQ': 111,
            'MTRAN': 112,
            'DCEIG': 107,
            'MCEIG': 110,
            #'HEAT'     : None,
            #'STRUCTURE': None,
            #'DIVERGE'  : None,
            'FLUTTER': 145,
            'SAERO': 146,
        }

        self.rsolmap_to_str = {
            66: 'NONLIN',
            101: 'SESTSTATIC',  # linear static
            103: 'SEMODES',  # modal
            105: 'BUCKLING',  # buckling
            106: 'NLSTATIC',  # non-linear static
            107: 'SEDCEIG',  # direct complex frequency response
            108: 'SEDFREQ',  # direct frequency response
            109: 'SEDTRAN',  # direct transient response
            110: 'SEMCEIG',  # modal complex eigenvalue
            111: 'SEMFREQ',  # modal frequency response
            112: 'SEMTRAN',  # modal transient response
            114: 'CYCSTATX',
            115: 'CYCMODE',
            116: 'CYCBUCKL',
            118: 'CYCFREQ',
            129: 'NLTRAN',  # nonlinear transient
            144: 'AESTAT',  # static aeroelastic
            145: 'FLUTTR',  # flutter/aeroservoelastic
            146: 'SEAERO',  # dynamic aeroelastic
            153: 'NLSCSH',  # nonlinear static thermal
            159: 'NLTCSH',  # nonlinear transient thermal
            190: 'DBTRANS',
            200: 'DESOPT',  # optimization
        }