示例#1
0
class MFnMultiPlotAdapter(MFnPlotAdapter):
    """ The base class for adapting function implementation in order to plot
    it in a plotting toolkit (either Chaco or Matplotlib)
    """

    # rr: test only, needs to be written in a more robust way
    mline_style = List(100 * ['solid'])

    mline_color = List(100 * ['black'])

    mline_width = List(100 * [2.0])
示例#2
0
class MFnMultiLine(HasTraits):

    # Public Traits
    lines = List( MFnLineArray )
    
    xdata = Property( List( Array ) ) 
    def _get_xdata(self):
        return [ mfn.xdata for mfn in self.lines ]
    
    ydata = Property( List( Array ) ) 
    def _get_ydata(self):
        return [ mfn.ydata for mfn in self.lines ]
    
    data_changed = Event
示例#3
0
class ECBLFBM(ECBLBase):
    '''Effective crack bridge Law based on fiber-bundle-model.'''

    sig_tex_u = Float(1216, input=True)
    eps_tex_u = Float(0.014, input=True)
    m = Float(0.5, input=True)

    cnames = ['eps_tex_u', 'm']

    u0 = List([0.01266923, 0.5])

    eps_arr = Property(depends_on='+input')

    @cached_property
    def _get_eps_arr(self):
        return np.linspace(0, self.eps_tex_u, num=100.)

    sig_arr = Property(depends_on='+input')

    @cached_property
    def _get_sig_arr(self):
        sig_tex_u = self.sig_tex_u
        eps_tex_u = self.eps_tex_u
        eps_arr = self.eps_arr
        m = self.m
        return (
            sig_tex_u / eps_tex_u / exp(-pow(exp(-log(m) / self.m), 1.0 * m)) *
            eps_arr *
            np.exp(-np.power(eps_arr / eps_tex_u * exp(-log(m) / m), 1.0 * m)))
示例#4
0
class ECBLLinear(ECBLBase):
    '''Effective crack bridge Law with linear elastic response.'''

    eps_tex_u = Float(0.01, enter_set=True, auto_set=False, input=True)
    E_tex = Float(80000, enter_set=True, auto_set=False, input=True)
    u0 = List([0.01, 80000.], enter_set=True, auto_set=False)

    sig_tex_u = Property(depends_on='+input')

    @cached_property
    def _get_sig_tex_u(self):
        return self.E_tex * self.eps_tex_u

    cnames = ['eps_tex_u', 'E_tex']

    eps_arr = Property(depends_on='+input')

    @cached_property
    def _get_eps_arr(self):
        return np.array([0., self.eps_tex_u])

    sig_arr = Property(depends_on='+input')

    @cached_property
    def _get_sig_arr(self):
        # with limit for eps_tex
        #
        return self.E_tex * self.eps_arr
示例#5
0
文件: wiki.py 项目: rosoba/simvisage
class WikiGen(HasTraits):

    rf_list = List([Filament,
                     CBClampedFiber,
                     CBInfiniteFiber,
                     CBShortFiber,
                     POClampedFiber,
                     POInfiniteFiber,
                     POShortFiber])

    max_x = Float(0.01, enter_set=True, auto_set=False, config_change=True)
    n_points = Int(200, enter_set=True, auto_set=False, config_change=True)

    def export_wiki(self):

        fname = os.path.join('wiki', 'rf.wiki')
        f = open(fname, 'w')

        for rf_class in self.rf_list:
            q = rf_class()

            f.write(str(q) + '\n')
            qname = q.__class__.__name__

            p.figure()
            q.plot(p, linewidth=2, color='navy')

            fig_fname = os.path.join('wiki', qname + '.png')
            p.savefig(fig_fname)
示例#6
0
class ECBLCubic(ECBLBase):
    '''Effective crack bridge Law using a cubic polynomial.'''

    sig_tex_u = Float(1250, input=True)
    eps_tex_u = Float(0.016, input=True)
    var_a = Float(-5e+6, input=True)

    cnames = ['eps_tex_u', 'var_a']

    u0 = List([0.016, -5000000.])

    eps_arr = Property(depends_on='+input')

    @cached_property
    def _get_eps_arr(self):
        return np.linspace(0, self.eps_tex_u, num=100.)

    sig_arr = Property(depends_on='+input')

    @cached_property
    def _get_sig_arr(self):
        # for horizontal tangent at eps_tex_u
        sig_tex_u, var_a, eps_tex_u = self.sig_tex_u, self.var_a, self.eps_tex_u
        eps_arr = self.eps_arr
        var_b = -(sig_tex_u + 2. * var_a * eps_tex_u**3.) / eps_tex_u**2.
        var_c = -3. * var_a * eps_tex_u**2. - 2. * var_b * eps_tex_u
        sig_arr = var_a * eps_arr**3. + var_b * eps_arr**2. + var_c * eps_arr
        return sig_arr
示例#7
0
文件: rv_view.py 项目: simvisage/bmcs
class RVModelView(ModelView):
    '''
    ModelView class for displaying the table of parameters and
    set the distribution parameters of random variables
    '''

    title = Str('randomization setup')

    model = Instance(SPIRRID)

    rv_list = List(RIDVariable)

    @on_trait_change('model.rf')
    def get_rv_list(self):
        self.rv_list = [
            RIDVariable(s=self.model,
                        rf=self.model.rf,
                        varname=nm,
                        trait_value=st) for nm, st in
            zip(self.model.rf.param_keys, self.model.rf.param_values)
        ]

    selected_var = Instance(RIDVariable)

    def _selected_var_default(self):
        return self.rv_list[0]

    title = Str('random variable editor')

    selected_var = Instance(RIDVariable)

    traits_view = View(VSplit(
        HGroup(
            Item('rv_list', editor=rv_list_editor, show_label=False),
            id='rid.tview.randomization.rv',
            label='Model variables',
        ),
        HGroup(
            Item('selected_var@', show_label=False, resizable=True),
            id='rid.tview.randomization.distr',
            label='Distribution',
        ),
        scrollable=True,
        id='rid.tview.tabs',
        dock='tab',
    ),
                       title='RANDOM VARIABLES',
                       id='rid.ridview',
                       dock='tab',
                       resizable=True,
                       height=1.0,
                       width=1.0)
示例#8
0
class NDIdxInterp(HasTraits):

    # nd array of values (measured, computed..) of
    # size orthogonalize(axes_values)
    data = Array

    # list of control input parameter values
    axes_values = List(Array(float))

    def __call__(self, *gcoords, **kw):
        '''kw: dictionary of values to interpolate for;
        len(kw) has to be equal the data dimension
        '''
        order = kw.get('order', 1)
        mode = kw.get('mode', 'nearest')

        # check if the number of dimensions to interpolate
        # in equals the number of given coordinates
        if len(self.axes_values) != len(gcoords):
            raise TypeError('''method takes {req} arguments
            ({given} given)'''.format(req=len(self.axes_values),
                                      given=len(gcoords)))
        icoords = self.get_icoords(gcoords)

        # create a meshgrid for the interpolation
        icoords = orthogonalize_filled(icoords)
        data = self.data
        # interpolate the value (linear)
        # a, b, c = [0.5, 0.5, 0.5], [0, 0, 0], [0, 1, 2]
        # icoords = [a, b, c]
        val = ndimage.map_coordinates(data, icoords, order=order, mode=mode)
        return val

    def get_icoords(self, gcoords):
        '''
        gcoords: values to be interpolated for
        this method transforms the global coords to "index" coords
        '''
        icoords = [
            np.interp(gcoord, axis_values, np.arange(len(axis_values)))
            for gcoord, axis_values in zip(gcoords, self.axes_values)
        ]
        return icoords
示例#9
0
class ECBLBilinear(ECBLBase):
    '''Effective crack bridge Law using a cubic polynomial.'''

    sig_tex_u = Float(1250, input=True)
    eps_tex_u = Float(0.014, input=True)
    var_a = Float(50000, input=True)
    eps_el_fraction = Float(0.0001, input=True)

    cnames = ['eps_tex_u', 'var_a']

    u0 = List([0.014, 50000.])

    eps_arr = Property(depends_on='+input')

    @cached_property
    def _get_tex_arr(self):
        return np.hstack(
            [0., self.eps_el_fraction * self.eps_tex_u, self.eps_tex_u])

    sig_arr = Property(depends_on='+input')

    @cached_property
    def _get_sig_arr(self):
        return np.hstack([0., self.var_a * self.sig_tex_u, self.sig_tex_u])
示例#10
0
class LS(HasTraits):
    '''Limit state class
    '''

    # backward link to the info shell to access the
    # input data when calculating
    # the limit-state-specific values
    #
    ls_table = WeakRef

    # parameters of the limit state
    #
    dir = Enum(DIRLIST)
    stress_res = Enum(SRLIST)

    #-------------------------------
    # ls columns
    #-------------------------------
    # defined in the subclasses
    #
    ls_columns = List
    show_ls_columns = Bool(True)

    #-------------------------------
    # sr columns
    #-------------------------------

    # stress resultant columns - for ULS this is defined in the subclasses
    #
    sr_columns = List(['m', 'n'])
    show_sr_columns = Bool(True)

    # stress resultant columns - generated from the parameter combination
    # dir and stress_res - one of MX, NX, MY, NY
    #
    m_varname = Property(Str)

    def _get_m_varname(self):
        # e.g. mx_N
        appendix = self.dir + '_' + self.stress_res
        return 'm' + appendix

    n_varname = Property(Str)

    def _get_n_varname(self):
        # e.g. nx_N
        appendix = self.dir + '_' + self.stress_res
        return 'n' + appendix

    n = Property(Float)

    def _get_n(self):
        return getattr(self.ls_table, self.n_varname)

    m = Property(Float)

    def _get_m(self):
        return getattr(self.ls_table, self.m_varname)

    #-------------------------------
    # geo columns form info shell
    #-------------------------------

    geo_columns = List(['elem_no', 'X', 'Y', 'Z', 'D_elem'])
    show_geo_columns = Bool(True)

    elem_no = Property(Float)

    def _get_elem_no(self):
        return self.ls_table.elem_no

    X = Property(Float)

    def _get_X(self):
        return self.ls_table.X

    Y = Property(Float)

    def _get_Y(self):
        return self.ls_table.Y

    Z = Property(Float)

    def _get_Z(self):
        return self.ls_table.Z

    D_elem = Property(Float)

    def _get_D_elem(self):
        return self.ls_table.D_elem

    #-------------------------------
    # state columns form info shell
    #-------------------------------


#    state_columns = List( ['mx', 'my', 'mxy', 'nx', 'ny', 'nxy' ] )
    state_columns = List([
        'mx',
        'my',
        'mxy',
        'nx',
        'ny',
        'nxy',
        'sigx_lo',
        'sigy_lo',
        'sigxy_lo',
        'sig1_lo',
        'sig2_lo',
        'alpha_sig_lo',
        'sigx_up',
        'sigy_up',
        'sigxy_up',
        'sig1_up',
        'sig2_up',
        'alpha_sig_up',
    ])

    show_state_columns = Bool(True)

    mx = Property(Float)

    def _get_mx(self):
        return self.ls_table.mx

    my = Property(Float)

    def _get_my(self):
        return self.ls_table.my

    mxy = Property(Float)

    def _get_mxy(self):
        return self.ls_table.mxy

    nx = Property(Float)

    def _get_nx(self):
        return self.ls_table.nx

    ny = Property(Float)

    def _get_ny(self):
        return self.ls_table.ny

    nxy = Property(Float)

    def _get_nxy(self):
        return self.ls_table.nxy

    # evaluate principal stresses
    # upper face:
    #
    sigx_up = Property(Float)

    def _get_sigx_up(self):
        return self.ls_table.sigx_up

    sigy_up = Property(Float)

    def _get_sigy_up(self):
        return self.ls_table.sigy_up

    sigxy_up = Property(Float)

    def _get_sigxy_up(self):
        return self.ls_table.sigxy_up

    sig1_up = Property(Float)

    def _get_sig1_up(self):
        return self.ls_table.sig1_up

    sig2_up = Property(Float)

    def _get_sig2_up(self):
        return self.ls_table.sig2_up

    alpha_sig_up = Property(Float)

    def _get_alpha_sig_up(self):
        return self.ls_table.alpha_sig_up

    # lower face:
    #
    sigx_lo = Property(Float)

    def _get_sigx_lo(self):
        return self.ls_table.sigx_lo

    sigy_lo = Property(Float)

    def _get_sigy_lo(self):
        return self.ls_table.sigy_lo

    sigxy_lo = Property(Float)

    def _get_sigxy_lo(self):
        return self.ls_table.sigxy_lo

    sig1_lo = Property(Float)

    def _get_sig1_lo(self):
        return self.ls_table.sig1_lo

    sig2_lo = Property(Float)

    def _get_sig2_lo(self):
        return self.ls_table.sig2_lo

    alpha_sig_lo = Property(Float)

    def _get_alpha_sig_lo(self):
        return self.ls_table.alpha_sig_lo

    #-------------------------------
    # ls table
    #-------------------------------

    # all columns associated with the limit state including the corresponding
    # stress resultants
    #
    columns = Property(List,
                       depends_on='show_geo_columns, show_state_columns,\
                                             show_sr_columns, show_ls_columns')

    @cached_property
    def _get_columns(self):
        columns = []

        if self.show_geo_columns:
            columns += self.geo_columns

        if self.show_state_columns:
            columns += self.state_columns

        if self.show_sr_columns:
            columns += self.sr_columns

        if self.show_ls_columns:
            columns += self.ls_columns

        return columns

    # select column used for sorting the data in selected sorting order
    #
    sort_column = Enum(values='columns')

    def _sort_column_default(self):
        return self.columns[-1]

    sort_order = Enum('descending', 'ascending', 'unsorted')

    #-------------------------------------------------------
    # get the maximum value of the selected variable
    # 'max_in_column' of the current sheet (only one sheet)
    #-------------------------------------------------------

    # get the maximum value of the chosen column
    #
    max_in_column = Enum(values='columns')

    def _max_in_column_default(self):
        return self.columns[-1]

    max_value = Property(depends_on='max_in_column')

    def _get_max_value(self):
        col = getattr(self, self.max_in_column)[:, 0]
        return max(col)

    #-------------------------------------------------------
    # get the maximum value and the corresponding case of
    # the selected variable 'max_in_column' in all (!) sheets
    #-------------------------------------------------------

    max_value_all = Property(depends_on='max_in_column')

    def _get_max_value_all(self):
        return self.ls_table.max_value_and_case[
            self.max_in_column]['max_value']

    max_case = Property(depends_on='max_in_column')

    def _get_max_case(self):
        return self.ls_table.max_value_and_case[self.max_in_column]['max_case']

    #-------------------------------------------------------
    # get ls_table for View
    #-------------------------------------------------------

    # stack columns together for table used by TabularEditor
    #
    ls_array = Property(
        Array,
        depends_on='sort_column, sort_order, show_geo_columns, \
                                              show_state_columns, show_sr_columns, show_ls_columns'
    )

    @cached_property
    def _get_ls_array(self):

        arr_list = [getattr(self, col) for col in self.columns]

        # get the array currently selected by the sort_column enumeration
        #
        sort_arr = getattr(self, self.sort_column)[:, 0]
        sort_idx = argsort(sort_arr)
        ls_array = hstack(arr_list)

        if self.sort_order == 'descending':
            return ls_array[sort_idx[::-1]]
        if self.sort_order == 'ascending':
            return ls_array[sort_idx]
        if self.sort_order == 'unsorted':
            return ls_array

    #---------------------------------
    # plot outputs in mlab-window
    #---------------------------------

    plot_column = Enum(values='columns')
    plot = Button

    def _plot_fired(self):
        X = self.ls_table.X[:, 0]
        Y = self.ls_table.Y[:, 0]
        Z = self.ls_table.Z[:, 0]
        plot_col = getattr(self, self.plot_column)[:, 0]

        if self.plot_column == 'n_tex':
            plot_col = where(plot_col < 0, 0, plot_col)

        mlab.figure(figure="SFB532Demo",
                    bgcolor=(1.0, 1.0, 1.0),
                    fgcolor=(0.0, 0.0, 0.0))

        mlab.points3d(
            X,
            Y,
            (-1.0) * Z,
            plot_col,
            #                       colormap = "gist_rainbow",
            #                       colormap = "Reds",
            colormap="YlOrBr",
            mode="cube",
            scale_factor=0.15)

        mlab.scalarbar(title=self.plot_column, orientation='vertical')

        mlab.show

    # name of the trait that is used to assess the evaluated design
    #
    assess_name = Str('')

    #-------------------------------
    # ls group
    #-------------------------------

    # @todo: the dynamic selection of the columns to be displayed
    # does not work in connection with the LSArrayAdapter
    ls_group = VGroup(
        HGroup(  #Item( 'assess_name' ),
            Item('max_in_column'),
            Item('max_value', style='readonly', format_str='%6.2f'),
            Item('max_value_all', style='readonly', format_str='%6.2f'),
            Item('max_case', style='readonly', label='found in case: '),
        ),
        HGroup(
            Item('sort_column'),
            Item('sort_order'),
            Item('show_geo_columns', label='show geo'),
            Item('show_state_columns', label='show state'),
            Item('show_sr_columns', label='show sr'),
            Item('plot_column'),
            Item('plot'),
        ),
    )
示例#11
0
class Randomization( HasTraits ):
    '''Multidimensional statistical integration.
    
    Its name SPIRRID is an acronym for 
    Set of Parallel Independent Random Responses with Identical Distributions
    
    The package implements the evaluation of an integral over a set of 
    random variables affecting a response function RF and distributed 
    according to a probabilistic distribution PDistrib.
    
    The input parameters are devided in four categories in order
    to define state consistency of the evaluation. The outputs 
    are define as cached properties that are reevaluated in response
    to changes in the inputs.
    
    The following events accummulate changes in the input parameters of spirrid:
    rf_change - change in the response function
    rand_change - change in the randomization
    conf_change - change in the configuration of the algorithm
    eps_change - change in the studied range of the process control variable       
    '''
    #--------------------------------------------------------------------
    # Response function 
    #--------------------------------------------------------------------
    #
    rf = Instance( IRF )
    def _rf_changed( self ):
        self.on_trait_change( self._set_rf_change, 'rf.changed' )

    #--------------------------------------------------------------------
    # Specification of random parameters 
    #--------------------------------------------------------------------
    # 
    rv_list = Property( List( RandomVariable ), depends_on = 'rf_change' )
    @cached_property
    def _get_rv_list( self ):
        rf = self.rf
        param_tuple = zip( rf.param_keys, rf.param_values, rf.param_traits )
        return [ RandomVariable( spirrid = self, rf = self.rf,
                     name = nm, trait_value = tv, source_trait = st )
                 for nm, tv, st in param_tuple ]

    # key-based access to the random variables
    rv_dict = Property( Dict, depends_on = 'rf_change' )
    @cached_property
    def _get_rv_dict( self ):
        d = {}
        for rv in self.rv_list:
            d[rv.name] = rv
        return d

    def set_random( self, variable, distribution = 'uniform', discr_type = 'T grid',
                    loc = 0., scale = 1., shape = 1., n_int = 30 ):
        '''Declare a variable as random 
        '''
        self.rv_dict[ variable ].set_random( distribution, discr_type,
                                             loc, scale, shape, n_int )

    def unset_random( self, variable ):
        '''Delete declaration of random variable
        '''
        self.rv_dict[ variable ].unset_random()

    def unset_all_random( self ):
        '''Set all variables to detereministic'''
        map( lambda rv: rv.unset_random, self.rv_list )

    n_rv = Property( depends_on = 'rnd_change' )
    @cached_property
    def _get_n_rv( self ):
        return self.rv_random_keys.size

    # subsidiary methods for sorted access to the random variables.
    # (note dictionary has not defined order of its items)
    rv_random_keys = Property( List, depends_on = 'rf_change' )
    @cached_property
    def _get_rv_random_keys( self ):
        random_pattern = array( [ rv.random for rv in self.rv_list ], dtype = bool )
        ridx = where( random_pattern == True )[0]
        return self.rv_keys[ ridx ]

    # subsidiary methods for sorted access to the random variables.
    # (note dictionary has not defined order of its items)
    rv_keys = Property( List, depends_on = 'rf_change' )
    @cached_property
    def _get_rv_keys( self ):
        return array( self.rf.param_keys )

    #--------------------------------------------------------------------
    # Define which changes in the response function and in the 
    # statistical parameters are relevant for reevaluation of the response
    #--------------------------------------------------------------------
    rf_change = Event
    @on_trait_change( 'rf.changed' )
    def _set_rf_change( self ):
        self.rf_change = True

    rand_change = Event
    @on_trait_change( 'rv_list, rv_list.changed' )
    def _set_rand_change( self ):
        self.rand_change = True

    conf_change = Event
    @on_trait_change( '+alg_option' )
    def _set_conf_change( self ):
        self.conf_change = True

    eps_change = Event
    @on_trait_change( '+eps_range' )
    def _set_eps_change( self ):
        self.eps_change = True

    # List of discretized statistical domains
    # 
    theta_arr_list = Property( depends_on = 'rf_change, rand_change' )
    @cached_property
    def _get_theta_arr_list( self ):
        '''Get list of arrays with discretized RandomVariables.
        '''
        return [ rv.theta_arr for rv in self.rv_list ]

    # Discretized statistical domain
    # 
    theta_ogrid = Property( depends_on = 'rf_change, rand_change' )
    @cached_property
    def _get_theta_ogrid( self ):
        '''Get orthogonal list of arrays with discretized RandomVariables.
        '''
        return orthogonalize( self.theta_arr_list )

    #---------------------------------------------------------------------------------
    # PDF * Theta arrays oriented in enumerated dimensions - broadcasting possible
    #---------------------------------------------------------------------------------
    dG_ogrid = Property( depends_on = 'rf_change, rand_change' )
    @cached_property
    def _get_dG_ogrid( self ):
        '''Get orthogonal list of arrays with PDF * Theta product of.
        '''
        dG_arr_list = [ rv.dG_arr for rv in self.rv_list ]
        return orthogonalize( dG_arr_list )

    #---------------------------------------------------------------------------------
    # PDF grid - mutually multiplied arrays of PDF
    #---------------------------------------------------------------------------------
    dG_grid = Property( depends_on = 'rf_change, rand_change' )
    @cached_property
    def _get_dG_grid( self ):
        if len( self.dG_ogrid ):
            return reduce( lambda x, y: x * y, self.dG_ogrid )
        else:
            return 1.0
