コード例 #1
0
ファイル: size_effect_theory.py プロジェクト: rostar/rostar
class SizeEffect( HasTraits ):
    '''
    Size effect depending on the yarn length
    '''

    l_b = Float( 0.1, auto_set = False, enter_set = True, # [m]
                  desc = 'yarn total length',
                  modified = True )
    m_f = Float( 5, auto_set = False, enter_set = True, # [-]
                desc = 'Weibull shape parameter for filaments',
                modified = True )
    Nf = Int( 24000, auto_set = False, enter_set = True, # [-]
                desc = 'number of filaments in yarn',
                modified = True )
    l_rho = Float( 0.02, auto_set = False, enter_set = True, # [m]
                desc = 'autocorrelation length for fiber strength dispersion',
                modified = True )
    s_rho = Float( 2500, auto_set = False, enter_set = True, # [m]
            desc = 'scale parameter for autocorrelation length',
            modified = True )

    # these parameters are called plot, but the model should not 
    # interfere with the view (@todo resolve)
    l_plot = Float( 80., auto_set = False, enter_set = True, # [m]
                desc = 'maximum yarn length',
                modified = True )

    min_plot_length = Float( 0.0001, auto_set = False, enter_set = True, # [m]
                desc = 'minimum yarn length',
                modified = True )

    n_points = Int( 100, auto_set = False, enter_set = True,
                desc = 'points to plot',
                modified = True )

    # autocorrelation length function
    def fl( self, l ):
        return ( self.l_rho / ( self.l_rho + l ) ) ** ( 1. / self.m_f )
    '''second option'''
    #    return (l/self.l_rho + self.l_rho/(self.l_rho + l))**(-1./self.m_f)

    # scale parameter depending on length
    def s( self, l ):
        return self.fl( l ) * self.s_rho

    def mu_f( self, l ):
        return weibull_min( self.m_f, scale = self.s( l ), loc = 0.0 ).stats( 'm' )

    def mu_b( self, l ):
        return self.m_f ** ( -1.0 / self.m_f ) * self.s( l ) * exp( -1.0 / self.m_f )
コード例 #2
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)
コード例 #3
0
ファイル: spirrid_nd_rr.py プロジェクト: simvisage/bmcs
class RV(HasTraits):
    '''Class representing the definition and discretization of a random variable.
    '''
    name = Str

    pd = Instance(IPDistrib)

    def _pd_changed(self):
        self.pd.n_segments = self._n_int

    changed = Event

    @on_trait_change('pd.changed')
    def _set_changed(self):
        self.changed = True

    _n_int = Int
    n_int = Property

    def _set_n_int(self, value):
        if self.pd:
            self.pd.n_segments = value
        self._n_int = value

    def _get_n_int(self):
        return self.pd.n_segments

    # index within the randomization
    idx = Int(0)

    theta_arr = Property(Array('float_'), depends_on='changed')

    @cached_property
    def _get_theta_arr(self):
        '''Get the discretization from pdistrib and shift it
        such that the midpoints of the segments are used for the
        integration.
        '''
        x_array = self.pd.x_array
        # Note assumption of equidistant discretization
        theta_array = x_array[:-1] + self.pd.dx / 2.0
        return theta_array

    pdf_arr = Property(Array('float_'), depends_on='changed')

    @cached_property
    def _get_pdf_arr(self):
        return self.pd.get_pdf_array(self.theta_arr)

    dG_arr = Property(Array('float_'), depends_on='changed')

    @cached_property
    def _get_dG_arr(self):
        d_theta = self.theta_arr[1] - self.theta_arr[0]
        return self.pdf_arr * d_theta

    def get_rvs_theta_arr(self, n_samples):
        return self.pd.get_rvs_array(n_samples)
コード例 #4
0
class RV(HasTraits):

    def __init__(self, type, loc = 0.0, scale = 0.0, shape = 1.0,
                  *args, **kw):
        '''Convenience initialization'''
        super(RV, self).__init__(*args, **kw)
        self.type = type
        self.loc = loc
        self.scale = scale
        self.shape = shape
        self.args = args
        self.kw = kw

    def __str__(self):
        return '%s( loc = %g, scale = %g, shape = %g)[n_int = %s]' % \
            (self.type, self.loc, self.scale, self.shape, str(self.n_int))

    # number of integration points
    n_int = Int(None)

    # location parameter
    loc = Float

    # scale parameter
    scale = Float

    # shape parameter
    shape = Float

    # type specifier
    type = Str

    # hidden property instance of the scipy stats distribution
    _distr = Property(depends_on = 'mu,std,loc,type')
    @cached_property
    def _get__distr(self):
        '''Construct a distribution.
        '''
        if self.n_int == None:
            n_segments = 10
        else:
            n_segments = self.n_int
        pd = PD(distr_choice = self.type, n_segments = n_segments)
        pd.distr_type.set(scale = self.scale, shape = self.shape, loc = self.loc)
        return pd

    # access methods to pdf, ppf, rvs
    def pdf(self, x):
        return self._distr.pdf(x)

    def ppf(self, x):
        return self._distr.ppf(x)

    def rvs(self, x):
        return self._distr.rvs(x)
コード例 #5
0
ファイル: size_effect_theory.py プロジェクト: rostar/rostar
class FilBun( SizeEffect ):

    nf = Int( 50 )
    K = Float( 72e9 * 0.89e-6 )
    weib = Property
    def _get_weib( self ):
        return weibull_min( self.m_f, scale = self.s( 0.2 ) / self.K )
    def filaments( self ):
        no = linspace( 0.001, 0.999, self.nf )
        strains = self.weib.ppf( no )
        return strains
コード例 #6
0
ファイル: iid_order_stats.py プロジェクト: rosoba/simvisage
class IIDOrderStats(HasTraits):

    distr = 'distribution'

    n = Int(10, auto_set=False, enter_set=True, desc='number of realizations')

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

    x_arr = np.linspace(0, 13, 300)

    def n_realizations(self):
        return self.distr.ppf(np.random.rand(self.n))

    def kth_pdf(self):
        '''evaluates the PDF of the kth entry'''
        n = self.n
        k = self.k
        x = self.x_arr
        fct = sp.misc.factorial
        pdf = self.distr.pdf
        cdf = self.distr.cdf
        constant = fct(n) / (fct(k - 1) * fct(n - k))
        return constant * pdf(x) * cdf(x)**(k - 1) * (1 - cdf(x))**(n - k)

    def kth_cdf(self):
        '''evaluates the CDF of the kth entry'''
        n = self.n
        k = self.k
        x = self.x_arr
        sf = self.distr.sf
        cdf = self.distr.cdf
        CDF = np.zeros(len(x))
        CDF2 = np.zeros(len(x))
        for l in range(n - k + 1):
            i = l + k
            CDF += sp.misc.common.comb(n, i) * cdf(x)**i * sf(x)**(n - i)
        return CDF
コード例 #7
0
class ECBLPiecewiseLinear(ECBLBase):
    '''Effective crack bridge Law using a piecewise linear function.'''

    sig_level_arr = Array(float, input=True)

    def _sig_level_arr_default(self):
        E_eff = self.sig_tex_u / self.eps_tex_u
        return E_eff * self.eps_arr

    sig_tex_u = Float(800.0, input=True)
    eps_tex_u = Float(0.01, input=True)
    n_eps = Int(2, input=True)

    eps_fraction_arr = Property(depends_on='n_eps')

    @cached_property
    def _get_eps_fraction_arr(self):
        return np.linspace(0.0, 1.0, self.n_eps)

    cnames = ['eps_tex_u', 'sig_level_arr']

    u0 = Property(depends_on='eps_tex_u, sig_tex_u, eps_fraction_list')

    @cached_property
    def _get_u0(self):
        return self.sig_level_arr[1:]

    eps_arr = Array(float)

    def _eps_arr_default(self):
        return self.eps_fraction_arr * self.eps_tex_u

    sig_arr = Array(float)

    def _sig_arr_default(self):
        return self.sig_level_arr

    def set_sig_eps_arr(self, eps_arr, sig_arr):
        self.eps_arr = eps_arr
        self.sig_arr = sig_arr
コード例 #8
0
    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
コード例 #9
0
class SimDT(IBVModel):
    '''Simulation: Disk Test
    '''

    implements(ISimModel)

    material_density_roof = Float(-22.4e-3)  # [MN/m^3]

    #----------------------------------------------------
    # elements
    #----------------------------------------------------

    n_elems = Int(50, input=True)
    thickness = Float(1.0, input=True)

    vtk_r = Float(0.9, input=True)

    # fets used for roof
    #
    fets_disk = Instance((FETSEval), depends_on='+ps_levels, +input')

    def _fets_disk_default(self):
        # fe_quad_serendipity_roof is defined in base class
        # connected with material properties of the roof
        #
        mats = MATS2DElastic(E=3.1e5, nu=0.0, stress_state='plane_stress')
        fets = FETS2D4Q8U(mats_eval=mats)
        fets.vtk_r *= self.vtk_r
        return fets

    geo_disk = Property(depends_on='+ps_levels, +input')

    @cached_property
    def _get_geo_disk(self):
        # list of local origins of each roof defined in global coordinates
        # (for MRDetail two roofs are considered due to symmetry)
        #
        gt = GeoSquare2Circle(circle_center=[0.0, 0.0],
                              circle_radius=1.0,
                              square_edge=4.0)
        return gt

    #----------------------------------------------------
    # fe-grids
    #----------------------------------------------------

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

    @cached_property
    def _get_fe_disk_grid(self):
        fe_grid = FEGrid(coord_min=(-1, -1),
                         coord_max=(1, 1),
                         geo_transform=self.geo_disk,
                         shape=(self.n_elems, self.n_elems),
                         fets_eval=self.fets_disk)
        return fe_grid

    bc_fixed = Property(depends_on='+ps_levels, +input')

    @cached_property
    def _get_bc_fixed(self):
        fe_disk_grid = self.fe_disk_grid

        extension = 0.1
        alpha_45 = math.pi / 4.0

        bc00 = BCDof(var='u',
                     dof=fe_disk_grid[0, 0, 0, 0].dofs[0, 0, 1],
                     value=-extension * math.cos(alpha_45))

        bc00_link = BCDof(var='u',
                          dof=fe_disk_grid[0, 0, 0, 0].dofs[0, 0, 0],
                          link_dofs=[fe_disk_grid[0, 0, 0, 0].dofs[0, 0, 1]],
                          link_coeffs=[1.0],
                          value=0)

        bc10 = BCDof(var='u',
                     dof=fe_disk_grid[-1, 0, -1, 0].dofs[0, 0, 1],
                     value=-extension * math.cos(alpha_45))

        bc10_link = BCDof(var='u',
                          dof=fe_disk_grid[-1, 0, -1, 0].dofs[0, 0, 0],
                          link_dofs=[fe_disk_grid[-1, 0, -1, 0].dofs[0, 0, 1]],
                          link_coeffs=[-1.0],
                          value=0)

        bc11 = BCDof(var='u',
                     dof=fe_disk_grid[-1, -1, -1, -1].dofs[0, 0, 1],
                     value=extension * math.cos(alpha_45))

        bc11_link = BCDof(
            var='u',
            dof=fe_disk_grid[-1, -1, -1, -1].dofs[0, 0, 0],
            link_dofs=[fe_disk_grid[-1, -1, -1, -1].dofs[0, 0, 1]],
            link_coeffs=[1.0],
            value=0)

        bc01 = BCDof(var='u',
                     dof=fe_disk_grid[0, -1, 0, -1].dofs[0, 0, 1],
                     value=extension * math.cos(alpha_45))

        bc01_link = BCDof(var='u',
                          dof=fe_disk_grid[0, -1, 0, -1].dofs[0, 0, 0],
                          link_dofs=[fe_disk_grid[0, -1, 0, -1].dofs[0, 0, 1]],
                          link_coeffs=[-1.0],
                          value=0)

        n_xy = self.n_elems / 2

        bc_bottom = BCDof(var='u',
                          dof=fe_disk_grid[n_xy, 0, 0, 0].dofs[0, 0, 1],
                          value=-extension)
        bc_right = BCDof(var='u',
                         dof=fe_disk_grid[-1, n_xy, -1, 0].dofs[0, 0, 0],
                         value=extension)
        bc_top = BCDof(var='u',
                       dof=fe_disk_grid[n_xy, -1, 0, -1].dofs[0, 0, 1],
                       value=extension)
        bc_left = BCDof(var='u',
                        dof=fe_disk_grid[0, n_xy, 0, 0].dofs[0, 0, 0],
                        value=-extension)

        return [
            bc_left, bc_right, bc_top, bc_bottom, bc00, bc00_link, bc10,
            bc10_link, bc11, bc11_link, bc01, bc01_link
        ]

    #----------------------------------------------------
    # ps_study
    #----------------------------------------------------
    def peval(self):
        '''
        Evaluate the model and return the array of results specified
        in the method get_sim_outputs.
        '''

        # DISPLACEMENT
        #
        U = self.tloop.eval()

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

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

    rtrace_list = List

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

    max_princ_stress = Instance(RTraceDomainListField)

    def _max_princ_stress_default(self):
        return RTraceDomainListField(
            name='max principle stress',
            idx=0,
            var='max_principle_sig',
            warp=True,
            #                                      position = 'int_pnts',
            record_on='update',
        )

    sig_app = Property(Instance(RTraceDomainListField),
                       depends_on='+ps_levels, +input')

    @cached_property
    def _get_sig_app(self):
        return RTraceDomainListField(
            name='sig_app',
            position='int_pnts',
            var='sig_app',
            record_on='update',
        )

    u = Property(Instance(RTraceDomainListField),
                 depends_on='+ps_levels, +input')

    @cached_property
    def _get_u(self):
        return RTraceDomainListField(
            name='displacement',
            var='u',
            warp=True,
            record_on='update',
        )

    #----------------------------------------------------
    # time loop
    #----------------------------------------------------

    tline = Instance(TLine)

    def _tline_default(self):
        return TLine(min=0.0, step=1.0, max=1.0)

    tloop = Property(depends_on='+ps_levels, +input')

    @cached_property
    def _get_tloop(self):

        roof = self.fe_disk_grid

        # self.bc_roof_deadweight + \
        bc_list = self.bc_fixed

        ts = TS(sdomain=[roof],
                dof_resultants=True,
                bcond_list=bc_list,
                rtrace_list=self.rtrace_list)

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

        return tloop
コード例 #10
0
class ECBReinfTexUniform(ECBReinfComponent):
    '''Cross section characteristics needed for tensile specimens
    '''

    height = DelegatesTo('matrix_cs')
    '''height of reinforced cross section
    '''

    n_layers = Int(12, auto_set=False, enter_set=True, geo_input=True)
    '''total number of reinforcement layers [-]
    '''

    n_rovings = Int(23, auto_set=False, enter_set=True, geo_input=True)
    '''number of rovings in 0-direction of one composite layer of the
    bending test [-]:
    '''

    A_roving = Float(0.461, auto_set=False, enter_set=True, geo_input=True)
    '''cross section of one roving [mm**2]'''
    def convert_eps_tex_u_2_lo(self, eps_tex_u):
        '''Convert the strain in the lowest reinforcement layer at failure
        to the strain at the bottom of the cross section'''
        eps_up = self.state.eps_up
        return eps_up + (eps_tex_u - eps_up) / self.z_ti_arr[0] * self.height

    def convert_eps_lo_2_tex_u(self, eps_lo):
        '''Convert the strain at the bottom of the cross section to the strain
        in the lowest reinforcement layer at failure'''
        eps_up = self.state.eps_up
        return (eps_up + (eps_lo - eps_up) / self.height * self.z_ti_arr[0])

    '''Convert the MN to kN
    '''

    #===========================================================================
    # material properties
    #===========================================================================

    sig_tex_u = Float(1216., auto_set=False, enter_set=True, tt_input=True)
    '''Ultimate textile stress measured in the tensile test [MPa]
    '''

    #===========================================================================
    # Distribution of reinforcement
    #===========================================================================

    s_tex_z = Property(depends_on=ECB_COMPONENT_AND_EPS_CHANGE)
    '''spacing between the layers [m]'''

    @cached_property
    def _get_s_tex_z(self):
        return self.height / (self.n_layers + 1)

    z_ti_arr = Property(depends_on=ECB_COMPONENT_AND_EPS_CHANGE)
    '''property: distance of each reinforcement layer from the top [m]:
    '''

    @cached_property
    def _get_z_ti_arr(self):
        return np.array([
            self.height - (i + 1) * self.s_tex_z for i in range(self.n_layers)
        ],
                        dtype=float)

    zz_ti_arr = Property
    '''property: distance of reinforcement layers from the bottom
    '''

    def _get_zz_ti_arr(self):
        return self.height - self.z_ti_arr

    #===========================================================================
    # Discretization conform to the tex layers
    #===========================================================================

    eps_i_arr = Property(depends_on=ECB_COMPONENT_AND_EPS_CHANGE)
    '''Strain at the level of the i-th reinforcement layer
    '''

    @cached_property
    def _get_eps_i_arr(self):
        # ------------------------------------------------------------------------
        # geometric params independent from the value for 'eps_t'
        # ------------------------------------------------------------------------
        height = self.height
        eps_lo = self.state.eps_lo
        eps_up = self.state.eps_up
        # strain at the height of each reinforcement layer [-]:
        #
        return eps_up + (eps_lo - eps_up) * self.z_ti_arr / height

    eps_ti_arr = Property(depends_on=ECB_COMPONENT_AND_EPS_CHANGE)
    '''Tension strain at the level of the i-th layer of the fabrics
    '''

    @cached_property
    def _get_eps_ti_arr(self):
        return (np.fabs(self.eps_i_arr) + self.eps_i_arr) / 2.0

    eps_ci_arr = Property(depends_on=ECB_COMPONENT_AND_EPS_CHANGE)
    '''Compression strain at the level of the i-th layer.
    '''

    @cached_property
    def _get_eps_ci_arr(self):
        return (-np.fabs(self.eps_i_arr) + self.eps_i_arr) / 2.0

    #===========================================================================
    # Effective crack bridge law
    #===========================================================================
    ecb_law_type = Trait('fbm',
                         dict(fbm=ECBLFBM,
                              cubic=ECBLCubic,
                              linear=ECBLLinear,
                              bilinear=ECBLBilinear),
                         tt_input=True)
    '''Selector of the effective crack bridge law type
    ['fbm', 'cubic', 'linear', 'bilinear']'''

    ecb_law = Property(Instance(ECBLBase), depends_on='+tt_input')
    '''Effective crack bridge law corresponding to ecb_law_type'''

    @cached_property
    def _get_ecb_law(self):
        return self.ecb_law_type_(sig_tex_u=self.sig_tex_u, cs=self)

    show_ecb_law = Button
    '''Button launching a separate view of the effective crack bridge law.
    '''

    def _show_ecb_law_fired(self):
        ecb_law_mw = ConstitutiveLawModelView(model=self.ecb_law)
        ecb_law_mw.edit_traits(kind='live')
        return

    tt_modified = Event

    sig_ti_arr = Property(depends_on=ECB_COMPONENT_AND_EPS_CHANGE)
    '''Stresses at the i-th fabric layer.
    '''

    @cached_property
    def _get_sig_ti_arr(self):
        return self.ecb_law.mfn_vct(self.eps_ti_arr)

    f_ti_arr = Property(depends_on=ECB_COMPONENT_AND_EPS_CHANGE)
    '''force at the height of each reinforcement layer [kN]:
    '''

    @cached_property
    def _get_f_ti_arr(self):
        sig_ti_arr = self.sig_ti_arr
        n_rovings = self.n_rovings
        A_roving = self.A_roving
        return sig_ti_arr * n_rovings * A_roving / self.unit_conversion_factor

    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.height
        # eps ti
        ax.plot([-self.eps_lo, -self.eps_up], [0, self.height], 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.height])
        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.height
        # 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.height])
        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('height', 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'])
コード例 #11
0
ファイル: mr_quarter.py プロジェクト: rosoba/simvisage
class MRquarter(MushRoofModel):

    implements(ISimModel)
    mushroof_part = 'quarter'

    n_elems_xy_quarter = Int(6, ps_levels=[3, 15, 5])
    n_elems_z = Int(2, ps_levels=[1, 4, 2])

    #----------------------------------------------------
    # elements
    #----------------------------------------------------
    vtk_r = Float(0.9)

    # default roof
    fe_roof = Instance(
        FETSEval,
        ps_levels=[
            'fe2d5_quad_serendipity', 'fe_quad_serendipity', 'fe_linear',
            'fe_quad_lagrange'
        ],
        depends_on='+initial_strain_roof, +initial_strain_col, +vtk_r')

    def _fe_roof_default(self):
        fets = self.fe2d5_quad_serendipity
        #        fets = self.fe_quad_serendipity
        fets.vtk_r *= self.vtk_r
        return fets

    #----------------------------------------------------
    # grid and geometric transformation
    #----------------------------------------------------
    fe_grid_roof = Property(Instance(FEGrid), depends_on='+ps_levels, +input')

    @cached_property
    def _get_fe_grid_roof(self):
        return FEGrid(coord_min=(0.0, 0.0, 0.0),
                      coord_max=(1.0, 1.0, 1.0),
                      geo_transform=self.hp_shell,
                      shape=(self.n_elems_xy, self.n_elems_xy, self.n_elems_z),
                      fets_eval=self.fe2d5_quad_serendipity)
#                       fets_eval = self.fe_roof)
#                       fets_eval = self.fe_quad_serendipity)

    mats_roof = Property(Instance(MATS2D5MicroplaneDamage),
                         depends_on='+input')
    #    mats_roof = Property( Instance( MATS3DElastic), depends_on = '+input' )
    @cached_property
    def _get_mats_roof(self):
        # return MATS3DElastic(E=self.E_roof, nu=self.nu)
        return MATS2D5MicroplaneDamage(E=29100.0,
                                       nu=0.2,
                                       n_mp=30,
                                       symmetrization='sum-type',
                                       model_version='compliance',
                                       phi_fn=self.phi_fn)

    fe2d5_quad_serendipity = Property(Instance(FETSEval, transient=True),
                                      depends_on='+input')

    def _get_fe2d5_quad_serendipity(self):
        return FETS2D58H20U(mats_eval=self.mats_roof)

    fe_quad_serendipity = Property(Instance(FETSEval, transient=True),
                                   depends_on='+input')

    def _get_fe_quad_serendipity(self):
        return FETS3D8H20U(mats_eval=self.mats_roof)

    shrink_factor = Float(1.0)
    # shell
    #
    hp_shell = Property(Instance(HPShell), depends_on='+ps_levels, +input')

    @cached_property
    def _get_hp_shell(self):
        return HPShell(length_xy_quarter=self.length_xy_quarter /
                       self.shrink_factor,
                       length_z=self.length_z / self.shrink_factor,
                       n_elems_xy_quarter=self.n_elems_xy_quarter,
                       n_elems_z=self.n_elems_z,
                       scalefactor_delta_h=self.scalefactor_delta_h,
                       mushroof_part='quarter',
                       shift_elems=False,
                       X0=self.X0)

    #----------------------------------------------------
    # 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_center_top_z = U[self.center_top_dof][0, 0, 2]
        print 'u_center_top_z', u_center_top_z
        return np.array([u_center_top_z], dtype='float_')


#        max_princ_stress = max(self.max_princ_stress._get_field_data().flatten())
#        return np.array([ u_center_top_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 principal stress', unit='MPa'),
        ]

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

    rtrace_list = List

    def _rtrace_list_default(self):
        return [self.eps_app, self.sig_app, self.max_omega_i, self.phi_pdc]

    max_lambda = Float(1.0, input=True)
    '''Maximum lambda factor to impose on the structure.
    The final loading loading level is calculated
    as the reference boundary conditions multiplied by the lambda_factor
    and uls_factor. Thus, lambda factor defines the load level as a multiple
    of the load level predicted by the linear analysis.
    '''

    f_w_diagram = Property(Instance(RTraceGraph),
                           depends_on='+ps_levels, +input')

    @cached_property
    def _get_f_w_diagram(self):
        domain = self.fe_grid_roof
        w_z = domain[-1, -1, -1, -1, -1, -1].dofs[0, 0, 2]
        return RTraceGraph(
            name='load - corner deflection',
            var_x='U_k',
            idx_x=w_z,
            transform_x='-x',
            var_y='time',
            idx_y=0,
            # transform_y='y * %g' % self.lambda_factor,
            record_on='update')

    n_steps = Int(15.0, auto_set=False, enter_set=False, input=True)
    time_fn_load = Instance(MFnLineArray, input=True)

    def _time_fn_load_default(self):
        eta = 0.27 * 1.2
        return MFnLineArray(xdata=[0.0, 1.0, 3.0, 5.0, 8.0, 15.0],
                            ydata=[0.0, 1.0, 1.0 / eta, 1.78 / eta, 8.0, 9.05])

    boundary_x1 = Property(depends_on='+input')

    @cached_property
    def _get_boundary_x1(self):
        return self.fe_grid_roof.domain[-1, :, -1, -1, :, -1]

    #----------------------------------------------------
    # time loop
    #----------------------------------------------------

    tloop = Property(depends_on='+ps_levels, +input')

    @cached_property
    def _get_tloop(self):
        domain = self.fe_grid_roof

        #----------------------------------------------------
        # loading and boundaries
        #----------------------------------------------------

        #--- LC1: dead load
        # g = 22.4 kN/m^3
        # orientation: global z-direction;
        material_density_roof = -22.43e-3  # [MN/m^3]

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

        #--- LC2 additional boundary load
        # gA = 0,35 kN/m^2
        # orientation: global z-direction (following the curved structure);
        boundary_dead_load = -0.35e-3  # [MN/m]

        #--- LC3 snow
        # s = 0,79 kN/m^2
        # orientation: global z-direction (projection);
        surface_load_s = -0.85e-3  # [MN/m^2]

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

        # NOTE: additional line-loads at the edge of the roof need to be considered!

        upper_surface = domain[:, :, -1, :, :, -1]
        whole_domain = domain[:, :, :, :, :, :]
        boundary_x1 = domain[-1, :, -1, -1, :, -1]
        boundary_y1 = domain[:, -1, -1, :, -1, -1]

        time_fn_load = self.time_fn_load

        time_fn_permanent_load = MFnLineArray(xdata=[0.0, 1.0],
                                              ydata=[0.0, 1.0])
        time_fn_snow_load = MFnLineArray(xdata=[0.0, 1.0], ydata=[0.0, 0.0])

        force_bc = [
            # own weight
            BCSlice(name='self weight',
                    var='f',
                    value=material_density_roof,
                    dims=[2],
                    integ_domain='global',
                    time_function=time_fn_load.get_value,
                    slice=whole_domain),

            # LC2: additional dead-load
            BCSlice(name='additional load',
                    var='f',
                    value=additional_dead_load,
                    dims=[2],
                    integ_domain='global',
                    time_function=time_fn_load.get_value,
                    slice=upper_surface),

            # LC2: additional boundary-load
            BCSlice(name='additional boundary load 1',
                    var='f',
                    value=boundary_dead_load,
                    dims=[2],
                    integ_domain='global',
                    time_function=time_fn_load.get_value,
                    slice=boundary_x1),

            # LC2: additional boundary-load
            BCSlice(name='additional boundary load 2',
                    var='f',
                    value=boundary_dead_load,
                    dims=[2],
                    integ_domain='global',
                    time_function=time_fn_load.get_value,
                    slice=boundary_y1),
            # LC3: snow load
            BCSlice(name='snow load',
                    var='f',
                    value=surface_load_s,
                    dims=[2],
                    integ_domain='global',
                    time_function=time_fn_snow_load.get_value,
                    slice=upper_surface),

            #                     # LC3: wind
            #                     BCSlice( var = 'f', value = surface_load_w, dims = [2],
            #                              integ_domain = 'global',
            #                              slice = upper_surface )
        ]

        bc_symplane_yz = BCSlice(var='u',
                                 value=0.,
                                 dims=[0],
                                 slice=domain[0, :, :, 0, :, :])
        bc_symplane_xz = BCSlice(var='u',
                                 value=0.,
                                 dims=[1],
                                 slice=domain[:, 0, :, :, 0, :])
        bc_support_000 = BCSlice(var='u',
                                 value=0.,
                                 dims=[2],
                                 slice=domain[0, 0, 0, :, :, 0])

        #        bc_column = [
        #                     BCSlice( var = 'u'  , dims = [0, 1, 2],
        #                              slice = domain[self.n_elems_xy_quarter - 1,
        #                                               self.n_elems_xy_quarter - 1,
        #                                               0,
        #                                               0, -1, 0 ],
        #                              value = 0. ),
        #                    BCSlice( var = 'u'  , dims = [0, 1, 2],
        #                            slice = domain[self.n_elems_xy_quarter - 1,
        #                                           self.n_elems_xy_quarter - 1 ,
        #                                           0,
        #                                           - 1, 0, 0],
        #                            value = 0. )]

        # bc_corner_load   = BCSlice( var = 'f', value = -nodal_load, dims = [2], slice = domain[-1,-1,-1,-1,-1,-1] )
        # bc_topface_load  = BCSlice( var = 'f', value = -nodal_load, dims = [2], slice = domain[:,:,-1,:,:,-1] )

        #        support_z_dofs = domain[0, 0, 0, :, : , 0].dofs[:, :, 2]
        #        support_f_w = RTraceGraph(name='force - corner deflection',
        #                           var_x='time', idx_x=0,
        #                           transform_x='x * %g' % lambda_failure,
        #                           var_y='F_int', idx_y_arr=np.unique(support_z_dofs.flatten()),
        #                           transform_y='-y',
        #                           record_on='update')

        rtrace_list = [self.f_w_diagram] + self.rtrace_list

        ts = TS(sdomain=[domain],
                dof_resultants=True,
                bcond_list=[bc_symplane_yz, bc_symplane_xz, bc_support_000] +
                force_bc,
                rtrace_list=rtrace_list)

        step = 1.0  # self.n_steps
        # Add the time-loop control
        tloop = TLoop(tstepper=ts,
                      RESETMAX=0,
                      KMAX=70,
                      tolerance=0.5e-3,
                      tline=TLine(min=0.0, step=step,
                                  max=1.0))  # self.max_lambda))
        return tloop
コード例 #12
0
ファイル: mr_quarter.py プロジェクト: rosoba/simvisage
class MRquarterDB(MRquarter):
    '''get 'phi_fn' as calibrated by the fitter and stored in the DB
    '''

    # vary the failure strain in PhiFnGeneralExtended:
    factor_eps_fail = Float(1.4, input=True, ps_levels=(1.0, 1.2, 3))

    #-----------------
    # composite cross section unit cell:
    #-----------------
    #
    ccs_unit_cell_key = Enum('FIL-10-09_2D-05-11_0.00462_all0',
                             CCSUnitCell.db.keys(),
                             simdb=True,
                             input=True,
                             auto_set=False,
                             enter_set=True)

    ccs_unit_cell_ref = Property(Instance(SimDBClass),
                                 depends_on='ccs_unit_cell_key')

    @cached_property
    def _get_ccs_unit_cell_ref(self):
        return CCSUnitCell.db[self.ccs_unit_cell_key]

    #-----------------
    # damage function:
    #-----------------
    #
    material_model = Str(input=True)

    def _material_model_default(self):
        # return the material model key of the first DamageFunctionEntry
        # This is necessary to avoid an ValueError at setup
        return self.ccs_unit_cell_ref.damage_function_list[0].material_model

    calibration_test = Str(input=True)

    def _calibration_test_default(self):
        # return the material model key of the first DamageFunctionEntry
        # This is necessary to avoid an ValueError at setup
        return self.ccs_unit_cell_ref.damage_function_list[0].calibration_test

    damage_function = Property(Instance(MFnLineArray), depends_on='+input')

    @cached_property
    def _get_damage_function(self):
        print 'getting damage function'
        return self.ccs_unit_cell_ref.get_param(self.material_model,
                                                self.calibration_test)

    #-----------------
    # phi function extended:
    #-----------------
    #
    phi_fn = Property(Instance(PhiFnGeneralExtended),
                      depends_on='+input,+ps_levels')

    @cached_property
    def _get_phi_fn(self):
        return PhiFnGeneralExtendedExp(mfn=self.damage_function,
                                       Dfp=0.01,
                                       Efp_frac=0.007)


#        return PhiFnGeneralExtended( mfn = self.damage_function,
#                                     factor_eps_fail = self.factor_eps_fail )

#----------------------------------------------------------------------------------
# mats_eval
#----------------------------------------------------------------------------------

# age of the plate at the time of testing
# NOTE: that the same phi-function is used independent of age. This assumes a
# an afine/proportional damage evolution for different ages.
#

    age = Int(
        28,  # input = True
    )

    # composite E-modulus
    #
    E_c = Property(Float, depends_on='+input')

    @cached_property
    def _get_E_c(self):
        return self.ccs_unit_cell_ref.get_E_c_time(self.age)

    # Poisson's ratio
    #
    nu = Property(Float, depends_on='+input')

    @cached_property
    def _get_nu(self):
        return self.ccs_unit_cell_ref.nu
コード例 #13
0
class SPIRRID( Randomization ):

    #---------------------------------------------------------------------------------------------
    # Range of the control process variable epsilon
    # Define particular control variable points with
    # the cv array or an equidistant range with (min, max, n)
    #---------------------------------------------------------------------------------------------

    cv = Array( eps_range = True )
    min_eps = Float( 0.0, eps_range = True )
    max_eps = Float( 0.0, eps_range = True )
    n_eps = Float( 80, eps_range = True )

    eps_arr = Property( depends_on = 'eps_change' )
    @cached_property
    def _get_eps_arr( self ):

        # @todo: !!! 
        # This is a side-effect in a property - CRIME !! [rch]
        # No clear access interface points - naming inconsistent.
        # define a clean property with a getter and setter
        # 
        # if the array of control variable points is not given
        if len( self.cv ) == 0:

            n_eps = self.n_eps
            min_eps = self.min_eps
            max_eps = self.max_eps

            return linspace( min_eps, max_eps, n_eps )
        else:
            return self.cv

    #------------------------------------------------------------------------------------
    # Configuration of the algorithm
    #------------------------------------------------------------------------------------
    # 
    # cached_dG_grid:
    # If set to True, the cross product between the pdf values of all random variables
    # will be precalculated and stored in an n-dimensional grid
    # otherwise the product is performed for every epsilon in the inner loop anew
    # 
    cached_dG = Bool( True, alg_option = True )

    # compiled_eps_loop:
    # If set True, the loop over the control variable epsilon is compiled
    # otherwise, python loop is used.
    compiled_eps_loop = Bool( False, alg_option = True )

    # compiled_QdG_loop:
    # If set True, the integration loop over the product between the response function
    # and the pdf . theta product is performed in c
    # otherwise the numpy arrays are used.
    compiled_QdG_loop = Bool( False, alg_option = True )
    def _compiled_QdG_loop_changed( self ):
        '''If the inner loop is not compiled, the outer loop 
        must not be compiled as well.
        '''
        if self.compiled_QdG_loop == False:
            self.compiled_eps = False

    arg_list = Property( depends_on = 'rf_change, rand_change, conf_change' )
    @cached_property
    def _get_arg_list( self ):

        arg_list = []
        # create argument string for inline function
        if self.compiled_eps_loop:
            arg_list += [ 'mu_q_arr', 'e_arr' ]
        else:
            arg_list.append( 'e' )

        arg_list += ['%s_flat' % name for name in self.rv_keys ]

        if self.cached_dG:
            arg_list += [ 'dG_grid' ]
        else:
            arg_list += [ '%s_pdf' % name for name in self.rv_keys ]

        return arg_list

    dG_C_code = Property( depends_on = 'rf_change, rand_change, conf_change' )
    @cached_property
    def _get_dG_C_code( self ):
        if self.cached_dG: # q_g - blitz matrix used to store the grid
            code_str = '\tdouble pdf = dG_grid(' + \
                       ','.join( [ 'i_%s' % name
                                  for name in self.rv_keys ] ) + \
                       ');\n'
        else: # qg
            code_str = '\tdouble pdf = ' + \
                       '*'.join( [ ' *( %s_pdf + i_%s)' % ( name, name )
                                  for name in self.rv_keys ] ) + \
                       ';\n'
        return code_str

    #------------------------------------------------------------------------------------
    # Configurable generation of C-code for mean curve evaluation
    #------------------------------------------------------------------------------------
    C_code = Property( depends_on = 'rf_change, rand_change, conf_change, eps_change' )
    @cached_property
    def _get_C_code( self ):

        code_str = ''
        if self.compiled_eps_loop:

            # create code string for inline function
            #
            code_str += 'for( int i_eps = 0; i_eps < %g; i_eps++){\n' % self.n_eps

            if self.cached_dG:

                # multidimensional index needed for dG_grid 
                # blitz arrays must be used also for other arrays
                #
                code_str += 'double eps = e_arr( i_eps );\n'

            else:
                # pointer access possible for single dimensional arrays 
                # use the pointer arithmetics for accessing the pdfs
                code_str += '\tdouble eps = *( e_arr + i_eps );\n'

        else:

            # create code string for inline function
            #
            code_str += 'double eps = e;\n'

        code_str += 'double mu_q(0);\n'
        code_str += 'double q(0);\n'

        code_str += '#line 100\n'
        # create code for constant params
        for name, value in list(self.const_param_dict.items()):
            code_str += 'double %s = %g;\n' % ( name, value )

        # generate loops over random params

        for rv in self.rv_list:

            name = rv.name
            n_int = rv.n_int

            # create the loop over the random variable
            #
            code_str += 'for( int i_%s = 0; i_%s < %g; i_%s++){\n' % ( name, name, n_int, name )
            if self.cached_dG:

                # multidimensional index needed for pdf_grid - use blitz arrays
                #
                code_str += '\tdouble %s = %s_flat( i_%s );\n' % ( name, name, name )
            else:

                # pointer access possible for single dimensional arrays 
                # use the pointer arithmetics for accessing the pdfs
                code_str += '\tdouble %s = *( %s_flat + i_%s );\n' % ( name, name, name )

        if len( self.rv_keys ) > 0:
            code_str += self.dG_C_code
            code_str += self.rf.C_code + \
                       '// Store the values in the grid\n' + \
                       '\tmu_q +=  q * pdf;\n'
        else:
            code_str += self.rf.C_code + \
                       '\tmu_q += q;\n'

        # close the random loops
        #
        for name in self.rv_keys:
            code_str += '};\n'

        if self.compiled_eps_loop:
            if self.cached_dG: # blitz matrix
                code_str += 'mu_q_arr(i_eps) = mu_q;\n'
            else:
                code_str += '*(mu_q_arr + i_eps) = mu_q;\n'
            code_str += '};\n'
        else:
            code_str += 'return_val = mu_q;'
        return code_str

    compiler_verbose = Int( 0 )
    compiler = Str( 'gcc' )

    # Option of eval that induces the calculation of variation
    # in parallel with the mean value so that interim values of Q_grid 
    # are directly used for both.
    #
    implicit_var_eval = Bool( False, alg_option = True )

    def _eval( self ):
        '''Evaluate the integral based on the configuration of algorithm.
        '''
        if self.cached_dG == False and self.compiled_QdG_loop == False:
            raise NotImplementedError('Configuration for pure Python integration is too slow and is not implemented')

        self._set_compiler()
        # prepare the array of the control variable discretization
        #
        eps_arr = self.eps_arr
        mu_q_arr = zeros_like( eps_arr )

        # prepare the variable for the variance
        var_q_arr = None
        if self.implicit_var_eval:
            var_q_arr = zeros_like( eps_arr )

        # prepare the parameters for the compiled function in 
        # a separate dictionary
        c_params = {}

        if self.compiled_eps_loop:

            # for compiled eps_loop the whole input and output array must be passed to c
            #
            c_params['e_arr'] = eps_arr
            c_params['mu_q_arr'] = mu_q_arr
            #c_params['n_eps' ] = n_eps

        if self.compiled_QdG_loop:

            # prepare the lengths of the arrays to set the iteration bounds
            #
            for rv in self.rv_list:
                c_params[ '%s_flat' % rv.name ] = rv.theta_arr

        if len( self.rv_list ) > 0:
            if self.cached_dG:
                c_params[ 'dG_grid' ] = self.dG_grid
            else:
                for rv in self.rv_list:
                    c_params['%s_pdf' % rv.name] = rv.dG_arr
        else:
                c_params[ 'dG_grid' ] = self.dG_grid

        if self.cached_dG:
            conv = converters.blitz
        else:
            conv = converters.default

        t = time.clock()

        if self.compiled_eps_loop:

            # C loop over eps, all inner loops must be compiled as well
            #
            if self.implicit_var_eval:
                raise NotImplementedError('calculation of variance not available in the compiled version')

            inline( self.C_code, self.arg_list, local_dict = c_params,
                    type_converters = conv, compiler = self.compiler,
                    verbose = self.compiler_verbose )

        else:

            # Python loop over eps
            #
            for idx, e in enumerate( eps_arr ):

                if self.compiled_QdG_loop:

                    if self.implicit_var_eval:
                        raise NotImplementedError('calculation of variance not available in the compiled version')

                    # C loop over random dimensions
                    #
                    c_params['e'] = e # prepare the parameter
                    mu_q = inline( self.C_code, self.arg_list, local_dict = c_params,
                                   type_converters = conv, compiler = self.compiler,
                                   verbose = self.compiler_verbose )
                else:

                    # Numpy loops over random dimensions
                    #
                    # get the rf grid for all combinations of
                    # parameter values
                    #          
                    Q_grid = self.rf( e, **self.param_dict )

                    # multiply the response grid with the contributions
                    # of pdf distributions (weighted by the delta of the
                    # random variable disretization)
                    #

                    if not self.implicit_var_eval:
                        # only mean value needed, the multiplication can be done
                        # in-place
                        Q_grid *= self.dG_grid
                        # sum all the values to get the integral 
                        mu_q = sum( Q_grid )
                    else:
                        # get the square values of the grid
                        Q_grid2 = Q_grid ** 2
                        # make an inplace product of Q_grid with the weights
                        Q_grid *= self.dG_grid
                        # make an inplace product of the squared Q_grid with the weights
                        Q_grid2 *= self.dG_grid
                        # sum all values to get the mean
                        mu_q = sum( Q_grid )
                        # sum all squared values to get the variance
                        var_q = sum( Q_grid2 ) - mu_q ** 2

                # add the value to the return array
                mu_q_arr[idx] = mu_q

                if self.implicit_var_eval:
                    var_q_arr[idx] = var_q

        duration = time.clock() - t
        return  mu_q_arr, var_q_arr, duration

    def eval_i_dG_grid( self ):
        '''Get the integral of the pdf * theta grid.
        '''
        return sum( self.dG_grid )

    #---------------------------------------------------------------------------------------------
    # Output properties
    #---------------------------------------------------------------------------------------------

    # container for the data obtained in the integration
    #
    # This is not only the mean curve but also variance and 
    # execution statistics. Such an implementation 
    # concentrates the critical part of the algorithmic 
    # evaluation and avoids duplication of code and 
    # repeated calls. The results are cached in the tuple.
    # They are accessed by the convenience properties defined
    # below. 
    #  
    results = Property( depends_on = 'rand_change, conf_change, eps_change' )
    @cached_property
    def _get_results( self ):
        return self._eval()

    #---------------------------------------------------------------------------------------------
    # Output accessors
    #---------------------------------------------------------------------------------------------
    # the properties that access the cached results and give them a name

    mu_q_arr = Property()
    def _get_mu_q_arr( self ):
        '''mean of q at eps'''
        return self.results[0]

    var_q_arr = Property()
    def _get_var_q_arr( self ):
        '''variance of q at eps'''
        # switch on the implicit evaluation of variance 
        # if it has not been the case so far
        if not self.implicit_var_eval:
            self.implicit_var_eval = True

        return self.results[1]

    exec_time = Property()
    def _get_exec_time( self ):
        '''Execution time of the last evaluation.
        '''
        return self.results[2]

    mean_curve = Property()
    def _get_mean_curve( self ):
        '''Mean response curve.
        '''
        return MFnLineArray( xdata = self.eps_arr, ydata = self.mu_q_arr )

    var_curve = Property()
    def _get_var_curve( self ):
        '''variance of q at eps'''
        return MFnLineArray( xdata = self.eps_arr, ydata = self.var_q_arr )

    #---------------------------------------------------------------------------------------------
    # Auxiliary methods
    #---------------------------------------------------------------------------------------------
    def _set_compiler( self ):
        '''Catch eventual mismatch between scipy.weave and compiler 
        '''
        try:
            uname = os.uname()[3]
        except:
            # it is not Linux - just let it go and suffer
            return

        #if self.compiler == 'gcc':
            #os.environ['CC'] = 'gcc-4.1'
            #os.environ['CXX'] = 'g++-4.1'
            #os.environ['OPT'] = '-DNDEBUG -g -fwrapv -O3'

    traits_view = View( Item( 'rf@', show_label = False ),
                        width = 0.3, height = 0.3,
                        resizable = True,
                        scrollable = True,
                        )