示例#12
0
class RunTable(SimDBClass):
    '''Manage the combinations of exec configurations and randomization patterns.
    '''

    name = Str(simdb=True)

    memsize = Float(1e4, simdb=True)

    s = Property(Instance(SPIRRID), depends_on='rf')

    @cached_property
    def _get_s(self):
        return SPIRRID(rf=self.rf,
                       min_eps=0.00,
                       max_eps=1.0,
                       n_eps=20,
                       compiler_verbose=0)

    rf = Instance(IRF, simdb=True)

    config_list = List(config=True)

    def _config_list_default(self):
        return ['I', 'IV']

    config_dict = Property(depends_on='config_list')

    @cached_property
    def _get_config_dict(self):
        cd = {}
        for config_idx in self.config_list:
            cd[config_idx] = config_dict[config_idx]
        return cd

    rand_list = List(rand=True)

    run_arr = Property(Array, depends_on='+rand,+config')

    @cached_property
    def _get_run_arr(self):
        # generate the runs to be performed
        run_table = [[
            SingleRun(run_table=self, config=config, rand_idx_arr=rand_idx_arr)
            for rand_idx_arr in self.rand_list
        ] for config in self.config_dict.items()]

        return array(run_table)

    exec_time_arr = Array
    n_int_arr = Array
    real_memsize_arr = Array

    calculate = Button()

    def _calculate_fired(self):
        s = self.run_arr.shape
        self.exec_time_arr = array(
            [run.exec_time for run in self.run_arr.flatten()]).reshape(s)
        self.n_int_arr = array([run.n_int
                                for run in self.run_arr.flatten()]).reshape(s)
        self.real_memsize_arr = array(
            [run.real_memsize for run in self.run_arr.flatten()]).reshape(s)
        self.save()
        self._redraw_fired()

    clear = Button()

    def _clear_fired(self):
        figure = self.figure
        figure.clear()
        self.data_changed = True

    figure = Instance(Figure, transient=True)

    def _figure_default(self):
        figure = Figure(facecolor='white')
        #figure.add_axes( [0.08, 0.13, 0.85, 0.74] )
        return figure

    data_changed = Event(True)

    normalized_numpy = Bool(True)
    c_code = Bool(False)

    redraw = Button()

    def _redraw_fired(self):
        figure = self.figure
        axes = figure.gca()
        self.plot(axes)
        self.data_changed = True

    redraw_in_window = Button()

    def _redraw_in_window_fired(self):
        figure = plt.figure(0)
        axes = figure.gca()
        self.plot(axes)
        plt.show()

    def plot(self, ax):

        exec_time_arr = self.exec_time_arr
        n_int_arr = self.n_int_arr[0, :]
        real_memsize_arr = self.real_memsize_arr[0, :]

        rand_arr = arange(len(self.rand_list)) + 1
        width = 0.45

        if exec_time_arr.shape[0] == 1:
            shift = width / 2.0
            ax.bar(rand_arr - shift,
                   exec_time_arr[0, :],
                   width,
                   color='lightgrey')

        elif self.exec_time_arr.shape[0] == 2:
            max_exec_time = nmax(exec_time_arr)

            ax.set_ylabel('$\mathrm{execution \, time \, [sec]}$', size=20)
            ax.set_xlabel(
                '$n_{\mathrm{rnd}}  \;-\; \mathrm{number \, of \, random \, parameters}$',
                size=20)

            ax.bar(rand_arr - width,
                   exec_time_arr[0, :],
                   width,
                   hatch='/',
                   color='white',
                   label='C')  # , color = 'lightgrey' )
            ax.bar(rand_arr,
                   exec_time_arr[1, :],
                   width,
                   color='lightgrey',
                   label='numpy')

            yscale = 1.25
            ax_xlim = rand_arr[-1] + 1
            ax_ylim = max_exec_time * yscale

            ax.set_xlim(0, ax_xlim)
            ax.set_ylim(0, ax_ylim)

            ax2 = ax.twinx()
            ydata = exec_time_arr[1, :] / exec_time_arr[0, :]
            ax2.plot(rand_arr,
                     ydata,
                     '-o',
                     color='black',
                     linewidth=1,
                     label='numpy/C')

            ax2.plot([rand_arr[0] - 1, rand_arr[-1] + 1], [1, 1], '-')
            ax2.set_ylabel(
                '$\mathrm{time}(  \mathsf{numpy}  ) / \mathrm{ time }(\mathsf{C}) \; [-]$',
                size=20)
            ax2_ylim = nmax(ydata) * yscale
            ax2_xlim = rand_arr[-1] + 1
            ax2.set_ylim(0, ax2_ylim)
            ax2.set_xlim(0, ax2_xlim)

            ax.set_xticks(rand_arr)
            ax.set_xticklabels(rand_arr, size=14)
            xticks = ['%.2g' % n_int for n_int in n_int_arr]
            ax3 = ax.twiny()
            ax3.set_xlim(0, rand_arr[-1] + 1)
            ax3.set_xticks(rand_arr)
            ax3.set_xlabel('$n_{\mathrm{int}}$', size=20)
            ax3.set_xticklabels(xticks, rotation=30)

            'set the tick label size of the lower X axis'
            X_lower_tick = 14
            xt = ax.get_xticklabels()
            for t in xt:
                t.set_fontsize(X_lower_tick)

            'set the tick label size of the upper X axis'
            X_upper_tick = 12
            xt = ax3.get_xticklabels()
            for t in xt:
                t.set_fontsize(X_upper_tick)

            'set the tick label size of the Y axes'
            Y_tick = 14
            yt = ax2.get_yticklabels() + ax.get_yticklabels()
            for t in yt:
                t.set_fontsize(Y_tick)

            'set the legend position and font size'
            leg_fontsize = 16
            leg = ax.legend(loc=(0.02, 0.83))
            for t in leg.get_texts():
                t.set_fontsize(leg_fontsize)
            leg = ax2.legend(loc=(0.705, 0.90))
            for t in leg.get_texts():
                t.set_fontsize(leg_fontsize)

    traits_view = View(Item('name'),
                       Item('memsize'),
                       Item('rf'),
                       Item('config_dict'),
                       Item('rand_list'),
                       HGroup(
                           Item('calculate', show_label=False),
                           Item('redraw', show_label=False),
                           Item('clear', show_label=False),
                           Item('redraw_in_window', show_label=False),
                       ),
                       Item('figure',
                            editor=MPLFigureEditor(),
                            resizable=True,
                            show_label=False),
                       buttons=['OK', 'Cancel'])
示例#13
0
class ECBCrossSection(ECBCrossSectionState):
    '''Cross section characteristics needed for tensile specimens
    '''

    matrix_cs = Instance(ECBMatrixCrossSection)
    def _matrix_cs_default(self):
        return ECBMatrixCrossSection()

    reinf = List(ECBReinfComponent)
    '''Components of the cross section including the matrix and reinforcement.
    '''

    matrix_cs_with_state = Property(depends_on='matrix_cs')
    @cached_property
    def _get_matrix_cs_with_state(self):
        self.matrix_cs.state = self
        return self.matrix_cs

    reinf_components_with_state = Property(depends_on='reinf')
    '''Components linked to the strain state of the cross section
    '''
    @cached_property
    def _get_reinf_components_with_state(self):
        for r in self.reinf:
            r.state = self
            r.matrix_cs = self.matrix_cs
        return self.reinf

    height = DelegatesTo('matrix_cs')

    unit_conversion_factor = Constant(1000.0)

    '''Convert the MN to kN
    '''

    #===========================================================================
    # State management
    #===========================================================================
    changed = Event
    '''Notifier of a changed in some component of a cross section
    '''

    @on_trait_change('+eps_input')
    def _notify_eps_change(self):
        self.changed = True
        self.matrix_cs.eps_changed = True
        for c in self.reinf:
            c.eps_changed = True

    #===========================================================================
    # Cross-sectional stress resultants
    #===========================================================================

    N = Property(depends_on='changed')
    '''Get the resulting normal force.
    '''
    @cached_property
    def _get_N(self):
        N_matrix = self.matrix_cs_with_state.N
        return N_matrix + np.sum([c.N for c in self.reinf_components_with_state])

    M = Property(depends_on='changed')
    '''Get the resulting moment.
    '''
    @cached_property
    def _get_M(self):
        M_matrix = self.matrix_cs_with_state.M
        M = M_matrix + np.sum([c.M for c in self.reinf_components_with_state])
        return M - self.N * self.height / 2.

    figure = Instance(Figure)
    def _figure_default(self):
        figure = Figure(facecolor='white')
        figure.add_axes([0.08, 0.13, 0.85, 0.74])
        return figure

    data_changed = Event

    replot = Button
    def _replot_fired(self):

        self.figure.clear()
        ax = self.figure.add_subplot(2, 2, 1)
        self.plot_eps(ax)

        ax = self.figure.add_subplot(2, 2, 2)
        self.plot_sig(ax)

        ax = self.figure.add_subplot(2, 2, 3)
        self.cc_law.plot(ax)

        ax = self.figure.add_subplot(2, 2, 4)
        self.ecb_law.plot(ax)

        self.data_changed = True

    def plot_eps(self, ax):
        # ax = self.figure.gca()

        d = self.thickness
        # eps ti
        ax.plot([-self.eps_lo, -self.eps_up], [0, self.thickness], color='black')
        ax.hlines(self.zz_ti_arr, [0], -self.eps_ti_arr, lw=4, color='red')

        # eps cj
        ec = np.hstack([self.eps_cj_arr] + [0, 0])
        zz = np.hstack([self.zz_cj_arr] + [0, self.thickness ])
        ax.fill(-ec, zz, color='blue')

        # reinforcement layers
        eps_range = np.array([max(0.0, self.eps_lo),
                              min(0.0, self.eps_up)], dtype='float')
        z_ti_arr = np.ones_like(eps_range)[:, None] * self.z_ti_arr[None, :]
        ax.plot(-eps_range, z_ti_arr, 'k--', color='black')

        # neutral axis
        ax.plot(-eps_range, [d, d], 'k--', color='green', lw=2)

        ax.spines['left'].set_position('zero')
        ax.spines['right'].set_color('none')
        ax.spines['top'].set_color('none')
        ax.spines['left'].set_smart_bounds(True)
        ax.spines['bottom'].set_smart_bounds(True)
        ax.xaxis.set_ticks_position('bottom')
        ax.yaxis.set_ticks_position('left')

    def plot_sig(self, ax):

        d = self.thickness
        # f ti
        ax.hlines(self.zz_ti_arr, [0], -self.f_ti_arr, lw=4, color='red')

        # f cj
        f_c = np.hstack([self.f_cj_arr] + [0, 0])
        zz = np.hstack([self.zz_cj_arr] + [0, self.thickness ])
        ax.fill(-f_c, zz, color='blue')

        f_range = np.array([np.max(self.f_ti_arr), np.min(f_c)], dtype='float_')
        # neutral axis
        ax.plot(-f_range, [d, d], 'k--', color='green', lw=2)

        ax.spines['left'].set_position('zero')
        ax.spines['right'].set_color('none')
        ax.spines['top'].set_color('none')
        ax.spines['left'].set_smart_bounds(True)
        ax.spines['bottom'].set_smart_bounds(True)
        ax.xaxis.set_ticks_position('bottom')
        ax.yaxis.set_ticks_position('left')

    view = View(HSplit(Group(
                HGroup(
                Group(Item('thickness', springy=True),
                      Item('width'),
                      Item('n_layers'),
                      Item('n_rovings'),
                      Item('A_roving'),
                      label='Geometry',
                      springy=True
                      ),
                Group(Item('eps_up', label='Upper strain', springy=True),
                      Item('eps_lo', label='Lower strain'),
                      label='Strain',
                      springy=True
                      ),
                springy=True,
                ),
                HGroup(
                Group(VGroup(
                      Item('cc_law_type', show_label=False, springy=True),
                      Item('cc_law', label='Edit', show_label=False, springy=True),
                      Item('show_cc_law', label='Show', show_label=False, springy=True),
                      springy=True
                      ),
                      Item('f_ck', label='Compressive strength'),
                      Item('n_cj', label='Discretization'),
                      label='Concrete',
                      springy=True
                      ),
                Group(VGroup(
                      Item('ecb_law_type', show_label=False, springy=True),
                      Item('ecb_law', label='Edit', show_label=False, springy=True),
                      Item('show_ecb_law', label='Show', show_label=False, springy=True),
                      springy=True,
                      ),
                      label='Reinforcement',
                      springy=True
                      ),
                springy=True,
                ),
                Group(Item('s_tex_z', label='vertical spacing', style='readonly'),
                      label='Layout',
                      ),
                Group(
                HGroup(Item('M', springy=True, style='readonly'),
                       Item('N', springy=True, style='readonly'),
                       ),
                       label='Stress resultants'
                       ),
                scrollable=True,
                             ),
                Group(Item('replot', show_label=False),
                      Item('figure', editor=MPLFigureEditor(),
                           resizable=True, show_label=False),
                      id='simexdb.plot_sheet',
                      label='plot sheet',
                      dock='tab',
                      ),
                       ),
                width=0.8,
                height=0.7,
                resizable=True,
                buttons=['OK', 'Cancel'])
示例#14
0
class ECBLBase(CLBase):
    '''Base class for Effective Crack Bridge Laws.'''

    u0 = List([0.0, 0.0])
示例#15
0
 class Solver(HasTraits):
     title = Str('solver')
     solver_components = List()
示例#16
0
class CompositeCrackBridgeLoop(HasTraits):

    reinforcement_lst = List(Instance(Reinforcement))
    w = Float
    E_m = Float
    Ll = Float
    Lr = Float

    V_f_tot = Property(depends_on='reinforcement_lst+')

    @cached_property
    def _get_V_f_tot(self):
        V_f_tot = 0.0
        for reinf in self.reinforcement_lst:
            V_f_tot += reinf.V_f
        return V_f_tot

    E_c = Property(depends_on='reinforcement_lst+')

    @cached_property
    def _get_E_c(self):
        E_fibers = 0.0
        for reinf in self.reinforcement_lst:
            E_fibers += reinf.V_f * reinf.E_f
        return self.E_m * (1. - self.V_f_tot) + E_fibers

    sorted_theta = Property(depends_on='reinforcement_lst+')

    @cached_property
    def _get_sorted_theta(self):
        '''sorts the integral points by bond in descending order'''
        depsf_arr = np.array([])
        V_f_arr = np.array([])
        E_f_arr = np.array([])
        xi_arr = np.array([])
        stat_weights_arr = np.array([])
        nu_r_arr = np.array([])
        for reinf in self.reinforcement_lst:
            n_int = len(np.hstack((np.array([]), reinf.depsf_arr)))
            depsf_arr = np.hstack((depsf_arr, reinf.depsf_arr))
            V_f_arr = np.hstack((V_f_arr, np.repeat(reinf.V_f, n_int)))
            E_f_arr = np.hstack((E_f_arr, np.repeat(reinf.E_f, n_int)))
            xi_arr = np.hstack((xi_arr, np.repeat(reinf.xi, n_int)))
            stat_weights_arr = np.hstack(
                (stat_weights_arr, np.repeat(reinf.stat_weights, n_int)))
            nu_r_arr = np.hstack((nu_r_arr, reinf.nu_r))
        argsort = np.argsort(depsf_arr)[::-1]
        return depsf_arr[argsort], V_f_arr[argsort], E_f_arr[argsort], \
                xi_arr[argsort],  stat_weights_arr[argsort], \
                nu_r_arr[argsort]

    sorted_depsf = Property(depends_on='reinforcement_lst+')

    @cached_property
    def _get_sorted_depsf(self):
        return self.sorted_theta[0]

    sorted_V_f = Property(depends_on='reinforcement_lst+')

    @cached_property
    def _get_sorted_V_f(self):
        return self.sorted_theta[1]

    sorted_E_f = Property(depends_on='reinforcement_lst+')

    @cached_property
    def _get_sorted_E_f(self):
        return self.sorted_theta[2]

    sorted_xi = Property(depends_on='reinforcement_lst+')

    @cached_property
    def _get_sorted_xi(self):
        return self.sorted_theta[3]

    sorted_stats_weights = Property(depends_on='reinforcement_lst+')

    @cached_property
    def _get_sorted_stats_weights(self):
        return self.sorted_theta[4]

    sorted_nu_r = Property(depends_on='reinforcement_lst+')

    @cached_property
    def _get_sorted_nu_r(self):
        return self.sorted_theta[5]

    sorted_xi_cdf = Property(depends_on='reinforcement_lst+')

    @cached_property
    def _get_sorted_xi_cdf(self):
        '''breaking strain: CDF for random and Heaviside for discrete values'''
        # TODO: does not work for reinforcement types with the same xi
        methods = []
        masks = []
        for reinf in self.reinforcement_lst:
            masks.append(self.sorted_xi == reinf.xi)
            if isinstance(reinf.xi, FloatType):
                methods.append(lambda x: 1.0 * (reinf.xi <= x))
            elif isinstance(reinf.xi, RV):
                methods.append(reinf.xi._distr.cdf)
            elif isinstance(reinf.xi, WeibullFibers):
                methods.append(reinf.xi.weibull_fibers_Pf)
        return methods, masks

    def vect_xi_cdf(self, epsy, x_short, x_long):
        Pf = np.zeros_like(self.sorted_depsf)
        methods, masks = self.sorted_xi_cdf
        for i, method in enumerate(methods):
            if method.__name__ == 'weibull_fibers_Pf':
                Pf += method(epsy * masks[i],
                             self.sorted_depsf,
                             x_short=x_short,
                             x_long=x_long)
            else:
                Pf += method(epsy * masks[i])
        return Pf

    def dem_depsf(self, depsf, damage):
        '''evaluates the deps_m given deps_f
        at that point and the damage array'''
        Kf = self.sorted_V_f * self.sorted_nu_r * \
            self.sorted_stats_weights * self.sorted_E_f
        Kf_intact_bonded = np.sum(Kf * (depsf <= self.sorted_depsf) *
                                  (1. - damage))
        Kf_broken = np.sum(Kf * damage)
        Kf_add = Kf_intact_bonded + Kf_broken
        Km = (1. - self.V_f_tot) * self.E_m
        E_mtrx = Km + Kf_add
        mean_acting_T = np.sum(self.sorted_depsf *
                               (self.sorted_depsf < depsf) * Kf *
                               (1. - damage))
        return mean_acting_T / E_mtrx

    def double_sided(self, defi, x0, demi, em0, um0, damage):
        dxi = (-defi * x0 - demi * x0 +
               (defi * x0**2 * demi + demi**2 * x0**2 - 2 * defi * em0 * x0 +
                2 * defi * um0 + defi * self.w - 2 * demi * em0 * x0 +
                2 * demi * um0 + demi * self.w)**(.5)) / (defi + demi)
        dem = self.dem_depsf(defi, damage)
        emi = em0 + demi * dxi
        umi = um0 + (em0 + emi) * dxi / 2.
        return dxi, dem, emi, umi

    def one_sided(self, defi, x0, demi, em0, um0, clamped, damage):
        w = self.w
        xs = clamped[0]
        ums = clamped[1]
        dxi = (-xs * demi - demi * x0 - defi * xs - defi * x0 +
               (2 * demi * x0 * defi * xs + demi * x0**2 * defi +
                2 * demi**2 * x0 * xs + 3 * defi * xs**2 * demi -
                2 * demi * xs * em0 - 2 * demi * em0 * x0 -
                2 * defi * xs * em0 - 2 * defi * em0 * x0 + demi**2 * x0**2 +
                2 * defi**2 * xs**2 + xs**2 * demi**2 + 2 * demi * um0 +
                2 * demi * ums + 2 * demi * w + 2 * defi * um0 +
                2 * defi * ums + 2 * defi * w)**(0.5)) / (demi + defi)
        dem = self.dem_depsf(defi, damage)
        emi = em0 + demi * dxi
        umi = um0 + (em0 + emi) * dxi / 2.
        return dxi, dem, emi, umi

    def clamped(self, defi, xs, xl, ems, eml, ums, uml):
        c1 = eml * xl - uml
        c2 = ems * xs - ums
        c3 = defi * xl**2 / 2.
        c4 = defi * xs**2 / 2.
        c5 = (defi * (xl - xs) + (eml - ems)) * xs
        h = (self.w - c1 - c2 - c3 - c4 - c5) / (xl + xs)
        return defi * xl + eml + h

    def damage_residuum(self, iter_damage):
        um_short, em_short, x_short = [0.0], [0.0], [0.0]
        um_long, em_long, x_long = [0.0], [0.0], [0.0]
        init_dem = self.dem_depsf(np.infty, iter_damage)
        dem_short = [init_dem]
        dem_long = [init_dem]
        epsf0 = np.zeros_like(self.sorted_depsf)
        Lmin = min(self.Ll, self.Lr)
        Lmax = max(self.Ll, self.Lr)
        for i, defi in enumerate(self.sorted_depsf):
            if x_short[-1] < Lmin and x_long[-1] < Lmax:
                '''double sided pullout'''
                dxi, dem, emi, umi = self.double_sided(defi, x_short[-1],
                                                       dem_short[-1],
                                                       em_short[-1],
                                                       um_short[-1],
                                                       iter_damage)
                if x_short[-1] + dxi < Lmin:
                    # dx increment does not reach the boundary
                    dem_short.append(dem)
                    dem_long.append(dem)
                    x_short.append(x_short[-1] + dxi)
                    x_long.append(x_long[-1] + dxi)
                    em_short.append(emi)
                    em_long.append(emi)
                    um_short.append(umi)
                    um_long.append(umi)
                    epsf0[i] = (em_short[-1] + x_short[-1] * defi)
                else:
                    # boundary reached at shorter side
                    deltax = Lmin - x_short[-1]
                    x_short.append(Lmin)
                    em_short.append(em_short[-1] + dem_short[-1] * deltax)
                    um_short.append(um_short[-1] +
                                    (em_short[-2] + em_short[-1]) * deltax /
                                    2.)
                    short_side = [x_short[-1], um_short[-1]]
                    dxi, dem, emi, umi = self.one_sided(
                        defi, x_long[-1], dem_long[-1], em_long[-1],
                        um_long[-1], short_side, iter_damage)

                    if x_long[-1] + dxi >= Lmax:
                        # boundary reached at longer side
                        deltax = Lmax - x_long[-1]
                        x_long.append(Lmax)
                        em_long.append(em_long[-1] + dem_long[-1] * deltax)
                        um_long.append(um_long[-1] +
                                       (em_long[-2] + em_long[-1]) * deltax /
                                       2.)
                        epsf0_clamped = self.clamped(defi, x_short[-1],
                                                     x_long[-1], em_short[-1],
                                                     em_long[-1], um_short[-1],
                                                     um_long[-1])
                        epsf0[i] = epsf0_clamped
                    else:
                        dem_long.append(dem)
                        x_long.append(x_long[-1] + dxi)
                        em_long.append(emi)
                        um_long.append(umi)
                        epsf0[i] = (em_long[-1] + x_long[-1] * defi)

            elif x_short[-1] == Lmin and x_long[-1] < Lmax:
                #one sided pullout
                clamped = [x_short[-1], um_short[-1]]
                dxi, dem, emi, umi = self.one_sided(defi, x_long[-1],
                                                    dem_long[-1], em_long[-1],
                                                    um_long[-1], clamped,
                                                    iter_damage)
                if x_long[-1] + dxi < Lmax:
                    dem_long.append(dem)
                    x_long.append(x_long[-1] + dxi)
                    em_long.append(emi)
                    um_long.append(umi)
                    epsf0[i] = (em_long[-1] + x_long[-1] * defi)
                else:
                    dxi = Lmax - x_long[-1]
                    x_long.append(Lmax)
                    em_long.append(em_long[-1] + dem_long[-1] * dxi)
                    um_long.append(um_long[-1] +
                                   (em_long[-2] + em_long[-1]) * dxi / 2.)
                    epsf0_clamped = self.clamped(defi, x_short[-1], x_long[-1],
                                                 em_short[-1], em_long[-1],
                                                 um_short[-1], um_long[-1])
                    epsf0[i] = epsf0_clamped

            elif x_short[-1] == Lmin and x_long[-1] == Lmax:
                #clamped fibers
                epsf0_clamped = self.clamped(defi, x_short[-1], x_long[-1],
                                             em_short[-1], em_long[-1],
                                             um_short[-1], um_long[-1])
                epsf0[i] = epsf0_clamped
        self._x_arr = np.hstack(
            (-np.array(x_short)[::-1][:-1], np.array(x_long)))
        self._epsm_arr = np.hstack(
            (np.array(em_short)[::-1][:-1], np.array(em_long)))
        self._epsf0_arr = epsf0
        residuum = self.vect_xi_cdf(epsf0, x_short=x_short,
                                    x_long=x_long) - iter_damage
        return residuum

    _x_arr = Array

    def __x_arr_default(self):
        return np.repeat(1e-10, len(self.sorted_depsf))

    _epsm_arr = Array

    def __epsm_arr_default(self):
        return np.repeat(1e-10, len(self.sorted_depsf))

    _epsf0_arr = Array

    def __epsf0_arr_default(self):
        return np.repeat(1e-10, len(self.sorted_depsf))

    damage = Property(depends_on='w, Ll, Lr, reinforcement+')

    @cached_property
    def _get_damage(self):
        ff = time.clock()
        if self.w == 0.:
            damage = np.zeros_like(self.sorted_depsf)
        else:
            ff = t.clock()
            try:
                damage = broyden2(self.damage_residuum,
                                  0.2 * np.ones_like(self.sorted_depsf),
                                  maxiter=20)
            except:
                print 'broyden2 does not converge fast enough: switched to fsolve for this step'
                damage = fsolve(self.damage_residuum,
                                0.2 * np.ones_like(self.sorted_depsf))
            print 'damage =', np.sum(damage) / len(
                damage), 'iteration time =', time.clock() - ff, 'sec'
        return damage