コード例 #14
0
ファイル: spirrid_lab.py プロジェクト: rosoba/simvisage
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
コード例 #15
0
ファイル: nid_order_stats.py プロジェクト: simvisage/bmcs
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)))
コード例 #16
0
ファイル: hp_shell.py プロジェクト: rosoba/simvisage
class HPShell(HasTraits):
    '''Geometry definition of a hyperbolic parabolid shell.
    '''

    #-----------------------------------------------------------------
    # geometric parameters of the shell
    #-----------------------------------------------------------------

    # dimensions of the shell for one quarter of mush_roof
    #
    length_xy_quarter = Float(3.5, input=True)  # [m]
    length_z = Float(0.927, input=True)  # [m]

    # corresponds to the delta in the geometry .obj-file with name '4x4m' as a cut off
    #
    delta_h = Float(0.865, input=True)  # [m]

    # scale factors for geometric dimensions
    # NOTE: parameters can be scaled separately, i.e. scaling of 'delta_h' (inclination of the shell)
    # does not effect the scaling of the thickness
    #
    scalefactor_delta_h = Float(1.00, input=True)  # [-]
    scalefactor_length_xy = Float(1.00, input=True)  # [-]

    # thickness of the shell
    # NOTE: only used by the option 'const_reinf_layer'
    #
    t_shell = Float(0.06, input=True)  # [m]

    width_top_col = Float(0.45, input=True)  # [m]

    # factor shifting the z coordinates at the middle nodes of the edges upwards
    # in order to include the effect of imperfection in the formwork
    z_imperfection_factor = Float(0.0)

    #-----------------------------------------------------------------
    # specify the relation of the total structure (in the 'mushroof'-model)
    # with respect to a quarter of one shell defined in 'HPShell'
    #-----------------------------------------------------------------

    # @todo: "four" is not supported by "n_elems_xy_dict"in mushroff_model
    mushroof_part = Enum('one', 'quarter', 'four', input=True)

    # 'scale_size' parameter is used as scale factor for different mushroof parts
    # Defines the proportion between the length of the total model
    # with respect to the length of a quarter shell as the
    # basic substructure of which the model consists of.
    # @todo: add "depends_on" or remove "cached_property"
    # @todo: move to class definition of "mushroof_model" not in "HPShell"
    #        (also see there "n_elems_dict" with implicit "scale_factor")
    #
    scale_size = Property(Float, depends_on='mushroof_part')

    @cached_property
    def _get_scale_size(self):
        scale_dict = {'quarter': 1.0, 'one': 2.0, 'four': 4.0}
        return scale_dict[self.mushroof_part]

    # origin of the shell
    #
    X0 = Array(float, input=True)

    def _X0_default(self):
        return array([0., 0., 0.])

    #-----------------------------------------------------------------
    # discretisation
    #-----------------------------------------------------------------

    # number of element used for the discretisation ( dimensions of the entire model)
    #
    n_elems_xy_quarter = Int(5, input=True)
    n_elems_z = Int(3, input=True)

    n_elems_xy = Property(Int, depends_on='n_elems_xy_quarter, +input')

    @cached_property
    def _get_n_elems_xy(self):
        return self.n_elems_xy_quarter * self.scale_size

    #-----------------------------------------------------------------
    # option: 'shift_elems'
    #-----------------------------------------------------------------

    # shift of column elements
    # if set to "True" (default) the information defined in 'shift_array' is used.
    #
    shift_elems = Bool(True, input=True)

    # 'shift_array' is used to place element corners at a defined global
    # position in order to connect the shell with the corner nodes of the column.
    # [x_shift, y_shift, number of element s between the coordinate position]
    # NOTE: 'shift_array' needs to have shape (:,3)!
    #
    shift_array = Array(float, input=True)

    def _shift_array_default(self):
        return array(
            [[self.width_top_col / 2**0.5, self.width_top_col / 2**0.5, 1]])

    #-----------------------------------------------------------------
    # option: 'const_reinf_layer'
    #-----------------------------------------------------------------
    # 'const_reinf_layer' - parameter is used only for the non-linear analysis,
    # where an element layer with a constant thickness is needed to simulate the
    # reinforced concrete at the top and bottom of the TRC-shell.
    #
    const_reinf_layer_elem = Bool(False, input=True)
    t_reinf_layer = Float(0.03, input=True)  # [m]
    n_elems_reinf_layer = Int(
        1, input=True)  #number of dofs used for edge refinement

    #-----------------------------------------------------------------
    # read vertice points of the shell and derive a normalized
    # RBF-function for the shell approximation
    #-----------------------------------------------------------------

    # "lowerface_cut_off" - option replaces constant height for the coordinates
    # which connect to the column (this cuts of the shell geometry horizontally
    # at the bottom of the lower face of the shell geometry.
    #
    cut_off_lowerface = Bool(True, input=True)

    # choose geometric file (obj-data file)
    #
    geo_input_name = Enum('350x350cm', '4x4m', '02', input=True)

    # filter for '4x4m' file needs to be done to have regular grid
    # in order to rbf-function leading to stable solution without oscilation
    #
    geo_filter = Dict({'4x4m': delete_second_rows})

    #                        ,'350x350cm' : delete_second_rows} )

    def _read_arr(self, side='lowerface_'):
        '''read the robj-file saved in the subdirectory 
        'geometry_files'
        '''
        file_name = side + self.geo_input_name + '.robj'
        file_path = join('geometry_files', file_name)
        # get an array with the vertice coordinates
        #
        v_arr = read_rsurface(file_path)
        #        print 'v_arr before filtering \n', v_arr
        #        print 'v_arr.shape before filtering \n', v_arr.shape
        filter = self.geo_filter.get(self.geo_input_name, None)
        if filter != None:
            v_arr = filter(v_arr)


#        print 'v_arr after filtering \n', v_arr
#        print 'v_arr.shape after filtering \n', v_arr.shape
        return v_arr

    # array of the vertex positions in global
    # x,y,z-coordinates defining the lower surface of the shell
    #
    vl_arr = Property(Array(float), depends_on='geo_input_name')

    @cached_property
    def _get_vl_arr(self):
        vl_arr = self._read_arr('lowerface_')
        if self.cut_off_lowerface == True:
            print '--- lower face z-coords cut off ---'

            # z-values of the coords from the lower face are cut off.
            # From the highest z-coordinate of the lower face the vertical
            # distance is 'delta h (for 4x4m: delta_h = 1.0m).
            # At this limit the lower face is cut off.
            # NOTE: the global z coordinate is assumed to point up
            # and must be given in the same unite as 'delta_h', i.e. in [m].
            #
            vl_z_max = max(vl_arr[:, 2])
            if self.geo_input_name == '4x4m':
                # NOTE: the global z-coordinates are given in the geo data file in [m]
                # no conversion of unites necessary (self.delta_h is given in [m])
                delta_h = self.delta_h
            elif self.geo_input_name == '350x350cm':
                # NOTE: the global z-coordinates are given in the geo data file in [cm]
                # convert delta_h from [m] to [cm]
                #
                delta_h = self.delta_h * 100.
            vl_z_min = vl_z_max - delta_h
            vl_arr_z = where(vl_arr[:, 2] < vl_z_min, vl_z_min, vl_arr[:, 2])
            vl_arr = c_[vl_arr[:, 0:2], vl_arr_z]

        return vl_arr

    # array of the vertex positions in global
    # x,y,z-coordinates defining the upper surface of the shell
    #
    vu_arr = Property(Array(float), depends_on='geo_input_name')

    @cached_property
    def _get_vu_arr(self):
        return self._read_arr('upperface_')

    # normalized coordinates of the vertices for the lowerface
    # NOTE: the underline character indicates a normalized value
    # @todo: 'normalize_rsurfaces' is called twice for 'vl_arr_' and 'vu_arr_'
    #
    vl_arr_ = Property(Array(float), depends_on='geo_input_name')

    @cached_property
    def _get_vl_arr_(self):
        vl_arr_, vu_arr_ = normalize_rsurfaces(self.vl_arr, self.vu_arr)
        return vl_arr_

    # normalized coordinates of the vertices for the lowerface
    # NOTE: the underline character indicates a normalized value
    #
    vu_arr_ = Property(Array(float), depends_on='geo_input_name')

    @cached_property
    def _get_vu_arr_(self):
        vl_arr_, vu_arr_ = normalize_rsurfaces(self.vl_arr, self.vu_arr)
        return vu_arr_

    rbf_l_ = Property(Instance(Rbf), depends_on='geo_input_name')

    @cached_property
    def _get_rbf_l_(self):
        # use a radial basis function approximation (rbf) (i.e. interpolation of
        # scattered data) based on the normalized vertex points of the lower face
        #
        xl_ = self.vl_arr_[:, 0]
        yl_ = self.vl_arr_[:, 1]
        zl_ = self.vl_arr_[:, 2]

        # flip the orientation of the local coordinate axis
        # depending on the geometry file used
        #
        if self.geo_input_name == '350x350cm':
            xl_ = 1 - self.vl_arr_[:, 0]
        if self.geo_input_name == '4x4m':
            yl_ = 1 - self.vl_arr_[:, 1]

        rbf_l_ = Rbf(xl_, yl_, zl_, function='cubic')
        #        rbf_l_ = Rbf( xl_, yl_, zl_, function = 'linear' )
        return rbf_l_

    rbf_u_ = Property(Instance(Rbf), depends_on='geo_input_name')

    @cached_property
    def _get_rbf_u_(self):
        # use a radial basis function approximation (rbf) (i.e. interpolation of
        # scattered data) based on the normalized vertex points of the upper face
        #
        xu_ = self.vu_arr_[:, 0]
        yu_ = self.vu_arr_[:, 1]
        zu_ = self.vu_arr_[:, 2]

        # flip the orientation of the local coordinate axis
        # depending on the geometry file used
        #
        if self.geo_input_name == '350x350cm':
            xu_ = 1 - self.vu_arr_[:, 0]
        if self.geo_input_name == '4x4m':
            yu_ = 1 - self.vu_arr_[:, 1]

        rbf_u_ = Rbf(xu_, yu_, zu_, function='cubic')
        #        rbf_u_ = Rbf( xu_, yu_, zu_, function = 'linear' )
        return rbf_u_

    #------------------------------------------------------------------------------
    # hp_shell geometric transformation
    # NOTE: returns the global coordinates of the shell based on the supplied local
    #       grid points
    #------------------------------------------------------------------------------

    def __call__(self, points):
        '''Return the global coordinates of the supplied local points.
        '''

        # number of local grid points for each coordinate direction
        # NOTE: values must range between 0 and 1
        #
        xi_, yi_, zi_ = points[:, 0], points[:, 1], points[:, 2]

        # insert imperfection (shift the middle node of the shell upwards)
        imp = self.z_imperfection_factor
        zi_ += imp * xi_ + imp * yi_ - 2 * imp * xi_ * yi_

        # size of total structure
        #
        # @todo: move to class definition of "mushroof_model" and send to "__call__"
        scale_size = self.scale_size
        # @todo: add "_quarter" (see above)
        length_xy_tot = self.length_xy_quarter * scale_size
        n_elems_xy_quarter = self.n_elems_xy_quarter

        #        print 'HPShell n_elems_xy_quarter', n_elems_xy_quarter
        # distance from origin for each mushroof_part
        #
        def d_origin_fn(self, coords):
            if self.mushroof_part == 'quarter':
                return coords
            if self.mushroof_part == 'one':
                return abs(2.0 * coords - 1.0)
            # @todo: corresponding "scale_factor" needs to be added
            #        in order for this to work
            if self.mushroof_part == 'four':
                return where(coords < 0.5, abs(4 * coords - 1),
                             abs(-4 * coords + 3))

        # element at column shift
        #
        if self.shift_elems == True:

            # define the origin for each model part
            #
            def origin_fn(self, coords):
                if self.mushroof_part == 'quarter':
                    return zeros_like(coords)
                if self.mushroof_part == 'one':
                    return ones_like(xi_) * 0.5
                if self.mushroof_part == 'four':
                    return where(coords < 0.5, 0.25, 0.75)

            def piecewise_linear_fn(x, x_fix_arr_, y_fix_arr_):
                '''creates a piecewise linear_fn going through the fix_points
                values need to be normed running between 0..1
                and values have to be unique'''
                x_fix_arr_ = hstack((0, x_fix_arr_, 1))
                y_fix_arr_ = hstack((0, y_fix_arr_, 1))
                rbf_fn_ = Rbf(x_fix_arr_, y_fix_arr_,
                              function='linear')  #rbf has to be linear
                return rbf_fn_(x)

            # define origin for quarter
            #
            xi_origin_arr_ = origin_fn(self, xi_)
            yi_origin_arr_ = origin_fn(self, yi_)
            #            print 'xi_origin_arr_', xi_origin_arr_

            # delta towards origin
            #
            xi_delta_arr_ = (xi_ - xi_origin_arr_) * scale_size
            yi_delta_arr_ = (yi_ - yi_origin_arr_) * scale_size
            #            print 'xi_delta_arr_', xi_delta_arr

            # define sign
            #
            xi_sign_arr = where(xi_delta_arr_ == 0., 0.,
                                xi_delta_arr_ / abs(xi_delta_arr_))
            yi_sign_arr = where(yi_delta_arr_ == 0., 0.,
                                yi_delta_arr_ / abs(yi_delta_arr_))
            #            print 'xi_sign_arr', xi_sign_arr

            # fix points defined in shift array as normelized values
            #
            x_fix_ = self.shift_array[:, 0] / self.length_xy_quarter
            #            print 'x_fix_', x_fix_

            y_fix_ = self.shift_array[:, 1] / self.length_xy_quarter
            n_fix_ = add.accumulate(self.shift_array[:,
                                                     2]) / n_elems_xy_quarter

            #            print 'add.accumulate( self.shift_array[:, 2] )', add.accumulate( self.shift_array[:, 2] )
            #            print 'n_fix_', n_fix_
            #            print 'piecewise_linear_fn', piecewise_linear_fn( abs( xi_delta_arr_ ),
            #                                                                   n_fix_,
            #                                                                   x_fix_ ) / scale_size

            # new xi_
            #
            xi_ = xi_origin_arr_ + xi_sign_arr * piecewise_linear_fn(
                abs(xi_delta_arr_), n_fix_, x_fix_) / scale_size

            #            print 'xi_new', xi_

            # new yi
            #
            yi_ = yi_origin_arr_ + yi_sign_arr * piecewise_linear_fn(
                abs(yi_delta_arr_), n_fix_, y_fix_) / scale_size

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

        # values are used to calculate the z-coordinate using RBF-function of the quarter
        # (= values of the distance to the origin as absolute value)
        #
        xi_rbf_ = d_origin_fn(self, xi_)
        #        print 'xi_rbf_', xi_rbf_
        yi_rbf_ = d_origin_fn(self, yi_)

        # get the z-value at the supplied local grid points
        # of the lower face
        #
        zi_lower_ = self.rbf_l_(xi_rbf_, yi_rbf_)

        # get the z-value at the supplied local grid points
        # of the upper face
        #
        zi_upper_ = self.rbf_u_(xi_rbf_, yi_rbf_)

        # constant edge element transformation
        #
        if self.const_reinf_layer_elem == True:
            # arrange and check data
            #
            if self.t_reinf_layer > self.t_shell / 2. or self.n_elems_z < 3:
                print '--- constant edge element transformation canceled ---'
                print 'the following condition needs to be fullfilled: \n'
                print 'self.t_reinf_layer <= self.t_shell/2 and self.n_elems_z >= 3'
            else:
                n_elems_z = float(self.n_elems_z)
                # normed thickness will evaluate as t_reinf_layer at each element
                t_reinf_layer_ = self.t_reinf_layer / self.length_z / (
                    zi_upper_ - zi_lower_)

                # zi_old set off from top which needs to be shifted
                delta_ = self.n_elems_reinf_layer / n_elems_z

                # get upper, lower and internal coordinates, that need to be shifted
                zi_lower = where(zi_ <= delta_)
                zi_upper = where(abs(1 - zi_) <= delta_ + 1e-10)
                zi_inter = where(abs(zi_ - 0.5) < 0.5 - (delta_ + 1e-10))

                # narrowing of coordinates
                zi_[zi_lower] = zi_[zi_lower] * t_reinf_layer_[
                    zi_lower] / delta_
                zi_[zi_upper] = 1 - (
                    1 - zi_[zi_upper]) * t_reinf_layer_[zi_upper] / delta_
                zi_[zi_inter] = t_reinf_layer_[zi_inter] + \
                                (zi_[zi_inter] - delta_) / (1 - 2 * delta_)\
                                 * (1 - 2 * t_reinf_layer_[zi_inter])
                print '--- constant edge elements transformation done ---'

        # thickness is multiplied by the supplied zi coordinate
        #
        z_ = (zi_lower_ * self.scalefactor_delta_h +
              (zi_upper_ - zi_lower_) * zi_)

        # coordinates of origin
        #
        X_0, Y_0, Z_0 = self.X0

        print '--- geometric transformation done ---'

        # multiply the local grid points with the real dimensions in order to obtain the
        # global coordinates of the mushroof_part:
        #
        return c_[X_0 + (xi_ * length_xy_tot) * self.scalefactor_length_xy,
                  Y_0 + (yi_ * length_xy_tot) * self.scalefactor_length_xy,
                  Z_0 + z_ * self.length_z]
コード例 #17
0
ファイル: calibration.py プロジェクト: rostar/rostar
class Model(HasTraits):

    test_xdata = Array
    test_ydata = Array
    w_min = Float(0.0, auto_set=False, enter_set=True, params=True)
    w_max = Float(2., auto_set=False, enter_set=True, params=True)
    w_pts = Int(100, auto_set=False, enter_set=True, params=True)
    Ef = Float(181e3, auto_set=False, enter_set=True, params=True)
    V_f = Float(1.0, params=True)
    r = Float(3.5e-3, params=True)

    w = Property(Array, depends_on='w_min,w_max,w_pts')

    @cached_property
    def _get_w(self):
        return np.linspace(self.w_min, self.w_max, self.w_pts)

    interpolate_experiment = Property(depends_on='test_xdata,test_ydata,w')

    @cached_property
    def _get_interpolate_experiment(self):
        interp = interp1d(self.test_xdata,
                          self.test_ydata,
                          bounds_error=False,
                          fill_value=0.0)
        return interp(self.w)

    def model_free(self, tau_loc, tau_shape, tau_scale):
        xi_shape = 6.7
        #xi_scale = 3243. / (182e3 * (pi * 3.5e-3 **2 * 50.)**(-1./xi_shape)*gamma(1+1./xi_shape))
        xi_scale = 7.6e-3
        #CS=8.
        #mu_tau = 1.3 * self.r * 3.6 * (1.-0.01) / (2. * 0.01 * CS)
        #tau_scale = (mu_tau - tau_loc)/tau_shape
        #xi_scale = 0.0077
        #xi_shape = 6.7
        #tau_scale = (mu_tau - tau_loc)/tau_shape
        cb = CBClampedRandXi(pullout=False)
        spirrid = SPIRRID(q=cb, sampling_type='LHS')
        tau = RV('gamma', shape=tau_shape, scale=tau_scale, loc=tau_loc)
        w = self.w
        spirrid.eps_vars = dict(w=w)
        spirrid.theta_vars = dict(tau=tau,
                                  E_f=self.Ef,
                                  V_f=self.V_f,
                                  r=self.r,
                                  m=xi_shape,
                                  sV0=xi_scale)
        spirrid.n_int = 5000
        sigma_c = spirrid.mu_q_arr / self.r**2
        plt.plot(w, sigma_c)
        return sigma_c

    lack = 1e10

    def lack_of_fit(self, params):
        tau_loc = params[0]
        tau_shape = params[1]
        tau_scale = params[2]
        print params
        lack = np.sum((self.model_free(tau_loc, tau_shape, tau_scale) -
                       self.interpolate_experiment)**2)
        print 'params = ', params
        print 'relative lack of fit', np.sqrt(lack) / np.sum(
            self.interpolate_experiment)
        if lack < self.lack:
            print 'DRAW'
            self.lack = lack
            plt.ion()
            plt.cla()
            plt.plot(self.w, self.interpolate_experiment, color='black')
            plt.plot(self.w,
                     self.model_free(tau_loc, tau_shape, tau_scale),
                     color='red',
                     lw=2)
            plt.draw()
            plt.show()

        return lack

    def eval_params(self):
        params = minimize(self.lack_of_fit,
                          np.array([0.0, 0.01, 1.0]),
                          method='L-BFGS-B',
                          bounds=((0.0, .01), (0.01, 1.), (0.1, 5.)))
        return params
コード例 #18
0
class ExpSH(ExType):
    '''Experiment: Shell Test
    '''
#    label = Str('slab test')
    implements(IExType)

    #--------------------------------------------------------------------
    # register a change of the traits with metadata 'input'
    #--------------------------------------------------------------------

    input_change = Event
    @on_trait_change('+input, ccs.input_change, +ironing_param')
    def _set_input_change(self):
        self.input_change = True

    #--------------------------------------------------------------------------------
    # specify inputs:
    #--------------------------------------------------------------------------------

    edge_length = Float(1.25, unit = 'm', input = True, table_field = True,
                           auto_set = False, enter_set = True)
    thickness = Float(0.03, unit = 'm', input = True, table_field = True,
                           auto_set = False, enter_set = True)

    # age of the concrete at the time of testing
    age = Int(28, unit = 'd', input = True, table_field = True,
                             auto_set = False, enter_set = True)
    loading_rate = Float(0.50, unit = 'mm/min', input = True, table_field = True,
                            auto_set = False, enter_set = True)

    #--------------------------------------------------------------------------
    # composite cross section
    #--------------------------------------------------------------------------

    ccs = Instance(CompositeCrossSection)
    def _ccs_default(self):
        '''default settings correspond to 
        setup '7u_MAG-07-03_PZ-0708-1'
        '''
        fabric_layout_key = 'MAG-07-03'
#        fabric_layout_key = '2D-02-06a'
        concrete_mixture_key = 'PZ-0708-1'