示例#17
0
class ULS(LS):
    '''Ultimate limit state
    '''

    #--------------------------------------------------------
    # ULS: material parameters (Inputs)
    #--------------------------------------------------------

    # gamma-factor
    gamma = Float(1.5, input=True)

    # long term reduction factor
    beta = Float(1.0, input=True)

    # INDEX l: longitudinal direction of the textile (MAG-02-02-06a)
    # characteristic tensile strength of the tensile specimen [N/mm2]
    f_tk_l = Float(537, input=True)

    # design value of the tensile strength of the tensile specimen [N/mm2]
    # containing a gamma-factor of 1.5 and d long term reduction factor of 0.7
    # f_td_l = 251

    f_td_l = Property(Float, depends_on='+input')

    def _get_f_td_l(self):
        return self.beta * self.f_tk_l / self.gamma

    # cross sectional area of the reinforcement [mm2/m]
    a_t_l = Float(71.65, input=True)

    # INDEX q: orthogonal direction of the textile (MAG-02-02-06a)
    # characteristic tensile strength of the tensile specimen [N/mm2]
    f_tk_q = Float(511, input=True)

    # design value of the tensile strength of the tensile specimen [kN/m]
    # f_td_q = 238
    f_td_q = Property(Float, depends_on='+input')

    def _get_f_td_q(self):
        return self.beta * self.f_tk_q / self.gamma

    # cross sectional area of the reinforcement [mm2/m]
    a_t_q = Float(53.31, input=True)

    # tensile strength of the textile reinforcement [kN/m]
    f_Rtex_l = Property(Float, depends_on='+input')

    def _get_f_Rtex_l(self):
        return self.a_t_l * self.f_td_l / 1000.

    # tensile strength of the textile reinforcement [kN/m]
    f_Rtex_q = Property(Float)

    def _get_f_Rtex_q(self, depends_on='+input'):
        return self.a_t_q * self.f_td_q / 1000.

    # tensile strength of the textile reinforcement [kN/m]
    # as simplification the lower value of 0- and 90-direction is taken
    #
    # sig_composite,exp = 103.4 kN/14cm/6cm = 12.3 MPa
    # f_tex,exp = 103.4 kN/14cm/12layers = 61.5 kN/m
    # f_tex,k = f_tex,exp * 0,81 (EN-DIN 1990) = 0.82*61.5 kN/m = 50.4 kN/m
    # f_tex,d = f_tex,k / 1,5 = 33.6 kN/m
    #
    f_Rtex_l = f_Rtex_q = 34.3
    print 'NOTE: f_Rtex_l = f_Rtex_q = set to %g kN/m !' % (f_Rtex_l)

    k_fl = 7.95 / 6.87
    print 'NOTE: k_fl = set to %g [-] !' % (k_fl)

    # ------------------------------------------------------------
    # ULS - derived params:
    # ------------------------------------------------------------

    # Parameters for the cracked state (GdT):
    # assumptions!

    # (resultierende statische Nutzhoehe)
    #
    d = Property(Float)

    def _get_d(self):
        return 0.75 * self.ls_table.D_elem

    # (Abstand Schwereachse zur resultierende Bewehrungslage)
    # chose the same amount of reinforcement at the top as at the bottom
    # i.e. zs = zs1 = zs2
    #
    zs = Property(Float)

    def _get_zs(self):
        return self.d - self.ls_table.D_elem / 2.

    # (Innerer Hebelarm)
    #
    z = Property(Float)

    def _get_z(self):
        return 0.9 * self.d

    # ------------------------------------------------------------
    # ULS: outputs
    # ------------------------------------------------------------

    ls_columns = List([
        'e', 'm_Eds', 'f_t', 'f_t_sig', 'beta_l', 'beta_q', 'f_Rtex',
        'k_fl_NM', 'n_tex'
    ])

    sr_columns = ['m', 'n', 'alpha', 'd', 'zs', 'z']

    alpha_varname = Property()

    def _get_alpha_varname(self):
        return 'alpha_' + self.stress_res

    alpha = Property

    def _get_alpha(self):
        return getattr(self.ls_table, self.alpha_varname)

    ls_values = Property(depends_on='+input')

    @cached_property
    def _get_ls_values(self):
        '''get the outputs for ULS
        '''
        #-------------------------------------------------
        # VAR 1:use simplified reinforced concrete approach
        #-------------------------------------------------
        n = self.n
        m = self.m
        alpha = self.alpha

        zs = self.zs
        z = self.z
        f_Rtex_l = self.f_Rtex_l
        f_Rtex_q = self.f_Rtex_q

        # (Exzentrizitaet)
        e = abs(m / n)
        e[n == 0] = 1E9  # if normal force is zero set e to very large value

        # moment at the height of the resulting reinforcement layer:
        m_Eds = abs(m) - zs * n

        # tensile force in the reinforcement for bending and compression
        f_t = m_Eds / z + n

        # check if the two conditions are true:
        cond1 = n > 0
        cond2 = e < zs
        bool_arr = cond1 * cond2
        # in case of pure tension in the cross section:
        f_t[bool_arr] = n[bool_arr] * (zs[bool_arr] + e[bool_arr]) / (
            zs[bool_arr] + zs[bool_arr])

        #-------------------------------------------------
        # VAR 2:use principal stresses to calculate the resulting tensile force
        #-------------------------------------------------
        #
        princ_stress_eval = True
        #        princ_stress_eval = False

        f_t_sig = self.sig1_lo * self.D_elem * 1000.
        if princ_stress_eval == True:
            print "NOTE: the principle tensile stresses are used to evaluate 'n_tex'"
            # resulting tensile force of the composite cross section[kN]
            # the entire (!) cross section is used!
            # as the maximum value of the tensile stresses at the top or the bottom
            # i.e. sig1_max = min( 0, max( self.sig1_up, self.sig1_lo ) )

            #---------------------------------------------------------
            # initialize arrays t be filled by case distinction:
            #---------------------------------------------------------
            #
            f_t_sig = zeros_like(self.sig1_up)
            alpha = zeros_like(self.sig1_up)

            k_fl_NM = ones_like(self.sig1_up)
            # absolute value of the bending stress created by mx or my
            sig_b = (abs(self.sig1_lo) + abs(self.sig1_up)) / 2

            #---------------------------------------------------------
            # conditions for case distinction
            #---------------------------------------------------------

            cond_t_up = self.sig1_up > 0.  # compression stress upper side
            cond_t_lo = self.sig1_lo > 0.  # compression stress lower side

            cond_u_gt_l = abs(self.sig1_up) > abs(
                self.sig1_lo
            )  # absolute value of upper stress greater then lower stress
            cond_l_gt_u = abs(self.sig1_lo) > abs(
                self.sig1_up
            )  # absolute value of lower stress greater then lower stress
            cond_u_eq_l = abs(self.sig1_up) == abs(
                self.sig1_lo
            )  # absolute values of upper stress equals lower stress

            cond_b = self.sig1_up * self.sig1_lo < 0  # bending case
            cond_u_gt_0 = self.sig1_up > 0  # value of upper stress greater then 0.
            cond_l_gt_0 = self.sig1_lo > 0  # value of lower stress greater then 0.

            cond_c_up = self.sig1_up < 0.  # compression stress upper side
            cond_c_lo = self.sig1_lo < 0.  # compression stress lower side

            #---------------------------------------------------------
            # tension case:
            #---------------------------------------------------------

            # sig_up > sig_lo
            bool_arr = cond_t_up * cond_t_lo * cond_u_gt_l
            alpha[bool_arr] = self.alpha_sig_up[bool_arr]
            k_fl_NM[bool_arr] = 1.0
            f_t_sig[bool_arr] = self.sig1_up[bool_arr] * self.D_elem[
                bool_arr] * 1000.

            # sig_lo > sig_up
            bool_arr = cond_t_up * cond_t_lo * cond_l_gt_u
            alpha[bool_arr] = self.alpha_sig_lo[bool_arr]
            k_fl_NM[bool_arr] = 1.0
            f_t_sig[bool_arr] = self.sig1_lo[bool_arr] * self.D_elem[
                bool_arr] * 1000.

            # sig_lo = sig_up
            bool_arr = cond_t_up * cond_t_lo * cond_u_eq_l
            alpha[bool_arr] = (self.alpha_sig_lo[bool_arr] +
                               self.alpha_sig_up[bool_arr]) / 2.
            k_fl_NM[bool_arr] = 1.0
            f_t_sig[bool_arr] = self.sig1_lo[bool_arr] * self.D_elem[
                bool_arr] * 1000.

            #---------------------------------------------------------
            # bending case (= different signs)
            #---------------------------------------------------------

            # bending with tension at the lower side
            # AND sig_N > 0 (--> bending and tension; sig1_lo results from bending and tension)
            bool_arr = cond_b * cond_l_gt_0 * cond_l_gt_u
            alpha[bool_arr] = self.alpha_sig_lo[bool_arr]
            k_fl_NM[ bool_arr ] = 1.0 + ( self.k_fl - 1.0 ) * \
                                 ( 1.0 - ( sig_b[ bool_arr ] - abs( self.sig1_up[ bool_arr] ) ) / self.sig1_lo[ bool_arr ] )
            f_t_sig[bool_arr] = self.sig1_lo[bool_arr] * self.D_elem[
                bool_arr] * 1000. / k_fl_NM[bool_arr]

            # bending with tension at the lower side
            # AND sig_N < 0 (--> bending and compression; sig1_lo results only from bending)
            bool_arr = cond_b * cond_l_gt_0 * cond_u_gt_l
            alpha[bool_arr] = self.alpha_sig_lo[bool_arr]
            k_fl_NM[bool_arr] = self.k_fl
            f_t_sig[bool_arr] = self.sig1_lo[bool_arr] * self.D_elem[
                bool_arr] * 1000. / k_fl_NM[bool_arr]

            # bending with tension at the upper side
            # AND sig_N > 0 (--> bending and tension; sig1_up results from bending and tension)
            bool_arr = cond_b * cond_u_gt_0 * cond_u_gt_l
            alpha[bool_arr] = self.alpha_sig_up[bool_arr]
            k_fl_NM[ bool_arr ] = 1.0 + ( self.k_fl - 1.0 ) * \
                                 ( 1.0 - ( sig_b[ bool_arr ] - abs( self.sig1_lo[ bool_arr] ) ) / self.sig1_up[ bool_arr ] )

            f_t_sig[bool_arr] = self.sig1_up[bool_arr] * self.D_elem[
                bool_arr] * 1000. / k_fl_NM[bool_arr]

            # bending with tension at the upper side
            # AND sig_N < 0 (--> bending and compression; sig1_up results only from bending)
            bool_arr = cond_b * cond_u_gt_0 * cond_l_gt_u
            alpha[bool_arr] = self.alpha_sig_up[bool_arr]
            k_fl_NM[bool_arr] = self.k_fl
            f_t_sig[bool_arr] = self.sig1_up[bool_arr] * self.D_elem[
                bool_arr] * 1000. / k_fl_NM[bool_arr]

            #---------------------------------------------------------
            # compression case:
            #---------------------------------------------------------

            bool_arr = cond_c_up * cond_c_lo
            # deflection angle is of minor interest use this simplification
            alpha[bool_arr] = (self.alpha_sig_up[bool_arr] +
                               self.alpha_sig_up[bool_arr]) / 2.
            f_t_sig[bool_arr] = 0.
            k_fl_NM[bool_arr] = 1.0

        #------------------------------------------------------------
        # get angel of deflection of the textile reinforcement
        #------------------------------------------------------------

        # angel of deflection of the textile reinforcement for dimensioning in x-direction
        # distinguished between longitudinal (l) and transversal (q) direction

#        # ASSUMPTION: worst case angle used
#        # as first step use the worst case reduction due to deflection possible (at 55 degrees)
#        beta_l = 55. * pi / 180. * ones_like( alpha )
#        beta_q = ( 90. - 55. ) * pi / 180. * ones_like( alpha )

# @todo: as second step use the value for an alternating layup (i.e. deflection angle)
# @todo: get the correct formula for the demonstrator arrangement
# i.e. the RFEM coordinate system orientation
#        print "NOTE: deflection angle is used to evaluate 'n_tex'"
        beta_l = 90 - abs(alpha)  # [degree]
        beta_q = abs(alpha)  # [degree]

        # resulting strength of the bi-directional textile considering the
        # deflection of the reinforcement in the loading direction:
        f_Rtex = f_Rtex_l * cos( beta_l * pi / 180. ) * ( 1 - beta_l / 90. ) + \
                 f_Rtex_q * cos( beta_q * pi / 180. ) * ( 1 - beta_q / 90. )

        # f_Rtex= 11.65 kN/m corresponds to sig_Rtex = 585 MPa
        #
        #        f_Rtex = 11.65 * ones_like( alpha )

        # f_Rtex= 10.9 kN/m corresponds to sig_Rtex = 678 MPa
        # with 1/3*( 679 + 690 + 667 ) = 678 MPa
        #
        #        f_Rtex = 10.9 * ones_like( alpha )

        # f_Rtex = 10.00 kN/m corresponds to sig_Rtex = 610 MPa
        #
        #        f_Rtex = 10.00 * ones_like( alpha )

        #        print 'NOTE: f_Rtex set to %g kN/m !' % ( f_Rtex[0] )

        if princ_stress_eval == False:
            # necessary number of reinforcement layers
            n_tex = f_t / f_Rtex

            return {
                'e': e,
                'm_Eds': m_Eds,
                'f_t': f_t,
                'f_t_sig': f_t_sig,
                'beta_l': beta_l,
                'beta_q': beta_q,
                'f_Rtex': f_Rtex,
                'n_tex': n_tex
            }

        elif princ_stress_eval == True:
            # NOTE: as the entire (!) cross section is used to calculate 'f_tex_sig'
            # the number of layers is evaluated also directly for the entire (!)
            # cross section!
            #
            n_tex = f_t_sig / f_Rtex

            return {
                'e': e,
                'm_Eds': m_Eds,
                'f_t': f_t,
                'f_t_sig': f_t_sig,
                'beta_l': beta_l,
                'beta_q': beta_q,
                'f_Rtex': f_Rtex,
                'n_tex': n_tex,
                'k_fl_NM': k_fl_NM
            }

    e = Property

    def _get_e(self):
        return self.ls_values['e']

    m_Eds = Property

    def _get_m_Eds(self):
        return self.ls_values['m_Eds']

    f_t = Property

    def _get_f_t(self):
        return self.ls_values['f_t']

    f_t_sig = Property

    def _get_f_t_sig(self):
        return self.ls_values['f_t_sig']

    beta_l = Property

    def _get_beta_l(self):
        return self.ls_values['beta_l']

    beta_q = Property

    def _get_beta_q(self):
        return self.ls_values['beta_q']

    f_Rtex = Property

    def _get_f_Rtex(self):
        return self.ls_values['f_Rtex']

    k_fl_NM = Property

    def _get_k_fl_NM(self):
        return self.ls_values['k_fl_NM']

    n_tex = Property

    def _get_n_tex(self):
        return self.ls_values['n_tex']

    assess_name = 'max_n_tex'
    max_n_tex = Property(depends_on='+input')

    @cached_property
    def _get_max_n_tex(self):
        return ndmax(self.n_tex)


#    assess_name = 'max_sig1_up'
#    max_sig1_up = Property( depends_on = '+input' )
#    @cached_property
#    def _get_max_sig1_up( self ):
#        return ndmax( self.sig1_up )

#    assess_name = 'max_sig1_lo'
#    max_sig1_lo = Property( depends_on = '+input' )
#    @cached_property
#    def _get_max_sig1_lo( self ):
#        return ndmax( self.sig1_lo )

#-------------------------------
# ls view
#-------------------------------

# @todo: the dynamic selection of the columns to be displayed
# does not work in connection with the LSArrayAdapter

    traits_view = View(VGroup(
        HGroup(
            VGroup(Item(name='gamma',
                        label='safety factor material [-]:  gamma '),
                   Item(name='beta',
                        label='reduction long term durability [-]:  beta '),
                   label='safety factors'),
            VGroup(Item(name='f_tk_l',
                        label='characteristic strength textil [MPa]:  f_tk_l ',
                        format_str="%.1f"),
                   Item(name='f_td_l',
                        label='design strength textil [MPa]:  f_td_l ',
                        style='readonly',
                        format_str="%.1f"),
                   Item(name='a_t_l',
                        label='cross sectional area textil [mm^2]:  a_t_l ',
                        style='readonly',
                        format_str="%.1f"),
                   Item(name='f_Rtex_l',
                        label='design strength textil [kN/m]:  f_Rtex_l ',
                        style='readonly',
                        format_str="%.0f"),
                   label='material properties (longitudinal)'),
            VGroup(Item(name='f_tk_q',
                        label='characteristic strength textil [MPa]:  f_tk_q ',
                        format_str="%.1f"),
                   Item(name='f_td_q',
                        label='design strength textil [MPa]:  f_td_q ',
                        style='readonly',
                        format_str="%.1f"),
                   Item(name='a_t_q',
                        label='cross sectional area textil [mm^2]:  a_t_q ',
                        style='readonly',
                        format_str="%.1f"),
                   Item(name='f_Rtex_q',
                        label='design strength textil [kN/m]: f_Rtex_q ',
                        style='readonly',
                        format_str="%.0f"),
                   label='material Properties (transversal)'),
        ),
        VGroup(
            Include('ls_group'),
            Item('ls_array',
                 show_label=False,
                 editor=TabularEditor(adapter=LSArrayAdapter()))),
    ),
                       resizable=True,
                       scrollable=True,
                       height=1000,
                       width=1100)
示例#18
0
class SLS(LS):
    '''Serviceability limit state
    '''

    # ------------------------------------------------------------
    # SLS: material parameters (Inputs)
    # ------------------------------------------------------------

    # tensile strength [MPa]
    f_ctk = Float(4.0, input=True)

    # flexural tensile strength [MPa]
    f_m = Float(5.0, input=True)

    # ------------------------------------------------------------
    # SLS - derived params:
    # ------------------------------------------------------------

    # area
    #
    A = Property(Float)

    def _get_A(self):
        return self.ls_table.D_elem * 1.

    # moment of inertia
    #
    W = Property(Float)

    def _get_W(self):
        return 1. * self.ls_table.D_elem**2 / 6.

    # ------------------------------------------------------------
    # SLS: outputs
    # ------------------------------------------------------------

    ls_columns = List([
        'sig_n',
        'sig_m',
        'eta_n',
        'eta_m',
        'eta_tot',
    ])

    ls_values = Property(depends_on='+input')

    @cached_property
    def _get_ls_values(self):
        '''get the outputs for SLS
        '''
        n = self.n
        m = self.m

        A = self.A
        W = self.W
        f_ctk = self.f_ctk
        f_m = self.f_m

        sig_n = n / A / 1000.
        sig_m = abs(m / W) / 1000.
        eta_n = sig_n / f_ctk
        eta_m = sig_m / f_m
        eta_tot = eta_n + eta_m

        return {
            'sig_n': sig_n,
            'sig_m': sig_m,
            'eta_n': eta_n,
            'eta_m': eta_m,
            'eta_tot': eta_tot
        }

    sig_n = Property

    def _get_sig_n(self):
        return self.ls_values['sig_n']

    sig_m = Property

    def _get_sig_m(self):
        return self.ls_values['sig_m']

    eta_n = Property

    def _get_eta_n(self):
        return self.ls_values['eta_n']

    eta_m = Property

    def _get_eta_m(self):
        return self.ls_values['eta_m']

    eta_tot = Property

    def _get_eta_tot(self):
        return self.ls_values['eta_tot']

    assess_name = 'max_eta_tot'

    #    assess_name = 'max_sig1_up'
    #
    #    max_sig1_up = Property( depends_on = '+input' )
    #    @cached_property
    #    def _get_max_sig1_up( self ):
    #        return ndmax( self.sig1_up )

    # @todo: make it possible to select the assess value:
    #
    #    assess_name = Enum( values = 'columns' )
    #    def _assess_name_default( self ):
    #        return self.columns[-1]

    max_eta_tot = Property(depends_on='+input')

    @cached_property
    def _get_max_eta_tot(self):
        return ndmax(self.eta_tot)

    #-------------------------------
    # ls view
    #-------------------------------

    # @todo: the dynamic selection of the columns to be displayed
    # does not work in connection with the LSArrayAdapter
    traits_view = View(
        VGroup(
            HGroup(
                Item(name='f_ctk',
                     label='Tensile strength concrete [MPa]: f_ctk '),
                Item(name='f_m',
                     label='Flexural tensile trength concrete [MPa]: f_m ')),
            VGroup(
                Include('ls_group'),

                # @todo: currently LSArrayAdapter must be called both
                #        in SLS and ULS separately to configure columns
                #        arrangement individually
                #
                Item('ls_array',
                     show_label=False,
                     editor=TabularEditor(adapter=LSArrayAdapter()))),
        ),
        resizable=True,
        scrollable=True,
        height=1000,
        width=1100)
示例#19
0
 class SPIRRIDUI(HasTraits):
     title = Str('simvisage SPIRRID')
     image = Image('pics/spirrid.png')
     comp_parts = List()
示例#20
0
class RandomField(HasTraits):
    '''
    This class implements a 3D random field on a regular grid
    and allows for interpolation using the EOLE method
    '''
    lacor_arr = Array(Float, modified=True) #(nD,1) array of autocorrelation lengths
    nDgrid = List(Array, modified=True) # list of nD entries: each entry is an array of points in the part. dimension
    reevaluate = Event
    seed = Bool(False)
    distr_type = Enum('Gauss', 'Weibull', modified=True)
    stdev = Float(1.0, modified=True)
    mean = Float(0.0, modified=True)
    shape = Float(5.0, modified=True)
    scale = Float(1.0, modified=True)
    loc = Float(0.0, modified=True)
    
    def acor(self, dx, lacor):
        '''autocorrelation function'''
        C = e ** (-(dx / lacor) ** 2)
        return C

    eigenvalues = Property(depends_on='+modified')
    @cached_property
    def _get_eigenvalues(self):
        '''evaluates the eigenvalues and eigenvectors of the covariance matrix'''
        # creating distances from the first coordinate
        for i, grid_i in enumerate(self.nDgrid):
            self.nDgrid[i] -= grid_i[0]
        # creating a symm. toeplitz matrix with (xgrid, xgrid) data points
        coords_lst = [toeplitz(grid_i) for grid_i in self.nDgrid]
        # apply the autocorrelation func. on the coord matrices to obtain the covariance matrices
        C_matrices = [self.acor(coords_i, self.lacor_arr[i]) for i, coords_i in enumerate(coords_lst)]
        # evaluate the eigenvalues and eigenvectors of the autocorrelation matrices
        eigen_lst = []
        for i, C_i in enumerate(C_matrices):
            print 'evaluating eigenvalues for dimension ' + str(i+1)
            lambda_i, Phi_i = eigh(C_i)
            # truncate the eigenvalues at 99% of tr(C)
            truncation_limit = 0.99 * np.trace(C_i)
            argsort = np.argsort(lambda_i)
            cum_sum_lambda = np.cumsum(np.sort(lambda_i)[::-1])
            idx_trunc = int(np.sum(cum_sum_lambda < truncation_limit))
            eigen_lst.append([lambda_i[argsort[::-1]][:idx_trunc], Phi_i[:, argsort[::-1]][:,:idx_trunc]])
        print 'complete'
        Lambda_C = 1.0
        Phi_C = 1.0
        for lambda_i, Phi_i in eigen_lst:
            Lambda_i = np.diag(lambda_i)
            Lambda_C = np.kron(Lambda_C, Lambda_i)
            Phi_C = np.kron(Phi_C, Phi_i)
        
        return Lambda_C, Phi_C
    
    generated_random_vector = Property(Array, depends_on='reevaluate')
    @cached_property
    def _get_generated_random_vector(self):
        if self.seed == True:
            np.random.seed(141)
        # points between 0 to 1 with an equidistant step for the LHS
        # No. of points = No. of truncated eigenvalues
        npts = self.eigenvalues[0].shape[0]
        randsim = np.linspace(0.5/npts, 1 - 0.5/npts, npts)
        # shuffling points for the simulation
        np.random.shuffle(randsim)
        # matrix containing standard Gauss distributed random numbers
        xi = norm().ppf(randsim)
        return xi
    
    random_field = Property(Array, depends_on='+modified')
    @cached_property
    def _get_random_field(self):
        '''simulates the Gaussian random field'''
        # evaluate the eigenvalues and eigenvectors of the autocorrelation matrix
        Lambda_C_sorted, Phi_C_sorted = self.eigenvalues
        # generate the RF with standardized Gaussian distribution
        ydata = np.dot(np.dot(Phi_C_sorted, (Lambda_C_sorted) ** 0.5), self.generated_random_vector)
        # transform the standardized Gaussian distribution
        if self.distr_type == 'Gauss':
            # scaling the std. distribution
            scaled_ydata = ydata * self.stdev + self.mean
        elif self.distr_type == 'Weibull':
            # setting Weibull params
            Pf = norm().cdf(ydata)
            scaled_ydata = weibull_min(self.shape, scale=self.scale, loc=self.loc).ppf(Pf)
        shape = tuple([len(grid_i) for grid_i in self.nDgrid])
        rf = np.reshape(scaled_ydata, shape)
        return rf
    
    def interpolate_rf(self, coords):
        '''interpolate RF values using the EOLE method
        coords = list of 1d arrays of coordinates'''
        # check consistency of dimensions
        if len(coords) != len(self.nDgrid):
            raise ValueError('point dimension differs from random field dimension')
        # create the covariance matrix
        C_matrices = [self.acor(coords_i.reshape(1, len(coords_i)) - self.nDgrid[i].reshape(len(self.nDgrid[i]),1), self.lacor_arr[i]) for i, coords_i in enumerate(coords)]
        
        C_u = 1.0
        for i, C_ui in enumerate(C_matrices):
            if i == 0:
                C_u *= C_ui
            else:
                C_u = C_u.reshape(C_u.shape[0], 1, C_u.shape[1]) * C_ui
            grid_size = 1.0
            for j in np.arange(i+1):
                grid_size *= len(self.nDgrid[j])
            C_u = C_u.reshape(grid_size,len(coords[0]))

        Lambda_Cx, Phi_Cx = self.eigenvalues
        # values interpolated in the standardized Gaussian rf 
        u = np.sum(self.generated_random_vector / np.diag(Lambda_Cx) ** 0.5 * np.dot(C_u.T, Phi_Cx), axis=1)
        if self.distr_type == 'Gauss':
            scaled_u = u * self.stdev + self.mean
        elif self.distr_type == 'Weibull':
            Pf = norm().cdf(u)
            scaled_u = weibull_min(self.shape, scale=self.scale, loc=self.loc).ppf(Pf)
        return scaled_u
示例#21
0
 class Postprocessor(HasTraits):
     title = Str('postprocessor')
     post_components = List()
示例#22
0
class CompositeCrackBridge(HasTraits):

    reinforcement_lst = List(Instance(Reinforcement))
    w = Float
    E_m = Float
    Ll = Float
    Lr = Float

    V_f_tot = Property(depends_on='reinforcement_lst+')

    @cached_property
    def _get_V_f_tot(self):
        V_f_tot = 0.0
        for reinf in self.reinforcement_lst:
            V_f_tot += reinf.V_f
        return V_f_tot

    E_c = Property(depends_on='reinforcement_lst+')

    @cached_property
    def _get_E_c(self):
        E_fibers = 0.0
        for reinf in self.reinforcement_lst:
            E_fibers += reinf.V_f * reinf.E_f
        E_c = self.E_m * (1. - self.V_f_tot) + E_fibers
        return E_c * (1. + 1e-15)

    sorted_reinf_lst = Property(Tuple(List, List),
                                depends_on='reinforcement_lst')

    @cached_property
    def _get_sorted_reinf_lst(self):
        cont_reinf_lst = []
        short_reinf_lst = []
        for reinf in self.reinforcement_lst:
            if reinf.__class__ == ContinuousFibers:
                cont_reinf_lst.append(reinf)
            elif reinf.__class__ == ShortFibers:
                short_reinf_lst.append(reinf)
        return cont_reinf_lst, short_reinf_lst

    cont_fibers_instance = Instance(CrackBridgeContFibers)

    def _cont_fibers_instance_default(self):
        return CrackBridgeContFibers()

    cont_fibers = Property(Instance(CrackBridgeContFibers),
                           depends_on='reinforcement_lst+,Ll,Lr,E_m,w')

    @cached_property
    def _get_cont_fibers(self):
        cbcf = self.cont_fibers_instance
        cbcf.w = self.w
        cbcf.Ll = self.Ll
        cbcf.Lr = self.Lr
        cbcf.E_m = self.E_m
        cbcf.E_c = self.E_c
        cbcf.cont_reinf_lst = self.sorted_reinf_lst[0]
        return cbcf

    short_fibers_instance = Instance(CrackBridgeShortFibers)

    def _short_fibers_instance_default(self):
        return CrackBridgeShortFibers()

    short_fibers = Property(Instance(CrackBridgeShortFibers),
                            depends_on='reinforcement_lst+,E_m,w')

    @cached_property
    def _get_short_fibers(self):
        cbsf = self.short_fibers_instance
        cbsf.w = self.w
        cbsf.E_m = self.E_m
        cbsf.E_c = self.E_c
        cbsf.short_reinf_lst = self.sorted_reinf_lst[1]
        return cbsf

    _x_arr = Property(Array, depends_on='w,E_m,Ll,Lr,reinforcement_lst+')

    @cached_property
    def _get__x_arr(self):
        if len(self.sorted_reinf_lst[0]) != 0 and len(
                self.sorted_reinf_lst[1]) != 0:
            added_x = np.hstack(
                (self.cont_fibers.x_arr, self.short_fibers.x_arr))
            sorted_unique_x = np.unique(added_x)
            return sorted_unique_x
        elif len(self.sorted_reinf_lst[0]) != 0:
            return self.cont_fibers.x_arr
        elif len(self.sorted_reinf_lst[1]) != 0:
            return self.short_fibers.x_arr

    _epsm_arr = Property(Array, depends_on='w,E_m,Ll,Lr,reinforcement_lst+')

    @cached_property
    def _get__epsm_arr(self):
        if len(self.sorted_reinf_lst[0]) != 0 and len(
                self.sorted_reinf_lst[1]) != 0:
            epsm_cont_interp = MFnLineArray(xdata=self.cont_fibers.x_arr,
                                            ydata=self.cont_fibers.epsm_arr)
            epsm_short_interp = MFnLineArray(xdata=self.short_fibers.x_arr,
                                             ydata=self.short_fibers.epsm_arr)
            added_epsm_cont = self.cont_fibers.epsm_arr + epsm_short_interp.get_values(
                self.cont_fibers.x_arr)
            added_epsm_short = self.short_fibers.epsm_arr + epsm_cont_interp.get_values(
                self.short_fibers.x_arr)
            sorted_unique_idx = np.unique(np.hstack(
                (self.cont_fibers.x_arr, self.short_fibers.x_arr)),
                                          return_index=True)[1]
            return np.hstack(
                (added_epsm_cont, added_epsm_short))[sorted_unique_idx]
        elif len(self.sorted_reinf_lst[0]) != 0:
            return self.cont_fibers.epsm_arr
        elif len(self.sorted_reinf_lst[1]) != 0:
            self.short_fibers.w = self.w
            return self.short_fibers.epsm_arr

    _epsf_arr = Property(Array, depends_on='w,E_m,Ll,Lr,reinforcement_lst+')

    @cached_property
    def _get__epsf_arr(self):
        ''' only for continuous reinforcement '''
        if len(self.sorted_reinf_lst[0]) != 0 and len(
                self.sorted_reinf_lst[1]) == 0:
            self.cont_fibers.w = self.w
            return self.cont_fibers.epsf_arr
        else:
            raise ValueError('epsf can only be computed for continuous fibers')

    _epsf0_arr = Property(Array, depends_on='w,E_m,Ll,Lr,reinforcement_lst+')

    @cached_property
    def _get__epsf0_arr(self):
        if len(self.sorted_reinf_lst[0]) != 0 and len(
                self.sorted_reinf_lst[1]) != 0:
            epsf0_cont = self.cont_fibers.epsf0_arr
            epsf0_short = self.short_fibers.epsf0_arr
        elif len(self.sorted_reinf_lst[0]) != 0:
            epsf0_cont = self.cont_fibers.epsf0_arr
            epsf0_short = np.array([])
        elif len(self.sorted_reinf_lst[1]) != 0:
            epsf0_cont = np.array([])
            epsf0_short = self.short_fibers.epsf0_arr
        return epsf0_cont, epsf0_short

    _epsf0_arr_cont = Property(Array,
                               depends_on='w,E_m,Ll,Lr,reinforcement_lst+')

    @cached_property
    def _get__epsf0_arr_cont(self):
        return self._epsf0_arr[0]

    _epsf0_arr_short = Property(Array,
                                depends_on='w,E_m,Ll,Lr,reinforcement_lst+')

    @cached_property
    def _get__epsf0_arr_short(self):
        return self._epsf0_arr[1]

    sigma_c = Property(depends_on='w,E_m,Ll,Lr,reinforcement_lst+')

    @cached_property
    def _get_sigma_c(self):
        if len(self.sorted_reinf_lst[0]) != 0 and len(
                self.sorted_reinf_lst[1]) != 0:
            sigma_c_cont = np.sum(
                self._epsf0_arr_cont * self.cont_fibers.sorted_stats_weights *
                self.cont_fibers.sorted_V_f * self.cont_fibers.sorted_nu_r *
                self.cont_fibers.sorted_E_f * (1. - self.cont_fibers.damage))
            sigma_c_short = np.sum(self._epsf0_arr_short *
                                   self.short_fibers.sorted_V_f *
                                   self.short_fibers.sorted_E_f)
        elif len(self.sorted_reinf_lst[0]) != 0:
            sigma_c_cont = np.sum(
                self._epsf0_arr_cont * self.cont_fibers.sorted_stats_weights *
                self.cont_fibers.sorted_V_f * self.cont_fibers.sorted_nu_r *
                self.cont_fibers.sorted_E_f * (1. - self.cont_fibers.damage))
            sigma_c_short = 0.0
        elif len(self.sorted_reinf_lst[1]) != 0:
            sigma_c_cont = 0.0
            sigma_c_short = np.sum(self._epsf0_arr_short *
                                   self.short_fibers.sorted_V_f *
                                   self.short_fibers.sorted_E_f)
        return sigma_c_cont + sigma_c_short
示例#23
0
class InterpolatedSPIRRID(HasTraits):

    adaption = Instance(RangeAdaption)

    def preinterpolate(self, mu_w_x, sigma_f_cutoff, x_adapt):
        # values to create array grid
        axes_values = [sigma_f_cutoff, x_adapt]
        preinterp = NDIdxInterp(data=mu_w_x, axes_values=axes_values)
        # values to interpolate for
        load_sigma_f = self.initial_eps_vars[0]
        x = self.initial_eps_vars[1]
        interp_coords = [load_sigma_f, x]
        return preinterp(*interp_coords, mode='constant')

    interp_grid = Property()

    @cached_property
    def _get_interp_grid(self):
        print 'evaluating mean response and adapting ranges...'
        spirrid_result = self.spirrid_result
        print 'complete'
        axes_values = self.initial_eps_vars
        ni = NDIdxInterp(data=spirrid_result, axes_values=axes_values)
        return ni

    spirrid_result = Property(Array)

    @cached_property
    def _get_spirrid_result(self):
        Ll = self.adaption.BC_range
        Lr = Ll
        result = np.zeros((self.adaption.load_n_sigma_c, self.adaption.n_x,
                           self.adaption.n_BC, self.adaption.n_BC))
        loops_tot = len(Ll) * len(Lr)
        for i, ll in enumerate(Ll):
            for j, lr in enumerate(Lr):
                # adapt w range
                w_opt, sigma_f_opt = self.adaption.adapt_w_range(ll, lr)
                # adapt x range
                x_opt = np.linspace(-ll, lr, self.adaption.n_x)
                self.adaption.spirrid.eps_vars = dict(w=w_opt, x=x_opt)
                self.adaption.spirrid.theta_vars['Ll'] = ll
                self.adaption.spirrid.theta_vars['Lr'] = lr
                # evaluate 2D (w,x) SPIRRID with adapted ranges x and w
                mu_w_x = self.adaption.spirrid.mu_q_arr
                # preinterpolate particular result for the given x and sigma ranges
                mu_w_x_interp = \
                self.preinterpolate(mu_w_x, sigma_f_opt, x_opt).T
                mask = np.where(self.adaption.load_sigma_f <= sigma_f_opt[-1],
                                1, np.NaN)[:, np.newaxis]
                mu_w_x_interp = mu_w_x_interp * mask
                # eps_vars = orthogonalize([np.arange(len(w_opt)), np.arange(len(x_opt))])
                # m.surf(eps_vars[0], eps_vars[1], mu_w_x * 0.05)
                # m.surf(eps_vars[0], eps_vars[1], mu_w_x_interp * 0.05)
                # m.show()
                # store the particular result for BC ll and lr into the result array
                result[:, :, i, j] = mu_w_x_interp
                current_loop = i * len(Lr) + j + 1
                print 'progress: %2.1f %%' % \
                (current_loop / float(loops_tot) * 100.)
        return result

    initial_eps_vars = Property(List(Array))

    @cached_property
    def _get_initial_eps_vars(self):
        return [
            self.adaption.load_sigma_f, self.adaption.x_init,
            self.adaption.BC_range, self.adaption.BC_range
        ]

    def __call__(self, *args):
        '''
        evaluation of force profile in the vicinity of a crack bridge
        '''
        args = list(args)
        load_sigma_f = args[0] / self.adaption.spirrid.theta_vars['V_f']
        # fiber stress
        args[0] = load_sigma_f
        self.load_sigma_f = load_sigma_f
        return self.interp_grid(*args)
示例#24
0
class LCCTable(HasTraits):
    '''Loading Case Manager.
    Generates and sorts the loading case combinations
    of all specified loading cases.
    '''

    # define ls
    #
    ls = Trait('ULS', {'ULS': ULS, 'SLS': SLS})

    # lcc-instance for the view
    #
    lcc = Instance(LCC)

    #-------------------------------
    # Define loading cases:
    #-------------------------------

    # path to the directory containing the state data files
    #
    data_dir = Directory

    # list of load cases
    #
    lc_list_ = List(Instance(LC))

    lc_list = Property(List, depends_on='+filter')

    def _set_lc_list(self, value):
        self.lc_list_ = value

    def _get_lc_list(self):
        #        for lc in self.lc_list_:
        #            if lc.data_filter != self.data_filter:
        #                lc.data_filter = self.data_filter
        return self.lc_list_

    lcc_table_columns = Property(depends_on='lc_list_, +filter')

    def _get_lcc_table_columns(self):
        return [ ObjectColumn(label='Id', name='lcc_id') ] + \
               [ ObjectColumn(label=lc.name, name=lc.name)
                for idx, lc in enumerate(self.lc_list) ] + \
                [ ObjectColumn(label='assess_value', name='assess_value') ]

    geo_columns = Property(List(Str), depends_on='lc_list_, +filter')

    def _get_geo_columns(self):
        '''derive the order of the geo columns
        from the first element in 'lc_list'. The internal
        consistency is checked separately in the
        'check_consistency' method.
        '''
        return self.lc_list[0].geo_columns

    sr_columns = Property(List(Str), depends_on='lc_list_, +filter')

    def _get_sr_columns(self):
        '''derive the order of the stress resultants
        from the first element in 'lc_list'. The internal
        consistency is checked separately in the
        'check_consistency' method.
        '''
        return self.lc_list[0].sr_columns

    #-------------------------------
    # check consistency
    #-------------------------------

    def _check_for_consistency(self):
        ''' check input files for consitency:
        '''
        return True

    #-------------------------------
    # lc_arr
    #-------------------------------

    lc_arr = Property(Array)

    def _get_lc_arr(self):
        '''stack stress resultants arrays of all loading cases together.
        This yields an array of shape ( n_lc, n_elems, n_sr )
        '''
        sr_arr_list = [lc.sr_arr for lc in self.lc_list]
        #        for x in sr_arr_list:
        #            print x.shape

        return array(sr_arr_list)

    #-------------------------------
    # Array dimensions:
    #-------------------------------

    n_sr = Property(Int)

    def _get_n_sr(self):
        return len(self.sr_columns)

    n_lc = Property(Int)

    def _get_n_lc(self):
        return len(self.lc_list)

    n_lcc = Property(Int)

    def _get_n_lcc(self):
        return self.combi_arr.shape[0]

    n_elems = Property(Int)

    def _get_n_elems(self):
        return self.lc_list[0].sr_arr.shape[0]

    #-------------------------------
    # auxilary method for get_combi_arr
    #-------------------------------

    def _product(self, args):
        """
        Get all possible permutations of the security factors
        without changing the order of the loading cases.
        The method corresponds to the build-in function 'itertools.product'.
        Instead of returning a generator object a list of all
        possible permutations is returned. As argument a list of list
        needs to be defined. In the original version of 'itertools.product'
        the function takes a tuple as argument ("*args").
        """
        pools = map(tuple,
                    args)  # within original version args defined as *args
        result = [[]]
        for pool in pools:
            result = [x + [y] for x in result for y in pool]
        return result

    # ------------------------------------------------------------
    # 'combi_arr' - array containing indices of all loading case combinations:
    # ------------------------------------------------------------

    # list of indices of the position of the imposed loads in 'lc_list'
    #
#    imposed_idx_list = Property( List, depends_on = 'lc_list_, lc_list_.+input' )
    imposed_idx_list = Property(List, depends_on='lc_list_')

    @cached_property
    def _get_imposed_idx_list(self):
        '''list of indices for the imposed loads
        '''
        imposed_idx_list = []
        for i_lc, lc in enumerate(self.lc_list):
            cat = lc.category
            if cat == 'imposed-load':
                imposed_idx_list.append(i_lc)
        return imposed_idx_list

    # array containing the psi with name 'psi_key' for the specified
    # loading cases defined in 'lc_list'. For dead-loads no value for
    # psi exists. In this case a value of 1.0 is defined.
    # This yields an array of shape ( n_lc, )
    #
    def _get_psi_arr(self, psi_key):
        '''psi_key must be defined as:
        'psi_0', 'psi_1', or 'psi_2'
        Returns an 1d-array of shape ( n_lc, )
        '''
        # get list of ones (used for dead-loads):
        #
        psi_list = [1] * len(self.lc_list)

        # overwrite ones with psi-values in case of imposed-loads:
        #
        for imposed_idx in self.imposed_idx_list:
            psi_value = getattr(self.lc_list[imposed_idx], psi_key)
            psi_list[imposed_idx] = psi_value

        return array(psi_list, dtype='float_')

    # list containing names of the loading cases
    #
    lc_name_list = Property(List, depends_on='lc_list_')

    @cached_property
    def _get_lc_name_list(self):
        '''list of names of all loading cases
        '''
        return [lc.name for lc in self.lc_list]

    show_lc_characteristic = Bool(True)

    # combination array:
    #
    combi_arr = Property(Array, depends_on='lc_list_, combination_SLS')

    @cached_property
    def _get_combi_arr(self):
        '''array containing the security and combination factors
        corresponding to the specified loading cases.
        This yields an array of shape ( n_lcc, n_lc )

        Properties defined in the subclasses 'LCCTableULS', 'LCCTableSLS':
        - 'gamma_list' = list of security factors (gamma)
        - 'psi_lead' = combination factors (psi) of the leading imposed load
        - 'psi_non_lead' = combination factors (psi) of the non-leading imposed loads
        '''
        # printouts:
        #
        if self.ls == 'ULS':
            print '*** load case combinations for limit state ULS ***'
        else:
            print '*** load case combinations for limit state SLS ***'
            print '*** SLS combination used: % s ***' % (self.combination_SLS)

        #---------------------------------------------------------------
        # get permutations of safety factors ('gamma')
        #---------------------------------------------------------------
        #
        permutation_list = self._product(self.gamma_list)

        combi_arr = array(permutation_list)

        # check if imposed loads are defined
        # if not no further processing of 'combi_arr' is necessary:
        #
        if self.imposed_idx_list == []:

            # if option is set to 'True' the loading case combination table
            # is enlarged with an identity matrix in order to see the
            # characteristic values of each loading case.
            #
            if self.show_lc_characteristic:
                combi_arr = vstack([identity(self.n_lc), combi_arr])

            return combi_arr

        #---------------------------------------------------------------
        # get leading and non leading combination factors ('psi')
        #---------------------------------------------------------------
        # go through all possible cases of leading imposed loads
        # For the currently investigated imposed loading case the
        # psi value is taken from 'psi_leading_arr' for all other
        # imposed loads the psi value is taken from 'psi_non_lead_arr'

        # Properties are defined in the subclasses
        #
        psi_lead_arr = self.psi_lead_arr
        psi_non_lead_arr = self.psi_non_lead_arr

        # for SLS limit state case 'rare' all imposed loads are multiplied
        # with 'psi_2'. In this case no distinction between leading or
        # non-leading imposed loads needs to be performed.
        #
        if all(psi_lead_arr == psi_non_lead_arr):
            combi_arr_psi = combi_arr * psi_lead_arr

        # generate a list or arrays obtained by multiplication
        # with the psi-factors.
        # This yields a list of length = number of imposed-loads.
        #
        else:
            combi_arr_psi_list = []
            for imposed_idx in self.imposed_idx_list:
                # copy in order to preserve initial state of the array
                # and avoid in place modification
                psi_arr = copy(psi_non_lead_arr)
                psi_arr[imposed_idx] = psi_lead_arr[imposed_idx]
                combi_arr_lead_i = combi_arr[where(
                    combi_arr[:, imposed_idx] != 0)] * psi_arr
                combi_arr_psi_list.append(combi_arr_lead_i)

            combi_arr_psi_no_0 = vstack(combi_arr_psi_list)

            # missing cases without any dead load have to be added
            # get combinations with all!! imposed = 0
            #
            lcc_all_imposed_zero = where(
                (combi_arr[:, self.imposed_idx_list] == 0).all(axis=1))

            # add to combinations
            #
            combi_arr_psi = vstack(
                (combi_arr[lcc_all_imposed_zero], combi_arr_psi_no_0))

        #---------------------------------------------------------------
        # get exclusive loading cases ('exclusive_to')
        #---------------------------------------------------------------

        # get a list of lists containing the indices of the loading cases
        # that are defined exclusive to each other.
        # The list still contains duplicates, e.g. [1,2] and [2,1]
        #
        exclusive_list = []
        for i_lc, lc in enumerate(self.lc_list):

            # get related load case number
            #
            for exclusive_name in lc.exclusive_to:
                if exclusive_name in self.lc_name_list:
                    exclusive_idx = self.lc_name_list.index(exclusive_name)
                    exclusive_list.append([i_lc, exclusive_idx])

        # eliminate the duplicates in 'exclusive_list'
        #
        exclusive_list_unique = []
        for exclusive_list_entry in exclusive_list:
            if sorted(exclusive_list_entry) not in exclusive_list_unique:
                exclusive_list_unique.append(sorted(exclusive_list_entry))

        # delete the rows in combination array that contain
        # loading case combinations with imposed-loads that have been defined
        # as exclusive to each other.
        #
        combi_arr_psi_exclusive = combi_arr_psi
        #        print 'combi_arr_psi_exclusive', combi_arr_psi_exclusive
        for exclusive_list_entry in exclusive_list_unique:
            # check where maximum one value of the exclusive load cases is unequal to one
            #              LC1  LC2  LC3  (all LCs are defined as exclusive to each other)
            #
            # e.g.         1.5  0.9  0.8  (example of 'combi_arr_psi')
            #              1.5  0.0  0.0
            #              0.0  0.0  0.0  (combination with all imposed loads = 0 after multiplication wit psi and gamma)
            #              ...  ...  ...
            #
            # this would yield the following mask_arr (containing ones or zeros):
            # e.g.         1.0  1.0  1.0  --> sum = 3 --> true combi --> accepted combination
            #              1.0  0.0  0.0  --> sum = 1 --> false combi --> no accepted combination
            # e.g.         0.0  0.0  0.0  --> sum = 0 --> true combi --> accepted combination (only body-loads)
            #              ...  ...  ...
            #
            mask_arr = where(
                combi_arr_psi_exclusive[:, exclusive_list_entry] != 0, 1.0,
                0.0)
            #            print 'mask_arr', mask_arr
            true_combi = where(sum(mask_arr, axis=1) <= 1.0)
            #            print 'true_combi', true_combi
            combi_arr_psi_exclusive = combi_arr_psi_exclusive[true_combi]

        #---------------------------------------------------------------
        # create array with only unique load case combinations
        #---------------------------------------------------------------
        # If the psi values of an imposed-load are defined as zero this
        # may led to zero entries in 'combi_arr'. This would yield rows
        # in 'combi_arr' which are duplicates. Those rows are removed.

        # Add first row in 'combi_arr_psi_exclusive' to '_unique' array
        # This array must have shape (1, n_lc) in order to use 'axis'-option
        #
        combi_arr_psi_exclusive_unique = combi_arr_psi_exclusive[0][None, :]

        for row in combi_arr_psi_exclusive:
            # Check if all factors in one row are equal to the rows in 'unique' array.
            # If this is not the case for any row the combination is added to 'unique'.
            # Broadcasting is used for the bool evaluation:
            #
            if (row == combi_arr_psi_exclusive_unique).all(
                    axis=1.0).any() == False:
                combi_arr_psi_exclusive_unique = vstack(
                    (combi_arr_psi_exclusive_unique, row))

        # if option is set to 'True' the loading case combination table
        # is enlarged with an identity matrix in order to see the
        # characteristic values of each loading case.
        #