#        concrete_mixture_key = 'FIL-10-09'
#        orientation_fn_key = 'all0'                                           
        orientation_fn_key = '90_0'
        n_layers = 10
        s_tex_z = 0.030 / (n_layers + 1)
        ccs = CompositeCrossSection (
                    fabric_layup_list = [
                            plain_concrete(s_tex_z * 0.5),
                            FabricLayUp (
                                   n_layers = n_layers,
                                   orientation_fn_key = orientation_fn_key,
                                   s_tex_z = s_tex_z,
                                   fabric_layout_key = fabric_layout_key
                                   ),
                            plain_concrete(s_tex_z * 0.5)
                                        ],
                    concrete_mixture_key = concrete_mixture_key
                    )
        return ccs

    #--------------------------------------------------------------------------
    # Get properties of the composite 
    #--------------------------------------------------------------------------

    # E-modulus of the composite at the time of testing 
    E_c = Property(Float, unit = 'MPa', depends_on = 'input_change', table_field = True)
    def _get_E_c(self):
        return self.ccs.get_E_c_time(self.age)

    # E-modulus of the composite after 28 days
    E_c28 = DelegatesTo('ccs', listenable = False)

    # reinforcement ration of the composite 
    rho_c = DelegatesTo('ccs', listenable = False)

    #--------------------------------------------------------------------------------
    # define processing
    #--------------------------------------------------------------------------------

    # put this into the ironing procedure processor
    #
    jump_rtol = Float(1,
                      auto_set = False, enter_set = True,
                      ironing_param = True)


    data_array_ironed = Property(Array(float),
                                  depends_on = 'data_array, +ironing_param, +axis_selection')
    @cached_property
    def _get_data_array_ironed(self):
        '''remove the jumps in the displacement curves 
        due to resetting the displacement gauges. 
        '''
        print '*** curve ironing activated ***'

        # each column from the data array corresponds to a measured parameter 
        # e.g. displacement at a given point as function of time u = f(t))
        #
        data_array_ironed = copy(self.data_array)

        for idx in range(self.data_array.shape[1]):

            # use ironing method only for columns of the displacement gauges.
            #
            if self.names_and_units[0][ idx ] != 'Kraft' and \
                self.names_and_units[0][ idx ] != 'Bezugskanal' and \
                self.names_and_units[0][ idx ] != 'D_1o'and \
                self.names_and_units[0][ idx ] != 'D_2o'and \
                self.names_and_units[0][ idx ] != 'D_3o'and \
                self.names_and_units[0][ idx ] != 'D_4o'and \
                self.names_and_units[0][ idx ] != 'D_1u'and \
                self.names_and_units[0][ idx ] != 'D_2u'and \
                self.names_and_units[0][ idx ] != 'D_3u'and \
                self.names_and_units[0][ idx ] != 'D_4u'and \
                self.names_and_units[0][ idx ] != 'W30_vo'and \
                self.names_and_units[0][ idx ] != 'W30_hi':

                # 1d-array corresponding to column in data_array
                data_arr = copy(data_array_ironed[:, idx])

                # get the difference between each point and its successor
                jump_arr = data_arr[1:] - data_arr[0:-1]

                # get the range of the measured data 
                data_arr_range = max(data_arr) - min(data_arr)

                # determine the relevant criteria for a jump
                # based on the data range and the specified tolerances:
                jump_crit = self.jump_rtol * data_arr_range

                # get the indexes in 'data_column' after which a 
                # jump exceeds the defined tolerance criteria
                jump_idx = where(fabs(jump_arr) > jump_crit)[0]

                print 'number of jumps removed in data_arr_ironed for', self.names_and_units[0][ idx ], ': ', jump_idx.shape[0]
                # glue the curve at each jump together
                for jidx in jump_idx:
                    # get the offsets at each jump of the curve
                    shift = data_arr[jidx + 1] - data_arr[jidx]
                    # shift all succeeding values by the calculated offset
                    data_arr[jidx + 1:] -= shift

                data_array_ironed[:, idx] = data_arr[:]

        return data_array_ironed


    @on_trait_change('+ironing_param')
    def process_source_data(self):
        '''read in the measured data from file and assign
        attributes after array processing.        
        
        NOTE: if center displacement gauge ('WA_M') is missing the measured 
        displacement of the cylinder ('Weg') is used instead.
        A minor mistake is made depending on how much time passes
        before the cylinder has contact with the slab.
        '''
        print '*** process source data ***'

        self._read_data_array()
        # curve ironing:
        #
        self.processed_data_array = self.data_array_ironed

        # set attributes:
        #
        self._set_array_attribs()

    #--------------------------------------------------------------------------------
    # plot templates
    #--------------------------------------------------------------------------------

    plot_templates = {'force / time' : '_plot_force_time',
                      'force / deflections center' : '_plot_force_deflection_center',
                      'force / smoothed deflections center' : '_plot_smoothed_force_deflection_center',
                      'force / deflections' : '_plot_force_deflections',
                      'force / eps_t' : '_plot_force_eps_t',
                      'force / eps_c' : '_plot_force_eps_c',
                      'force / w_elastomer' : '_plot_force_w_elastomer',
                      'time / deflections' : '_plot_time_deflections'
                     }
    default_plot_template = 'force / time'

    def _plot_force_w_elastomer(self, axes):

        xkey = 'displacement [mm]'
        ykey = 'force [kN]'
        W_vl = self.W_vl
        W_vr = self.W_vr
        W_hl = self.W_hl
        W_hr = self.W_hr
        force = self.Kraft

        axes.set_xlabel('%s' % (xkey,))
        axes.set_ylabel('%s' % (ykey,))
        axes.plot(W_vl, force)
        axes.plot(W_vr, force)
        axes.plot(W_hl, force)
        axes.plot(W_hr, force)


    def _plot_force_time(self, axes):

        xkey = 'time [s]'
        ykey = 'force [kN]'
        xdata = self.Bezugskanal
        ydata = self.Kraft

        axes.set_xlabel('%s' % (xkey,))
        axes.set_ylabel('%s' % (ykey,))
        axes.plot(xdata, ydata
                       # color = c, linewidth = w, linestyle = s 
                       )

    def _plot_force_deflection_center(self, axes):

        xkey = 'deflection [mm]'
        ykey = 'force [kN]'
        xdata = -self.WD4
        ydata = self.Kraft

        axes.set_xlabel('%s' % (xkey,))
        axes.set_ylabel('%s' % (ykey,))
        axes.plot(xdata, ydata
                       # color = c, linewidth = w, linestyle = s 
                       )

    n_fit_window_fraction = Float(0.1)

    def _plot_smoothed_force_deflection_center(self, axes):

        xkey = 'deflection [mm]'
        ykey = 'force [kN]'

        # get the index of the maximum stress
        max_force_idx = argmax(self.Kraft)
        # get only the ascending branch of the response curve
        f_asc = self.Kraft[:max_force_idx + 1]
        w_asc = -self.WD4[:max_force_idx + 1]

        f_max = f_asc[-1]
        w_max = w_asc[-1]

        n_points = int(self.n_fit_window_fraction * len(w_asc))
        f_smooth = smooth(f_asc, n_points, 'flat')
        w_smooth = smooth(w_asc, n_points, 'flat')

        axes.plot(w_smooth, f_smooth, color = 'blue', linewidth = 2)

        secant_stiffness_w10 = (f_smooth[10] - f_smooth[0]) / (w_smooth[10] - w_smooth[0])
        w0_lin = array([0.0, w_smooth[10] ], dtype = 'float_')
        f0_lin = array([0.0, w_smooth[10] * secant_stiffness_w10 ], dtype = 'float_')

        axes.set_xlabel('%s' % (xkey,))
        axes.set_ylabel('%s' % (ykey,))


    def _plot_force_deflections(self, axes):

        xkey = 'displacement [mm]'
        ykey = 'force [kN]'

        # get the index of the maximum stress
        max_force_idx = argmax(self.Kraft)
        # get only the ascending branch of the response curve
        f_asc = self.Kraft[:max_force_idx + 1]

        WD1 = -self.WD1[:max_force_idx + 1]
        WD2 = -self.WD2[:max_force_idx + 1]
        WD3 = -self.WD3[:max_force_idx + 1]
        WD4 = -self.WD4[:max_force_idx + 1]
        WD5 = -self.WD5[:max_force_idx + 1]
        WD6 = -self.WD6[:max_force_idx + 1]
        WD7 = -self.WD7[:max_force_idx + 1]

        axes.plot(WD1, f_asc, color = 'blue', linewidth = 1 )
        axes.plot(WD2, f_asc, color = 'green', linewidth = 1 )
        axes.plot(WD3, f_asc, color = 'red', linewidth = 1 )
        axes.plot(WD4, f_asc, color = 'black', linewidth = 3 )
        axes.plot(WD5, f_asc, color = 'red', linewidth = 1 )
        axes.plot(WD6, f_asc, color = 'green', linewidth = 1 )
        axes.plot(WD7, f_asc, color = 'blue', linewidth = 1 )

        axes.set_xlabel('%s' % (xkey,))
        axes.set_ylabel('%s' % (ykey,))


    def _plot_time_deflections(self, axes):

        xkey = 'time [s]'
        ykey = 'deflections [mm]'

        time = self.Bezugskanal

        WD1 = -self.WD1
        WD2 = -self.WD2
        WD3 = -self.WD3
        WD4 = -self.WD4
        WD5 = -self.WD5
        WD6 = -self.WD6
        WD7 = -self.WD7

        axes.plot(time, WD1, color = 'blue', linewidth = 1 )
        axes.plot(time, WD2, color = 'green', linewidth = 1 )
        axes.plot(time, WD3, color = 'red', linewidth = 1 )
        axes.plot(time, WD4, color = 'black', linewidth = 3 )
        axes.plot(time, WD5, color = 'red', linewidth = 1 )
        axes.plot(time, WD6, color = 'green', linewidth = 1 )
        axes.plot(time, WD7, color = 'blue', linewidth = 1 )

        axes.set_xlabel('%s' % (xkey,))
        axes.set_ylabel('%s' % (ykey,))


    def _plot_force_eps_c(self, axes):

        xkey = 'force [kN]'
        ykey = 'strain [mm/m]'

        # get the index of the maximum stress
        max_force_idx = argmax(self.Kraft)
        # get only the ascending branch of the response curve
        f_asc = self.Kraft[:max_force_idx + 1]
        
        D_1u = -self.D_1u[:max_force_idx + 1]
        D_2u = -self.D_2u[:max_force_idx + 1]
        D_3u = -self.D_3u[:max_force_idx + 1]
        D_4u = -self.D_4u[:max_force_idx + 1]
        
        D_1o = -self.D_1o[:max_force_idx + 1]
        D_2o = -self.D_2o[:max_force_idx + 1]
        D_3o = -self.D_3o[:max_force_idx + 1]
        D_4o = -self.D_4o[:max_force_idx + 1]

        axes.plot(f_asc, D_1u, color = 'blue', linewidth = 1 )
        axes.plot(f_asc, D_2u, color = 'blue', linewidth = 1 )
        axes.plot(f_asc, D_3u, color = 'blue', linewidth = 1 )
        axes.plot(f_asc, D_4u, color = 'blue', linewidth = 1 )

        axes.plot(f_asc, D_1o, color = 'red', linewidth = 1 )
        axes.plot(f_asc, D_2o, color = 'red', linewidth = 1 )
        axes.plot(f_asc, D_3o, color = 'red', linewidth = 1 )
        axes.plot(f_asc, D_4o, color = 'red', linewidth = 1 )

        axes.set_xlabel('%s' % (xkey,))
        axes.set_ylabel('%s' % (ykey,))


    def _plot_force_eps_t(self, axes):

        xkey = 'strain [mm/m]'
        ykey = 'force [kN]'

        # get the index of the maximum stress
        max_force_idx = argmax(self.Kraft)
        # get only the ascending branch of the response curve
        f_asc = self.Kraft[:max_force_idx + 1]

        eps_vo = -self.W30_vo[:max_force_idx + 1] / 300. 
        eps_hi = -self.W30_hi[:max_force_idx + 1] / 300. 

        axes.plot(eps_vo, f_asc, color = 'blue', linewidth = 1 )
        axes.plot(eps_hi, f_asc, color = 'green', linewidth = 1 )

        axes.set_xlabel('%s' % (xkey,))
        axes.set_ylabel('%s' % (ykey,))


    #--------------------------------------------------------------------------------
    # view
    #--------------------------------------------------------------------------------

    traits_view = View(VGroup(
                         Group(
                              Item('jump_rtol', format_str = "%.4f"),
                              label = 'curve_ironing'
                              ),
                         Group(
                              Item('thickness', format_str = "%.3f"),
                              Item('edge_length', format_str = "%.3f"),
                              label = 'geometry'
                              ),
                         Group(
                              Item('loading_rate'),
                              Item('age'),
                              label = 'loading rate and age'
                              ),
                         Group(
                              Item('E_c', show_label = True, style = 'readonly', format_str = "%.0f"),
                              Item('ccs@', show_label = False),
                              label = 'composite cross section'
                              )
                         ),
                        scrollable = True,
                        resizable = True,
                        height = 0.8,
                        width = 0.6
                        )
コード例 #19
0
ファイル: rf_model_view.py プロジェクト: simvisage/bmcs
class RFModelView(ModelView):
    '''
    Size effect depending on the yarn length
    '''
    model = Instance(IRF)

    title = Str('RF browser')

    def init(self, info):
        for name in self.model.param_keys:
            self.on_trait_change(self._redraw, 'model.' + name)

    def close(self, info, is_ok):
        for name in self.model.param_keys:
            self.on_trait_change(self._redraw, 'model.' + name, remove=True)
        return is_ok

    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(True)

    eps_max = Float(0.1, enter_set=True, auto_set=False, config_change=True)

    n_eps = Int(20, enter_set=True, auto_set=False, config_change=True)

    x_name = Str('epsilon', enter_set=True, auto_set=False)
    y_name = Str('sigma', enter_set=True, auto_set=False)

    @on_trait_change('+config_change')
    def _redraw(self):

        figure = self.figure
        axes = self.figure.axes[0]

        in_arr = linspace(0.0, self.eps_max, self.n_eps)

        args = [in_arr] + self.model.param_values

        # get the number of parameters of the response function

        n_args = len(args)
        fn = frompyfunc(self.model.__call__, n_args, 1)

        out_arr = fn(*args)

        axes = self.figure.axes[0]
        axes.plot(in_arr, out_arr, linewidth=2)

        axes.set_xlabel(self.x_name)
        axes.set_ylabel(self.y_name)
        axes.legend(loc='best')

        self.data_changed = True

    show = Button

    def _show_fired(self):
        self._redraw()

    clear = Button

    def _clear_fired(self):
        axes = self.figure.axes[0]
        axes.clear()
        self.data_changed = True

    def default_traits_view(self):
        '''
        Generates the view from the param items.
        '''
        rf_param_items = [
            Item('model.' + name, format_str='%g')
            for name in self.model.param_keys
        ]
        plot_param_items = [
            Item('eps_max'),
            Item('n_eps'),
            Item('x_name', label='x-axis'),
            Item('y_name', label='y-axis')
        ]
        control_items = [
            Item('show', show_label=False),
            Item('clear', show_label=False),
        ]
        view = View(HSplit(
            VGroup(*rf_param_items,
                   label='Function Parameters',
                   id='stats.spirrid_bak.rf_model_view.rf_params',
                   scrollable=True),
            VGroup(*plot_param_items,
                   label='Plot Parameters',
                   id='stats.spirrid_bak.rf_model_view.plot_params'),
            VGroup(
                Item('model.comment', show_label=False, style='readonly'),
                label='Comment',
                id='stats.spirrid_bak.rf_model_view.comment',
                scrollable=True,
            ),
            VGroup(HGroup(*control_items),
                   Item('figure',
                        editor=MPLFigureEditor(),
                        resizable=True,
                        show_label=False),
                   label='Plot',
                   id='stats.spirrid_bak.rf_model_view.plot'),
            dock='tab',
            id='stats.spirrid_bak.rf_model_view.split'),
                    kind='modal',
                    resizable=True,
                    dock='tab',
                    buttons=['Ok', 'Cancel'],
                    id='stats.spirrid_bak.rf_model_view')
        return view
コード例 #20
0
class FunctionRandomization(HasStrictTraits):

    # response function
    q = Callable(input=True)

    #===========================================================================
    # Inspection of the response function parameters
    #===========================================================================
    var_spec = Property(depends_on='q')

    @cached_property
    def _get_var_spec(self):
        '''Get the names of the q_parameters'''
        if type(self.q) is types.FunctionType:
            arg_offset = 0
            q = self.q
        else:
            arg_offset = 1
            q = self.q.__call__
        argspec = inspect.getargspec(q)
        args = np.array(argspec.args[arg_offset:])
        dflt = np.array(argspec.defaults)
        return args, dflt

    var_names = Property(depends_on='q')

    @cached_property
    def _get_var_names(self):
        '''Get the array of default values.
        None - means no default has been specified
        '''
        return self.var_spec[0]

    var_defaults = Property(depends_on='q')

    @cached_property
    def _get_var_defaults(self):
        '''Get the array of default values.
        None - means no default has been specified
        '''
        dflt = self.var_spec[1]
        defaults = np.repeat(None, len(self.var_names))
        start_idx = min(len(dflt), len(defaults))
        defaults[-start_idx:] = dflt[-start_idx:]
        return defaults

    #===========================================================================
    # Control variable specification
    #===========================================================================
    evars = Dict(Str, Array, input_change=True)

    def __evars_default(self):
        return {'e': [0, 1]}

    evar_lst = Property()

    def _get_evar_lst(self):
        ''' sort entries according to var_names.'''
        return [self.evars[nm] for nm in self.evar_names]

    evar_names = Property(depends_on='evars')

    @cached_property
    def _get_evar_names(self):
        evar_keys = list(self.evars.keys())
        return [nm for nm in self.var_names if nm in evar_keys]

    evar_str = Property()

    def _get_evar_str(self):
        s_list = [
            '%s = [%g, ..., %g] (%d)' % (name, value[0], value[-1], len(value))
            for name, value in zip(self.evar_names, self.evar_lst)
        ]
        return string.join(s_list, '\n')

    # convenience property to specify a single control variable without
    # the need to send a dictionary
    e_arr = Property

    def _set_e_arr(self, e_arr):
        '''Get the first free argument of var_names and set it to e vars
        '''
        self.evars[self.var_names[0]] = e_arr

    #===========================================================================
    # Specification of parameter value / distribution
    #===========================================================================

    tvars = Dict(input_change=True)

    tvar_lst = Property(depends_on='tvars')

    @cached_property
    def _get_tvar_lst(self):
        '''sort entries according to var_names
        '''
        return [self.tvars[nm] for nm in self.tvar_names]

    tvar_names = Property

    def _get_tvar_names(self):
        '''get the tvar names in the order given by the callable'''
        tvar_keys = list(self.tvars.keys())
        return np.array([nm for nm in self.var_names if nm in tvar_keys],
                        dtype=str)

    tvar_str = Property()

    def _get_tvar_str(self):
        s_list = [
            '%s = %s' % (name, str(value))
            for name, value in zip(self.tvar_names, self.tvar_lst)
        ]
        return string.join(s_list, '\n')

    # number of integration points
    n_int = Int(10, input_change=True)
コード例 #21
0
ファイル: exp_st.py プロジェクト: rosoba/simvisage
class ExpST(ExType):
    '''Experiment: Slab Test
    '''
#    label = Str('slab test')
    implements(IExType)

    #--------------------------------------------------------------------
    # register a change of the traits with metadata 'input'
    #--------------------------------------------------------------------

    input_change = Event
    @on_trait_change('+input, ccs.input_change, +ironing_param')
    def _set_input_change(self):
        self.input_change = True

    #--------------------------------------------------------------------------------
    # specify inputs:
    #--------------------------------------------------------------------------------

    edge_length = Float(1.25, unit='m', input=True, table_field=True,
                           auto_set=False, enter_set=True)
    thickness = Float(0.06, unit='m', input=True, table_field=True,
                           auto_set=False, enter_set=True)

    # age of the concrete at the time of testing
    age = Int(28, unit='d', input=True, table_field=True,
                             auto_set=False, enter_set=True)
    loading_rate = Float(2.0, unit='mm/min', input=True, table_field=True,
                            auto_set=False, enter_set=True)

    #--------------------------------------------------------------------------
    # composite cross section
    #--------------------------------------------------------------------------

    ccs = Instance(CompositeCrossSection)
    def _ccs_default(self):
        '''default settings correspond to
        setup '7u_MAG-07-03_PZ-0708-1'
        '''
        fabric_layout_key = '2D-05-11'
#        fabric_layout_key = 'MAG-07-03'
#        fabric_layout_key = '2D-02-06a'
#        concrete_mixture_key = 'PZ-0708-1'
#        concrete_mixture_key = 'FIL-10-09'
#        concrete_mixture_key = 'barrelshell'
        concrete_mixture_key = 'PZ-0708-1'
#        orientation_fn_key = 'all0'
        orientation_fn_key = '90_0'
        n_layers = 2
        s_tex_z = 0.015 / (n_layers + 1)
        ccs = CompositeCrossSection (
                    fabric_layup_list=[
                            plain_concrete(0.035),
#                            plain_concrete(s_tex_z * 0.5),
                            FabricLayUp (
                                   n_layers=n_layers,
                                   orientation_fn_key=orientation_fn_key,
                                   s_tex_z=s_tex_z,
                                   fabric_layout_key=fabric_layout_key
                                   ),
#                            plain_concrete(s_tex_z * 0.5)
                            plain_concrete(0.5)
                                        ],
                    concrete_mixture_key=concrete_mixture_key
                    )
        return ccs

    #--------------------------------------------------------------------------
    # Get properties of the composite
    #--------------------------------------------------------------------------

    # E-modulus of the composite at the time of testing
    E_c = Property(Float, unit='MPa', depends_on='input_change', table_field=True)
    def _get_E_c(self):
        return self.ccs.get_E_c_time(self.age)

    # E-modulus of the composite after 28 days
    E_c28 = DelegatesTo('ccs', listenable=False)

    # reinforcement ration of the composite
    rho_c = DelegatesTo('ccs', listenable=False)

    #--------------------------------------------------------------------------------
    # define processing
    #--------------------------------------------------------------------------------

    # put this into the ironing procedure processor
    #
    jump_rtol = Float(0.1,
                      auto_set=False, enter_set=True,
                      ironing_param=True)


    data_array_ironed = Property(Array(float),
                                  depends_on='data_array, +ironing_param, +axis_selection')
    @cached_property
    def _get_data_array_ironed(self):
        '''remove the jumps in the displacement curves
        due to resetting the displacement gauges.
        '''
        print '*** curve ironing activated ***'

        # each column from the data array corresponds to a measured parameter
        # e.g. displacement at a given point as function of time u = f(t))
        #
        data_array_ironed = copy(self.data_array)

        for idx in range(self.data_array.shape[1]):

            # use ironing method only for columns of the displacement gauges.
            #
            if self.names_and_units[0][ idx ] != 'Kraft' and \
                self.names_and_units[0][ idx ] != 'Bezugskanal' and \
                self.names_and_units[0][ idx ] != 'Weg':

                # 1d-array corresponding to column in data_array
                data_arr = copy(data_array_ironed[:, idx])

                # get the difference between each point and its successor
                jump_arr = data_arr[1:] - data_arr[0:-1]

                # get the range of the measured data
                data_arr_range = max(data_arr) - min(data_arr)

                # determine the relevant criteria for a jump
                # based on the data range and the specified tolerances:
                jump_crit = self.jump_rtol * data_arr_range

                # get the indexes in 'data_column' after which a
                # jump exceeds the defined tolerance criteria
                jump_idx = where(fabs(jump_arr) > jump_crit)[0]

                print 'number of jumps removed in data_arr_ironed for', self.names_and_units[0][ idx ], ': ', jump_idx.shape[0]
                # glue the curve at each jump together
                for jidx in jump_idx:
                    # get the offsets at each jump of the curve
                    shift = data_arr[jidx + 1] - data_arr[jidx]
                    # shift all succeeding values by the calculated offset
                    data_arr[jidx + 1:] -= shift

                data_array_ironed[:, idx] = data_arr[:]

        return data_array_ironed


    @on_trait_change('+ironing_param')
    def process_source_data(self):
        '''read in the measured data from file and assign
        attributes after array processing.

        NOTE: if center displacement gauge ('WA_M') is missing the measured
        displacement of the cylinder ('Weg') is used instead.
        A minor mistake is made depending on how much time passes
        before the cylinder has contact with the slab.
        '''
        print '*** process source data ***'

        self._read_data_array()
        # curve ironing:
        #
        self.processed_data_array = self.data_array_ironed

        # set attributes:
        #
        self._set_array_attribs()

        if 'WA_M' not in self.factor_list:
            print '*** NOTE: Displacement gauge at center ("WA_M") missing. Cylinder displacement ("Weg") is used instead! ***'
            self.WA_M = self.Weg


    #--------------------------------------------------------------------------------
    # plot templates
    #--------------------------------------------------------------------------------

    plot_templates = {'force / deflection (all)' : '_plot_force_deflection',
#                      'force / average deflection (c; ce; e) interpolated'    : '_plot_force_deflection_avg_interpolated',
#                      'force / deflection (center)'               : '_plot_force_center_deflection',
#                      'smoothed force / deflection (center)'      : '_plot_force_center_deflection_smoothed',
#                      'force / deflection (edges)'                : '_plot_force_edge_deflection',
#                      'force / deflection (center-edges)'         : '_plot_force_center_edge_deflection',
#                      'force / average deflection (edges)'        : '_plot_force_edge_deflection_avg',
#                      'force / average deflection (center-edges)' : '_plot_force_center_edge_deflection_avg',
#                      'force / average deflection (c; ce; e)'     : '_plot_force_deflection_avg',
#                      'force / deflection (center) interpolated'  : '_plot_force_center_deflection_interpolated',
#                      'force / deflection (corner)'               : '_plot_force_corner_deflection',
#                      'edge_deflection_avg (front/back) / edge_deflection_avg (left/right)' : '_plot_edge_deflection_edge_deflection_avg',

                     }

    default_plot_template = 'force / deflection (center)'


    n_fit_window_fraction = Float(0.1)

    # get only the ascending branch of the response curve
    #
    max_force_idx = Property(Int)
    def _get_max_force_idx(self):
        '''get the index of the maximum force'''
        return argmax(-self.Kraft)

    f_asc = Property(Array)
    def _get_f_asc(self):
        '''get only the ascending branch of the response curve'''
        return -self.Kraft[:self.max_force_idx + 1]

    w_asc = Property(Array)
    def _get_w_asc(self):
        '''get only the ascending branch of the response curve'''
        return -self.WA_M[:self.max_force_idx + 1]

    n_points = Property(Int)
    def _get_n_points(self):
        return int(self.n_fit_window_fraction * len(self.w_asc))

    f_smooth = Property()
    def _get_f_smooth(self):
        return smooth(self.f_asc, self.n_points, 'flat')

    w_smooth = Property()
    def _get_w_smooth(self):
        return smooth(self.w_asc, self.n_points, 'flat')

    def _plot_force_deflection(self, axes, offset_w=0., color='blue', linewidth=1.5, linestyle='-'):
        '''plot the F-w-diagramm for all displacement gauges including maschine displacement
        '''
        xkey = 'deflection [mm]'
        ykey = 'force [kN]'

        max_force_idx = self.max_force_idx
#        max_force_idx = -2
        f_asc = -self.Kraft[:max_force_idx + 1]

        print 'self.factor_list', self.factor_list
        header_string = ''
        for i in self.factor_list[2:]:
            header_string = header_string + i + '; '
            T_arr = -getattr(self, i)
            T_asc = T_arr[:max_force_idx + 1]
            axes.plot(T_asc, f_asc, label=i)

        axes.legend()

        img_dir = os.path.join(simdb.exdata_dir, 'img_dir')
        # check if directory exist otherwise create
        #
        if os.path.isdir(img_dir) == False:
            os.makedirs(img_dir)
        test_series_dir = os.path.join(img_dir, 'slab_test_astark')
        # check if directory exist otherwise create
        #
        if os.path.isdir(test_series_dir) == False:
            os.makedirs(test_series_dir)
        out_file = os.path.join(test_series_dir, self.key)

        np.savetxt(out_file, self.processed_data_array, delimiter=';')

        # workaround for old numpy.savetxt version:
        f = open(out_file, 'r')
        temp = f.read()
        f.close()

        f = open(out_file, 'w')
        f.write(header_string)

        f.write(temp)
        f.close()



    def _plot_force_center_deflection(self, axes, offset_w=0., color='blue', linewidth=1.5, linestyle='-'):
        '''plot the F-w-diagramm for the center (c) deflection
        '''
        xkey = 'deflection [mm]'
        ykey = 'force [kN]'
        xdata = -self.WA_M
        ydata = -self.Kraft

        xdata += offset_w
#        axes.set_xlabel('%s' % (xkey,))
#        axes.set_ylabel('%s' % (ykey,))
        axes.plot(xdata, ydata, color=color, linewidth=linewidth, linestyle=linestyle)

    def _plot_force_corner_deflection(self, axes):
        '''plot the F-w-diagramm for the corner deflection (at the center of one of the supports)
        '''
        xkey = 'deflection [mm]'
        ykey = 'force [kN]'
        xdata = -self.WA_Eck
        ydata = -self.Kraft

#        axes.set_xlabel('%s' % (xkey,))
#        axes.set_ylabel('%s' % (ykey,))
        axes.plot(xdata, ydata
                       # color = c, linewidth = w, linestyle = s
                       )

    def _plot_force_center_deflection_smoothed(self, axes):
        '''plot the F-w-diagramm for the center (c) deflection (smoothed curves)
        '''
        axes.plot(self.w_smooth, self.f_smooth, color='blue', linewidth=1)
#        secant_stiffness_w10 = (f_smooth[10] - f_smooth[0]) / (w_smooth[10] - w_smooth[0])
#        w0_lin = array([0.0, w_smooth[10] ], dtype = 'float_')
#        f0_lin = array([0.0, w_smooth[10] * secant_stiffness_w10 ], dtype = 'float_')
        # axes.plot( w0_lin, f0_lin, color = 'black' )

    def _plot_force_center_deflection_interpolated(self, axes, linestyle='-', linewidth=1.5, plot_elastic_stiffness=True):
        '''plot the F-w-diagramm for the center (c) deflection (interpolated initial stiffness)
        '''
        # get the index of the maximum stress
        max_force_idx = argmax(-self.Kraft)
        # get only the ascending branch of the response curve
        f_asc = -self.Kraft[:max_force_idx + 1]
        w_m = -self.WA_M[:max_force_idx + 1]

#        w_m -= 0.17
#        axes.plot(w_m, f_asc, color = 'blue', linewidth = 1)

        # move the starting point of the center deflection curve to the point where the force starts
        # (remove offset in measured displacement where there is still no force measured)
        #
        idx_0 = np.where(f_asc > 0.0)[0][0]

        f_asc_cut = np.hstack([f_asc[ idx_0: ]])
        w_m_cut = np.hstack([w_m[ idx_0: ]]) - w_m[ idx_0 ]
#        print 'f_asc_cut.shape', f_asc_cut.shape
#        fw_arr = np.hstack([f_asc_cut[:, None], w_m_cut[:, None]])
#        print 'fw_arr.shape', fw_arr.shape
#        np.savetxt('ST-6c-2cm-TU_bs2_f-w_asc.csv', fw_arr, delimiter=';')
        axes.plot(w_m_cut, f_asc_cut, color='k', linewidth=linewidth, linestyle=linestyle)

        # composite E-modulus
        #
        E_c = self.E_c
        print 'E_c', E_c

        if self.thickness == 0.02 and self.edge_length == 0.80 and plot_elastic_stiffness == True:
            K_linear = E_c / 24900. * 1.056  # [MN/m]=[kN/mm] bending stiffness with respect to center force
            max_f = f_asc_cut[-1]
            w_linear = np.array([0., max_f / K_linear])
            f_linear = np.array([0., max_f])
            axes.plot(w_linear, f_linear, linewidth=linewidth, linestyle='--', color='k')
        if self.thickness == 0.03 and self.edge_length == 1.25 and plot_elastic_stiffness == True:
            K_linear = E_c / 24900. * 1.267  # [MN/m]=[kN/mm] bending stiffness with respect to center force
            max_f = f_asc_cut[-1]
            w_linear = np.array([0., max_f / K_linear])
            f_linear = np.array([0., max_f])
            axes.plot(w_linear, f_linear, linewidth=linewidth, linestyle='--', color='k')
        if self.thickness == 0.06 and self.edge_length == 1.25 and plot_elastic_stiffness == True:
            K_linear = E_c / 24900. * 10.14  # [MN/m]=[kN/mm] bending stiffness with respect to center force
            max_f = f_asc_cut[-1]
            w_linear = np.array([0., max_f / K_linear])
            f_linear = np.array([0., max_f])
            axes.plot(w_linear, f_linear, linewidth=linewidth, linestyle='--', color='k')

    def _plot_force_edge_deflection(self, axes):
        '''plot the F-w-diagramm for the edge (e) deflections
        '''
        max_force_idx = self.max_force_idx
        f_asc = self.f_asc
        w_v_asc = -self.WA_V[:max_force_idx + 1]
        w_h_asc = -self.WA_H[:max_force_idx + 1]
        w_l_asc = -self.WA_L[:max_force_idx + 1]
        w_r_asc = -self.WA_R[:max_force_idx + 1]
        axes.plot(w_v_asc, f_asc, color='blue', linewidth=1)
        axes.plot(w_h_asc, f_asc, color='blue', linewidth=1)
        axes.plot(w_l_asc, f_asc, color='green', linewidth=1)
        axes.plot(w_r_asc, f_asc, color='green', linewidth=1)

    def _plot_force_edge_deflection_avg(self, axes):
        '''plot the average F-w-diagramm for the edge (e) deflections
        '''
        max_force_idx = self.max_force_idx
        f_asc = self.f_asc
        w_v_asc = -self.WA_V[:max_force_idx + 1]
        w_h_asc = -self.WA_H[:max_force_idx + 1]
        w_l_asc = -self.WA_L[:max_force_idx + 1]
        w_r_asc = -self.WA_R[:max_force_idx + 1]
        # get the average displacement values of the corresponding displacement gauges
        w_vh_asc = (w_v_asc + w_h_asc) / 2
        w_lr_asc = (w_l_asc + w_r_asc) / 2
        axes.plot(w_vh_asc, f_asc, color='blue', linewidth=1, label='w_vh')
        axes.plot(w_lr_asc, f_asc, color='blue', linewidth=1, label='w_lr')
        axes.legend()

    def _plot_edge_deflection_edge_deflection_avg(self, axes):
        '''plot the average edge (e) deflections for the front/back and left/right
        '''
        max_force_idx = self.max_force_idx
        w_v_asc = -self.WA_V[:max_force_idx + 1]
        w_h_asc = -self.WA_H[:max_force_idx + 1]
        w_l_asc = -self.WA_L[:max_force_idx + 1]
        w_r_asc = -self.WA_R[:max_force_idx + 1]
        # get the average displacement values of the corresponding displacement gauges
        w_vh_asc = (w_v_asc + w_h_asc) / 2
        w_lr_asc = (w_l_asc + w_r_asc) / 2
        axes.plot(w_vh_asc, w_lr_asc, color='blue', linewidth=1, label='w_vh / w_lr')
        axes.plot(np.array([0, w_vh_asc[-1]]), np.array([0, w_vh_asc[-1]]), color='k', linewidth=1, linestyle='-')
        axes.legend()

    def _plot_force_center_edge_deflection(self, axes):
        '''plot the F-w-diagramm for the center-edge (ce) deflections
        '''
        max_force_idx = argmax(-self.Kraft)
        # get only the ascending branch of the response curve
        f_asc = -self.Kraft[:max_force_idx + 1]
        w_ml_asc = -self.WA_ML[:max_force_idx + 1]
        w_mr_asc = -self.WA_MR[:max_force_idx + 1]
        axes.plot(w_ml_asc, f_asc, color='blue', linewidth=1, label='w_ml')
        axes.plot(w_mr_asc, f_asc, color='blue', linewidth=1, label='w_mr')
        axes.legend()

    def _plot_force_center_edge_deflection_avg(self, axes):
        '''plot the average F-w-diagramm for the center-edge (ce) deflections
        '''
        # get the index of the maximum stress
        max_force_idx = argmax(-self.Kraft)
        # get only the ascending branch of the response curve
        f_asc = -self.Kraft[:max_force_idx + 1]
        w_ml_asc = -self.WA_ML[:max_force_idx + 1]
        w_mr_asc = -self.WA_MR[:max_force_idx + 1]
        # get the average displacement values of the corresponding displacement gauges
        w_mlmr_asc = (w_ml_asc + w_mr_asc) / 2
        axes.plot(w_mlmr_asc, f_asc, color='blue', linewidth=1)

    def _plot_force_deflection_avg(self, axes):
        '''plot the average F-w-diagramms for the center(c), center-edge (ce) and edge(vh) and edge (lr) deflections
        '''
        # get the index of the maximum stress
        max_force_idx = argmax(-self.Kraft)
        # get only the ascending branch of the response curve
        f_asc = -self.Kraft[:max_force_idx + 1]

        w_m = -self.WA_M[:max_force_idx + 1]
        axes.plot(w_m, f_asc, color='blue', linewidth=1)

        # ## center-edge deflection (ce)
        w_ml_asc = -self.WA_ML[:max_force_idx + 1]
        w_mr_asc = -self.WA_MR[:max_force_idx + 1]
        # get the average displacement values of the corresponding displacement gauges
        w_mlmr_asc = (w_ml_asc + w_mr_asc) / 2
        axes.plot(w_mlmr_asc, f_asc, color='red', linewidth=1)

        # ## edge deflections (e)
        w_v_asc = -self.WA_V[:max_force_idx + 1]
        w_h_asc = -self.WA_H[:max_force_idx + 1]
        w_l_asc = -self.WA_L[:max_force_idx + 1]
        w_r_asc = -self.WA_R[:max_force_idx + 1]
        # get the average displacement values of the corresponding displacement gauges
        w_vh_asc = (w_v_asc + w_h_asc) / 2
        w_lr_asc = (w_l_asc + w_r_asc) / 2
        axes.plot(w_vh_asc, f_asc, color='green', linewidth=1, label='w_vh')
        axes.plot(w_lr_asc, f_asc, color='blue', linewidth=1, label='w_lr')

#        # set axis-labels
#        xkey = 'deflection [mm]'
#        ykey = 'force [kN]'
#        axes.set_xlabel('%s' % (xkey,))
#        axes.set_ylabel('%s' % (ykey,))

    def _plot_force_deflection_avg_interpolated(self, axes, linewidth=1):
        '''plot the average F-w-diagrams for the center(c), center-edge (ce) and edge(vh) and edge (lr) deflections
        NOTE: center deflection curve is cut at its starting point in order to remove offset in the dispacement meassurement
        '''
        # get the index of the maximum stress
        max_force_idx = argmax(-self.Kraft)
        # get only the ascending branch of the response curve
        f_asc = -self.Kraft[:max_force_idx + 1]
        w_m = -self.WA_M[:max_force_idx + 1]

#        w_m -= 0.17
#        axes.plot(w_m, f_asc, color = 'blue', linewidth = 1)

        # move the starting point of the center deflection curve to the point where the force starts
        # (remove offset in measured displacement where there is still no force measured)
        #
        idx_0 = np.where(f_asc > 0.05)[0][0]

        f_asc_cut = f_asc[ idx_0: ]
        w_m_cut = w_m[ idx_0: ] - w_m[ idx_0 ]
        axes.plot(w_m_cut, f_asc_cut, color='k', linewidth=linewidth)

        # plot machine displacement (hydraulic cylinder)
        #
#        Weg_asc = -self.Weg[ :max_force_idx + 1 ]
#        axes.plot(Weg_asc, f_asc, color='k', linewidth=1.5)

        # ## center-edge deflection (ce)
        w_ml_asc = -self.WA_ML[:max_force_idx + 1]
        w_mr_asc = -self.WA_MR[:max_force_idx + 1]
        # get the average displacement values of the corresponding displacement gauges
        w_mlmr_asc = (w_ml_asc + w_mr_asc) / 2
#        axes.plot(w_mlmr_asc, f_asc, color='red', linewidth=1)
        axes.plot(w_ml_asc, f_asc, color='k', linewidth=linewidth)
        axes.plot(w_mr_asc, f_asc, color='k', linewidth=linewidth)

        # ## edge deflections (e)
        w_v_asc = -self.WA_V[:max_force_idx + 1]
        w_h_asc = -self.WA_H[:max_force_idx + 1]
        w_l_asc = -self.WA_L[:max_force_idx + 1]
        w_r_asc = -self.WA_R[:max_force_idx + 1]
        axes.plot(w_v_asc, f_asc, color='grey', linewidth=linewidth)
        axes.plot(w_h_asc, f_asc, color='grey', linewidth=linewidth)
        axes.plot(w_l_asc, f_asc, color='k', linewidth=linewidth)
        axes.plot(w_r_asc, f_asc, color='k', linewidth=linewidth)

        # get the average displacement values of the corresponding displacement gauges
#        w_vh_asc = (w_v_asc + w_h_asc) / 2
#        w_lr_asc = (w_l_asc + w_r_asc) / 2
#        axes.plot(w_vh_asc, f_asc, color='green', linewidth=1, label='w_vh')
#        axes.plot(w_lr_asc, f_asc, color='blue', linewidth=1, label='w_lr')

        # save 'F-w-arr_m-mlmr-vh-lr' in directory "/simdb/simdata/exp_st"
#        simdata_dir = os.path.join(simdb.simdata_dir, 'exp_st')
#        if os.path.isdir(simdata_dir) == False:
#            os.makedirs(simdata_dir)
#        filename = os.path.join(simdata_dir, 'F-w-arr_m-mlmr-vh-lr_' + self.key + '.csv')
#        Fw_m_mlmr_vh_lr_arr = np.hstack([f_asc[:, None], w_m[:, None] - w_m[ idx_0 ], w_mlmr_asc[:, None], w_vh_asc[:, None], w_lr_asc[:, None]])
#        print 'Fw_m_mlmr_vh_lr_arr'
#        np.savetxt(filename, Fw_m_mlmr_vh_lr_arr, delimiter=';')
#        print 'F-w-curves for center, middle, edges saved to file %s' % (filename)

    #--------------------------------------------------------------------------------
    # view
    #--------------------------------------------------------------------------------

    traits_view = View(VGroup(
                         Group(
                              Item('jump_rtol', format_str="%.4f"),
                              label='curve_ironing'
                              ),
                         Group(
                              Item('thickness', format_str="%.3f"),
                              Item('edge_length', format_str="%.3f"),
                              label='geometry'
                              ),
                         Group(
                              Item('loading_rate'),
                              Item('age'),
                              label='loading rate and age'
                              ),
                         Group(
                              Item('E_c', show_label=True, style='readonly', format_str="%.0f"),
                              Item('ccs@', show_label=False),
                              label='composite cross section'
                              )
                         ),
                        scrollable=True,
                        resizable=True,
                        height=0.8,
                        width=0.6
                        )
コード例 #22
0
class SCM(HasTraits):
    '''Stochastic Cracking Model - compares matrix strength and stress,
    inserts new CS instances at positions, where the matrix strength
    is lower than the stress; evaluates stress-strain diagram
    by integrating the strain profile along the composite'''

    length = Float(desc='composite specimen length')
    nx = Int(desc='# of discretization points for the whole specimen')
    CB_model = Instance(CompositeCrackBridge)
    load_sigma_c_arr = Array
    n_w_CB = Int(100, desc='# of discretization points for w')
    n_BC_CB = Int(15,
                  desc='# of discretization points for boundary conditions')

    representative_cb = Instance(RepresentativeCB)

    def _representative_cb_default(self):
        return RepresentativeCB(CB_model=self.CB_model,
                                load_sigma_c_arr=self.load_sigma_c_arr,
                                length=self.length,
                                n_w=self.n_w_CB,
                                n_BC=self.n_BC_CB)

    # list of composite stress at which cracks occur
    cracking_stress_lst = List
    # list of cracks positions
    crack_positions_lst = List

    x_arr = Property(Array, depends_on='length, nx')

    @cached_property
    def _get_x_arr(self):
        # discretizes the specimen length
        return np.linspace(0., self.length, self.nx)

    random_field = Instance(RandomField)

    matrix_strength = Property(depends_on='random_field.+modified')

    @cached_property
    def _get_matrix_strength(self):
        # evaluates a random field
        # realization and creates a spline reprezentation
        rf = self.random_field.random_field
        rf_spline = MFnLineArray(xdata=self.random_field.xgrid, ydata=rf)
        return rf_spline.get_values(self.x_arr)

    def get_cbs_lst(self, positions, cracking_stresses):
        # sorts the CBs by position and adjusts the boundary conditions
        # sort the CBs
        positions = np.array(positions)
        cracking_stresses = np.array(cracking_stresses)
        argsort = np.argsort(positions)
        sorted_positions = positions[argsort]
        sorted_cracking_stresses = cracking_stresses[argsort]

        cb_lst = []
        for i, position_i in enumerate(list(sorted_positions)):
            cb_i = CB(position=position_i,
                      representative_cb=self.representative_cb,
                      crack_load_sigma_c=sorted_cracking_stresses[i])
            # specify the boundaries
            if i == 0:
                # the leftmost crack
                cb_i.Ll = cb_i.position
            else:
                # there is a crack at the left hand side
                cb_i.Ll = (cb_i.position - cb_lst[-1].position) / 2.
                cb_lst[-1].Lr = cb_i.Ll
            if i == len(positions) - 1:
                # the rightmost crack
                cb_i.Lr = self.length - cb_i.position
            cb_lst.append(cb_i)

        for cb_i in cb_lst:
            # specify the x range for cracks
            mask_right = self.x_arr >= (cb_i.position - cb_i.Ll)
            mask_left = self.x_arr <= (cb_i.position + cb_i.Lr)
            cb_i.x = self.x_arr[mask_left * mask_right] - cb_i.position
        return cb_lst

    def get_current_cracking_state(self, load):
        '''Creates the list of CB objects that have been formed up to the current load
        '''
        idx_load_level = np.sum(np.array(self.cracking_stress_lst) <= load)
        cb_lst = self.get_cbs_lst(self.crack_positions_lst[:idx_load_level],
                                  self.cracking_stress_lst[:idx_load_level])
        return cb_lst

    def get_current_strnegth(self, load):
        if len(self.crack_positions_lst) is not 0:
            cb_lst = self.get_current_cracking_state(load)
            strengths = np.array([cb_i.max_sigma_c for cb_i in cb_lst])
            return np.min(strengths)
        else:
            return np.inf

    def sigma_m(self, load):
        Em = self.CB_model.E_m
        Ec = self.CB_model.E_c
        sigma_m = load * Em / Ec * np.ones(len(self.x_arr))
        if len(self.crack_positions_lst) != 0:
            cb_lst = self.get_current_cracking_state(load)
            for cb_i in cb_lst:
                crack_position_idx = np.argwhere(self.x_arr == cb_i.position)
                idx_l = crack_position_idx - len(np.nonzero(cb_i.x < 0.)[0])
                idx_r = crack_position_idx + len(
                    np.nonzero(cb_i.x > 0.)[0]) + 1
                sigma_m[idx_l:idx_r] = cb_i.get_epsm_x(float(load)) * Em
        return sigma_m

    def sigma_m_given_crack_lst(self, load):
        Em = self.CB_model.E_m
        Ec = self.CB_model.E_c
        sigma_m = load * Em / Ec * np.ones(len(self.x_arr))
        if len(self.crack_positions_lst) != 0:
            cb_lst = self.get_cbs_lst(self.crack_positions_lst,
                                      self.cracking_stress_lst)
            for cb_i in cb_lst:
                crack_position_idx = np.argwhere(self.x_arr == cb_i.position)
                idx_l = crack_position_idx - len(np.nonzero(cb_i.x < 0.)[0])
                idx_r = crack_position_idx + len(
                    np.nonzero(cb_i.x > 0.)[0]) + 1
                sigma_m[idx_l:idx_r] = cb_i.get_epsm_x(float(load)) * Em
        return sigma_m

    def residuum(self, q):
        '''Callback method for the identification of the
        next emerging crack calculated as the difference between
        the current matrix stress and strength. See the scipy newton call below.
        '''
        residuum = np.min(self.matrix_strength -
                          self.sigma_m_given_crack_lst(q))
        return residuum

    def evaluate(self):
        # seek for the minimum strength redundancy to find the position
        # of the next crack
        last_pos = pi
        sigc_min = 0.0
        while True:
            try:
                s = t.clock()
                sigc_min = newton(self.residuum, sigc_min)
                try:
                    sigc_min = brentq(self.residuum, 0.0, sigc_min - 1e-10)
                    print 'another root found!!!'
                except:
                    pass
                print 'evaluation of the matrix crack #' + str(
                    len(self.cracking_stress_lst) + 1), t.clock() - s, 's'
            except:
                print 'composite saturated'
                break
            print 'current strength = ', self.get_current_strnegth(sigc_min)
            crack_position = self.x_arr[np.argmin(self.matrix_strength -
                                                  self.sigma_m(sigc_min))]
            self.crack_positions_lst.append(crack_position)
            self.cracking_stress_lst.append(sigc_min - 1e-10)
            plt.plot(self.x_arr,
                     self.sigma_m(sigc_min) / self.CB_model.E_m,
                     color='blue',
                     lw=2)
            plt.plot(self.x_arr,
                     self.matrix_strength / self.CB_model.E_m,
                     color='black',
                     lw=2)
            plt.show()
            if float(crack_position) == last_pos:
                print last_pos
                raise ValueError('''got stuck in loop,
                try to adapt x, w, BC ranges''')
            last_pos = float(crack_position)