#        if self.show_lc_characteristic:
#            combi_arr_psi_exclusive_unique = vstack( [ identity( self.n_lc ), combi_arr_psi_exclusive_unique ] )

        return combi_arr_psi_exclusive_unique

    #-------------------------------
    # lcc_arr
    #-------------------------------

    lcc_arr = Property(Array, depends_on='lc_list_')

    @cached_property
    def _get_lcc_arr(self):
        '''Array of all loading case combinations following the
        loading cases define in 'lc_list' and the combinations
        defined in 'combi_arr'.
        This yields an array of shape ( n_lcc, n_elems, n_sr )
        '''
        self._check_for_consistency()

        combi_arr = self.combi_arr

        # 'combi_arr' is of shape ( n_lcc, n_lc )
        # 'lc_arr' is of shape ( n_lc, n_elems, n_sr )
        #
        lc_arr = self.lc_arr

        # Broadcasting is used to generate array containing the multiplied lc's
        # yielding an array of shape ( n_lcc, n_lc, n_elems, n_sr )
        #

        lc_combi_arr = lc_arr[None, :, :, :] * combi_arr[:, :, None, None]

        # Then the sum over index 'n_lc' is evaluated yielding
        # an array of all loading case combinations.
        # This yields an array of shape ( n_lcc, n_elem, n_sr )
        #
        lcc_arr = sum(lc_combi_arr, axis=1)

        return lcc_arr

    #-------------------------------
    # lcc_lists
    #-------------------------------

    lcc_list = Property(List, depends_on='lc_list_')

    @cached_property
    def _get_lcc_list(self):
        '''list of loading case combinations (instances of LCC)
        '''
        combi_arr = self.combi_arr
        lcc_arr = self.lcc_arr
        sr_columns = self.sr_columns
        geo_columns = self.geo_columns

        n_lcc = self.n_lcc

        # return a dictionary of the stress resultants
        # this is used by LSTable to determine the stress
        # resultants of the current limit state
        #
        lcc_list = []
        for i_lcc in range(n_lcc):

            state_data_dict = {}
            for i_sr, name in enumerate(sr_columns):
                state_data_dict[name] = lcc_arr[i_lcc, :, i_sr][:, None]

            geo_data_dict = self.geo_data_dict

            lcc = LCC(  # lcc_table = self,
                factors=combi_arr[i_lcc, :],
                lcc_id=i_lcc,
                ls_table=LSTable(geo_data=geo_data_dict,
                                 state_data=state_data_dict,
                                 ls=self.ls))

            for idx, lc in enumerate(self.lc_list):
                lcc.add_trait(lc.name, Int(combi_arr[i_lcc, idx]))

            lcc_list.append(lcc)

        return lcc_list

    #-------------------------------
    # geo_arr
    #-------------------------------

    geo_data_dict = Property(Dict, depends_on='lc_list_')

    @cached_property
    def _get_geo_data_dict(self):
        '''Array of global coords derived from the first loading case defined in lc_list.
        Coords are identical for all LC's.
        '''
        return self.lc_list[0].geo_data_dict

    #-------------------------------
    # min/max-values
    #-------------------------------

    def get_min_max_state_data(self):
        ''' get the surrounding curve of all 'lcc' values
        '''
        lcc_arr = self.lcc_arr
        min_arr = ndmin(lcc_arr, axis=0)
        max_arr = ndmax(lcc_arr, axis=0)
        return min_arr, max_arr

    #--------------------------------------
    # use for case 'max N*' nach ZiE
    # Fall 'maximale Normalkraft' nach ZiE
    #--------------------------------------
#    max_sr_grouped_dict = Property( Dict )
#    @cached_property
#    def _get_max_sr_grouped_dict( self ):
#        ''' get the surrounding curve for each stress resultant
#            shape lcc_array ( n_lcc, n_elems, n_sr )
#        '''
#        sr_columns = self.sr_columns
#        lcc_arr = self.lcc_arr
#        dict = {}
#        for i, sr in enumerate( self.sr_columns ):
#            idx_1 = argmax( abs( lcc_arr[:, :, i] ), axis = 0 )
#            idx_2 = arange( 0, idx_1.shape[0], 1 )
#            dict[sr] = lcc_arr[idx_1, idx_2, :]
#        return dict

#--------------------------------------
# use for case 'max eta' nach ZiE
# Fall max Ausnutzungsgrad nach ZiE
#--------------------------------------
    max_sr_grouped_dict = Property(Dict)

    @cached_property
    def _get_max_sr_grouped_dict(self):
        '''evaluate eta and prepare plot
        '''
        sr_columns = self.sr_columns
        lcc_arr = self.lcc_arr
        # ## N_s6cm_d results from 'V_op_d'*1.5
        # assume a distribution of stresses as for a simple
        # supported beam with cantilever corresponding
        # to the distance of the screws to each other and to the edge
        # of the TRC shell (33cm/17cm)
        #
        N_s6cm_d = lcc_arr[:, :, 2] * (17. + 33. + 1.) / 33.

        # ## V_s6cm_d results from 'N_ip_d'/2
        # assume an equal distribution (50% each) of the
        # normal forces to each screw
        #
        V_s6cm_d = lcc_arr[:, :, 0] * 0.56
        #        V_s6cm_d = ( ( lcc_arr[:, :, 0] / 2 ) ** 2 + ( lcc_arr[:, :, 1] * 1.5 ) ** 2 ) ** 0.5

        # resistance ac characteristic value obtained from the
        # experiment and EN DIN 1990
        #
        N_ck = 28.3
        V_ck = 63.8

        gamma_s = 1.5

        eta_N = N_s6cm_d / (N_ck / gamma_s)
        eta_V = abs(V_s6cm_d / (V_ck / gamma_s))
        eta_inter = (eta_N) + (eta_V)

        idx_max_hinge = eta_inter.argmax(axis=0)

        dict = {}
        for i, sr in enumerate(self.sr_columns):
            idx_1 = idx_max_hinge
            idx_2 = arange(0, idx_1.shape[0], 1)
            dict[sr] = lcc_arr[idx_1, idx_2, :]
        return dict

    def export_hf_max_grouped(self, filename):
        """exports the hinge forces as consistent pairs for the two case
        'max_eta' or 'max_N*'
        """
        from matplotlib import pyplot
        sr_columns = self.sr_columns
        dict = self.max_sr_grouped_dict
        length_xy_quarter = self.length_xy_quarter

        def save_bar_plot(x,
                          y,
                          filename='bla',
                          title='Title',
                          xlabel='xlabel',
                          ylabel='ylavel',
                          width=0.1,
                          xmin=0,
                          xmax=1000,
                          ymin=-1000,
                          ymax=1000,
                          figsize=[10, 5]):
            fig = pyplot.figure(facecolor="white", figsize=figsize)
            ax1 = fig.add_subplot(1, 1, 1)
            ax1.bar(x, y, width=width, align='center', color='green')
            ax1.set_xlim(xmin, xmax)
            ax1.set_ylim(ymin, ymax)
            ax1.set_xlabel(xlabel, fontsize=22)
            ax1.set_ylabel(ylabel, fontsize=22)
            if title == 'N_ip max':
                title = 'Fall max $\eta$'
#                title = 'Fall max $N^{*}$'

            if title == 'V_ip max':
                title = 'max $V_{ip}$'
            if title == 'V_op max':
                title = 'Fall max $V^{*}$'
            ax1.set_title(title)
            fig.savefig(filename, orientation='portrait', bbox_inches='tight')
            pyplot.clf()

        X = array(self.geo_data_dict['X_hf'])
        Y = array(self.geo_data_dict['Y_hf'])

        # symmetric axes
        #
        idx_sym = where(abs(Y[:, 0] - 2.0 * length_xy_quarter) <= 0.0001)
        X_sym = X[idx_sym].reshape(-1)
        idx_r0_r1 = where(abs(X[:, 0] - 2.0 * length_xy_quarter) <= 0.0001)
        X_r0_r1 = Y[idx_r0_r1].reshape(-1)

        for sr in sr_columns:
            F_int = dict[sr]  # first row N_ip, second V_ip third V_op
            F_sym = F_int[idx_sym, :].reshape(-1, len(sr_columns))
            F_r0_r1 = F_int[idx_r0_r1, :].reshape(-1, len(sr_columns))

            save_bar_plot(X_sym,
                          F_sym[:, 0].reshape(-1),
                          xlabel='$X$ [m]',
                          ylabel='$N^{*}_{Ed}$ [kN]',
                          filename=filename + 'N_ip' + '_sym_' + sr + '_max',
                          title=sr + ' max',
                          xmin=0.0,
                          xmax=3.5 * length_xy_quarter,
                          figsize=[10, 5],
                          ymin=-30,
                          ymax=+30)
            if self.link_type == 'inc_V_ip':
                save_bar_plot(X_sym,
                              F_sym[:, 1].reshape(-1),
                              xlabel='$X$ [m]',
                              ylabel='$V_{ip}$ [kN]',
                              filename=filename + 'V_ip' + '_sym_' + sr +
                              '_max',
                              title=sr + ' max',
                              xmin=0.0,
                              xmax=3.5 * length_xy_quarter,
                              figsize=[10, 5],
                              ymin=-30,
                              ymax=+30)

            save_bar_plot(X_sym,
                          F_sym[:, 2].reshape(-1),
                          xlabel='$X$ [m]',
                          ylabel='$V^{*}_{Ed}$ [kN]',
                          filename=filename + 'V_op' + '_sym_' + sr + '_max',
                          title=sr + ' max',
                          xmin=0.0,
                          xmax=3.5 * length_xy_quarter,
                          figsize=[10, 5],
                          ymin=-10,
                          ymax=+10)

            # r0_r1
            #
            save_bar_plot(X_r0_r1,
                          F_r0_r1[:, 0].reshape(-1),
                          xlabel='$Y$ [m]',
                          ylabel='$N^{*}_{Ed}$ [kN]',
                          filename=filename + 'N_ip' + '_r0_r1_' + sr + '_max',
                          title=sr + ' max',
                          xmin=0.0,
                          xmax=2.0 * length_xy_quarter,
                          figsize=[5, 5],
                          ymin=-30,
                          ymax=+30)
            if self.link_type == 'inc_V_ip':
                save_bar_plot(X_r0_r1,
                              F_r0_r1[:, 1].reshape(-1),
                              xlabel='$Y$ [m]',
                              ylabel='$V_{ip}$ [kN]',
                              filename=filename + 'V_ip' + '_r0_r1_' + sr +
                              '_max',
                              title=sr + ' max',
                              xmin=0.0,
                              xmax=2.0 * length_xy_quarter,
                              figsize=[5, 5],
                              ymin=-30,
                              ymax=+30)
            save_bar_plot(X_r0_r1,
                          F_r0_r1[:, 2].reshape(-1),
                          xlabel='$Y$ [m]',
                          ylabel='$V^{*}_{Ed}$ [kN]',
                          filename=filename + 'V_op' + '_r0_r1_' + sr + '_max',
                          title=sr + ' max',
                          xmin=0.0,
                          xmax=2.0 * length_xy_quarter,
                          figsize=[5, 5],
                          ymin=-10,
                          ymax=+10)

    def plot_interaction_s6cm(self):
        """get the maximum values (consistent pairs of N and V) and plot them in an interaction plot
        """

        lcc_arr = self.lcc_arr

        # ## F_Edt results from 'V_op_d'*1.5
        # assume a distribution of stresses as for a simple
        # supported beam with cantilever corresponding

        # to the distance of the screws to each other and to the edge
        # of the TRC shell (33cm/17cm)
        #
        F_Edt = lcc_arr[:, :, 2] * (17. + 33. + 1.) / 33.

        # ## F_EdV1 results from 'N_ip_d'/2
        # assume an equal distribution (50% each) of the
        # normal forces to each screw
        #
        F_EdV1 = lcc_arr[:, :, 0] * 0.56
        #        V_s6cm_d = ( ( lcc_arr[:, :, 0] / 2 ) ** 2 + ( lcc_arr[:, :, 1] * 1.5 ) ** 2 ) ** 0.5

        # resistance ac characteristic value obtained from the
        # experiment and EN DIN 1990
        #
        F_Rkt = 28.3
        F_RkV1 = 63.8

        gamma_M = 1.5

        eta_t = abs(F_Edt / (F_Rkt / gamma_M))
        eta_V1 = abs(F_EdV1 / (F_RkV1 / gamma_M))
        print 'eta_t.shape', eta_t.shape
        print 'eta_V1.shape', eta_V1.shape

        #        self.interaction_plot(abs(F_Edt), abs(F_EdV1))
        self.interaction_plot(eta_t, eta_V1)


#        eta_inter = ( eta_N ) + ( eta_V )
#
#        idx_max_hinge = eta_inter.argmax( axis = 0 )
#        idx_hinge = arange( 0, len( idx_max_hinge ), 1 )
#        plot_eta_N = eta_N[idx_max_hinge, idx_hinge]
#        plot_eta_V = eta_V[idx_max_hinge, idx_hinge]
#        self.interaction_plot( plot_eta_N, plot_eta_V )

    def interaction_plot(self, eta_N, eta_V):
        from matplotlib import font_manager
        ticks_font = font_manager.FontProperties(family='Times',
                                                 style='normal',
                                                 size=18,
                                                 weight='normal',
                                                 stretch='normal')
        from matplotlib import pyplot
        fig = pyplot.figure(facecolor="white", figsize=[10, 10])
        ax1 = fig.add_subplot(1, 1, 1)
        #            x = arange(0, 1.01, 0.01)
        #            y15 = (1 - x ** 1.5) ** (1 / 1.5)
        #            y = (1 - x)

        ax1.set_xlabel('$F_\mathrm{Ed,V1}/F_\mathrm{Rd,V1}$', fontsize=24)
        ax1.set_ylabel('$F_\mathrm{Ed,t}/F_\mathrm{Rd,t}$', fontsize=24)
        #            ax1.set_xlabel('$|N_\mathrm{Ed}|$' , fontsize=32)
        #            ax1.set_ylabel('$|V_\mathrm{Ed}|$', fontsize=32)

        #            ax1.plot(x , y, '--', color='black'
        #                      , linewidth=2.0)
        #            ax1.plot(x , y15, '--', color='black'
        #                      , linewidth=2.0)

        ax1.plot(eta_V, eta_N, 'wo', markersize=3)
        #            ax1.plot(eta_V, eta_N, 'o', color='green', markersize=8)

        #            ax1.plot( eta_V[where( limit < 1 )] , eta_N[where( limit < 1 )], 'o', markersize = 8 )
        #            ax1.plot( eta_V[where( limit > 1 )] , eta_N[where( limit > 1 )], 'o', color = 'red', markersize = 8 )

        for xlabel_i in ax1.get_xticklabels():
            xlabel_i.set_fontsize(24)
            xlabel_i.set_family('serif')

        for ylabel_i in ax1.get_yticklabels():
            ylabel_i.set_fontsize(24)
            ylabel_i.set_family('serif')

    #        ax1.plot( x , 1 - x, '--', color = 'black', label = 'lineare Interaktion' )

        ax1.set_xlim(0, 1.0)
        ax1.set_ylim(0, 1.0)
        ax1.legend()
        pyplot.show()
        pyplot.clf()

    # choose linking type (in-plane shear dof blocked or not)
    #
    link_type = Enum('exc_V_ip', 'inc_V_ip')

    # length of the shell (needed to plot the hinge forces plots correctly)
    #
    length_xy_quarter = 3.5  # m

    def export_hf_lc(self):
        """exports the hinge forces for each loading case separately
        """

        from matplotlib import pyplot
        sr_columns = self.sr_columns
        dict = self.max_sr_grouped_dict
        length_xy_quarter = self.length_xy_quarter

        def save_bar_plot(x,
                          y,
                          filename='bla',
                          xlabel='xlabel',
                          ylabel='ylavel',
                          ymin=-10,
                          ymax=10,
                          width=0.1,
                          xmin=0,
                          xmax=1000,
                          figsize=[10, 5]):
            fig = pyplot.figure(facecolor="white", figsize=figsize)
            ax1 = fig.add_subplot(1, 1, 1)
            ax1.bar(x, y, width=width, align='center', color='blue')
            ax1.set_xlim(xmin, xmax)
            ax1.set_ylim(ymin, ymax)
            ax1.set_xlabel(xlabel, fontsize=22)
            ax1.set_ylabel(ylabel, fontsize=22)
            fig.savefig(filename, orientation='portrait', bbox_inches='tight')
            pyplot.clf()

        X = array(self.geo_data_dict['X_hf'])
        Y = array(self.geo_data_dict['Y_hf'])

        # symmetric axes
        #
        idx_sym = where(abs(Y[:, 0] - 2.0 * length_xy_quarter) <= 0.0001)
        X_sym = X[idx_sym].reshape(-1)
        idx_r0_r1 = where(abs(X[:, 0] - 2.0 * length_xy_quarter) <= 0.0001)
        X_r0_r1 = Y[idx_r0_r1].reshape(-1)
        F_int = self.lc_arr

        for i, lc_name in enumerate(self.lc_name_list):
            filename = self.lc_list[i].plt_export

            max_N_ip = max(int(ndmax(F_int[i, :, 0], axis=0)) + 1, 1)
            max_V_ip = max(int(ndmax(F_int[i, :, 1], axis=0)) + 1, 1)
            max_V_op = max(int(ndmax(F_int[i, :, 2], axis=0)) + 1, 1)

            F_int_lc = F_int[i, :, :]  # first row N_ip, second V_ip third V_op
            F_sym = F_int_lc[idx_sym, :].reshape(-1, len(sr_columns))
            F_r0_r1 = F_int_lc[idx_r0_r1, :].reshape(-1, len(sr_columns))

            save_bar_plot(
                X_sym,
                F_sym[:, 0].reshape(-1),
                #                          xlabel = '$X$ [m]', ylabel = '$N^{ip}$ [kN]',
                xlabel='$X$ [m]',
                ylabel='$N^{*}$ [kN]',
                filename=filename + 'N_ip' + '_sym',
                xmin=0.0,
                xmax=3.5 * length_xy_quarter,
                ymin=-max_N_ip,
                ymax=max_N_ip,
                figsize=[10, 5])

            save_bar_plot(X_sym,
                          F_sym[:, 1].reshape(-1),
                          xlabel='$X$ [m]',
                          ylabel='$V_{ip}$ [kN]',
                          filename=filename + 'V_ip' + '_sym',
                          xmin=0.0,
                          xmax=3.5 * length_xy_quarter,
                          ymin=-max_V_ip,
                          ymax=max_V_ip,
                          figsize=[10, 5])

            save_bar_plot(
                X_sym,
                F_sym[:, 2].reshape(-1),
                #                          xlabel = '$X$ [m]', ylabel = '$V_{op}$ [kN]',
                xlabel='$X$ [m]',
                ylabel='$V^{*}$ [kN]',
                filename=filename + 'V_op' + '_sym',
                xmin=0.0,
                xmax=3.5 * length_xy_quarter,
                ymin=-max_V_op,
                ymax=max_V_op,
                figsize=[10, 5])

            # r0_r1
            #
            save_bar_plot(
                X_r0_r1,
                F_r0_r1[:, 0].reshape(-1),
                #                          xlabel = '$Y$ [m]', ylabel = '$N_{ip}$ [kN]',
                xlabel='$Y$ [m]',
                ylabel='$N^{*}$ [kN]',
                filename=filename + 'N_ip' + '_r0_r1',
                xmin=0.0,
                xmax=2.0 * length_xy_quarter,
                ymin=-max_N_ip,
                ymax=max_N_ip,
                figsize=[5, 5])
            save_bar_plot(X_r0_r1,
                          F_r0_r1[:, 1].reshape(-1),
                          xlabel='$Y$ [m]',
                          ylabel='$V_{ip}$ [kN]',
                          filename=filename + 'V_ip' + '_r0_r1',
                          xmin=0.0,
                          xmax=2.0 * length_xy_quarter,
                          ymin=-max_V_ip,
                          ymax=max_V_ip,
                          figsize=[5, 5])
            save_bar_plot(
                X_r0_r1,
                F_r0_r1[:, 2].reshape(-1),
                #                          xlabel = '$Y$ [m]', ylabel = '$V_{op}$ [kN]',
                xlabel='$Y$ [m]',
                ylabel='$V^{*}$ [kN]',
                filename=filename + 'V_op' + '_r0_r1',
                xmin=0.0,
                xmax=2.0 * length_xy_quarter,
                ymin=-max_V_op,
                ymax=max_V_op,
                figsize=[5, 5])

    # ------------------------------------------------------------
    # View
    # ------------------------------------------------------------

    traits_view = View(VGroup(
        VSplit(
            Item('lcc_list', editor=lcc_list_editor, show_label=False),
            Item('lcc@', show_label=False),
        ), ),
                       resizable=True,
                       scrollable=True,
                       height=1.0,
                       width=1.0)
示例#25
0
class MRfour(MushRoofModel):

    #----------------------------------------------------
    # elements
    #----------------------------------------------------
    vtk_r = Float(1.0)
    # default column
    fe_column = Instance(FETSEval, transient=True)

    def _fe_column_default(self):
        fets = self.fe_quad_serendipity_column
        fets.vtk_r *= self.vtk_r
        return fets

    # default roof
    fe_roof = Instance(FETSEval,
                       ps_levels=[
                           'fe_linear', 'fe2d5_quad_serendipity',
                           'fe_quad_serendipity_roof',
                           'fe_quad_serendipity_column', 'fe_quad_lagrange'
                       ])

    def _fe_roof_default(self):
        fets = self.fe_quad_serendipity_roof
        fets.vtk_r *= self.vtk_r
        return fets

    #----------------------------------------------------
    # geometric transformation
    #----------------------------------------------------

    hp_shells = Property(List(HPShell), depends_on='+ps_levels, +input')

    @cached_property
    def _get_hp_shells(self):
        X_list = [[0, 0, 0], [7, 0, 0], [0, 7, 0], [7, 7, 0]]
        return [
            HPShell(
                length_xy_quarter=self.length_xy_quarter,
                length_z=self.length_z,
                t_shell=self.t_shell,
                X0=X,
                n_elems_xy_quarter=self.n_elems_xy_quarter,
                n_elems_z=self.n_elems_z,
                #                    shift_elems_column = self.shift_elems_column,
                scalefactor_delta_h=self.scalefactor_delta_h,
                const_reinf_layer_elem=self.const_reinf_layer_elem,
                width_top_col=self.width_top_col,
                #                    n_elems_col = self.n_elems_col,
                mushroof_part=self.mushroof_part) for X in X_list
        ]

    columns = Property(Instance(GEOColumn), depends_on='+ps_levels, +input')

    @cached_property
    def _get_columns(self):
        ch = self.h_col / self.scalefactor_delta_h
        X_list = [[3.5, 3.5, -ch], [10.5, 3.5, -ch], [3.5, 10.5, -ch],
                  [10.5, 10.5, -ch]]
        return [
            GEOColumn(width_top=self.width_top_col,
                      X0=X,
                      width_bottom=self.width_bottom_col,
                      h_col=ch) for X in X_list
        ]

    #----------------------------------------------------
    # grid
    #----------------------------------------------------
    fe_grid_roofs = Property(Instance(FEGrid), depends_on='+ps_levels, +input')

    @cached_property
    def _get_fe_grid_roofs(self):
        return [
            FEGrid(coord_min=(0.0, 0.0, 0.0),
                   coord_max=(1.0, 1.0, 1.0),
                   geo_transform=hp_shell,
                   shape=(self.n_elems_xy_quarter, self.n_elems_xy_quarter,
                          self.n_elems_z),
                   fets_eval=self.fe_roof) for hp_shell in self.hp_shells
        ]

    fe_grid_columns = Property(Instance(FEGrid),
                               depends_on='+ps_levels, +input')

    @cached_property
    def _get_fe_grid_columns(self):
        return [
            FEGrid(coord_min=(0.0, 0.0, 0.0),
                   coord_max=(1.0, 1.0, 1.0),
                   geo_transform=column,
                   shape=(1, 1, 1),
                   fets_eval=self.fe_column) for column in self.columns
        ]

    #----------------------------------------------------
    # ps_study
    #----------------------------------------------------

    def peval(self):
        '''
        Evaluate the model and return the array of results specified
        in the method get_sim_outputs.
        '''
        U = self.tloop.eval()

        U_z = U[self.corner_dof_r00][0, 0, 2]

        #        max_princ_stress = max( self.max_princ_stress._get_field_data().flatten() )

        return array(
            [U_z],
            #                       max_princ_stress ],
            dtype='float_')

    def get_sim_outputs(self):
        '''
        Specifies the results and their order returned by the model
        evaluation.
        '''
        return [SimOut(name='u_z_free_corner', unit='m')]


#               SimOut( name = 'maximum principle stress', unit = 'MPa' ), ]

#----------------------------------------------------
# loading and boundaries
#----------------------------------------------------
#    lc_symm_dict = Property( Dict )
#    def _get_lc_symm_dict ( self ):
#        return {'g_mat_dens_roof':Float( -0.0224, unit = 'MN/m^3' ),
#                'g_mat_dens_column':Float( -0.024, unit = 'MN/m^3' ),
#                'g_surf_load_gA':Float( -0.20e-3, unit = 'MN/m^2' ),
#                's_surf_load':Float( -0.84e-3, unit = 'MN/m^2' ),
#                'w_surf_load':Float( -0.13e-3, unit = 'MN/m^2' ),
#                }
#--- LC0: verifying load for ps_study
# g = 1.0 kN/m^2
# orientation: global z-direction;

    f_z = Float(-1e-3, unit='MN/m^3')

    #--- LC1: dead load
    # g = 22.4 kN/m^3
    # orientation: global z-direction;
    material_density_roof = Float(-0.0224, unit='MN/m^3')
    material_density_column = Float(-0.0224, unit='MN/m^3')

    #--- LC2 additional dead load
    # gA = 0,20 kN/m^2
    # orientation: global z-direction (following the curved structure);
    surface_load_gA = Float(-0.20e-3, unit='MN/m^2')

    #--- LC3 snow
    # s = 0,79 kN/m^2
    # orientation: global z-direction (projection);
    surface_load_s = Float(-0.84e-3, unit='MN/m^2')

    #--- LC4 wind (pressure)
    # w = 0,13 kN/m^2
    # orientation: local t-direction (surface normal);
    surface_load_w = Float(-0.13e-3, unit='MN/m^2')

    force_bc_list = Property(List, depends_on='+ps_levels, +input')

    @cached_property
    def _get_force_bc_list(self):
        # NOTE: additional line-loads at the edge of the roof need to be considered!

        force_bc_list = []
        for roof, column in zip(self.fe_grid_roofs, self.fe_grid_columns):
            upper_surface = roof[:, :, -1, :, :, -1]
            #            whole_roof = roof[:, :, :, :, :, :]
            #            whole_column = column[:, :, :, :, :, :]

            force_bc = [
                #                         # LC0: dead load
                BCSlice(var='f',
                        value=self.f_z,
                        dims=[2],
                        integ_domain='global',
                        slice=upper_surface),

                #                         # LC1: dead load
                #                         BCSlice( var = 'f', value = self.material_density_roof, dims = [2],
                #                                  integ_domain = 'global',
                #                                  slice = whole_roof ),
                #                         BCSlice( var = 'f', value = self.material_density_column, dims = [2],
                #                                  integ_domain = 'global',
                #                                  slice = whole_column ),
                # LC2: additional dead load
                #                         BCSlice( var = 'f', value = self.surface_load_gA, dims = [2],
                #                                  integ_domain = 'global',
                #                                  slice = upper_surface ),
                #                         # LC3: snow load
                #                         BCSlice( var = 'f', value = self.surface_load_s, dims = [2],
                #                                  integ_domain = 'global',
                #                                  slice = upper_surface )
            ]
            force_bc_list += force_bc

        return force_bc_list

    displ_bc_list = Property(List, depends_on='+ps_levels, +input')

    @cached_property
    def _get_displ_bc_list(self):

        displ_bc_list = []
        for roof, column in zip(self.fe_grid_roofs, self.fe_grid_columns):
            bc_list = [
                BCSlice(var='u',
                        dims=[0, 1, 2],
                        slice=roof[self.n_elems_xy_quarter - 1,
                                   self.n_elems_xy_quarter - 1, 0, 0, -1, 0],
                        link_slice=column[0, 0, -1, 0, 0, -1],
                        link_coeffs=[1.0],
                        value=0.),
                BCSlice(var='u',
                        dims=[0, 1, 2],
                        slice=roof[self.n_elems_xy_quarter - 1,
                                   self.n_elems_xy_quarter - 1, 0, -1, 0, 0],
                        link_slice=column[-1, 0, -1, -1, 0, -1],
                        link_coeffs=[1.0],
                        value=0.),
                BCSlice(var='u',
                        dims=[0, 1, 2],
                        slice=roof[self.n_elems_xy_quarter,
                                   self.n_elems_xy_quarter, 0, -1, 0, 0],
                        link_slice=column[-1, -1, -1, -1, -1, -1],
                        link_coeffs=[1.0],
                        value=0.),
                BCSlice(var='u',
                        dims=[0, 1, 2],
                        slice=roof[self.n_elems_xy_quarter,
                                   self.n_elems_xy_quarter, 0, 0, -1, 0],
                        link_slice=column[0, -1, -1, 0, -1, -1],
                        link_coeffs=[1.0],
                        value=0.),
                BCSlice(
                    var='u',
                    dims=[0, 1, 2],
                    slice=column[:, :, 0, :, :, 0],
                    #                                 slice = column[ 0, 0, 0, -1, -1, 0 ],
                    value=0.0)
            ]
            displ_bc_list += bc_list
        return displ_bc_list

    wind_bc_list = Property(List, depends_on='+ps_levels, +input')

    @cached_property
    def _get_wind_bc_list(self):

        w_left_edge = 0.91e-3  # [MN/m]
        w_right_edge = 0.39e-3  # [MN/m]
        w_bottom_edge_0 = 1.14e-3  # [Mn/m]
        w_bottom_edge_1 = 0.65e-3  # [Mn/m]
        w_top_edge_0 = -w_bottom_edge_0  # [Mn/m]
        w_top_edge_1 = -w_bottom_edge_1  # [Mn/m]
        w_face_0_left = 0.89e-3  # MN/m^2
        w_face_0_right = -0.13e-3  # MN/m^2
        w_face_1_left = 0.72e-3  # MN/m^2
        w_face_1_right = w_face_0_right

        r00, r10, r01, r11 = self.fe_grid_roofs

        left_edge_0 = r00[0, :, -1, 0, :, -1]
        left_edge_1 = r01[0, :, -1, 0, :, -1]
        right_edge_0 = r10[-1, :, -1, 0, :, -1]
        right_edge_1 = r11[-1, :, -1, 0, :, -1]
        bottom_edge_0 = r00[:, 0, -1, :, 0, -1]
        bottom_edge_1 = r10[:, 0, -1, :, 0, -1]
        top_edge_0 = r01[:, -1, -1, :, -1, -1]
        top_edge_1 = r11[:, -1, -1, :, -1, -1]

        n_e_q = self.n_elems_xy_quarter
        face_00_left = r00[:n_e_q, :, -1, :, :, -1]
        face_00_right = r00[n_e_q:, :, -1, :, :, -1]
        face_01_left = r01[:n_e_q, :, -1, :, :, -1]
        face_01_right = r01[n_e_q:, :, -1, :, :, -1]
        face_10_left = r10[:n_e_q, :, -1, :, :, -1]
        face_10_right = r10[n_e_q:, :, -1, :, :, -1]
        face_11_left = r11[:n_e_q, :, -1, :, :, -1]
        face_11_right = r11[n_e_q:, :, -1, :, :, -1]

        wind_list = [
            # left edge - x direction
            BCSlice(var='f', dims=[0], slice=left_edge_0, value=w_left_edge),
            BCSlice(var='f', dims=[0], slice=left_edge_1, value=w_left_edge),
            # right edge - x direction
            BCSlice(var='f', dims=[0], slice=right_edge_0, value=w_right_edge),
            BCSlice(var='f', dims=[0], slice=right_edge_1, value=w_right_edge),
            # bottom edge - y direction
            BCSlice(var='f',
                    dims=[1],
                    slice=bottom_edge_0,
                    value=w_bottom_edge_0),
            BCSlice(var='f',
                    dims=[1],
                    slice=bottom_edge_1,
                    value=w_bottom_edge_1),
            # top edge - y direction
            BCSlice(var='f', dims=[1], slice=top_edge_0, value=w_top_edge_0),
            BCSlice(var='f', dims=[1], slice=top_edge_1, value=w_top_edge_1),
            # upper face left - left
            BCSlice(var='f', dims=[2], slice=face_00_left,
                    value=w_face_0_left),
            BCSlice(var='f', dims=[2], slice=face_01_left,
                    value=w_face_0_left),
            # upper face left - right
            BCSlice(var='f',
                    dims=[2],
                    slice=face_00_right,
                    value=w_face_0_right),
            BCSlice(var='f',
                    dims=[2],
                    slice=face_01_right,
                    value=w_face_0_right),
            # upper face right - left
            BCSlice(var='f', dims=[2], slice=face_10_left,
                    value=w_face_1_left),
            BCSlice(var='f', dims=[2], slice=face_11_left,
                    value=w_face_1_left),
            # upper face right - right
            BCSlice(var='f',
                    dims=[2],
                    slice=face_10_right,
                    value=w_face_1_right),
            BCSlice(var='f',
                    dims=[2],
                    slice=face_11_right,
                    value=w_face_1_right),
        ]
        return wind_list

    link_bc_list = Property(List, depends_on='+ps_levels, +input')

    @cached_property
    def _get_link_bc_list(self):
        r00, r10, r01, r11 = self.fe_grid_roofs
        link_bc_list = [
            BCSlice(var='u',
                    dims=[0, 1, 2],
                    slice=r00[-1, :, -1, -1, :-1, -1],
                    link_slice=r10[0, :, -1, 0, :-1, -1],
                    link_coeffs=[1.0],
                    value=0.),
            BCSlice(var='u',
                    dims=[0, 1, 2],
                    slice=r01[:, 0, -1, :-1, 0, -1],
                    link_slice=r00[:, -1, -1, :-1, -1, -1],
                    link_coeffs=[1.0],
                    value=0.),
            BCSlice(var='u',
                    dims=[0, 1, 2],
                    slice=r11[0, :, -1, 0, 1:, -1],
                    link_slice=r01[-1, :, -1, -1, 1:, -1],
                    link_coeffs=[1.0],
                    value=0.),
            BCSlice(var='u',
                    dims=[0, 1, 2],
                    slice=r10[:, -1, -1, 1:, -1, -1],
                    link_slice=r11[:, 0, -1, 1:, 0, -1],
                    link_coeffs=[1.0],
                    value=0.),
        ]
        return link_bc_list

    #----------------------------------------------------
    # response tracer
    #----------------------------------------------------

    rtrace_list = List

    def _rtrace_list_default(self):
        return [self.max_princ_stress, self.sig_app, self.u]

    # time loop
    tloop = Property(depends_on='+ps_levels, +input')

    @cached_property
    def _get_tloop(self):
        # self.fets.vtk_r *= 0.95

        roofs = self.fe_grid_roofs

        columns = self.fe_grid_columns

        r00, r10, r01, r11 = roofs

        self.corner_dof_r00 = r00[0, 0, 0, 0, 0, 0].dofs

        rtrace_list = self.rtrace_list

        ts = TS(
            sdomain=roofs + columns,
            dof_resultants=True,
            #                 bcond_list = self.wind_bc_list + self.displ_bc_list + self.link_bc_list,
            bcond_list=self.force_bc_list + self.displ_bc_list +
            self.link_bc_list,
            #                 bcond_list = self.displ_bc_list + self.link_bc_list,
            rtrace_list=rtrace_list)

        # Add the time-loop control
        tloop = TLoop(tstepper=ts, tolerance=1e-4, tline=self.tline)

        return tloop
示例#26
0
class LC(HasTraits):
    '''Loading case class
    '''
    # path to the directory containing the state data files
    #
    data_dir = Directory

    # name of the file containing the hinge forces
    # or the displacements
    #
    file_name = Str(input=True)

    plt_export = Property

    def _get_plt_export(self):
        basename = 'hf_' + self.name + '_'
        return os.path.join(data_dir, basename)

    # data filter (used to hide unwanted values, e.g. high sigularities etc.)
    #
    data_filter = Callable(input=True)

    def _data_filter_default(self):
        return lambda x: x  #  - do nothing by default

    # name of the loading case
    #
    name = Str(input=True)

    # category of the loading case
    #
    category = Enum('dead-load',
                    'additional dead-load',
                    'imposed-load',
                    input=True)

    # list of keys specifying the names of the loading cases
    # that can not exist at the same time, i.e. which are exclusive to each other
    #
    exclusive_to = List(Str, input=True)

    def _exclusive_to_default(self):
        return []

    # combination factors (need to be defined in case of imposed loads)
    #
    psi_0 = Float(input=True)
    psi_1 = Float(input=True)
    psi_2 = Float(input=True)

    # security factors ULS
    #
    gamma_fav = Float(input=True)

    def _gamma_fav_default(self):
        if self.category == 'dead-load':
            return 1.00
        if self.category == 'additional dead-load':
            return 0.00
        if self.category == 'imposed-load':
            return 0.00

    gamma_unf = Float(input=True)

    def _gamma_unf_default(self):
        if self.category == 'dead-load':
            return 1.35
        if self.category == 'additional dead-load':
            return 1.35
        if self.category == 'imposed-load':
            return 1.50

    # security factors SLS:
    # (used to distinguish combinations where imposed-loads
    # or additional-dead-loads are favorable or unfavorable.)
    #
    gamma_fav_SLS = Float(input=True)

    def _gamma_fav_SLS_default(self):
        if self.category == 'dead-load':
            return 1.00
        elif self.category == 'additional dead-load' or \
             self.category == 'imposed-load':
            return 0.00

    gamma_unf_SLS = Float(input=True)

    def _gamma_unf_SLS_default(self):
        return 1.00

    def _read_data(self, file_name):
        '''read state data and geo data from csv-file using ';' as filed delimiter and ' ' (blank)
        as text delimiter.
        '''
        print '*** read state data from file: %s ***' % (file_name)

        # hinge forces N,V in global coordinates (as obtained from FE-modell)
        #
        #        input_arr = loadtxt(file_name , delimiter=';', skiprows=2, usecols=(2, 3, 4, 5, 6))

        #        # hinge forces N*,V* in local (hinge) coordinate system (transformed by inclination angle of the hinges, i.e. shell geometry)
        #        #
        input_arr = loadtxt(file_name,
                            delimiter=';',
                            skiprows=2,
                            usecols=(2, 3, 4, 8, 9))

        # hinge position [m]
        #
        X_hf = input_arr[:, 0][:, None]
        Y_hf = input_arr[:, 1][:, None]
        Z_hf = input_arr[:, 2][:, None]

        # INPUT Matthias - RFEM
        X_hf += 3.5
        Y_hf += 3.5

        # local hinge forces [kN]
        #
        N_ip = input_arr[:, 3][:, None]
        V_op = input_arr[:, 4][:, None]
        V_ip = 0. * V_op

        return {
            'X_hf': X_hf,
            'Y_hf': Y_hf,
            'Z_hf': Z_hf,
            'N_ip': N_ip,
            'V_ip': V_ip,
            'V_op': V_op,
        }

    # original data (before filtering)
    #
    data_orig = Property(Dict, depends_on='file_name')

    @cached_property
    def _get_data_orig(self):
        return self._read_data(self.file_name)

    # data (after filtering)
    #
    data_dict = Property(Dict, depends_on='file_name, data_filter')

    @cached_property
    def _get_data_dict(self):
        d = {}
        for k, arr in self.data_orig.items():
            d[k] = self.data_filter(arr)
        return d

    sr_columns = List(['N_ip', 'V_ip', 'V_op'])
    geo_columns = List(['X_hf', 'Y_hf', 'Z_hf'])

    sr_arr = Property(Array)

    def _get_sr_arr(self):
        '''return the stress resultants of the loading case
        as stack of all sr-column arrays.
        '''
        data_dict = self.data_dict
        return hstack([data_dict[sr_key] for sr_key in self.sr_columns])

    geo_data_dict = Property(Array)

    def _get_geo_data_dict(self):
        '''Dict of coords as sub-Dict of read in data dict
        '''
        data_dict = self.data_dict
        geo_data_dict = {}
        for geo_key in self.geo_columns:
            geo_data_dict[geo_key] = data_dict[geo_key]
        return geo_data_dict

    def _read_data_u(self, file_name_u):
        '''used to read RFEM files
        read state data and geo date from csv-file using ';' as filed delimiter and ' ' (blank)
        as text delimiter for displacement.
        '''
        print '*** read state data from file: %s ***' % (file_name_u)

        # get the column headings defined in the first row
        # of the csv displacement input file
        #
        file = open(file_name_u, 'r')
        lines = file.readlines()
        column_headings = lines[1].split(';')
        # remove '\n' from last string element in list
        #
        column_headings[-1] = column_headings[-1][:-1]
        column_headings_arr = array(column_headings)

        # skip the first two columns for 'loadtxt';
        # therefore subtract index by 2

        # geo_data:
        #
        X_idx = where('jX' == column_headings_arr)[0] - 2
        Y_idx = where('jY' == column_headings_arr)[0] - 2
        Z_idx = where('jZ' == column_headings_arr)[0] - 2

        # state_data:
        #
        U_x_idx = where('uX' == column_headings_arr)[0] - 2
        U_y_idx = where('uY' == column_headings_arr)[0] - 2
        U_z_idx = where('uZ' == column_headings_arr)[0] - 2

        file.close()
        input_arr = loadtxt(file_name_u,
                            delimiter=';',
                            skiprows=2,
                            usecols=(2, 3, 4, 5, 6, 7))

        # global coords [m]
        #
        self.X_u = input_arr[:, X_idx] + 3.5
        self.Y_u = input_arr[:, Y_idx] + 3.5
        self.Z_u = input_arr[:, Z_idx]

        print 'self.X_u', self.X_u
        print 'self.Y_u', self.Y_u

        # hinge forces [kN]
        #
        self.U_x = input_arr[:, U_x_idx]
        self.U_y = input_arr[:, U_y_idx]
        self.U_z = input_arr[:, U_z_idx]