コード例 #23
0
class CodeGenCompiled(CodeGen):
    '''
        C-code is generated using the inline feature of scipy.
    '''
    # ===========================================================================
    # Inspection of the randomization - needed by CodeGenCompiled
    # ===========================================================================
    evar_names = Property(depends_on='q, recalc')

    @cached_property
    def _get_evar_names(self):
        return self.spirrid.evar_names

    var_names = Property(depends_on='q, recalc')

    @cached_property
    def _get_var_names(self):
        return self.spirrid.tvar_names

    # count the random variables
    n_rand_vars = Property(depends_on='theta_vars, recalc')

    @cached_property
    def _get_n_rand_vars(self):
        return self.spirrid.n_rand_vars

    # get the indexes of the random variables within the parameter list
    rand_var_idx_list = Property(depends_on='theta_vars, recalc')

    @cached_property
    def _get_rand_var_idx_list(self):
        return self.spirrid.rand_var_idx_list

    # get the names of the random variables
    rand_var_names = Property(depends_on='theta_vars, recalc')

    @cached_property
    def _get_rand_var_names(self):
        return self.var_names[self.rand_var_idx_list]

    # get the randomization arrays
    theta_arrs = Property(List, depends_on='theta_vars, recalc')

    @cached_property
    def _get_theta_arrs(self):
        '''Get flattened list of theta arrays.
        '''
        theta = self.spirrid.sampling.theta
        return _get_flat_arrays_from_list(self.rand_var_idx_list, theta)

    # get the randomization arrays
    dG_arrs = Property(List, depends_on='theta_vars, recalc')

    @cached_property
    def _get_dG_arrs(self):
        '''Get flattened list of weight factor arrays.
        '''
        dG = self.spirrid.sampling.dG_ogrid
        return _get_flat_arrays_from_list(self.rand_var_idx_list, dG)

    arg_names = Property(
        depends_on='rf_change, rand_change, +codegen_option, recalc')

    @cached_property
    def _get_arg_names(self):

        arg_names = []
        # create argument string for inline function
        if self.compiled_eps_loop:
            # @todo: e_arr must be evar_names
            arg_names += ['mu_q_arr', 'e_arr']
        else:
            arg_names.append('e')

        arg_names += ['%s_flat' % name for name in self.rand_var_names]

        arg_names += self._get_arg_names_dG()

        return arg_names

    ld = Trait('weave',
               dict(weave=CodeGenLangDictC(), cython=CodeGenLangDictCython()))

    # ===========================================================================
    # Configuration of the code
    # ===========================================================================
    #
    # compiled_eps_loop:
    # If set True, the loop over the control variable epsilon is compiled
    # otherwise, python loop is used.
    compiled_eps_loop = Bool(True, codegen_option=True)

    # ===========================================================================
    # compiled_eps_loop - dependent code
    # ===========================================================================

    compiled_eps_loop_feature = Property(
        depends_on='compiled_eps_loop, recalc')

    @cached_property
    def _get_compiled_eps_loop_feature(self):
        if self.compiled_eps_loop == True:
            return self.ld_.LD_BEGIN_EPS_LOOP_ACTIVE, self.ld_.LD_END_EPS_LOOP_ACTIVE
        else:
            return self.ld_.LD_ASSIGN_EPS, ''

    LD_BEGIN_EPS_LOOP = Property

    def _get_LD_BEGIN_EPS_LOOP(self):
        return self.compiled_eps_loop_feature[0]

    LD_END_EPS_LOOP = Property

    def _get_LD_END_EPS_LOOP(self):
        return self.compiled_eps_loop_feature[1]

    #
    # cached_dG:
    # If set to True, the cross product between the pdf values of all random variables
    # will be precalculated and stored in an n-dimensional grid
    # otherwise the product is performed for every epsilon in the inner loop anew
    #
    cached_dG = Bool(False, codegen_option=True)

    # ===========================================================================
    # cached_dG - dependent code
    # ===========================================================================
    cached_dG_feature = Property(depends_on='cached_dG, recalc')

    @cached_property
    def _get_cached_dG_feature(self):
        if self.compiled_eps_loop:
            if self.cached_dG == True:
                return self.ld_.LD_ACCESS_EPS_IDX, self.ld_.LD_ACCESS_THETA_IDX, self.ld_.LD_ASSIGN_MU_Q_IDX
            else:
                return self.ld_.LD_ACCESS_EPS_PTR, self.ld_.LD_ACCESS_THETA_PTR, self.ld_.LD_ASSIGN_MU_Q_PTR
        else:
            if self.cached_dG == True:
                return self.ld_.LD_ACCESS_EPS_IDX, self.ld_.LD_ACCESS_THETA_IDX, self.ld_.LD_ASSIGN_MU_Q_IDX
            else:
                return self.ld_.LD_ACCESS_EPS_PTR, self.ld_.LD_ACCESS_THETA_PTR, self.ld_.LD_ASSIGN_MU_Q_PTR

    LD_ACCESS_EPS = Property

    def _get_LD_ACCESS_EPS(self):
        return self.cached_dG_feature[0]

    LD_ACCESS_THETA = Property

    def _get_LD_ACCESS_THETA(self):
        return '%s' + self.cached_dG_feature[1]

    LD_ASSIGN_MU_Q = Property

    def _get_LD_ASSIGN_MU_Q(self):
        return self.cached_dG_feature[2]

    LD_N_TAB = Property

    def _get_LD_N_TAB(self):
        if self.spirrid.sampling_type == 'LHS' or self.spirrid.sampling_type == 'MCS':
            if self.compiled_eps_loop:
                return 3
            else:
                return 2
        else:
            if self.compiled_eps_loop:
                return self.n_rand_vars + 2
            else:
                return self.n_rand_vars + 1

    # ------------------------------------------------------------------------------------
    # Configurable generation of C-code for the mean curve evaluation
    # ------------------------------------------------------------------------------------
    code = Property(
        depends_on='rf_change, rand_change, +codegen_option, eps_change, recalc'
    )

    @cached_property
    def _get_code(self):

        code_str = ''
        if self.compiled_eps_loop:

            # create code string for inline function
            #
            n_eps = len(self.spirrid.evar_lst[0])
            code_str += self.LD_BEGIN_EPS_LOOP % {'i': n_eps}
            code_str += self.LD_ACCESS_EPS

        else:

            # create code string for inline function
            #
            code_str += self.ld_.LD_ASSIGN_EPS

        code_str += self.ld_.LD_INIT_MU_Q
        if self.compiled_eps_loop:
            code_str += '\t' + self.ld_.LD_INIT_Q
        else:
            code_str += self.ld_.LD_INIT_Q
        code_str += self.ld_.LD_LINE_MACRO
        # create code for constant params
        for name, distr in zip(self.var_names, self.spirrid.tvar_lst):
            if type(distr) is float:
                code_str += self.ld_.LD_INIT_THETA % (name, distr)

        code_str += self._get_code_dG_declare()

        inner_code_str = ''
        lang = self.ld + '_code'
        q_code = getattr(self.spirrid.q, lang)
        import textwrap
        q_code = textwrap.dedent(q_code)
        q_code_split = q_code.split('\n')
        for i, s in enumerate(q_code_split):
            q_code_split[i] = self.LD_N_TAB * '\t' + s
        q_code = '\n'.join(q_code_split)

        if self.n_rand_vars > 0:
            inner_code_str += self._get_code_dG_access()
            inner_code_str += q_code + '\n' + \
                        (self.LD_N_TAB) * '\t' + self.ld_.LD_EVAL_MU_Q
        else:
            inner_code_str += q_code + \
                       self.ld_.LD_ADD_MU_Q

        code_str += self._get_code_inner_loops(inner_code_str)

        if self.compiled_eps_loop:
            if self.cached_dG:  # blitz matrix
                code_str += self.ld_.LD_ASSIGN_MU_Q_IDX
            else:
                code_str += self.ld_.LD_ASSIGN_MU_Q_PTR
            code_str += self.LD_END_EPS_LOOP
        else:
            code_str += self.ld_.LD_RETURN_MU_Q
        return code_str

    compiler_verbose = Int(1)
    compiler = Property(Str)

    def _get_compiler(self):
        if platform.system() == 'Linux':
            return 'gcc'
        elif platform.system() == 'Windows':
            return 'mingw32'

    def get_code(self):
        if self.ld == 'weave':
            return self.get_c_code()
        elif self.ld == 'cython':
            return self.get_cython_code()

    def get_cython_code(self):

        cython_header = 'print "## spirrid_cython library reloaded!"\nimport numpy as np\ncimport numpy as np\nctypedef np.double_t DTYPE_t\ncimport cython\n\[email protected](False)\[email protected](False)\[email protected](True)\ndef mu_q(%s):\n\tcdef double mu_q\n'
        # @todo - for Cython cdef variables and generalize function def()
        arg_values = {}
        for name, theta_arr in zip(self.rand_var_names, self.theta_arrs):
            arg_values['%s_flat' % name] = theta_arr
        arg_values.update(self._get_arg_values_dG())

        DECLARE_ARRAY = 'np.ndarray[DTYPE_t, ndim=1] '
        def_dec = DECLARE_ARRAY + 'e_arr'
        def_dec += ',' + DECLARE_ARRAY
        def_dec += (',' + DECLARE_ARRAY).join(arg_values)

        cython_header = cython_header % def_dec
        cython_header += '    cdef double '
        cython_header += ', '.join(self.var_names) + ', eps, dG, q\n'
        cython_header += '    cdef int i_'
        cython_header += ', i_'.join(self.var_names) + '\n'
        if self.cached_dG:
            cython_header = cython_header.replace(
                r'1] dG_grid', r'%i] dG_grid' % self.n_rand_vars)
        if self.compiled_eps_loop == False:
            cython_header = cython_header.replace(
                r'np.ndarray[DTYPE_t, ndim=1] e_arr', r'double e_arr')
            cython_header = cython_header.replace(r'eps,', r'eps = e_arr,')
        cython_code = (cython_header + self.code).replace('\t', '    ')
        cython_file_name = 'spirrid_cython.pyx'

        print 'checking for previous cython code'
        regenerate_code = True
        if os.path.exists(cython_file_name):
            f_in = open(cython_file_name, 'r').read()
            if f_in == cython_code:
                regenerate_code = False

        if regenerate_code:
            infile = open(cython_file_name, 'w')
            infile.write(cython_code)
            infile.close()
            print 'pyx file updated'

        t = sysclock()

        import pyximport
        pyximport.install(reload_support=True,
                          setup_args={"script_args": ["--force"]})
        import spirrid_cython

        if regenerate_code:
            reload(spirrid_cython)

        print '>>> pyximport', sysclock() - t
        mu_q = spirrid_cython.mu_q

        def mu_q_method(eps):
            if self.compiled_eps_loop:
                args = {'e_arr': eps}
                args.update(arg_values)
                mu_q_arr = mu_q(**args)
            else:
                # Python loop over eps
                #
                mu_q_arr = np.zeros_like(eps, dtype=np.float64)
                for idx, e in enumerate(eps):
                    # C loop over random dimensions
                    #
                    arg_values['e_arr'] = e  # prepare the parameter
                    mu_q_val = mu_q(**arg_values)
                    # add the value to the return array
                    mu_q_arr[idx] = mu_q_val
            return mu_q_arr, None

        return mu_q_method

    def get_c_code(self):
        '''
            Return the code for the given sampling of the rand domain.
        '''
        def mu_q_method(e):
            '''Template for the evaluation of the mean response.
            '''
            self._set_compiler()

            compiler_args, linker_args = self.extra_args
            print 'compiler arguments'
            print compiler_args

            # prepare the array of the control variable discretization
            #
            eps_arr = e
            mu_q_arr = np.zeros_like(eps_arr)

            # prepare the parameters for the compiled function in
            # a separate dictionary
            arg_values = {}

            if self.compiled_eps_loop:

                # for compiled eps_loop the whole input and output array must be passed to c
                #
                arg_values['e_arr'] = eps_arr
                arg_values['mu_q_arr'] = mu_q_arr

            # prepare the lengths of the arrays to set the iteration bounds
            #

            for name, theta_arr in zip(self.rand_var_names, self.theta_arrs):
                arg_values['%s_flat' % name] = theta_arr

            arg_values.update(self._get_arg_values_dG())

            if self.cached_dG:
                conv = weave.converters.blitz
            else:
                conv = weave.converters.default

            if self.compiled_eps_loop:

                # C loop over eps, all inner loops must be compiled as well
                #
                weave.inline(self.code,
                             self.arg_names,
                             local_dict=arg_values,
                             extra_compile_args=compiler_args,
                             extra_link_args=linker_args,
                             type_converters=conv,
                             compiler=self.compiler,
                             verbose=self.compiler_verbose)

            else:

                # Python loop over eps
                #
                for idx, e in enumerate(eps_arr):

                    # C loop over random dimensions
                    #
                    arg_values['e'] = e  # prepare the parameter
                    mu_q = weave.inline(self.code,
                                        self.arg_names,
                                        local_dict=arg_values,
                                        extra_compile_args=compiler_args,
                                        extra_link_args=linker_args,
                                        type_converters=conv,
                                        compiler=self.compiler,
                                        verbose=self.compiler_verbose)

                    # add the value to the return array
                    mu_q_arr[idx] = mu_q

            var_q_arr = np.zeros_like(mu_q_arr)

            return mu_q_arr, var_q_arr

        return mu_q_method

    # ===========================================================================
    # Extra compiler arguments
    # ===========================================================================
    use_extra = Bool(False, codegen_option=True)

    extra_args = Property(depends_on='use_extra, +codegen_option, recalc')

    @cached_property
    def _get_extra_args(self):
        if self.use_extra == True:
            compiler_args = [
                "-DNDEBUG -g -fwrapv -O3 -march=native", "-ffast-math"
            ]  # , "-fno-openmp", "-ftree-vectorizer-verbose=3"]
            linker_args = []  # ["-fno-openmp"]
            return compiler_args, linker_args
        elif self.use_extra == False:
            return [], []

    # ===========================================================================
    # Auxiliary methods
    # ===========================================================================
    def _set_compiler(self):
        '''Catch eventual mismatch between scipy.weave and compiler 
        '''
        if platform.system() == 'Linux':
            # os.environ['CC'] = 'gcc-4.1'
            # os.environ['CXX'] = 'g++-4.1'
            os.environ['OPT'] = '-DNDEBUG -g -fwrapv -O3'
        elif platform.system() == 'Windows':
            # not implemented
            pass

    def _get_code_dG_declare(self):
        '''Constant dG value - for PGrid, MCS, LHS
        '''
        return ''

    def _get_code_dG_access(self):
        '''Default access to dG array - only needed by TGrid'''
        return ''

    def _get_arg_names_dG(self):
        return []

    def _get_arg_values_dG(self):
        return {}

    def __str__(self):
        s = 'C( '
        s += 'var_eval = %s, ' % ` self.implicit_var_eval `
        s += 'compiled_eps_loop = %s, ' % ` self.compiled_eps_loop `
        s += 'cached_dG = %s)' % ` self.cached_dG `
        return s
コード例 #24
0
class GeoST(HasTraits):
    '''Geometry definition of the slab test with round load introduction area
    corresponding to steel plate in the test setup.
    '''

    #-----------------------------------------------------------------
    # geometric parameters of the slab
    #-----------------------------------------------------------------
    # NOTE: coordinate system is placed where the symmetry planes cut each other,
    # i.e the center of the load introduction area (=middle of steel plate)

    # discretization of total slab in x- and y-direction (region 'L')
    #
    shape_xy = Int(14, input=True)

    # discretization of the load introduction plate (region 'R')
    #
    shape_R = Int(2, input=True)

    # ratio of the discretization, i.e. number of elements for each region
    #
    r_ = Property(depends_on='+input')

    @cached_property
    def _get_r_(self):
        return 1. * self.shape_R / self.shape_xy

    #-----------------
    # geometry:
    #-----------------

    # x and y-direction
    #
    length_quarter = Float(0.625, input=True)

    # Radius of load introduction plate
    #
    radius_plate = Float(0.10, input=True)

    # z-direction
    #
    thickness = Float(0.06, input=True)

    # specify offset (translation) for the plain concrete patch (if used)
    # in global coordinates
    #
    zoffset = Float(0.0, input=True)

    #    # used regular discretization up to y = L1
    #    # (by default use regular discretization up to support)
    #    #
    #    L1 = Float(0.30, input = True)

    def __call__(self, pts):
        print '*** geo_slab_test called ***'

        x_, y_, z_ = pts.T

        R = self.radius_plate
        L = self.length_quarter
        t = self.thickness

        #-------------------------------------------
        # transformation to global coordinates
        #-------------------------------------------

        x = np.zeros_like(x_)
        y = np.zeros_like(y_)
        z = z_ * t

        r_ = self.r_

        # 1. quadrant
        #
        bool_x = x_ >= r_
        bool_y = y_ >= r_
        bool_xy = bool_x * bool_y
        idx_xy = np.where(bool_xy == 1.)[0]
        x[idx_xy] = R + (x_[idx_xy] - r_) / (1 - r_) * (L - R)
        y[idx_xy] = R + (y_[idx_xy] - r_) / (1 - r_) * (L - R)

        # 2. quadrant
        #
        bool_x = x_ >= r_
        bool_y = y_ <= r_
        bool_xy = bool_x * bool_y
        idx_xy = np.where(bool_xy == 1.)[0]
        xR = R * np.cos(y_[idx_xy] / r_ * np.pi / 4.)
        x[idx_xy] = xR + (x_[idx_xy] - r_) / (1 - r_) * (L - xR)
        y[idx_xy] = y_[idx_xy] / r_ * R

        # 4. quadrant
        #
        bool_x = x_ <= r_
        bool_y = y_ >= r_
        bool_xy = bool_x * bool_y
        idx_xy = np.where(bool_xy == 1.)[0]
        x[idx_xy] = x_[idx_xy] / r_ * R
        yR = R * np.cos(x_[idx_xy] / r_ * np.pi / 4.)
        y[idx_xy] = yR + (y_[idx_xy] - r_) / (1 - r_) * (L - yR)

        # 3. quadrant (mesh in load introduction area)
        #
        bool_x = x_ <= r_
        bool_y = y_ <= r_
        bool_xy = bool_x * bool_y
        idx_xy = np.where(bool_xy == 1.)[0]
        xR = R * np.cos(y_[idx_xy] / r_ * np.pi / 4.)
        yR = R * np.cos(x_[idx_xy] / r_ * np.pi / 4.)
        x[idx_xy] = x_[idx_xy] / r_ * xR
        y[idx_xy] = y_[idx_xy] / r_ * yR

        # rotate coordinates in order to have the load introduction plate at the
        # top left corner of the grid
        # and add offset for translation
        #
        zoffset = self.zoffset
        pts = np.c_[L - x, L - y, z + zoffset]
        #        pts = np.c_[x, y, z]

        # switch order of the points in order to start in the opposite corner of the slab
        # instead of the center of the load introduction plate. The opposite center of the
        # slab corresponds to the origin of the slab in the model 'sim_st' (as generated by
        # the FEGrid mesh;
        #
        pts = pts[::-1]
        # switch back the order of the z-axis in order to maintain starting from 0
        #
        pts[:, -1] = pts[:, -1][::-1]

        #        print pts
        return pts
コード例 #25
0
class SimBT4PT(IBVModel):
    '''Simulation: four point bending test.
    '''

    input_change = Event

    @on_trait_change('+input,ccs_unit_cell.input_change')
    def _set_input_change(self):
        self.input_change = True

    implements(ISimModel)

    #-----------------
    # discretization:
    #-----------------

    # specify weather the elastomer is to be modeled or if the load is
    # introduced as line load
    #
    elstmr_flag = Bool(True)

    # discretization in x-direction (longitudinal):
    #
    outer_zone_shape_x = Int(6, input=True, ps_levels=(4, 12, 3))

    # discretization in x-direction (longitudinal):
    #
    load_zone_shape_x = Int(2, input=True, ps_levels=(1, 4, 1))

    # middle part discretization in x-direction (longitudinal):
    #
    mid_zone_shape_x = Int(3, input=True, ps_levels=(1, 4, 1))

    # discretization in y-direction (width):
    #
    shape_y = Int(2, input=True, ps_levels=(1, 4, 2))

    # discretization in z-direction:
    #
    shape_z = Int(2, input=True, ps_levels=(1, 3, 3))

    #-----------------
    # geometry:
    #-----------------
    #
    # edge length of the bending specimen (beam) (entire length without symmetry)
    #
    length = Float(1.50, input=True)

    elstmr_length = Float(0.05, input=True)
    mid_zone_length = Float(0.50, input=True)
    elstmr_thickness = Float(0.005, input=True)
    width = Float(0.20, input=True)
    thickness = Float(0.06, input=True)

    #-----------------
    # derived geometric parameters
    #-----------------
    #
    # half the length of the elastomer (load introduction
    # with included symmetry)
    #
    sym_specmn_length = Property

    def _get_sym_specmn_length(self):
        return self.length / 2.

    sym_mid_zone_specmn_length = Property

    def _get_sym_mid_zone_specmn_length(self):
        return self.mid_zone_length / 2.

    # half the length of the elastomer (load introduction
    # with included symmetry
    #
    sym_elstmr_length = Property

    def _get_sym_elstmr_length(self):
        return self.elstmr_length / 2.

    # half the specimen width
    #
    sym_width = Property

    def _get_sym_width(self):
        return self.width / 2.

    #----------------------------------------------------------------------------------
    # mats_eval
    #----------------------------------------------------------------------------------

    # age of the plate at the time of testing
    # NOTE: that the same phi-function is used independent of age. This assumes a
    # an afine/proportional damage evolution for different ages.
    #
    age = Int(28, input=True)

    # time stepping params
    #
    tstep = Float(0.05, auto_set=False, enter_set=True, input=True)
    tmax = Float(1.0, auto_set=False, enter_set=True, input=True)
    tolerance = Float(0.001, auto_set=False, enter_set=True, input=True)

    # specify type of 'linalg.norm'
    # default value 'None' sets norm to 2-norm,
    # i.e "norm = sqrt(sum(x_i**2))
    #
    # set 'ord=np.inf' to switch norm to
    # "norm = max(abs(x_i))"
    #
    ord = Enum(np.inf, None)

    n_mp = Int(30, input=True)

    # @todo: for mats_eval the information of the unit cell should be used
    # in order to use the same number of microplanes and model version etc...
    #
    specmn_mats = Property(Instance(MATS2D5MicroplaneDamage),
                           depends_on='input_change')

    @cached_property
    def _get_specmn_mats(self):
        return MATS2D5MicroplaneDamage(
            E=self.E_c,
            #                                 E=self.E_m,
            nu=self.nu,
            # corresponding to settings in "MatsCalib"
            n_mp=self.n_mp,
            symmetrization='sum-type',
            model_version='compliance',
            phi_fn=self.phi_fn)

    if elstmr_flag:
        elstmr_mats = Property(Instance(MATS3DElastic),
                               depends_on='input_change')

        @cached_property
        def _get_elstmr_mats(self):
            # specify a small elastomer stiffness (approximation)
            E_elast = self.E_c / 10.
            print 'effective elastomer E_modulus', E_elast
            return MATS3DElastic(E=E_elast, nu=0.4)

    #-----------------
    # fets:
    #-----------------

    # specify element shrink factor in plot of fe-model
    #
    vtk_r = Float(0.95)

    # use quadratic serendipity elements
    #
    specmn_fets = Property(Instance(FETSEval), depends_on='input_change')

    @cached_property
    def _get_specmn_fets(self):
        fets = FETS2D58H20U(mats_eval=self.specmn_mats)
        fets.vtk_r *= self.vtk_r
        return fets

    # use quadratic serendipity elements
    #
    elstmr_fets = Property(Instance(FETSEval), depends_on='input_change')

    @cached_property
    def _get_elstmr_fets(self):
        fets = FETS2D58H20U(mats_eval=self.elstmr_mats)
        fets.vtk_r *= self.vtk_r
        return fets

    fe_domain = Property(depends_on='+ps_levels, +input')

    @cached_property
    def _get_fe_domain(self):
        return FEDomain()

    #===========================================================================
    # fe level
    #===========================================================================

    outer_zone_specmn_fe_level = Property(depends_on='+ps_levels, +input')

    def _get_outer_zone_specmn_fe_level(self):
        return FERefinementGrid(name='outer zone specimen patch',
                                fets_eval=self.specmn_fets,
                                domain=self.fe_domain)

    load_zone_specmn_fe_level = Property(depends_on='+ps_levels, +input')

    def _get_load_zone_specmn_fe_level(self):
        return FERefinementGrid(name='load zone specimen patch',
                                fets_eval=self.specmn_fets,
                                domain=self.fe_domain)

    mid_zone_specmn_fe_level = Property(depends_on='+ps_levels, +input')

    def _get_mid_zone_specmn_fe_level(self):
        return FERefinementGrid(name='mid zone specimen patch',
                                fets_eval=self.specmn_fets,
                                domain=self.fe_domain)

    elstmr_fe_level = Property(depends_on='+ps_levels, +input')

    def _get_elstmr_fe_level(self):
        return FERefinementGrid(name='elastomer patch',
                                fets_eval=self.elstmr_fets,
                                domain=self.fe_domain)

    #===========================================================================
    # Grid definition
    #===========================================================================

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

    @cached_property
    def _get_mid_zone_specmn_fe_grid(self):
        # only a quarter of the beam is simulated due to symmetry:
        fe_grid = FEGrid(coord_min=(0., 0., 0.),
                         coord_max=(self.sym_mid_zone_specmn_length -
                                    self.sym_elstmr_length, self.sym_width,
                                    self.thickness),
                         shape=(self.mid_zone_shape_x, self.shape_y,
                                self.shape_z),
                         level=self.mid_zone_specmn_fe_level,
                         fets_eval=self.specmn_fets)
        return fe_grid

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

    @cached_property
    def _get_load_zone_specmn_fe_grid(self):
        # only a quarter of the beam is simulated due to symmetry:
        fe_grid = FEGrid(coord_min=(self.sym_mid_zone_specmn_length -
                                    self.sym_elstmr_length, 0., 0.),
                         coord_max=(self.sym_mid_zone_specmn_length +
                                    self.sym_elstmr_length, self.sym_width,
                                    self.thickness),
                         shape=(self.load_zone_shape_x, self.shape_y,
                                self.shape_z),
                         level=self.load_zone_specmn_fe_level,
                         fets_eval=self.specmn_fets)
        return fe_grid