示例#27
0
class SPIRRIDLAB(HasTraits):
    '''Class used for elementary parametric studies of spirrid.
    '''

    s = Instance(SPIRRID)

    evars = DelegatesTo('s')

    tvars = DelegatesTo('s')

    q = DelegatesTo('s')

    exact_arr = Array('float')

    dpi = Int

    plot_mode = Enum(['subplots', 'figures'])

    fig_output_dir = Directory('fig')

    @on_trait_change('fig_output_dir')
    def _check_dir(self):
        if os.access(self.fig_output_dir, os.F_OK) == False:
            os.mkdir(self.fig_output_dir)

    e_arr = Property

    def _get_e_arr(self):
        return self.s.evar_lst[0]

    hostname = Property

    def _get_hostname(self):
        return gethostname()

    qname = Str

    def get_qname(self):
        if self.qname == '':
            if isinstance(self.q, types.FunctionType):
                qname = self.q.__name__
            else:  # if isinstance(self.q, types.ClassType):
                qname = self.q.__class__.__name__
        else:
            qname = self.qname
        return qname

    show_output = False

    save_output = True

    plot_sampling_idx = Array(value=[0, 1], dtype=int)

    def _plot_sampling(self,
                       i,
                       n_col,
                       sampling_type,
                       p=p,
                       ylim=None,
                       xlim=None):
        '''Construct a spirrid object, run the calculation
        plot the mu_q / e curve and save it in the subdirectory.
        '''

        s = self.s
        s.sampling_type = sampling_type

        plot_idx = self.plot_sampling_idx

        qname = self.get_qname()

        # get n randomly selected realizations from the sampling
        theta = s.sampling.get_samples(500)
        tvar_x = s.tvar_lst[plot_idx[0]]
        tvar_y = s.tvar_lst[plot_idx[1]]
        min_x, max_x, d_x = s.sampling.get_theta_range(tvar_x)
        min_y, max_y, d_y = s.sampling.get_theta_range(tvar_y)
        # for vectorized execution add a dimension for control variable
        theta_args = [t[:, np.newaxis] for t in theta]
        q_arr = s.q(self.e_arr[None, :], *theta_args)
        if self.plot_mode == 'figures':
            f = p.figure(figsize=(7., 6.))
            f.subplots_adjust(left=0.15, right=0.97, bottom=0.15, top=0.92)
        if self.plot_mode == 'subplots':
            if i == 0:
                f = p.figure()
            p.subplot('2%i%i' % (n_col, (i + 1)))

        p.plot(theta[plot_idx[0]], theta[plot_idx[1]], 'o', color='grey')
        p.xlabel('$\lambda$')
        p.ylabel('$\\xi$')

        p.xlim(min_x, max_x)
        p.ylim(min_y, max_y)
        p.title(s.sampling_type)

        if self.save_output:
            fname = os.path.join(
                self.fig_output_dir,
                qname + '_sampling_' + s.sampling_type + '.png')
            p.savefig(fname, dpi=self.dpi)

        if self.plot_mode == 'figures':
            f = p.figure(figsize=(7., 5))
            f.subplots_adjust(left=0.15, right=0.97, bottom=0.18, top=0.91)
        elif self.plot_mode == 'subplots':
            p.subplot('2%i%i' % (n_col, (i + 5)))

        p.plot(self.e_arr, q_arr.T, color='grey')

        if len(self.exact_arr) > 0:
            p.plot(self.e_arr,
                   self.exact_arr,
                   label='exact solution',
                   color='black',
                   linestyle='--',
                   linewidth=2)

        # numerically obtained result
        p.plot(self.e_arr,
               s.mu_q_arr,
               label='numerical integration',
               linewidth=3,
               color='black')
        p.title(s.sampling_type)
        p.xlabel('$\\varepsilon$ [-]')
        p.ylabel(r'$q(\varepsilon;\, \lambda,\, \xi)$')
        if ylim:
            p.ylim(0.0, ylim)
        if xlim:
            p.xlim(0.0, xlim)
        p.xticks(position=(0, -.015))
        p.legend(loc=2)

        if self.save_output:
            fname = os.path.join(self.fig_output_dir,
                                 qname + '_' + s.sampling_type + '.png')
            p.savefig(fname, dpi=self.dpi)

    sampling_structure_btn = Button(label='compare sampling structure')

    @on_trait_change('sampling_structure_btn')
    def sampling_structure(self, **kw):
        '''Plot the response into the file in the fig subdirectory.
        '''
        if self.plot_mode == 'subplots':
            p.rcdefaults()
        else:
            fsize = 28
            p.rcParams['font.size'] = fsize
            rc('legend', fontsize=fsize - 8)
            rc('axes', titlesize=fsize)
            rc('axes', labelsize=fsize + 6)
            rc('xtick', labelsize=fsize - 8)
            rc('ytick', labelsize=fsize - 8)
            rc('xtick.major', pad=8)

        s_lst = ['TGrid', 'PGrid', 'MCS', 'LHS']

        for i, s in enumerate(s_lst):
            self._plot_sampling(i, len(s_lst), sampling_type=s, **kw)

        if self.show_output:
            p.show()

    n_int_range = Array()

    #===========================================================================
    # Output file names for sampling efficiency
    #===========================================================================
    fname_sampling_efficiency_time_nint = Property

    def _get_fname_sampling_efficiency_time_nint(self):
        return self.get_qname(
        ) + '_' + '%s' % self.hostname + '_time_nint' + '.png'

    fname_sampling_efficiency_error_nint = Property

    def _get_fname_sampling_efficiency_error_nint(self):
        return self.get_qname(
        ) + '_' + '%s' % self.hostname + '_error_nint' + '.png'

    fname_sampling_efficiency_error_time = Property

    def _get_fname_sampling_efficiency_error_time(self):
        return self.get_qname(
        ) + '_' + '%s' % self.hostname + '_error_time' + '.png'

    fnames_sampling_efficiency = Property

    def _get_fnames_sampling_efficiency(self):
        fnames = [self.fname_sampling_efficiency_time_nint]
        if len(self.exact_arr) > 0:
            fnames += [
                self.fname_sampling_efficiency_error_nint,
                self.fname_sampling_efficiency_error_time
            ]
        return fnames

    #===========================================================================
    # Run sampling efficiency studies
    #===========================================================================

    sampling_types = Array(value=['TGrid', 'PGrid', 'MCS', 'LHS'], dtype=str)

    sampling_efficiency_btn = Button(label='compare sampling efficiency')

    @on_trait_change('sampling_efficiency_btn')
    def sampling_efficiency(self):
        '''
        Run the code for all available sampling types.
        Plot the results.
        '''
        def run_estimation(n_int, sampling_type):
            # instantiate spirrid with samplingetization methods
            print 'running', sampling_type, n_int
            self.s.set(n_int=n_int, sampling_type=sampling_type)
            n_sim = self.s.sampling.n_sim
            exec_time = np.sum(self.s.exec_time)
            return self.s.mu_q_arr, exec_time, n_sim

        # vectorize the estimation to accept arrays
        run_estimation_vct = np.vectorize(run_estimation, [object, float, int])

        #===========================================================================
        # Generate the inspected domain of input parameters using broadcasting
        #===========================================================================

        run_estimation_vct([5], ['PGrid'])

        sampling_types = self.sampling_types
        sampling_colors = np.array(
            ['grey', 'black', 'grey', 'black'],
            dtype=str)  # 'blue', 'green', 'red', 'magenta'
        sampling_linestyle = np.array(['--', '--', '-', '-'], dtype=str)

        # run the estimation on all combinations of n_int and sampling_types
        mu_q, exec_time, n_sim_range = run_estimation_vct(
            self.n_int_range[:, None], sampling_types[None, :])

        p.rcdefaults()
        f = p.figure(figsize=(12, 6))
        f.subplots_adjust(left=0.06, right=0.94)

        #===========================================================================
        # Plot the results
        #===========================================================================
        p.subplot(1, 2, 1)
        p.title('response for %d $n_\mathrm{sim}$' % n_sim_range[-1, -1])
        for i, (sampling, color, linestyle) in enumerate(
                zip(sampling_types, sampling_colors, sampling_linestyle)):
            p.plot(self.e_arr,
                   mu_q[-1, i],
                   color=color,
                   label=sampling,
                   linestyle=linestyle)

        if len(self.exact_arr) > 0:
            p.plot(self.e_arr,
                   self.exact_arr,
                   color='black',
                   label='Exact solution')

        p.legend(loc=1)
        p.xlabel('e', fontsize=18)
        p.ylabel('q', fontsize=18)

        # @todo: get n_sim - x-axis
        p.subplot(1, 2, 2)
        for i, (sampling, color, linestyle) in enumerate(
                zip(sampling_types, sampling_colors, sampling_linestyle)):
            p.loglog(n_sim_range[:, i],
                     exec_time[:, i],
                     color=color,
                     label=sampling,
                     linestyle=linestyle)

        p.legend(loc=2)
        p.xlabel('$n_\mathrm{sim}$', fontsize=18)
        p.ylabel('$t$ [s]', fontsize=18)

        if self.save_output:
            basename = self.fname_sampling_efficiency_time_nint
            fname = os.path.join(self.fig_output_dir, basename)
            p.savefig(fname, dpi=self.dpi)

        #===========================================================================
        # Evaluate the error
        #===========================================================================

        if len(self.exact_arr) > 0:
            er = ErrorEval(exact_arr=self.exact_arr)

            def eval_error(mu_q, error_measure):
                return error_measure(mu_q)

            eval_error_vct = np.vectorize(eval_error)

            error_measures = np.array(
                [er.eval_error_max, er.eval_error_energy, er.eval_error_rms])
            error_table = eval_error_vct(mu_q[:, :, None],
                                         error_measures[None, None, :])

            f = p.figure(figsize=(14, 6))
            f.subplots_adjust(left=0.07, right=0.97, wspace=0.26)

            p.subplot(1, 2, 1)
            p.title('max rel. lack of fit')
            for i, (sampling, color, linestyle) in enumerate(
                    zip(sampling_types, sampling_colors, sampling_linestyle)):
                p.loglog(n_sim_range[:, i],
                         error_table[:, i, 0],
                         color=color,
                         label=sampling,
                         linestyle=linestyle)

            #p.ylim( 0, 10 )
            p.legend()
            p.xlabel('$n_\mathrm{sim}$', fontsize=18)
            p.ylabel('$\mathrm{e}_{\max}$ [-]', fontsize=18)

            p.subplot(1, 2, 2)
            p.title('rel. root mean square error')
            for i, (sampling, color, linestyle) in enumerate(
                    zip(sampling_types, sampling_colors, sampling_linestyle)):
                p.loglog(n_sim_range[:, i],
                         error_table[:, i, 2],
                         color=color,
                         label=sampling,
                         linestyle=linestyle)
            p.legend()
            p.xlabel('$n_{\mathrm{sim}}$', fontsize=18)
            p.ylabel('$\mathrm{e}_{\mathrm{rms}}$ [-]', fontsize=18)

            if self.save_output:
                basename = self.fname_sampling_efficiency_error_nint
                fname = os.path.join(self.fig_output_dir, basename)
                p.savefig(fname, dpi=self.dpi)

            f = p.figure(figsize=(14, 6))
            f.subplots_adjust(left=0.07, right=0.97, wspace=0.26)

            p.subplot(1, 2, 1)
            p.title('rel. max lack of fit')
            for i, (sampling, color, linestyle) in enumerate(
                    zip(sampling_types, sampling_colors, sampling_linestyle)):
                p.loglog(exec_time[:, i],
                         error_table[:, i, 0],
                         color=color,
                         label=sampling,
                         linestyle=linestyle)
            p.legend()
            p.xlabel('time [s]', fontsize=18)
            p.ylabel('$\mathrm{e}_{\max}$ [-]', fontsize=18)

            p.subplot(1, 2, 2)
            p.title('rel. root mean square error')
            for i, (sampling, color, linestyle) in enumerate(
                    zip(sampling_types, sampling_colors, sampling_linestyle)):
                p.loglog(exec_time[:, i],
                         error_table[:, i, 2],
                         color=color,
                         label=sampling,
                         linestyle=linestyle)
            p.legend()
            p.xlabel('time [s]', fontsize=18)
            p.ylabel('$\mathrm{e}_{\mathrm{rms}}$ [-]', fontsize=18)

            if self.save_output:
                basename = self.fname_sampling_efficiency_error_time
                fname = os.path.join(self.fig_output_dir, basename)
                p.savefig(fname, dpi=self.dpi)

        if self.show_output:
            p.show()

    #===========================================================================
    # Efficiency of numpy versus C code
    #===========================================================================
    run_lst_detailed_config = Property(List)

    def _get_run_lst_detailed_config(self):
        run_lst = []
        if hasattr(self.q, 'c_code'):
            run_lst += [
                #                ('c',
                #                 {'cached_dG'         : True,
                #                  'compiled_eps_loop' : True },
                #                  'go-',
                #                  '$\mathsf{C}_{\\varepsilon} \{\, \mathsf{C}_{\\theta} \{\,  q(\\varepsilon,\\theta) \cdot G[\\theta] \,\}\,\} $ - %4.2f sec',
                #                  ),
                #                ('c',
                #                 {'cached_dG'         : True,
                #                  'compiled_eps_loop' : False },
                #                 'r-2',
                #                 '$\mathsf{Python} _{\\varepsilon} \{\, \mathsf{C}_{\\theta} \{\,  q(\\varepsilon,\\theta) \cdot G[\\theta] \,\}\,\} $ - %4.2f sec'
                #                 ),
                #                ('c',
                #                 {'cached_dG'         : False,
                #                  'compiled_eps_loop' : True },
                #                 'r-2',
                #                 '$\mathsf{C}_{\\varepsilon} \{\, \mathsf{C}_{\\theta} \{\, q(\\varepsilon,\\theta) \cdot g[\\theta_1] \cdot \ldots \cdot g[\\theta_m] \,\}\,\} $ - %4.2f sec'
                #                 ),
                (
                    'c',
                    {
                        'cached_dG': False,
                        'compiled_eps_loop': False
                    },
                    'bx-',
                    '$\mathsf{Python} _{\\varepsilon} \{\, \mathsf{C}_{\\theta}  \{\, q(\\varepsilon,\\theta) \cdot g[\\theta_1] \cdot \ldots \cdot g[\\theta_m] \,\} \,\} $ - %4.2f sec',
                )
            ]
        if hasattr(self.q, 'cython_code'):
            run_lst += [
                #                ('cython',
                #                 {'cached_dG'         : True,
                #                  'compiled_eps_loop' : True },
                #                  'go-',
                #                  '$\mathsf{Cython}_{\\varepsilon} \{\, \mathsf{Cython}_{\\theta} \{\,  q(\\varepsilon,\\theta) \cdot G[\\theta] \,\}\,\} $ - %4.2f sec',
                #                  ),
                #                ('cython',
                #                 {'cached_dG'         : True,
                #                  'compiled_eps_loop' : False },
                #                 'r-2',
                #                 '$\mathsf{Python} _{\\varepsilon} \{\, \mathsf{Cython}_{\\theta} \{\,  q(\\varepsilon,\\theta) \cdot G[\\theta] \,\}\,\} $ - %4.2f sec'
                #                 ),
                #                ('cython',
                #                 {'cached_dG'         : False,
                #                  'compiled_eps_loop' : True },
                #                 'r-2',
                #                 '$\mathsf{Cython}_{\\varepsilon} \{\, \mathsf{Cython}_{\\theta} \{\, q(\\varepsilon,\\theta) \cdot g[\\theta_1] \cdot \ldots \cdot g[\\theta_m] \,\}\,\} $ - %4.2f sec'
                #                 ),
                #                ('cython',
                #                 {'cached_dG'         : False,
                #                  'compiled_eps_loop' : False },
                #                  'bx-',
                #                  '$\mathsf{Python} _{\\varepsilon} \{\, \mathsf{Cython}_{\\theta}  \{\, q(\\varepsilon,\\theta) \cdot g[\\theta_1] \cdot \ldots \cdot g[\\theta_m] \,\} \,\} $ - %4.2f sec',
                #                 )
            ]
        if hasattr(self.q, '__call__'):
            run_lst += [
                #                ('numpy',
                #                 {},
                #                 'y--',
                #                 '$\mathsf{Python}_{\\varepsilon} \{\,  \mathsf{Numpy}_{\\theta} \{\,  q(\\varepsilon,\\theta) \cdot G[\\theta] \,\} \,\} $ - %4.2f sec'
                #                 )
            ]
        return run_lst

    # number of recalculations to get new time.
    n_recalc = Int(2)

    def codegen_efficiency(self):
        # define a tables with the run configurations to start in a batch

        basenames = []

        qname = self.get_qname()

        s = self.s

        legend = []
        legend_lst = []
        time_lst = []
        p.figure()

        for idx, run in enumerate(self.run_lst_detailed_config):
            code, run_options, plot_options, legend_string = run
            s.codegen_type = code
            s.codegen.set(**run_options)
            print 'run', idx, run_options

            for i in range(self.n_recalc):
                s.recalc = True  # automatically proagated within spirrid
                print 'execution time', s.exec_time

            p.plot(s.evar_lst[0], s.mu_q_arr, plot_options)

            # @todo: this is not portable!!
            #legend.append(legend_string % s.exec_time)
            #legend_lst.append(legend_string[:-12])
            time_lst.append(s.exec_time)

        p.xlabel('strain [-]')
        p.ylabel('stress')
        #p.legend(legend, loc = 2)
        p.title(qname)

        if self.save_output:
            print 'saving codegen_efficiency'
            basename = qname + '_' + 'codegen_efficiency' + '.png'
            basenames.append(basename)
            fname = os.path.join(self.fig_output_dir, basename)
            p.savefig(fname, dpi=self.dpi)

        self._bar_plot(legend_lst, time_lst)
        p.title('%s' % s.sampling_type)
        if self.save_output:
            basename = qname + '_' + 'codegen_efficiency_%s' % s.sampling_type + '.png'
            basenames.append(basename)
            fname = os.path.join(self.fig_output_dir, basename)
            p.savefig(fname, dpi=self.dpi)

        if self.show_output:
            p.show()

        return basenames

    #===========================================================================
    # Efficiency of numpy versus C code
    #===========================================================================
    run_lst_language_config = Property(List)

    def _get_run_lst_language_config(self):
        run_lst = []
        if hasattr(self.q, 'c_code'):
            run_lst += [(
                'c',
                {
                    'cached_dG': False,
                    'compiled_eps_loop': False
                },
                'bx-',
                '$\mathsf{Python} _{\\varepsilon} \{\, \mathsf{C}_{\\theta}  \{\, q(\\varepsilon,\\theta) \cdot g[\\theta_1] \cdot \ldots \cdot g[\\theta_m] \,\} \,\} $ - %4.2f sec',
            )]
        if hasattr(self.q, 'cython_code'):
            run_lst += [(
                'cython',
                {
                    'cached_dG': False,
                    'compiled_eps_loop': False
                },
                'bx-',
                '$\mathsf{Python} _{\\varepsilon} \{\, \mathsf{Cython}_{\\theta}  \{\, q(\\varepsilon,\\theta) \cdot g[\\theta_1] \cdot \ldots \cdot g[\\theta_m] \,\} \,\} $ - %4.2f sec',
            )]
        if hasattr(self.q, '__call__'):
            run_lst += [(
                'numpy', {}, 'y--',
                '$\mathsf{Python}_{\\varepsilon} \{\,  \mathsf{Numpy}_{\\theta} \{\,  q(\\varepsilon,\\theta) \cdot G[\\theta] \,\} \,\} $ - %4.2f sec'
            )]
        return run_lst

    extra_compiler_args = Bool(True)
    le_sampling_lst = List(['LHS', 'PGrid'])
    le_n_int_lst = List([440, 5000])

    #===========================================================================
    # Output file names for language efficiency
    #===========================================================================
    fnames_language_efficiency = Property

    def _get_fnames_language_efficiency(self):
        return [
            '%s_codegen_efficiency_%s_extra_%s.png' %
            (self.qname, self.hostname, extra)
            for extra in [self.extra_compiler_args]
        ]

    language_efficiency_btn = Button(label='compare language efficiency')

    @on_trait_change('language_efficiency_btn')
    def codegen_language_efficiency(self):
        # define a tables with the run configurations to start in a batch

        home_dir = expanduser("~")

        #        pyxbld_dir = os.path.join(home_dir, '.pyxbld')
        #        if os.path.exists(pyxbld_dir):
        #            shutil.rmtree(pyxbld_dir)

        python_compiled_dir = os.path.join(home_dir, '.python27_compiled')
        if os.path.exists(python_compiled_dir):
            shutil.rmtree(python_compiled_dir)

        for extra, fname in zip([self.extra_compiler_args],
                                self.fnames_language_efficiency):
            print 'extra compilation args:', extra
            legend_lst = []
            error_lst = []
            n_sim_lst = []
            exec_times_sampling = []

            meth_lst = zip(self.le_sampling_lst, self.le_n_int_lst)
            for item, n_int in meth_lst:
                print 'sampling method:', item
                s = self.s
                s.exec_time  # eliminate first load time delay (first column)
                s.n_int = n_int
                s.sampling_type = item
                exec_times_lang = []

                for idx, run in enumerate(self.run_lst_language_config):
                    code, run_options, plot_options, legend_string = run

                    #os.system('rm -fr ~/.python27_compiled')

                    s.codegen_type = code
                    s.codegen.set(**run_options)
                    if s.codegen_type == 'c':
                        s.codegen.set(**dict(use_extra=extra))
                    print 'run', idx, run_options

                    exec_times_run = []
                    for i in range(self.n_recalc):
                        s.recalc = True  # automatically propagated
                        exec_times_run.append(s.exec_time)
                        print 'execution time', s.exec_time

                    legend_lst.append(legend_string[:-12])
                    if s.codegen_type == 'c':
                        # load weave.inline time from tmp file and fix values in time_arr
                        #@todo - does not work on windows
                        import tempfile
                        tdir = tempfile.gettempdir()
                        f = open(os.path.join(tdir, 'w_time'), 'r')
                        value_t = float(f.read())
                        f.close()
                        exec_times_run[0][1] = value_t
                        exec_times_run[0][2] -= value_t
                        exec_times_lang.append(exec_times_run)
                    else:
                        exec_times_lang.append(exec_times_run)

                print 'legend_lst', legend_lst
                n_sim_lst.append(s.sampling.n_sim)
                exec_times_sampling.append(exec_times_lang)
                #===========================================================================
                # Evaluate the error
                #===========================================================================
                if len(self.exact_arr) > 0:
                    er = ErrorEval(exact_arr=self.exact_arr)
                    error_lst.append((er.eval_error_rms(s.mu_q_arr),
                                      er.eval_error_max(s.mu_q_arr)))

            times_arr = np.array(exec_times_sampling, dtype='d')
            self._multi_bar_plot(meth_lst, legend_lst, times_arr, error_lst,
                                 n_sim_lst)
            if self.save_output:
                fname_path = os.path.join(self.fig_output_dir, fname)
                p.savefig(fname_path, dpi=self.dpi)

        if self.show_output:
            p.show()

    def combination_efficiency(self, tvars_det, tvars_rand):
        '''
        Run the code for all available random parameter combinations.
        Plot the results.
        '''
        qname = self.get_qname()

        s = self.s
        s.set(sampling_type='TGrid')

        # list of all combinations of response function parameters
        rv_comb_lst = list(powerset(s.tvars.keys()))

        p.figure()
        exec_time_lst = []

        for id, rv_comb in enumerate(rv_comb_lst[163:219]):  # [1:-1]
            s.tvars = tvars_det
            print 'Combination', rv_comb

            for rv in rv_comb:
                s.tvars[rv] = tvars_rand[rv]

            #legend = []
            #p.figure()
            time_lst = []
            for idx, run in enumerate(self.run_lst):
                code, run_options, plot_options, legend_string = run
                print 'run', idx, run_options
                s.codegen_type = code
                s.codegen.set(**run_options)

                #p.plot(s.evar_lst[0], s.mu_q_arr, plot_options)

                #print 'integral of the pdf theta', s.eval_i_dG_grid()
                print 'execution time', s.exec_time
                time_lst.append(s.exec_time)
                #legend.append(legend_string % s.exec_time)
            exec_time_lst.append(time_lst)
        p.plot(np.array((1, 2, 3, 4)), np.array(exec_time_lst).T)
        p.xlabel('method')
        p.ylabel('time')

        if self.save_output:
            print 'saving codegen_efficiency'
            fname = os.path.join(
                self.fig_output_dir,
                qname + '_' + 'combination_efficiency' + '.png')
            p.savefig(fname, dpi=self.dpi)

        if self.show_output:
            p.title(s.q.title)
            p.show()

    def _bar_plot(self, legend_lst, time_lst):
        rc('font', size=15)
        #rc('font', family = 'serif', style = 'normal', variant = 'normal', stretch = 'normal', size = 15)
        fig = p.figure(figsize=(10, 5))

        n_tests = len(time_lst)
        times = np.array(time_lst)
        x_norm = times[1]
        xmax = times.max()
        rel_xmax = xmax / x_norm
        rel_times = times / x_norm
        m = int(rel_xmax % 10)

        if m < 5:
            x_max_plt = int(rel_xmax) - m + 10
        else:
            x_max_plt = int(rel_xmax) - m + 15

        ax1 = fig.add_subplot(111)
        p.subplots_adjust(left=0.45, right=0.88)
        #fig.canvas.set_window_title('window title')
        pos = np.arange(n_tests) + 0.5
        rects = ax1.barh(pos,
                         rel_times,
                         align='center',
                         height=0.5,
                         color='w',
                         edgecolor='k')

        ax1.set_xlabel('normalized execution time [-]')
        ax1.axis([0, x_max_plt, 0, n_tests])
        ax1.set_yticks(pos)
        ax1.set_yticklabels(legend_lst)

        for rect, t in zip(rects, rel_times):
            width = rect.get_width()

            xloc = width + (0.03 * rel_xmax)
            clr = 'black'
            align = 'left'

            yloc = rect.get_y() + rect.get_height() / 2.0
            ax1.text(xloc,
                     yloc,
                     '%4.2f' % t,
                     horizontalalignment=align,
                     verticalalignment='center',
                     color=clr)  #, weight = 'bold')

        ax2 = ax1.twinx()
        ax1.plot([1, 1], [0, n_tests], 'k--')
        ax2.set_yticks([0] + list(pos) + [n_tests])
        ax2.set_yticklabels([''] + ['%4.2f s' % s for s in list(times)] + [''])
        ax2.set_xticks([0, 1] + range(5, x_max_plt + 1, 5))
        ax2.set_xticklabels(
            ['%i' % s for s in ([0, 1] + range(5, x_max_plt + 1, 5))])

    def _multi_bar_plot(self, title_lst, legend_lst, time_arr, error_lst,
                        n_sim_lst):
        '''Plot the results if the code efficiency. 
        '''
        p.rcdefaults()
        fsize = 14
        fig = p.figure(figsize=(15, 3))
        rc('font', size=fsize)
        rc('legend', fontsize=fsize - 2)
        legend_lst = ['weave', 'cython', 'numpy']

        # times are stored in 3d array - dimensions are:
        n_sampling, n_lang, n_run, n_times = time_arr.shape
        print 'arr', time_arr.shape
        times_sum = np.sum(time_arr, axis=n_times)

        p.subplots_adjust(left=0.1,
                          right=0.95,
                          wspace=0.1,
                          bottom=0.15,
                          top=0.8)

        for meth_i in range(n_sampling):

            ax1 = fig.add_subplot(1, n_sampling, meth_i + 1)
            ax1.set_xlabel('execution time [s]')
            ytick_pos = np.arange(n_lang) + 1

            #        ax1.axis([0, x_max_plt, 0, n_lang])
            # todo: **2 n_vars
            if len(self.exact_arr) > 0:
                ax1.set_title(
                    '%s: $ n_\mathrm{sim} = %s, \mathrm{e}_\mathrm{rms}=%s, \mathrm{e}_\mathrm{max}=%s$'
                    % (title_lst[meth_i][0],
                       self._formatSciNotation('%.2e' % n_sim_lst[meth_i]),
                       self._formatSciNotation('%.2e' % error_lst[meth_i][0]),
                       self._formatSciNotation('%.2e' % error_lst[meth_i][1])))
            else:
                ax1.set_title(
                    '%s: $ n_\mathrm{sim} = %s$' %
                    (title_lst[meth_i][0],
                     self._formatSciNotation('%.2e' % n_sim_lst[meth_i])))
            ax1.set_yticks(ytick_pos)
            if meth_i == 0:
                ax1.set_yticklabels(legend_lst, fontsize=fsize + 2)
            else:
                ax1.set_yticklabels([])

            ax1.set_xlim(0, 1.2 * np.max(times_sum[meth_i]))

            distance = 0.2
            height = 1.0 / n_run - distance
            offset = height / 2.0

            colors = ['w', 'w', 'w', 'r', 'y', 'b', 'g', 'm']
            hatches = ['/', '\\', 'x', '-', '+', '|', 'o', 'O', '.', '*']
            label_lst = ['sampling', 'compilation', 'integration']

            for i in range(n_run):
                pos = np.arange(n_lang) + 1 - offset + i * height
                end_bar_pos = np.zeros((n_lang, ), dtype='d')
                for j in range(n_times):
                    if i > 0:
                        label = label_lst[j]
                    else:
                        label = None
                    bar_lengths = time_arr[meth_i, :, i, j]
                    rects = ax1.barh(pos,
                                     bar_lengths,
                                     align='center',
                                     height=height,
                                     left=end_bar_pos,
                                     color=colors[j],
                                     edgecolor='k',
                                     hatch=hatches[j],
                                     label=label)
                    end_bar_pos += bar_lengths
                for k in range(n_lang):
                    x_val = times_sum[meth_i, k,
                                      i] + 0.01 * np.max(times_sum[meth_i])
                    ax1.text(x_val,
                             pos[k],
                             '$%4.2f\,$s' % x_val,
                             horizontalalignment='left',
                             verticalalignment='center',
                             color='black')  #, weight = 'bold')
                    if meth_i == 0:
                        ax1.text(0.02 * np.max(times_sum[0]),
                                 pos[k],
                                 '$%i.$' % (i + 1),
                                 horizontalalignment='left',
                                 verticalalignment='center',
                                 color='black',
                                 bbox=dict(pad=0., ec="w", fc="w"))
            p.legend(loc=0)

    def _formatSciNotation(self, s):
        # transform 1e+004 into 1e4, for example
        tup = s.split('e')
        try:
            significand = tup[0].rstrip('0').rstrip('.')
            sign = tup[1][0].replace('+', '')
            exponent = tup[1][1:].lstrip('0')
            if significand == '1':
                # reformat 1x10^y as 10^y
                significand = ''
            if exponent:
                exponent = '10^{%s%s}' % (sign, exponent)
            if significand and exponent:
                return r'%s{\cdot}%s' % (significand, exponent)
            else:
                return r'%s%s' % (significand, exponent)

        except IndexError, msg:
            return s