#    if elstmr_flag:

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

    @cached_property
    def _get_elstmr_fe_grid(self):
        fe_grid = FEGrid(coord_min=(self.sym_mid_zone_specmn_length -
                                    self.sym_elstmr_length, 0.,
                                    self.thickness),
                         coord_max=(self.sym_mid_zone_specmn_length +
                                    self.sym_elstmr_length, self.sym_width,
                                    self.thickness + self.elstmr_thickness),
                         level=self.elstmr_fe_level,
                         shape=(self.load_zone_shape_x, self.shape_y, 1),
                         fets_eval=self.elstmr_fets)
        return fe_grid

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

    @cached_property
    def _get_outer_zone_specmn_fe_grid(self):
        # only a quarter of the plate is simulated due to symmetry:
        fe_grid = FEGrid(coord_min=(self.sym_mid_zone_specmn_length +
                                    self.sym_elstmr_length, 0., 0.),
                         coord_max=(self.sym_specmn_length, self.sym_width,
                                    self.thickness),
                         shape=(self.outer_zone_shape_x, self.shape_y,
                                self.shape_z),
                         level=self.outer_zone_specmn_fe_level,
                         fets_eval=self.specmn_fets)
        return fe_grid

    #===========================================================================
    # Boundary conditions
    #===========================================================================
    w_max = Float(-0.030, input=True)  # [m]

    w_max = Float(-0.030, input=True)  # [m]

    bc_list = Property(depends_on='+ps_levels, +input')

    @cached_property
    def _get_bc_list(self):
        mid_zone_specimen = self.mid_zone_specmn_fe_grid
        load_zone_specimen = self.load_zone_specmn_fe_grid
        outer_zone_specimen = self.outer_zone_specmn_fe_grid

        if self.elstmr_flag:
            elastomer = self.elstmr_fe_grid

        #--------------------------------------------------------------
        # boundary conditions for the symmetry
        #--------------------------------------------------------------
        # symmetry in the xz-plane
        # (Note: the x-axis corresponds to the axis of symmetry along the longitudinal axis of the beam)
        #
        bc_outer_zone_symplane_xz = BCSlice(var='u',
                                            value=0.,
                                            dims=[1],
                                            slice=outer_zone_specimen[:,
                                                                      0, :, :,
                                                                      0, :])
        bc_load_zone_symplane_xz = BCSlice(var='u',
                                           value=0.,
                                           dims=[1],
                                           slice=load_zone_specimen[:, 0, :, :,
                                                                    0, :])
        bc_mid_zone_symplane_xz = BCSlice(var='u',
                                          value=0.,
                                          dims=[1],
                                          slice=mid_zone_specimen[:, 0, :, :,
                                                                  0, :])

        if self.elstmr_flag:
            bc_el_symplane_xz = BCSlice(var='u',
                                        value=0.,
                                        dims=[1],
                                        slice=elastomer[:, 0, :, :, 0, :])
        # symmetry in the yz-plane
        #
        bc_mid_zone_symplane_yz = BCSlice(var='u',
                                          value=0.,
                                          dims=[0],
                                          slice=mid_zone_specimen[0, :, :,
                                                                  0, :, :])

        #--------------------------------------------------------------
        # boundary conditions for the support
        #--------------------------------------------------------------
        bc_support_0y0 = BCSlice(var='u',
                                 value=0.,
                                 dims=[2],
                                 slice=outer_zone_specimen[-1, :, 0, -1, :, 0])

        #--------------------------------------------------------------
        # connect all grids
        #--------------------------------------------------------------
        link_loadzn_outerzn = BCDofGroup(
            var='u',
            value=0.,
            dims=[0, 1, 2],
            get_dof_method=load_zone_specimen.get_right_dofs,
            get_link_dof_method=outer_zone_specimen.get_left_dofs,
            link_coeffs=[1.])
        link_midzn_loadzn = BCDofGroup(
            var='u',
            value=0.,
            dims=[0, 1, 2],
            get_dof_method=mid_zone_specimen.get_right_dofs,
            get_link_dof_method=load_zone_specimen.get_left_dofs,
            link_coeffs=[1.])

        if self.elstmr_flag:
            link_elstmr_loadzn_z = BCDofGroup(
                var='u',
                value=0.,
                dims=[2],
                get_dof_method=elastomer.get_back_dofs,
                get_link_dof_method=load_zone_specimen.get_front_dofs,
                link_coeffs=[1.])

            # hold elastomer in a single point in order to avoid kinematic movement yielding singular K_mtx
            #
            bc_elstmr_fix = BCSlice(var='u',
                                    value=0.,
                                    dims=[0],
                                    slice=elastomer[0, 0, 0, 0, 0, 0])

        #--------------------------------------------------------------
        # loading
        #--------------------------------------------------------------
        # w_max = center displacement:
        w_max = self.w_max

        if self.elstmr_flag:
            # apply displacement at all top nodes of the elastomer (surface load)
            #
            bc_w = BCSlice(var='u',
                           value=w_max,
                           dims=[2],
                           slice=elastomer[:, :, -1, :, :, -1])
        else:
            bc_w = BCSlice(
                var='u',
                value=w_max,
                dims=[2],
                # slice is only exactly in the center of the loading zone for 'load_zone_shape_x' = 2
                # center line of the load zone
                slice=load_zone_specimen[0, :, -1, -1, :, -1])


#        f_max = 0.010 / 4. / self.sym_width
#        bc_line_f = BCSlice(var = 'f', value = f_max, dims = [2],
#                            # slice is only valid for 'load_zone_shape_x' = 2
#                            # center line of the load zone
#                            slice = load_zone_specimen[0, :, -1, -1, :, -1])

        bc_list = [
            bc_outer_zone_symplane_xz,
            bc_load_zone_symplane_xz,
            bc_mid_zone_symplane_xz,
            bc_mid_zone_symplane_yz,
            #
            link_midzn_loadzn,
            link_loadzn_outerzn,
            bc_support_0y0,
            #
            bc_w,
        ]

        if self.elstmr_flag:
            bc_list += [bc_el_symplane_xz, link_elstmr_loadzn_z, bc_elstmr_fix]

        return bc_list

    #----------------------
    # tloop
    #----------------------

    tloop = Property(depends_on='input_change')

    @cached_property
    def _get_tloop(self):

        #--------------------------------------------------------------
        # ts
        #--------------------------------------------------------------

        mid_zone_spec = self.mid_zone_specmn_fe_grid
        load_zone_spec = self.load_zone_specmn_fe_grid
        outer_zone_spec = self.outer_zone_specmn_fe_grid

        if self.elstmr_flag:
            # ELSTRMR TOP SURFACE
            # dofs at elastomer top surface (used to integrate the force)
            #
            elastomer = self.elstmr_fe_grid
            elstmr_top_dofs_z = elastomer[:, :, -1, :, :,
                                          -1].dofs[:, :, 2].flatten()
            load_dofs_z = np.unique(elstmr_top_dofs_z)
            print 'load_dofs_z', load_dofs_z
        else:
            # LINE LOAD TOP OF LOAD ZONE
            # dofs at center line of the specmn load zone (used to integrate the force)
            # note slice index in x-direction is only valid for load_zone_shape_x = 2 !
            #
            load_zone_spec_topline_dofs_z = load_zone_spec[
                0, :, -1, -1, :, -1].dofs[:, :, 2].flatten()
            load_dofs_z = np.unique(load_zone_spec_topline_dofs_z)
            print 'load_dofs_z', load_dofs_z

        # SUPPRT LINE
        # dofs at support line of the specmn (used to integrate the force)
        #
        outer_zone_spec_supprtline_dofs_z = outer_zone_spec[
            -1, :, 0, -1, :, 0].dofs[:, :, 2].flatten()
        supprt_dofs_z = np.unique(outer_zone_spec_supprtline_dofs_z)
        print 'supprt_dofs_z', supprt_dofs_z

        # CENTER DOF (used for tracing of the displacement)
        #
        center_bottom_dof = mid_zone_spec[0, 0, 0, 0, 0, 0].dofs[0, 0, 2]
        print 'center_bottom_dof', center_bottom_dof

        # THIRDPOINT DOF (used for tracing of the displacement)
        # dofs at center middle of the laod zone at the bottom side
        #
        # NOTE: slice index in x-direction is only valid for load_zone_shape_x = 2 !
        thirdpoint_bottom_dof = load_zone_spec[0, 0, 0, -1, 0, 0].dofs[0, 0, 2]
        print 'thirdpoint_bottom_dof', thirdpoint_bottom_dof

        # force-displacement-diagram (CENTER)
        #
        self.f_w_diagram_center = RTraceGraph(
            name='displacement_elasttop (center) - force',
            var_x='U_k',
            idx_x=center_bottom_dof,
            var_y='F_int',
            idx_y_arr=load_dofs_z,
            record_on='update',
            transform_x='-x * 1000',  # %g * x' % ( fabs( w_max ),),
            # due to symmetry the total force sums up from four parts of the beam (2 symmetry axis):
            #
            transform_y='-4000. * y')

        # force-displacement-diagram_supprt (SUPPRT)
        #
        self.f_w_diagram_supprt = RTraceGraph(
            name='displacement_supprtline (center) - force',
            var_x='U_k',
            idx_x=center_bottom_dof,
            var_y='F_int',
            idx_y_arr=supprt_dofs_z,
            record_on='update',
            transform_x='-x * 1000',  # %g * x' % ( fabs( w_max ),),
            # due to symmetry the total force sums up from four parts of the beam (2 symmetry axis):
            #
            transform_y='4000. * y')

        # force-displacement-diagram (THIRDPOINT)
        #
        self.f_w_diagram_thirdpoint = RTraceGraph(
            name='displacement_elasttop (thirdpoint) - force',
            var_x='U_k',
            idx_x=thirdpoint_bottom_dof,
            var_y='F_int',
            idx_y_arr=load_dofs_z,
            record_on='update',
            transform_x='-x * 1000',  # %g * x' % ( fabs( w_max ),),
            # due to symmetry the total force sums up from four parts of the beam (2 symmetry axis):
            #
            transform_y='-4000. * y')

        ts = TS(
            sdomain=self.fe_domain,
            bcond_list=self.bc_list,
            rtrace_list=[
                self.f_w_diagram_center,
                self.f_w_diagram_thirdpoint,
                self.f_w_diagram_supprt,
                RTraceDomainListField(name='Displacement',
                                      var='u',
                                      idx=0,
                                      warp=True),
                #                             RTraceDomainListField(name = 'Stress' ,
                #                                            var = 'sig_app', idx = 0, warp = True,
                #                                            record_on = 'update'),
                #                             RTraceDomainListField(name = 'Strain' ,
                #                                        var = 'eps_app', idx = 0, warp = True,
                #                                        record_on = 'update'),
                #                             RTraceDomainListField(name = 'Damage' ,
                #                                        var = 'omega_mtx', idx = 0, warp = True,
                #                                        record_on = 'update'),
                RTraceDomainListField(name='max_omega_i',
                                      warp=True,
                                      var='max_omega_i',
                                      idx=0,
                                      record_on='update'),
                #                             RTraceDomainListField(name = 'IStress' ,
                #                                            position = 'int_pnts',
                #                                            var = 'sig_app', idx = 0,
                #                                            record_on = 'update'),
                #                             RTraceDomainListField(name = 'IStrain' ,
                #                                            position = 'int_pnts',
                #                                            var = 'eps_app', idx = 0,
                #                                            record_on = 'update'),
            ])

        # Add the time-loop control
        tloop = TLoop(tstepper=ts,
                      KMAX=50,
                      tolerance=self.tolerance,
                      RESETMAX=0,
                      tline=TLine(min=0.0, step=self.tstep, max=self.tmax),
                      ord=self.ord)

        return tloop

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

        self.f_w_diagram_center.refresh()
        F_max = max(self.f_w_diagram_center.trace.ydata)

        u_center_top_z = U[self.center_top_dofs][0, 0, 2]
        return array([u_center_top_z, F_max], dtype='float_')

    def get_sim_outputs(self):
        '''
        Specifies the results and their order returned by the model
        evaluation.
        '''
        return [
            SimOut(name='u_center_top_z', unit='m'),
            SimOut(name='F_max', unit='kN')
        ]
コード例 #26
0
class PDistrib(HasTraits):

    implements = IPDistrib

    # puts all chosen continuous distributions distributions defined
    # in the scipy.stats.distributions module as a list of strings
    # into the Enum trait
    distr_choice = Enum(distr_enum)
    distr_dict = Dict(distr_dict)

    #    distr_choice = Enum('sin2x', 'weibull_min', 'sin_distr', 'uniform', 'norm')
    #    distr_dict = {'sin2x' : sin2x,
    #                  'uniform' : uniform,
    #                  'norm' : norm,
    #                  'weibull_min' : weibull_min,
    #                  'sin_distr' : sin_distr}

    # instantiating the continuous distributions
    distr_type = Property(Instance(Distribution), depends_on='distr_choice')

    @cached_property
    def _get_distr_type(self):
        return Distribution(self.distr_dict[self.distr_choice])

    # change monitor - accumulate the changes in a single event trait
    changed = Event

    @on_trait_change('distr_choice, distr_type.changed, quantile, n_segments')
    def _set_changed(self):
        self.changed = True

    # ------------------------------------------------------------------------
    # Methods setting the statistical modments
    # ------------------------------------------------------------------------
    mean = Property

    def _get_mean(self):
        return self.distr_type.mean

    def _set_mean(self, value):
        self.distr_type.mean = value

    variance = Property

    def _get_variance(self):
        return self.distr_type.mean

    def _set_variance(self, value):
        self.distr_type.mean = value

    # ------------------------------------------------------------------------
    # Methods preparing visualization
    # ------------------------------------------------------------------------

    quantile = Float(0.00001, auto_set=False, enter_set=True)
    range = Property(Tuple(Float), depends_on='distr_type.changed, quantile')

    @cached_property
    def _get_range(self):
        return (self.distr_type.distr.ppf(self.quantile),
                self.distr_type.distr.ppf(1 - self.quantile))

    n_segments = Int(500, auto_set=False, enter_set=True)

    dx = Property(Float, depends_on='distr_type.changed, quantile, n_segments')

    @cached_property
    def _get_dx(self):
        range_length = self.range[1] - self.range[0]
        return range_length / self.n_segments

    # -------------------------------------------------------------------------
    # Discretization of the distribution domain
    # -------------------------------------------------------------------------
    x_array = Property(Array('float_'),
                       depends_on='distr_type.changed,'
                       'quantile, n_segments')

    @cached_property
    def _get_x_array(self):
        '''Get the intrinsic discretization of the distribution
        respecting its  bounds.
        '''
        return linspace(self.range[0], self.range[1], self.n_segments + 1)

    # ===========================================================================
    # Access function to the scipy distribution
    # ===========================================================================
    def pdf(self, x):
        return self.distr_type.distr.pdf(x)

    def cdf(self, x):
        return self.distr_type.distr.cdf(x)

    def rvs(self, n):
        return self.distr_type.distr.rvs(n)

    def ppf(self, e):
        return self.distr_type.distr.ppf(e)

    # ===========================================================================
    # PDF - permanent array
    # ===========================================================================

    pdf_array = Property(Array('float_'),
                         depends_on='distr_type.changed,'
                         'quantile, n_segments')

    @cached_property
    def _get_pdf_array(self):
        '''Get pdf values in intrinsic positions'''
        return self.distr_type.distr.pdf(self.x_array)

    def get_pdf_array(self, x_array):
        '''Get pdf values in externally specified positions'''
        return self.distr_type.distr.pdf(x_array)

    # ===========================================================================
    # CDF permanent array
    # ===========================================================================
    cdf_array = Property(Array('float_'),
                         depends_on='distr_type.changed,'
                         'quantile, n_segments')

    @cached_property
    def _get_cdf_array(self):
        '''Get cdf values in intrinsic positions'''
        return self.distr_type.distr.cdf(self.x_array)

    def get_cdf_array(self, x_array):
        '''Get cdf values in externally specified positions'''
        return self.distr_type.distr.cdf(x_array)

    # -------------------------------------------------------------------------
    # Randomization
    # -------------------------------------------------------------------------
    def get_rvs_array(self, n_samples):
        return self.distr_type.distr.rvs(n_samples)
コード例 #27
0
ファイル: result_view.py プロジェクト: rosoba/simvisage
class ResultView(HasTraits):

    spirrid_view = Instance(SPIRRIDModelView)

    title = Str('result plot')

    n_samples = Int(10)

    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(True)

    clear = Button

    def _clear_fired(self):
        axes = self.figure.axes[0]
        axes.clear()
        self.data_changed = True

    def get_rvs_theta_arr(self, n_samples):
        rvs_theta_arr = array([
            repeat(value, n_samples)
            for value in self.spirrid_view.model.rf.param_values
        ])
        for idx, name in enumerate(self.spirrid_view.model.rf.param_keys):
            rv = self.spirrid_view.model.rv_dict.get(name, None)
            if rv:
                rvs_theta_arr[idx, :] = rv.get_rvs_theta_arr(n_samples)
        return rvs_theta_arr

    sample = Button(desc='Show samples')

    def _sample_fired(self):
        n_samples = 20

        self.spirrid_view.model.set(
            min_eps=0.00,
            max_eps=self.spirrid_view.max_eps,
            n_eps=self.spirrid_view.n_eps,
        )

        # get the parameter combinations for plotting
        rvs_theta_arr = self.get_rvs_theta_arr(n_samples)

        eps_arr = self.spirrid_view.model.eps_arr

        figure = self.figure
        axes = figure.gca()

        for theta_arr in rvs_theta_arr.T:
            q_arr = self.spirrid_view.model.rf(eps_arr, *theta_arr)
            axes.plot(eps_arr, q_arr, color='grey')

        self.data_changed = True

    @on_trait_change('spirrid_view.data_changed')
    def _redraw(self):

        figure = self.figure
        axes = figure.gca()

        mc = self.spirrid_view.model.mean_curve
        xdata = mc.xdata
        mean_per_fiber = mc.ydata
        # total expectation for independent variables = product of marginal expectations
        mean = mean_per_fiber * self.spirrid_view.mean_parallel_links

        axes.set_title(self.spirrid_view.plot_title, weight='bold')
        axes.plot(xdata, mean, linewidth=2, label=self.spirrid_view.run_legend)

        if self.spirrid_view.stdev:
            # get the variance at x from SPIRRID
            variance = self.spirrid_view.model.var_curve.ydata

            # evaluate variance for the given mean and variance of parallel links
            # law of total variance D[xy] = E[x]*D[y] + D[x]*[E[y]]**2
            variance = self.spirrid_view.mean_parallel_links * variance + \
                    self.spirrid_view.stdev_parallel_links ** 2 * mean_per_fiber ** 2
            stdev = sqrt(variance)

            axes.plot(xdata,
                      mean + stdev,
                      linewidth=2,
                      color='black',
                      ls='dashed',
                      label='stdev')
            axes.plot(xdata,
                      mean - stdev,
                      linewidth=2,
                      ls='dashed',
                      color='black')
            axes.fill_between(xdata,
                              mean + stdev,
                              mean - stdev,
                              color='lightgrey')

        axes.set_xlabel(self.spirrid_view.label_x, weight='semibold')
        axes.set_ylabel(self.spirrid_view.label_y, weight='semibold')
        axes.legend(loc='best')

        if xdata.any() == 0.:
            self.figure.clear()

        self.data_changed = True

    traits_view = View(
        HGroup(Item('n_samples', label='No of samples'),
               Item('sample', show_label=False, resizable=False),
               Item('clear', show_label=False, resizable=False,
                    springy=False)),
        Item('figure', show_label=False, editor=MPLFigureEditor()))