示例#28
0
class YMBAutoCorrelView(HasTraits):

    correl_data = Instance(YMBAutoCorrel)

    axes_adjust = List([0.1, 0.1, 0.8, 0.8])

    data = Property
    def _get_data(self):
        return self.correl_data.data

    zero = Constant(0)
    slider_max = Property()
    def _get_slider_max(self):
        return self.data.n_cuts - 1

    cut_slider = Range('zero', 'slider_max', mode='slider', auto_set=False, enter_set=True, modified=True)
    vcut_slider = Range('zero', 'slider_max', mode='slider', auto_set=False, enter_set=True, modified=True)

    cut_slider_on = Bool(False, modified=True)

    color = Str('blue')

    figure = Instance(Figure)

    def _figure_default(self):
        figure = Figure()
        figure.add_axes(self.axes_adjust)
        return figure

    data_changed = Event(True)
    @on_trait_change('correl_data.input_change, +modified')
    def _redraw(self):
        # TODO: set correct ranges, fix axis range (axes.xlim)
        print 'redrawing xxxx'
        figure = self.figure
        figure.clear()
        var_data = self.correl_data.corr_arr
        id = self.cut_slider
        if self.cut_slider_on == True:
            i = self.cut_slider
            j = self.vcut_slider
            plot_data = getattr(self.data, self.correl_data.var_enum_)
            # plot_data = vstack( [plot_data[:, i], plot_data[:, j]] ).T
            # plot only values > -1
            # plot_data = plot_data[prod( plot_data >= 0, axis = 1, dtype = bool )]
            plot_data_x = plot_data[:, i]
            plot_data_y = plot_data[:, j]
            plot_data_corr = min(corrcoef(plot_data_x, plot_data_y))
            plot_data_corr_spear = spearmanr(plot_data_x, plot_data_y)[0]

            left, width = 0.1, 0.65
            bottom, height = 0.1, 0.65
            bottom_h = left_h = left + width + 0.02

            rect_scatter = [left, bottom, width, height]
            rect_histx = [left, bottom_h, width, 0.2]
            rect_histy = [left_h, bottom, 0.2, height]

            axScatter = figure.add_axes(rect_scatter)
            axHistx = figure.add_axes(rect_histx)
            axHisty = figure.add_axes(rect_histy)
            axScatter.clear()
            axHistx.clear()
            axHisty.clear()

            from matplotlib.ticker import NullFormatter
            axHistx.xaxis.set_major_formatter(NullFormatter())
            axHisty.yaxis.set_major_formatter(NullFormatter())

            axScatter.scatter(plot_data_x,
                               plot_data_y)

            # binwidth = 0.25
            # xymax = max( [max( abs( self.data.cf[:, j] ) ), max( abs( self.data.cf[:, i] ) )] )
            # lim = ( int( xymax / binwidth ) + 1 ) * binwidth

            # axScatter.set_xlim( ( -lim, lim ) )
            # axScatter.set_ylim( ( -lim, lim ) )

            # bins = arange( -lim, lim + binwidth, binwidth )
            axHistx.hist(plot_data_x.compressed(), bins=40)
            axHisty.hist(plot_data_y.compressed(), bins=40, orientation='horizontal')
            axHistx.set_xlim(axScatter.get_xlim())
            axHisty.set_ylim(axScatter.get_ylim())

            axScatter.set_xlabel('$\mathrm{cut\, %i}$' % self.cut_slider, fontsize=16)
            axScatter.set_ylabel('$\mathrm{cut\, %i}$' % self.vcut_slider, fontsize=16)
            axScatter.text(axScatter.get_xlim()[0], axScatter.get_ylim()[0],
                             'actual set correlation %.3f (Pearson), %.3f (Spearman)' % (plot_data_corr, plot_data_corr_spear), color='r')

        if self.cut_slider_on == False:
            figure.add_axes(self.axes_adjust)
            axes = figure.axes[0]
            axes.clear()
            x_coor = self.data.x_coord
            axes.grid()
            for i in range(0, var_data.shape[1]):
                axes.plot(x_coor[i:] - x_coor[i],
                           var_data[i, (i):], '-x', color=self.color)
            # approximate by the polynomial (of the i-th order)
            # axes.plot( x_coor, self.correl_data.peval( x_coor, self.correl_data.fit_correl ), 'b', linewidth = 3 )
            setp(axes.get_xticklabels(), position=(0, -.025))
            axes.set_xlabel('$x \, [\mathrm{mm}]$', fontsize=15)
            axes.set_ylabel('$\mathrm{correlation}$', fontsize=15)
            axes.set_ylim(-1, 1)

        self.data_changed = True


    traits_view = View(Group(Item('correl_data', show_label=False, style='custom'),
                              HGroup(
                       Item('cut_slider_on', label='Scatter'),
                       Item('cut_slider', show_label=False, springy=True, enabled_when='cut_slider_on == True'),
                       Item('vcut_slider', show_label=False, springy=True, enabled_when='cut_slider_on == True'),
                       ),
                       Group(Item('figure', style='custom',
                              editor=MPLFigureEditor(),
                              show_label=False)
                              , id='figure.view'),
                       ),
                       resizable=True,
                        )
示例#29
0
class NIDOrderStats(HasTraits):

    distr_list = List(desc='NID distributions')

    n = Property(Int, depends_on='distr_list', desc='number of realizations')

    def _get_n(self):
        return len(self.distr_list)

    k = Int(1,
            auto_set=False,
            enter_set=True,
            desc='kth order statistics to evaluate')

    x_arr = np.linspace(0, 10, 200)

    cdf_arr = Property(Array, depends_on='distr_list')

    @cached_property
    def _get_cdf_arr(self):
        '''creates a 2D array of shape (m,x_arr) containing m CDFs'''
        cdf_arr = np.ones((self.n + 2, len(self.x_arr)))
        for i, distr in enumerate(self.distr_list):
            cdf_arr[i] = distr.cdf(self.x_arr)
        return cdf_arr

    sf_arr = Property(Array, depends_on='distr_list')

    @cached_property
    def _get_sf_arr(self):
        '''creates a 2D array of shape (m,x_arr) containing m SFs'''
        sf_arr = np.ones((self.n + 2, len(self.x_arr)))
        for i, distr in enumerate(self.distr_list):
            sf_arr[i] = distr.sf(self.x_arr)
        return sf_arr

    pdf_arr = Property(Array, depends_on='distr_list')

    @cached_property
    def _get_pdf_arr(self):
        '''creates a 2D array of shape (m,x_arr) containing m PDFs'''
        pdf_arr = np.ones((self.n + 2, len(self.x_arr)))
        for i, distr in enumerate(self.distr_list):
            pdf_arr[i] = distr.pdf(self.x_arr)
        return pdf_arr

    def kth_pdf(self):
        '''evaluates the PDF of the kth entry; cases k = 1 and k > 1 are distinguished
            The most general formula is used here. For higher performance use CIDOrderStats'''
        if len(self.distr_list) == self.n:
            n = self.n
            k = self.k
            if n >= k:
                fct = sp.misc.factorial
                # the constant actually tells how many redundances are present in the summation
                constant = 1. / (fct(k - 1) * fct(n - k))
                summation = np.zeros(len(self.x_arr))
                permutations = it.permutations(list(range(n)), n)
                loop_run = True
                t = time.clock()
                while loop_run == True:
                    try:
                        idx = list(next(permutations))
                        if k == 1:
                            id_pdf = idx[k - 1]
                            pdf = self.pdf_arr[id_pdf]
                            if n == 1:
                                PDF = pdf
                                summation += PDF.flatten()
                            elif n == 2:
                                id_sf = idx[1]
                                sf = self.sf_arr[id_sf]
                                PDF = pdf * sf
                                summation += PDF.flatten()
                            else:
                                id_sf = idx[k:]
                                sf = self.sf_arr[id_sf]
                                PDF = pdf * sf.prod(axis=0)
                                summation += PDF.flatten()
                        else:
                            id_cdf = idx[:k - 1]
                            cdf = self.cdf_arr[id_cdf]
                            id_pdf = idx[k - 1]
                            pdf = self.pdf_arr[id_pdf]
                            id_sf = idx[k:]
                            sf = self.sf_arr[id_sf]
                            PDF = cdf.prod(axis=0) * pdf * sf.prod(axis=0)
                            summation += PDF.flatten()
                    except StopIteration:
                        loop_run = False

                print(('NID', time.clock() - t, 's'))
                return constant * summation

            else:
                raise ValueError('n < k')
        else:
            raise ValueError('%i distributions required, %i given' %
                             (self.n, len(self.distr_list)))
示例#30
0
class CompositeCrackBridge(HasTraits):

    reinforcement_lst = List(Instance(Reinforcement))
    w = Float
    E_m = Float
    Ll = Float
    Lr = Float
    damage_initial_value = Array

    V_f_tot = Property(depends_on='reinforcement_lst+')

    @cached_property
    def _get_V_f_tot(self):
        V_f_tot = 0.0
        for reinf in self.reinforcement_lst:
            V_f_tot += reinf.V_f
        return V_f_tot

    E_c = Property(depends_on='reinforcement_lst+')

    @cached_property
    def _get_E_c(self):
        E_fibers = 0.0
        for reinf in self.reinforcement_lst:
            E_fibers += reinf.V_f * reinf.E_f
        E_c = self.E_m * (1. - self.V_f_tot) + E_fibers
        return E_c * (1. + 1e-15)

    sorted_theta = Property(depends_on='reinforcement_lst+')

    @cached_property
    def _get_sorted_theta(self):
        '''sorts the integral points by bond in descending order'''
        depsf_arr = np.array([])
        V_f_arr = np.array([])
        E_f_arr = np.array([])
        xi_arr = np.array([])
        stat_weights_arr = np.array([])
        nu_r_arr = np.array([])
        r_arr = np.array([])
        for reinf in self.reinforcement_lst:
            n_int = len(np.hstack((np.array([]), reinf.depsf_arr)))
            depsf_arr = np.hstack((depsf_arr, reinf.depsf_arr))
            V_f_arr = np.hstack((V_f_arr, np.repeat(reinf.V_f, n_int)))
            E_f_arr = np.hstack((E_f_arr, np.repeat(reinf.E_f, n_int)))
            xi_arr = np.hstack((xi_arr, np.repeat(reinf.xi, n_int)))
            #            stat_weights_arr = np.hstack((stat_weights_arr,
            #                                          np.repeat(reinf.stat_weights, n_int)))
            stat_weights_arr = np.hstack(
                (stat_weights_arr, reinf.stat_weights))
            nu_r_arr = np.hstack((nu_r_arr, reinf.nu_r))
            r_arr = np.hstack((r_arr, reinf.r_arr))
        argsort = np.argsort(depsf_arr)[::-1]
        # sorting the masks for the evaluation of F
        idxs = np.array([])
        for i, reinf in enumerate(self.reinforcement_lst):
            idxs = np.hstack((idxs, i * np.ones_like(reinf.depsf_arr)))
        masks = []
        for i, reinf in enumerate(self.reinforcement_lst):
            masks.append((idxs == i)[argsort])
        max_depsf = [
            np.max(reinf.depsf_arr) for reinf in self.reinforcement_lst
        ]
        masks = [masks[i] for i in np.argsort(max_depsf)[::-1]]
        return depsf_arr[argsort], V_f_arr[argsort], E_f_arr[argsort], \
                xi_arr[argsort], stat_weights_arr[argsort], \
                nu_r_arr[argsort], masks, r_arr[argsort]

    sorted_depsf = Property(depends_on='reinforcement_lst+')

    @cached_property
    def _get_sorted_depsf(self):
        return self.sorted_theta[0]

    sorted_V_f = Property(depends_on='reinforcement_lst+')

    @cached_property
    def _get_sorted_V_f(self):
        return self.sorted_theta[1]

    sorted_E_f = Property(depends_on='reinforcement_lst+')

    @cached_property
    def _get_sorted_E_f(self):
        return self.sorted_theta[2]

    sorted_xi = Property(depends_on='reinforcement_lst+')

    @cached_property
    def _get_sorted_xi(self):
        return self.sorted_theta[3]

    sorted_stats_weights = Property(depends_on='reinforcement_lst+')

    @cached_property
    def _get_sorted_stats_weights(self):
        return self.sorted_theta[4]

    sorted_nu_r = Property(depends_on='reinforcement_lst+')

    @cached_property
    def _get_sorted_nu_r(self):
        return self.sorted_theta[5]

    sorted_masks = Property(depends_on='reinforcement_lst+')

    @cached_property
    def _get_sorted_masks(self):
        return self.sorted_theta[6]

    sorted_r = Property(depends_on='reinforcement_lst+')

    @cached_property
    def _get_sorted_r(self):
        return self.sorted_theta[7]

    sorted_xi_cdf = Property(depends_on='reinforcement_lst+,Ll,Lr')

    @cached_property
    def _get_sorted_xi_cdf(self):
        '''breaking strain: CDF for random and Heaviside for discrete values'''
        # TODO: does not work for reinforcement types with the same xi
        methods = []
        masks = []
        for reinf in self.reinforcement_lst:
            masks.append(self.sorted_xi == reinf.xi)
            if isinstance(reinf.xi, FloatType):
                methods.append(lambda x: 1.0 * (reinf.xi <= x))
            elif isinstance(reinf.xi, RV):
                methods.append(reinf.xi._distr.cdf)
            elif isinstance(reinf.xi, WeibullFibers):
                reinf.xi.Ll = self.Ll
                reinf.xi.Lr = self.Lr
                methods.append(reinf.xi.cdf)
        return methods, masks

    Kf = Property(depends_on='reinforcement_lst+')

    @cached_property
    def _get_Kf(self):
        return self.sorted_V_f * self.sorted_nu_r * \
                self.sorted_stats_weights * self.sorted_E_f

    def vect_xi_cdf(self, epsy, x_short, x_long):
        Pf = np.zeros_like(self.sorted_depsf)
        methods, masks = self.sorted_xi_cdf
        for i, method in enumerate(methods):
            if method.__doc__ == 'weibull_fibers_cdf_mc':
                Pf[masks[i]] += method(epsy[masks[i]],
                                       self.sorted_depsf[masks[i]],
                                       self.sorted_r[masks[i]],
                                       x_short[masks[i]], x_long[masks[i]])
            elif method.__doc__ == 'weibull_fibers_cdf_cb_elast':
                Pf[masks[i]] += method(epsy[masks[i]],
                                       self.sorted_depsf[masks[i]],
                                       self.sorted_r[masks[i]],
                                       x_short[masks[i]], x_long[masks[i]])
            else:
                Pf[masks[i]] += method(epsy[masks[i]])
        return Pf

    def dem_depsf_vect(self, damage):
        '''evaluates the deps_m given deps_f
        at that point and the damage array'''
        Kf_intact = self.Kf * (1. - damage)
        Kf_intact_bonded = np.hstack((0.0, np.cumsum((Kf_intact))))[:-1]
        Kf_broken = np.sum(self.Kf - Kf_intact)
        Kf_add = Kf_intact_bonded + Kf_broken
        Km = (1. - self.V_f_tot) * self.E_m
        E_mtrx = Km + Kf_add
        mu_T = np.cumsum((self.sorted_depsf * Kf_intact)[::-1])[::-1]
        return mu_T / E_mtrx

    def F(self, dems, amin):
        '''Auxiliary function (see Part II, appendix B)
        '''
        F = np.zeros_like(self.sorted_depsf)
        for i, mask in enumerate(self.sorted_masks):
            depsfi = self.sorted_depsf[mask]
            demsi = dems[mask]
            fi = 1. / (depsfi + demsi)
            F[mask] = np.hstack((np.array([0.0]), cumtrapz(fi, -depsfi)))
            if i == 0:
                C = 0.0
            else:
                depsf0 = self.sorted_depsf[self.sorted_masks[i - 1]]
                depsf1 = depsfi[0]
                idx = np.sum(depsf0 > depsf1) - 1
                depsf2 = depsf0[idx]
                a1 = np.exp(F[self.sorted_masks[i - 1]][idx] / 2. +
                            np.log(amin))
                p = depsf2 - depsf1
                q = depsf1 + demsi[0]
                amin_i = np.sqrt(a1**2 + p / q * a1**2)
                C = np.log(amin_i / amin)
            F[mask] += 2 * C
        return F

    def clamped(self, Lmin, Lmax, init_dem):
        a = np.hstack((-Lmin, 0.0, Lmax))
        em = np.hstack((init_dem * Lmin, 0.0, init_dem * Lmax))
        epsf0 = (self.sorted_depsf / 2. * (Lmin**2 + Lmax**2) + self.w +
                 em[0] * Lmin / 2. + em[-1] * Lmax / 2.) / (Lmin + Lmax)
        return a, em, epsf0

    def profile(self, iter_damage, Lmin, Lmax):
        '''
        '''
        # matrix strain derivative with resp. to z as a function of T
        dems = self.dem_depsf_vect(iter_damage)
        # initial matrix strain derivative
        init_dem = dems[0]
        # debonded length of fibers with Tmax
        amin = (self.w /
                (np.abs(init_dem) + np.abs(self.sorted_depsf[0])))**0.5
        # integrated f(depsf) - see article
        F = self.F(dems, amin)
        # a1 is a(depsf) for double sided pullout
        a1 = amin * np.exp(F / 2.)
        #aX = np.exp((-np.log(np.abs(self.sorted_depsf) + dems) + np.log(self.w)) / 2.)
        if Lmin < a1[0] and Lmax < a1[0]:
            # all fibers debonded up to Lmin and Lmax
            a, em, epsf0 = self.clamped(Lmin, Lmax, init_dem)

        elif Lmin < a1[0] and Lmax >= a1[0]:
            # all fibers debonded up to Lmin but not up to Lmax
            amin = -Lmin + np.sqrt(2 * Lmin**2 + 2 * self.w /
                                   (self.sorted_depsf[0] + init_dem))
            C = np.log(amin**2 + 2 * Lmin * amin - Lmin**2)
            a2 = np.sqrt(2 * Lmin**2 + np.exp((F + C))) - Lmin
            if Lmax < a2[0]:
                a, em, epsf0 = self.clamped(Lmin, Lmax, init_dem)
            else:
                if Lmax <= a2[-1]:
                    idx = np.sum(a2 < Lmax) - 1
                    a = np.hstack((-Lmin, 0.0, a2[:idx + 1], Lmax))
                    em2 = np.cumsum(np.diff(np.hstack((0.0, a2))) * dems)
                    em = np.hstack((init_dem * Lmin, 0.0, em2[:idx + 1],
                                    em2[idx] + (Lmax - a2[idx]) * dems[idx]))
                    um = np.trapz(em, a)
                    epsf01 = em2[:idx +
                                 1] + a2[:idx + 1] * self.sorted_depsf[:idx +
                                                                       1]
                    epsf02 = (self.w + um + self.sorted_depsf[idx + 1:] / 2. *
                              (Lmin**2 + Lmax**2)) / (Lmin + Lmax)
                    epsf0 = np.hstack((epsf01, epsf02))
                else:
                    a = np.hstack((-Lmin, 0.0, a2, Lmax))
                    em2 = np.cumsum(np.diff(np.hstack((0.0, a2))) * dems)
                    em = np.hstack((init_dem * Lmin, 0.0, em2, em2[-1]))
                    epsf0 = em2 + self.sorted_depsf * a2
        elif a1[0] < Lmin and a1[-1] > Lmin:
            # some fibers are debonded up to Lmin, some are not
            # boundary condition position
            idx1 = np.sum(a1 <= Lmin)
            # a(T) for one sided pullout
            # first debonded length amin for one sided PO
            depsfLmin = self.sorted_depsf[idx1]
            p = (depsfLmin + dems[idx1])
            a_short = np.hstack((a1[:idx1], Lmin))
            em_short = np.cumsum(
                np.diff(np.hstack((0.0, a_short))) * dems[:idx1 + 1])
            emLmin = em_short[-1]
            umLmin = np.trapz(np.hstack((0.0, em_short)),
                              np.hstack((0.0, a_short)))
            amin = -Lmin + np.sqrt(4 * Lmin**2 * p**2 - 4 * p * emLmin * Lmin +
                                   4 * p * umLmin - 2 * p * Lmin**2 *
                                   depsfLmin + 2 * p * self.w) / p
            C = np.log(amin**2 + 2 * amin * Lmin - Lmin**2)
            a2 = (np.sqrt(2 * Lmin**2 + np.exp(F + C - F[idx1])) - Lmin)[idx1:]
            # matrix strain profiles - shorter side
            a_short = np.hstack((-Lmin, -a1[:idx1][::-1], 0.0))
            dems_short = np.hstack((dems[:idx1], dems[idx1]))
            em_short = np.hstack(
                (0.0, np.cumsum(np.diff(-a_short[::-1]) * dems_short)))[::-1]
            if a2[-1] > Lmax:
                idx2 = np.sum(a2 <= Lmax)
                # matrix strain profiles - longer side
                a_long = np.hstack((a1[:idx1], a2[:idx2]))
                em_long = np.cumsum(
                    np.diff(np.hstack((0.0, a_long))) * dems[:idx1 + idx2])
                a = np.hstack((a_short, a_long, Lmax))
                em = np.hstack(
                    (em_short, em_long,
                     em_long[-1] + (Lmax - a_long[-1]) * dems[idx1 + idx2]))
                um = np.trapz(em, a)
                epsf01 = em_long + a_long * self.sorted_depsf[:idx1 + idx2]
                epsf02 = (self.w + um + self.sorted_depsf[idx1 + idx2:] / 2. *
                          (Lmin**2 + Lmax**2)) / (Lmin + Lmax)
                epsf0 = np.hstack((epsf01, epsf02))
            else:
                a_long = np.hstack((0.0, a1[:idx1], a2, Lmax))
                a = np.hstack((a_short, a_long[1:]))
                dems_long = dems
                em_long = np.hstack(
                    (np.cumsum(np.diff(a_long[:-1]) * dems_long)))
                em_long = np.hstack((em_long, em_long[-1]))
                em = np.hstack((em_short, em_long))
                epsf0 = em_long[:-1] + self.sorted_depsf * a_long[1:-1]
        elif a1[-1] <= Lmin:
            # double sided pullout
            a = np.hstack((-Lmin, -a1[::-1], 0.0, a1, Lmax))
            em1 = np.cumsum(np.diff(np.hstack((0.0, a1))) * dems)
            em = np.hstack((em1[-1], em1[::-1], 0.0, em1, em1[-1]))
            epsf0 = em1 + self.sorted_depsf * a1
        self._x_arr = a
        self._epsm_arr = em
        self._epsf0_arr = epsf0
        a_short = -a[a < 0.0][1:][::-1]
        if len(a_short) < len(self.sorted_depsf):
            a_short = np.hstack(
                (a_short,
                 Lmin * np.ones(len(self.sorted_depsf) - len(a_short))))
        a_long = a[a > 0.0][:-1]
        if len(a_long) < len(self.sorted_depsf):
            a_long = np.hstack(
                (a_long, Lmax * np.ones(len(self.sorted_depsf) - len(a_long))))
        return epsf0, a_short, a_long

    def damage_residuum(self, iter_damage):
        if np.any(iter_damage < 0.0) or np.any(iter_damage > 1.0):
            return np.ones_like(iter_damage) * 2.0
        else:
            Lmin = min(self.Ll, self.Lr)
            Lmax = max(self.Ll, self.Lr)
            epsf0, x_short, x_long = self.profile(iter_damage, Lmin, Lmax)
            residuum = self.vect_xi_cdf(epsf0, x_short=x_short,
                                        x_long=x_long) - iter_damage
            return residuum

    _x_arr = Array

    def __x_arr_default(self):
        return np.repeat(1e-10, len(self.sorted_depsf))

    _epsm_arr = Array

    def __epsm_arr_default(self):
        return np.repeat(1e-10, len(self.sorted_depsf))

    _epsf0_arr = Array

    def __epsf0_arr_default(self):
        return np.repeat(1e-10, len(self.sorted_depsf))

    damage = Property(depends_on='w, Ll, Lr, reinforcement+')

    @cached_property
    def _get_damage(self):
        if self.w == 0.:
            damage = np.zeros_like(self.sorted_depsf)
        else:
            ff = t.clock()
            try:

                damage = root(self.damage_residuum,
                              np.ones_like(self.sorted_depsf) * 0.2,
                              method='excitingmixing',
                              options={'maxiter': 100})
                if np.any(damage.x < 0.0) or np.any(damage.x > 1.0):
                    raise ValueError
                damage = damage.x
                self.damage_initial_value = damage
            except:
                print 'fast opt method does not converge: switched to a slower, robust method for this step'
                damage = root(self.damage_residuum,
                              np.ones_like(self.sorted_depsf) * 0.2,
                              method='krylov')
                damage = damage.x
            # print 'damage =', np.sum(damage) / len(damage), 'iteration time =', t.clock() - ff, 'sec'
        return damage