コード例 #28
0
class MushRoofModelNonLin(MRquarter):
    '''Overload the nonlinear model.
    '''

    #-----------------
    # composite cross section unit cell:
    #-----------------
    #
    ccs_unit_cell_key = Enum(CCSUnitCell.db.keys(),
                             simdb=True,
                             input=True,
                             auto_set=False,
                             enter_set=True)

    ccs_unit_cell_ref = Property(Instance(SimDBClass),
                                 depends_on='ccs_unit_cell_key')

    @cached_property
    def _get_ccs_unit_cell_ref(self):
        return CCSUnitCell.db[self.ccs_unit_cell_key]

    # vary the failure strain in PhiFnGeneralExtended:
    factor_eps_fail = Float(1.0, input=True, ps_levels=(1.0, 1.2, 3))

    #-----------------
    # damage function:
    #-----------------
    #
    material_model = Str(input=True)

    def _material_model_default(self):
        # return the material model key of the first DamageFunctionEntry
        # This is necessary to avoid an ValueError at setup
        return self.ccs_unit_cell_ref.damage_function_list[0].material_model

    calibration_test = Str(input=True)

    def _calibration_test_default(self):
        # return the material model key of the first DamageFunctionEntry
        # This is necessary to avoid an ValueError at setup
        return self.ccs_unit_cell_ref.damage_function_list[0].calibration_test

    damage_function = Property(Instance(MFnLineArray),
                               depends_on='input_change')

    @cached_property
    def _get_damage_function(self):
        return self.ccs_unit_cell_ref.get_param(self.material_model,
                                                self.calibration_test)

    #-----------------
    # phi function extended:
    #-----------------
    #
    phi_fn = Property(Instance(PhiFnGeneralExtended),
                      depends_on='input_change,+ps_levels')

    @cached_property
    def _get_phi_fn(self):
        return PhiFnGeneralExtended(mfn=self.damage_function,
                                    factor_eps_fail=self.factor_eps_fail)

    #----------------------------------------------------------------------------------
    # mats_eval
    #----------------------------------------------------------------------------------

    # age of the plate at the time of testing
    # NOTE: that the same phi-function is used independent of age. This assumes a
    # an afine/proportional damage evolution for different ages.
    #
    age = Int(
        28,  #input = True
    )

    # composite E-modulus
    #
    E_c = Property(Float, depends_on='input_change')

    @cached_property
    def _get_E_c(self):
        return self.ccs_unit_cell_ref.get_E_c_time(self.age)

    # Poisson's ratio
    #
    nu = Property(Float, depends_on='input_change')

    @cached_property
    def _get_nu(self):
        return self.ccs_unit_cell_ref.nu

    # @todo: for mats_eval the information of the unit cell should be used
    # in order to use the same number of microplanes and model version etc...
    #
    mats = Property(Instance(MATS2D5MicroplaneDamage),
                    depends_on='input_change')

    @cached_property
    def _get_mats(self):
        mats = MATS2D5MicroplaneDamage(E=self.E_c,
                                       nu=self.nu,
                                       n_mp=30,
                                       symmetrization='sum-type',
                                       model_version='compliance',
                                       phi_fn=self.phi_fn)

        return mats

    tline = Instance(TLine)

    def _tline_default(self):
        return TLine(min=0.0, step=1.0, max=8.0)

    rtrace_list = List

    def _rtrace_list_default(self):
        return [
            #                                 RTraceDomainListField( name = 'Displacement' ,
            #                                                var = 'u', idx = 0, warp = True ),
            #                                 RTraceDomainListField( name = 'Stress' ,
            #                                                var = 'sig_app', idx = 0, warp = True,
            #                                                record_on = 'update', ),
            #                    self.max_princ_stress,
            RTraceDomainListField(name='Damage',
                                  var='omega_mtx',
                                  idx=0,
                                  warp=True,
                                  record_on='update'),
        ]
コード例 #29
0
class RV( HasTraits ):
    '''Class representing the definition and discretization of a random variable.
    '''
    name = Str

    pd = Instance( IPDistrib )
    def _pd_changed( self ):
        self.pd.n_segments = self._n_int

    changed = Event
    @on_trait_change( 'pd.changed,+changed' )
    def _set_changed( self ):
        self.changed = True

    _n_int = Int
    n_int = Property
    def _set_n_int( self, value ):
        if self.pd:
            self.pd.n_segments = value
        self._n_int = value
    def _get_n_int( self ):
        return self.pd.n_segments

    # index within the randomization
    idx = Int( 0 )

    # type of the RV discretization 
    discr_type = Enum( 'T grid', 'P grid', 'MC',
                        changed = True )
    def _discr_type_default( self ):
        return 'T grid'

    theta_arr = Property( Array( 'float_' ), depends_on = 'changed' )
    @cached_property
    def _get_theta_arr( self ):
        '''Get the discr_type of the pdistrib
        '''
        if self.discr_type == 'T grid':

            # Get the discr_type from pdistrib and shift it
            # such that the midpoints of the segments are used for the
            # integration.

            x_array = self.pd.x_array
            # Note assumption of T grid discr_type
            theta_array = x_array[:-1] + self.pd.dx / 2.0

        elif self.discr_type == 'P grid':

            # P grid disretization generated from the inverse cummulative
            # probability
            #
            distr = self.pd.distr_type.distr
            # Grid of constant probabilities
            pi_arr = linspace( 0.5 / self.n_int, 1. - 0.5 / self.n_int, self.n_int )
            theta_array = distr.ppf( pi_arr )

        return theta_array

    dG_arr = Property( Array( 'float_' ), depends_on = 'changed' )
    @cached_property
    def _get_dG_arr( self ):

        if self.discr_type == 'T grid':

            d_theta = self.theta_arr[1] - self.theta_arr[0]
            return self.pd.get_pdf_array( self.theta_arr ) * d_theta

        elif self.discr_type == 'P grid':

            # P grid disretization generated from the inverse cummulative
            # probability
            #
            return array( [ 1.0 / float( self.n_int ) ], dtype = 'float_' )

    def get_rvs_theta_arr( self, n_samples ):
        return self.pd.get_rvs_array( n_samples )
コード例 #30
0
ファイル: mr_one.py プロジェクト: rosoba/simvisage
class MRone(MushRoofModel):

    implements(ISimModel)
    mushroof_part = 'one'
    #===============================================================================
    # fe_grid
    #===============================================================================

    n_elems_xy_quarter = Int(10, input=True)  # , ps_levels = [4, 16, 5] )
    n_elems_z = Int(1, input=True)  # , ps_levels = [1, 2, 1] )
    n_elems_col_z = Int(10, input=True, ps_levels=[5, 20, 3])
    n_elems_col_xy = Int(2, input=True, ps_levels=[2, 4, 1])

    shift_elems = True

    vtk_r = Float(1.00)

    # default roof
    fe_roof = Instance((FETSEval), depends_on='+ps_levels, +input')

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

    # default plate
    fe_plate = Instance((FETSEval), depends_on='+ps_levels, +input')

    def _fe_plate_default(self):
        fets = self.fe_quad_serendipity_plate
        fets.ngp_r = 3
        fets.ngp_s = 3
        fets.ngp_t = 3
        fets.vtk_r *= self.vtk_r
        return fets

    # shell
    #
    hp_shell = Property(Instance(HPShell), depends_on='+ps_levels, +input')

    @cached_property
    def _get_hp_shell(self):
        return HPShell(length_xy_quarter=self.length_xy_quarter,
                       length_z=self.length_z,
                       n_elems_xy_quarter=self.n_elems_xy_quarter,
                       n_elems_z=self.n_elems_z,
                       scalefactor_delta_h=self.scalefactor_delta_h,
                       const_reinf_layer_elem=self.const_reinf_layer_elem,
                       width_top_col=self.width_top_col,
                       mushroof_part=self.mushroof_part,
                       shift_array=self.shift_array,
                       X0=self.X0)

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

    @cached_property
    def _get_plate(self):
        return GEOColumn(
            width_top=self.width_top_col,
            width_bottom=self.width_top_col,
            X0=[3.5, 3.5, -self.t_plate],  # - 0.25],
            h_col=self.t_plate)

    # column
    #
#    X0_column = Array( [ 4., 4., -3.] )
    column = Property(Instance(GEOColumn), depends_on='+ps_levels, +input')

    @cached_property
    def _get_column(self):
        return GEOColumn(
            width_top_col=self.width_top_col,
            width_bottom_col=self.width_bottom_col,
            h_col=self.h_col - self.t_plate,
            # r_pipe = self.r_pipe,
            X0=[3.5, 3.5, -(self.h_col)])  # - 0.5] )

    # default column
    fe_column = Instance((FETSEval),
                         transient=True,
                         depends_on='+ps_levels, +input')

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

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

    @cached_property
    def _get_fe_grid_roof(self):
        return FEGrid(coord_min=(0.0, 0.0, 0.0),
                      coord_max=(1.0, 1.0, 1.0),
                      geo_transform=self.hp_shell,
                      shift_array=self.shift_array,
                      shape=(self.n_elems_xy, self.n_elems_xy, self.n_elems_z),
                      fets_eval=self.fe_roof)

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

    @cached_property
    def _get_fe_grid_column(self):
        return FEGrid(coord_min=(0.0, 0.0, 0.0),
                      coord_max=(1.0, 1.0, 1.0),
                      geo_transform=self.column,
                      shape=(self.n_elems_col_xy, self.n_elems_col_xy,
                             self.n_elems_col_z),
                      fets_eval=self.fe_column)

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

    @cached_property
    def _get_fe_grid_plate(self):
        return FEGrid(coord_min=(0.0, 0.0, 0.0),
                      coord_max=(1.0, 1.0, 1.0),
                      geo_transform=self.plate,
                      shape=(self.n_elems_col_xy, self.n_elems_col_xy, 2),
                      fets_eval=self.fe_plate)

    #===============================================================================
    # 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_edge = U[self.edge_corner_1_dof][0, 0, 2]

        F_int = self.tloop.tstepper.F_int

        F_int_slice_x = F_int[self.edge_roof_right]
        F_int_slice_y = F_int[self.edge_roof_top]

        # bring dofs into right order for plot
        #
        F_hinge_in_order_x = self.sort_by_dofs(self.edge_roof_top,
                                               F_int_slice_x)
        F_hinge_in_order_y = self.sort_by_dofs(self.edge_roof_top,
                                               F_int_slice_y)
        F_hinge_x = append(F_hinge_in_order_x[:, :-1, 0],
                           F_hinge_in_order_x[-1, -1, 0])
        F_hinge_y = append(F_hinge_in_order_y[:, :-1, 1],
                           F_hinge_in_order_y[-1, -1, 1])
        F_hinge_y_sum = sum(F_hinge_y.flatten())
        F_hinge_x_sum = sum(F_hinge_x.flatten())
        #
        #        self.visual_force_bar( F_hinge_x.flatten()
        #                               , y_label = "internal force x [MN]"
        #                               , Title = 'F_Hinge_x_shrinkage' )
        #        self.visual_force_bar( F_hinge_y.flatten()
        #                               , y_label = "internal force y [MN]"
        #                               , Title = 'F_Hinge_y_shrinkage' )
        print "u_edge", U_edge
        print "n_elems_xy_col", self.n_elems_col_xy
        print "n_elems_z_col", self.n_elems_col_z
        print "n_elems_xy_quarter", self.n_elems_xy_quarter
        print "n_elems_z", self.n_elems_z

        return array(
            [
                U_edge,
                #                        u_x_corner2,
                #                       F_hinge_y_sum] )
                #                        u_z_corner2,
                #                        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', unit='m'),
            #                 SimOut( name = 'u_x_corner2', unit = 'm' ),
            #                 SimOut( name = 'N Gelenk', unit = 'MN' ), ]
            #                 SimOut( name = 'u_z_corner2', unit = 'm' ),
            #                 SimOut( name = 'maximum principle stress', unit = 'MPa' )
        ]

    #===============================================================================
    # response tracer
    #===============================================================================

    rtrace_list = List

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

    shift_array = Array(value=[
        [0.45 / 2**0.5, 0.45 / 2**0.5, 1],
    ],
                        input=True)

    #===============================================================================
    # boundary conditions
    #===============================================================================

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

    @cached_property
    def _get_bc_plate_roof_link_list(self):
        '''
        links all plate corner nodes of each elements to the adjacent elements of the roof
        '''
        roof = self.fe_grid_roof
        plate = self.fe_grid_plate
        bc_col_link_list = []

        slice_1 = [
            BCSlice(var='u',
                    dims=[0, 1, 2],
                    slice=roof[self.n_elems_xy_quarter - 1,
                               self.n_elems_xy_quarter, 0, 0, 0, 0],
                    link_slice=plate[0, 0, -1, 0, 0, -1],
                    link_coeffs=[1.0],
                    value=0.)
        ]
        slice_2 = [
            BCSlice(var='u',
                    dims=[0, 1, 2],
                    slice=roof[self.n_elems_xy_quarter,
                               self.n_elems_xy_quarter - 1, 0, 0, 0, 0],
                    link_slice=plate[-1, 0, -1, -1, 0, -1],
                    link_coeffs=[1.0],
                    value=0.)
        ]

        slice_3 = [
            BCSlice(var='u',
                    dims=[0, 1, 2],
                    slice=roof[self.n_elems_xy_quarter + 1,
                               self.n_elems_xy_quarter, 0, 0, 0, 0],
                    link_slice=plate[-1, -1, -1, -1, -1, -1],
                    link_coeffs=[1.0],
                    value=0.)
        ]

        slice_4 = [
            BCSlice(var='u',
                    dims=[0, 1, 2],
                    slice=roof[self.n_elems_xy_quarter,
                               self.n_elems_xy_quarter + 1, 0, 0, 0, 0],
                    link_slice=plate[0, -1, -1, 0, -1, -1],
                    link_coeffs=[1.0],
                    value=0.)
        ]

        slice_5 = [
            BCSlice(var='u',
                    dims=[0, 1, 2],
                    slice=roof[self.n_elems_xy_quarter,
                               self.n_elems_xy_quarter, 0, 0, 0, 0],
                    link_slice=plate[self.n_elems_col_xy / 2.0,
                                     self.n_elems_col_xy / 2.0, -1, 0, 0, -1],
                    link_coeffs=[1.0],
                    value=0.)
        ]

        bc_plate_roof_link_list = slice_1 + slice_2 + slice_3 + slice_4 + slice_5

        return bc_plate_roof_link_list

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

    @cached_property
    def _get_bc_roof_top_roof_low_link_list(self):
        '''
        links all plate corner nodes of each elements to the adjacent elements of the roof
        '''
        roof = self.fe_grid_roof
        plate = self.fe_grid_plate
        bc_roof_top_roof_low_link_list = []

        slice_1 = [
            BCSlice(var='u',
                    dims=[2],
                    link_slice=roof[self.n_elems_xy_quarter - 1,
                                    self.n_elems_xy_quarter, 0, 0, 0, 0],
                    slice=roof[self.n_elems_xy_quarter - 1,
                               self.n_elems_xy_quarter, -1, 0, 0, -1],
                    link_coeffs=[1.0],
                    value=0.)
        ]
        slice_2 = [
            BCSlice(var='u',
                    dims=[2],
                    link_slice=roof[self.n_elems_xy_quarter,
                                    self.n_elems_xy_quarter - 1, 0, 0, 0, 0],
                    slice=roof[self.n_elems_xy_quarter,
                               self.n_elems_xy_quarter - 1, -1, 0, 0, -1],
                    link_coeffs=[1.0],
                    value=0.)
        ]

        slice_3 = [
            BCSlice(var='u',
                    dims=[2],
                    link_slice=roof[self.n_elems_xy_quarter + 1,
                                    self.n_elems_xy_quarter, 0, 0, 0, 0],
                    slice=roof[self.n_elems_xy_quarter + 1,
                               self.n_elems_xy_quarter, -1, 0, 0, -1],
                    link_coeffs=[1.0],
                    value=0.)
        ]

        slice_4 = [
            BCSlice(var='u',
                    dims=[2],
                    link_slice=roof[self.n_elems_xy_quarter,
                                    self.n_elems_xy_quarter + 1, 0, 0, 0, 0],
                    slice=roof[self.n_elems_xy_quarter,
                               self.n_elems_xy_quarter + 1, -1, 0, 0, -1],
                    link_coeffs=[1.0],
                    value=0.)
        ]

        slice_5 = [
            BCSlice(var='u',
                    dims=[2],
                    link_slice=roof[self.n_elems_xy_quarter,
                                    self.n_elems_xy_quarter, 0, 0, 0, 0],
                    slice=roof[self.n_elems_xy_quarter,
                               self.n_elems_xy_quarter, -1, 0, 0, -1],
                    link_coeffs=[1.0],
                    value=0.)
        ]

        bc_roof_top_roof_low_link_list = slice_1 + slice_2 + slice_3 + slice_4 + slice_5

        return bc_roof_top_roof_low_link_list

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

    @cached_property
    def _get_bc_plate_column_link_list(self):
        '''
        links all column nodes to plate nodes
        '''
        column = self.fe_grid_column
        plate = self.fe_grid_plate

        slice_1 = [
            BCSlice(var='u',
                    dims=[0, 1, 2],
                    slice=plate[:, :, 0, -1, -1, 0],
                    link_slice=column[:, :, -1, -1, -1, -1],
                    link_coeffs=[1.0],
                    value=0.)
        ]

        slice_2 = [
            BCSlice(var='u',
                    dims=[0, 1, 2],
                    slice=plate[:, :, 0, 0, 0, 0],
                    link_slice=column[:, :, -1, 0, 0, -1],
                    link_coeffs=[1.0],
                    value=0.)
        ]

        slice_3 = [
            BCSlice(var='u',
                    dims=[0, 1, 2],
                    slice=plate[:, :, 0, 0, -1, 0],
                    link_slice=column[:, :, -1, 0, -1, -1],
                    link_coeffs=[1.0],
                    value=0.)
        ]

        slice_4 = [
            BCSlice(var='u',
                    dims=[0, 1, 2],
                    slice=plate[:, :, 0, -1, 0, 0],
                    link_slice=column[:, :, -1, -1, 0, -1],
                    link_coeffs=[1.0],
                    value=0.)
        ]

        return slice_1 + slice_2 + slice_3 + slice_4
#        return [BCSlice( var = 'u'  , dims = [0, 1, 2],
#                         slice = plate[:,:,0,:,:, 0 ],
#                         link_slice = column[ :,:,-1 ,:,:,-1], link_coeffs = [1.0], value = 0. )]

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

    @cached_property
    def _get_link_edge_list(self):
        '''
        links all edge nodes to one node, for this node boundary conditions are applied,
        the complete force within the edge hinge can therefore be evaluated at one node
        '''
        roof = self.fe_grid_roof
        dof_constraint_0 = [
            BCSlice(var='u',
                    dims=[1],
                    slice=roof[:, -1, -1, :, -1, -1],
                    value=0.0)
        ]
        dof_constraint_1 = [
            BCSlice(var='u',
                    dims=[0],
                    slice=roof[-1, :, -1, -1, :, -1],
                    value=0.0)
        ]
        link_edge_list = dof_constraint_0 + dof_constraint_1
        return link_edge_list

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

    @cached_property
    def _get_bc_col_clamped_list(self):
        column = self.fe_grid_column
        constraint = [
            BCSlice(var='u',
                    dims=[0, 1, 2],
                    slice=column[:, :, 0, :, :, 0],
                    value=0.0)
        ]
        return constraint

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

    @cached_property
    def _get_bc_col_hinge_list(self):
        constraint = []
        column = self.fe_grid_column
        for i in range(0, self.n_elems_col):
            dof_const = [
                BCSlice(var='u',
                        dims=[0, 1, 2],
                        slice=column[i, 0, 0, 0, 0, 0],
                        link_slice=column[-1 - i, -1, 0, -1, -1, 0],
                        link_coeffs=[-1.0],
                        value=0.0)
            ]
            constraint = constraint + dof_const
        for i in range(0, self.n_elems_col):
            dof_const = [
                BCSlice(var='u',
                        dims=[0, 1, 2],
                        slice=column[0, -1 - i, 0, 0, -1, 0],
                        link_slice=column[-1, i, 0, -1, 0, 0],
                        link_coeffs=[-1.0],
                        value=0.0)
            ]
            constraint = constraint + dof_const

        return constraint

    #===============================================================================
    # loading cases for mr_one only symmetric
    #===============================================================================

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

    @cached_property
    def _get_lc_g_list(self):
        # slices
        roof = self.fe_grid_roof
        column = self.fe_grid_column
        upper_surf = roof[:, :, -1, :, :, -1]
        bottom_edge_roof = roof[:, 0, -1, :, 0, -1]
        left_edge_roof = roof[0, :, -1, 0, :, -1]

        # loads in global z- direction
        material_density_roof = -22.4e-3  # [MN/m^3]
        material_density_column = -26e-3  # [MN/m^3]
        additional_surface_load = -0.20e-3  # [MN/m^2]
        additional_t_constr = -0.02 * 22.4e-3
        edge_load = -0.35e-3  # [MN/m]
        return [
            BCSlice(var='f',
                    value=material_density_roof,
                    dims=[2],
                    integ_domain='global',
                    slice=roof[:, :, :, :, :, :]),
            BCSlice(var='f',
                    value=material_density_column,
                    dims=[2],
                    integ_domain='global',
                    slice=column[:, :, :, :, :, :]),
        ]


#                 BCSlice( var = 'f', value = additional_surface_load + additional_t_constr,
#                          dims = [2], integ_domain = 'global',
#                          slice = upper_surf ),
#                 BCSlice( var = 'f', value = edge_load, dims = [2],
#                          integ_domain = 'global',
#                          slice = bottom_edge_roof ),
#                 BCSlice( var = 'f', value = edge_load, dims = [2],
#                          integ_domain = 'global',
#                          slice = left_edge_roof )]

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

    @cached_property
    def _get_lc_s_list(self):
        # slices
        roof = self.fe_grid_roof
        upper_surf = roof[:, :, -1, :, :, -1]
        # loads in global z- direction
        snow_load = -0.85e-3
        return [
            BCSlice(var='f',
                    value=snow_load,
                    dims=[2],
                    integ_domain='global',
                    slice=upper_surf)
        ]

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

    def _get_lc_shrink_list(self):
        self.initial_strain_roof = True
        self.initial_strain_col = True
        self.t_up = -100
        self.t_lo = -100

    #===============================================================================
    # time loop
    #===============================================================================

    tloop = Property(depends_on='+ps_levels, +input')

    @cached_property
    def _get_tloop(self):
        roof = self.fe_grid_roof
        column = self.fe_grid_column
        plate = self.fe_grid_plate

        ts = TS(
            sdomain=[roof, plate, column],
            dof_resultants=True,
            bcond_list=

            # boundary conditions
            #
            self.bc_roof_top_roof_low_link_list +
            self.bc_plate_column_link_list + self.bc_plate_roof_link_list +
            self.link_edge_list + self.bc_col_clamped_list +

            # loading
            #
            self.lc_g_list,
            rtrace_list=self.rtrace_list)

        # Add the time-loop control
        tloop = TLoop(tstepper=ts, tolerance=1e-4, tline=self.tline)
        self.edge_corner_1_dof = roof[0, 0, 0, 0, 0, 0].dofs
        self.edge_corner_2_dof = roof[-1, 0, -1, -1, 0, -1].dofs
        self.dof = roof[-1, 0, -1, -1, 0, -1].dofs[0][0][0]
        self.edge_roof_top = roof[:, -1, -1, :, -1, -1].dofs
        self.edge_roof_right = roof[-1, :, -1, -1, :, -1].dofs

        return tloop