示例#1
0
class ECBLCalibState(HasStrictTraits):

    # rupture moment and normal force measured in the calibration experiment
    # (three point bending test)
    #
    Mu = Float(3.5, enter_set = True, auto_set = False, input = True) # [kNm]
    Nu = Float(0.0, enter_set = True, auto_set = False, input = True) # [kN]

    #===========================================================================
    # Cross Section Specification (Geometry and Layout)
    #===========================================================================

    cs_geo = Instance(ECBCrossSectionGeo)
    def _cs_geo_default(self):
        return ECBCrossSectionGeo(notify_change = self.set_modified)

    cs_state = Property(Instance(ECBCrossSectionState), depends_on = 'cs_geo')
    @cached_property
    def _get_cs_state(self):
        return ECBCrossSectionState(cs_geo = self.cs_geo,
                                    notify_change = self.set_modified)

    notify_change = Callable(None)

    modified = Event
    @on_trait_change('+input')
    def set_modified(self):
        self.modified = True
        if self.notify_change != None:
            self.notify_change()

    u0 = Property(Array(float), depends_on = 'cs_geo.modified, cs_state.modified')
    @cached_property
    def _get_u0(self):
        u0 = self.cs_state.ecb_law.u0
        eps_up = -self.cs_geo.cc_law.eps_c_u
        self.cs_state.set(eps_up = eps_up)
        eps_lo = self.cs_state.convert_eps_tex_u_2_lo(u0[0])
        return np.array([eps_lo, u0[1] ], dtype = 'float')

    # iteration counter
    #
    n = Int(0)
    def get_lack_of_fit(self, u):
        '''Return the difference between 'N_external' and 'N_internal' as well as 'M_external' and 'M_internal'
        N_c (=compressive force of the compressive zone of the concrete)
        N_t (=total tensile force of the reinforcement layers)
        '''

        print '--------------------iteration', self.n, '------------------------'
        self.n += 1
        # set iteration counter
        #
        eps_up = -self.cs_geo.cc_law.eps_c_u
        eps_lo = u[0]
        self.cs_state.set(eps_lo = eps_lo, eps_up = eps_up)

        eps_tex_u = self.cs_state.convert_eps_lo_2_tex_u(u[0])

        self.cs_geo.ecb_law.set_cparams(eps_tex_u, u[1])

        N_internal = self.cs_state.N
        M_internal = self.cs_state.M

        d_N = N_internal - self.Nu
        d_M = M_internal - self.Mu

        return np.array([ d_M, d_N ], dtype = float)

    # solution vector returned by 'fit_response'
    #
    u_sol = Property(Array(Float), depends_on = 'modified')
    @cached_property
    def _get_u_sol(self):
        '''iterate 'eps_t' such that the lack of fit between the calculated
        normal forces in the tensile reinforcement and the compressive zone (concrete)
        is smaller then 'xtol' defined in function 'brentq'.
        NOTE: the method 'get_lack_of_fit' returns the relative error.
        '''

        # use scipy-functionality to get the iterated value of 'eps_t'
        # NOTE: get_lack_of_fit must have a sign change as a requirement
        # for the function call 'brentq' to work property. 

        # The method brentq has optional arguments such as
        #   'xtol'    - absolut error (default value = 1.0e-12)
        #   'rtol'    - relative error (not supported at the time)
        #   'maxiter' - maximum numbers of iterations used
        #
        return fsolve(self.get_lack_of_fit, self.u0, xtol = 1.0e-5)

    #===========================================================================
    # Calibrated ecb_law_mfn
    #===========================================================================

    calibrated_ecb_law = Property(depends_on = 'modified')
    @cached_property
    def _get_calibrated_ecb_law(self):
        print 'NEW CALIBRATION'
        self.cs_geo.ecb_law.set_cparams(*self.u_sol)
        return self.cs_geo.ecb_law

    view = View(Item('Mu'),
                Item('Nu'),
                buttons = ['OK', 'Cancel']
                )
示例#2
0
class SimTTBC(IBVModel):
    '''Simulation: Tensile Test Buttsrap Clamping
    '''
    implements(ISimModel)

    #===========================================================================
    # Speciment geometry and discretization parameters
    #===========================================================================
    specimen_ne_x = Int(2,
                        input=True,
                        label='number of elements in x-direction')
    specimen_ne_y = Int(2,
                        input=True,
                        label='number of elements in y-direction')
    specimen_thickness = Float(0.01,
                               input=True,
                               label='thickness of the tensile specimen')
    specimen_length = Float(0.6,
                            input=True,
                            label='length of the tensile specimen')

    specimen_width = Float(0.1,
                           input=True,
                           label='length of the tensile specimen')

    #===========================================================================
    # Buttstrap geometry and discretization parameters
    #===========================================================================
    buttstrap_length = Int(0.2, input=True, label='length of the buttstrap')
    buttstrap_ne_y = Int(
        4, input=True, label='number of elements in buttstrap in y-direction')
    buttstrap_ne_x = Int(
        7, input=True, label='number of elements in buttstrap in x-direction')

    buttstrap_max_thickness = Float(0.04,
                                    input=True,
                                    label='maximum thickness of the buttstrap')
    buttstrap_min_thickness = Float(
        0.04, input=True, label='mimnimum thickness of the buttstrsp')

    #===========================================================================
    # Elastomer geometry
    #===========================================================================
    elastomer_thickness = Float(0.002,
                                input=True,
                                label='thickness of the elastomer')

    elastomer_ne_y = Int(
        1, input=True, label='number of elements in buttstrap in y-direction')
    elastomer_ne_x = Property

    def _get_elastomer_ne_x(self):
        return self.buttstrap_ne_x

    #===========================================================================
    # Friction interface geometry
    #===========================================================================
    friction_thickness = Float(0.005,
                               input=True,
                               label='thickness of the elastomer')

    friction_ne_y = Int(1,
                        input=True,
                        label='number of elements in buttstrap in y-direction')
    friction_ne_x = Property

    def _get_friction_ne_x(self):
        return self.buttstrap_ne_x

    vtk_r = Float(1.0, input=True)

    #===========================================================================
    # Element types
    #===========================================================================

    E_specimen = Int(31000.0,
                     input=True,
                     label='E Modulus of the specimen [MPa]')

    nu_specimen = Int(0.2, input=True, label='E Modulus of the specimen [-]')

    specimen_fets = Instance((FETSEval), depends_on='+ps_levels, +input')

    def _specimen_fets_default(self):
        # fe_quad_serendipity_roof is defined in base class
        # connected with material properties of the roof
        #
        E_eff = self.E_specimen * self.specimen_width
        mats = MATS2DElastic(E=E_eff,
                             nu=self.nu_specimen,
                             stress_state='plane_stress')
        fets = FETS2D4Q8U(mats_eval=mats)
        fets.vtk_r *= self.vtk_r
        return fets

    E_buttstrap = Int(210000.0,
                      input=True,
                      label='E Modulus of the buttstrap [MPa]')

    nu_buttstrap = Int(0.2,
                       input=True,
                       label='Poisson ratio of the buttstrap [-]')

    buttstrap_fets = Instance((FETSEval), depends_on='+ps_levels, +input')

    def _buttstrap_fets_default(self):
        # fe_quad_serendipity_roof is defined in base class
        # connected with material properties of the roof
        #
        E_eff = self.E_buttstrap * self.specimen_width
        mats = MATS2DElastic(E=E_eff,
                             nu=self.nu_buttstrap,
                             stress_state='plane_stress')
        fets = FETS2D4Q8U(mats_eval=mats)
        fets.vtk_r *= self.vtk_r
        return fets

    E_elastomer = Int(100.0,
                      input=True,
                      label='E Modulus of the elastomer [MPa]')

    nu_elastomer = Int(0.3,
                       input=True,
                       label='Poisson ratio of the elastomer [-]')

    elastomer_fets = Instance((FETSEval), depends_on='+ps_levels, +input')

    def _elastomer_fets_default(self):
        # fe_quad_serendipity_roof is defined in base class
        # connected with material properties of the roof
        #
        E_eff = self.E_buttstrap * self.specimen_width
        mats = MATS2DElastic(E=E_eff,
                             nu=self.nu_elastomer,
                             stress_state='plane_stress')
        fets = FETS2D4Q8U(mats_eval=mats)
        fets.vtk_r *= self.vtk_r
        return fets

    g = Float(400000,
              input=True,
              label='Shear stiffness between elastomer and specimen')

    t_max = Float(50,
                  input=True,
                  label='Frictional stress between elastomer and specimen')

    friction_fets = Instance((FETSEval), depends_on='+ps_levels, +input')

    def _friction_fets_default(self):
        width = self.specimen_width
        G = self.g * width
        T_max = self.t_max * width

        ifopen_law = MFnLineArray(ydata=[-1.0e+1, 0., 1.0e+10],
                                  xdata=[-1., 0., 1.])
        mats_ifopen = MATS1DElastic(stress_strain_curve=ifopen_law)

        mats = MATS1D5Bond(mats_phase1=MATS1DElastic(E=0),
                           mats_phase2=MATS1DElastic(E=0),
                           mats_ifslip=MATS1DPlastic(E=G,
                                                     sigma_y=T_max,
                                                     K_bar=0.,
                                                     H_bar=0.),
                           mats_ifopen=mats_ifopen)

        fets = FETS1D52L6ULRH(mats_eval=mats)  #quadratic
        fets.vtk_r *= self.vtk_r
        return fets

    #===========================================================================
    # Geometry transformation
    #===========================================================================
    specimen_cl_geo = Property(depends_on='+ps_levels, +input')

    @cached_property
    def _get_specimen_cl_geo(self):
        def geo_transform(points):
            points[:, 0] *= self.buttstrap_length
            points[:, 1] *= self.specimen_thickness
            return points

        return geo_transform

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

    @cached_property
    def _get_specimen_fl_geo(self):
        def geo_transform(points):
            points[:, 0] *= self.specimen_length
            points[:, 0] += self.buttstrap_length
            points[:, 1] *= self.specimen_thickness
            return points

        return geo_transform

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

    @cached_property
    def _get_buttstrap_geo(self):
        def geo_transform(points):
            x, y = points.T
            x *= self.buttstrap_length
            h_max = self.buttstrap_max_thickness
            h_min = self.buttstrap_min_thickness
            y *= (h_max - (h_max - h_min) / self.buttstrap_length * x)
            y_offset = (self.specimen_thickness + self.friction_thickness +
                        self.elastomer_thickness)
            points[:, 0], points[:, 1] = x, y + y_offset
            return points

        return geo_transform

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

    @cached_property
    def _get_buttstrap_clamp_geo(self):
        def geo_transform(points):
            x, y = points.T
            x *= self.buttstrap_length
            x -= self.buttstrap_length
            y *= self.buttstrap_max_thickness
            y_offset = (self.specimen_thickness + self.friction_thickness +
                        self.elastomer_thickness)
            points[:, 0], points[:, 1] = x, y + y_offset
            return points

        return geo_transform

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

    @cached_property
    def _get_elastomer_geo(self):
        def geo_transform(points):
            x, y = points.T
            x *= self.buttstrap_length
            h = self.elastomer_thickness
            y *= h
            y_offset = self.specimen_thickness + self.friction_thickness
            points[:, 0], points[:, 1] = x, y + y_offset
            return points

        return geo_transform

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

    @cached_property
    def _get_friction_geo(self):
        def geo_transform(points):
            x, y = points.T
            x *= self.buttstrap_length
            h = self.friction_thickness
            y *= h
            y_offset = self.specimen_thickness
            points[:, 0], points[:, 1] = x, y + y_offset
            return points

        return geo_transform

    #===========================================================================
    # FE-grids
    #===========================================================================

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

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

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

    def _get_specimen_fl_fe_level(self):
        return FERefinementGrid(name='specimen free level',
                                fets_eval=self.specimen_fets,
                                domain=self.fe_domain)

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

    def _get_specimen_cl_fe_level(self):
        return FERefinementGrid(name='specimen clamped level',
                                fets_eval=self.specimen_fets,
                                domain=self.fe_domain)

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

    def _get_buttstrap_fe_level(self):
        return FERefinementGrid(name='buttstrap level',
                                fets_eval=self.buttstrap_fets,
                                domain=self.fe_domain)

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

    def _get_buttstrap_clamp_fe_level(self):
        return FERefinementGrid(name='buttstrap clamp level',
                                fets_eval=self.buttstrap_fets,
                                domain=self.fe_domain)

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

    def _get_elastomer_fe_level(self):
        return FERefinementGrid(name='elastomer level',
                                fets_eval=self.elastomer_fets,
                                domain=self.fe_domain)

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

    def _get_friction_fe_level(self):
        return FERefinementGrid(name='friction level',
                                fets_eval=self.friction_fets,
                                domain=self.fe_domain)

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

    @cached_property
    def _get_specimen_fl_fe_grid(self):
        fe_grid = FEGrid(coord_min=(0, 0),
                         coord_max=(1, 1),
                         level=self.specimen_fl_fe_level,
                         geo_transform=self.specimen_fl_geo,
                         shape=(self.specimen_ne_x, self.specimen_ne_y),
                         fets_eval=self.specimen_fets)
        return fe_grid

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

    @cached_property
    def _get_specimen_cl_fe_grid(self):
        fe_grid = FEGrid(coord_min=(0, 0),
                         coord_max=(1, 1),
                         level=self.specimen_cl_fe_level,
                         geo_transform=self.specimen_cl_geo,
                         shape=(self.buttstrap_ne_x, self.specimen_ne_y),
                         fets_eval=self.specimen_fets)
        return fe_grid

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

    @cached_property
    def _get_buttstrap_fe_grid(self):
        fe_grid = FEGrid(coord_min=(0, 0),
                         coord_max=(1, 1),
                         level=self.buttstrap_fe_level,
                         geo_transform=self.buttstrap_geo,
                         shape=(self.buttstrap_ne_x, self.buttstrap_ne_y),
                         fets_eval=self.buttstrap_fets)
        return fe_grid

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

    @cached_property
    def _get_buttstrap_clamp_fe_grid(self):
        fe_grid = FEGrid(coord_min=(0, 0),
                         coord_max=(1, 1),
                         level=self.buttstrap_clamp_fe_level,
                         geo_transform=self.buttstrap_clamp_geo,
                         shape=(1, self.buttstrap_ne_y),
                         fets_eval=self.buttstrap_fets)
        return fe_grid

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

    @cached_property
    def _get_elastomer_fe_grid(self):
        fe_grid = FEGrid(coord_min=(0, 0),
                         coord_max=(1, 1),
                         level=self.elastomer_fe_level,
                         geo_transform=self.elastomer_geo,
                         shape=(self.elastomer_ne_x, self.elastomer_ne_y),
                         fets_eval=self.elastomer_fets)
        return fe_grid

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

    @cached_property
    def _get_friction_fe_grid(self):
        fe_grid = FEGrid(coord_min=(0, 0),
                         coord_max=(1, 1),
                         level=self.friction_fe_level,
                         geo_transform=self.friction_geo,
                         shape=(self.friction_ne_x, self.friction_ne_y),
                         fets_eval=self.friction_fets)
        return fe_grid

    #===========================================================================
    # Boundary conditions
    #===========================================================================
    bc_list = Property(depends_on='+ps_levels, +input')

    @cached_property
    def _get_bc_list(self):

        sp_fl_grid = self.specimen_fl_fe_grid
        sp_cl_grid = self.specimen_cl_fe_grid
        bs_grid = self.buttstrap_fe_grid
        bs_clamp_grid = self.buttstrap_clamp_fe_grid
        el_grid = self.elastomer_fe_grid
        fl_grid = self.friction_fe_grid

        link_sp_fl_cl = BCDofGroup(
            var='u',
            value=0.,
            dims=[0, 1],
            get_dof_method=sp_cl_grid.get_right_dofs,
            get_link_dof_method=sp_fl_grid.get_left_dofs,
            link_coeffs=[1.])

        link_fl_sp = BCDofGroup(var='u',
                                value=0.,
                                dims=[0, 1],
                                get_dof_method=fl_grid.get_bottom_dofs,
                                get_link_dof_method=sp_cl_grid.get_top_dofs,
                                link_coeffs=[1.])

        link_el_fl = BCDofGroup(var='u',
                                value=0.,
                                dims=[0, 1],
                                get_dof_method=el_grid.get_bottom_dofs,
                                get_link_dof_method=fl_grid.get_top_dofs,
                                link_coeffs=[1.])

        link_bs_el = BCDofGroup(var='u',
                                value=0.,
                                dims=[0, 1],
                                get_dof_method=bs_grid.get_bottom_dofs,
                                get_link_dof_method=el_grid.get_top_dofs,
                                link_coeffs=[1.])

        link_bs_clamp = BCDofGroup(var='u',
                                   value=0.,
                                   dims=[0, 1],
                                   get_dof_method=bs_clamp_grid.get_right_dofs,
                                   get_link_dof_method=bs_grid.get_left_dofs,
                                   link_coeffs=[1.])

        symx_bc = BCSlice(var='u',
                          slice=sp_fl_grid[-1, :, -1, :],
                          dims=[0],
                          value=0)

        symy_fl_bc = BCSlice(var='u',
                             slice=sp_fl_grid[:, 0, :, 0],
                             dims=[1],
                             value=0)

        symy_cl_bc = BCSlice(var='u',
                             slice=sp_cl_grid[:, 0, :, 0],
                             dims=[1],
                             value=0)

        cntl_bc = BCSlice(var='u',
                          slice=bs_clamp_grid[0, :, 0, :],
                          dims=[0],
                          value=-0.001)

        return [
            symx_bc, symy_fl_bc, symy_cl_bc, cntl_bc, link_sp_fl_cl,
            link_bs_clamp, link_fl_sp, link_el_fl, link_bs_el
        ]

    #----------------------------------------------------
    # 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):

        ts = TS(sdomain=self.fe_domain,
                dof_resultants=True,
                bcond_list=self.bc_list,
                rtrace_list=self.rtrace_list)

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

        return tloop
示例#3
0
class GridReinforcement(HasTraits):
    '''
    Class delivering reinforcement ratio for a grid reinforcement of a cross section
    '''

    h = Float(
        30,
        auto_set=False,
        enter_set=True,  # [mm]
        desc='the height of the cross section',
        modified=True)
    w = Float(
        100,
        auto_set=False,
        enter_set=True,  # [mm]
        desc='the width of the cross section',
        modified=True)
    n_f_h = Float(
        9,
        auto_set=False,
        enter_set=True,  # [-]
        desc='the number of fibers in the height direction',
        modified=True)
    n_f_w = Float(
        12,
        auto_set=False,
        enter_set=True,  # [-]
        desc='the number of fibers in the width direction',
        modified=True)
    a_f = Float(
        0.89,
        auto_set=False,
        enter_set=True,  # [m]
        desc='the cross sectional area of a single fiber',
        modified=True)

    A_tot = Property(Float, depends_on='+modified')

    def _get_A_tot(self):
        return self.h * self.w

    A_f = Property(Float, depends_on='+modified')

    def _get_A_f(self):
        n_f = self.n_f_h * self.n_f_w
        a_f = self.a_f
        return a_f * n_f

    rho = Property(Float, depends_on='+modified')

    @cached_property
    def _get_rho(self):
        return self.A_f / self.A_tot

    traits_view = View(
        VGroup(
            Group(Item('h', label='height'),
                  Item('w', label='width'),
                  label='cross section dimensions',
                  orientation='vertical'),
            Group(Item('a_f', label='area of a single fiber'),
                  Item('n_f_h', label='# in height direction'),
                  Item('n_f_w', label='# in width direction'),
                  label='layout of the fiber grid',
                  orientation='vertical'),
            Item('rho',
                 label='current reinforcement ratio',
                 style='readonly',
                 emphasized=True),
            #                           label = 'Cross section parameters',
            id='scm.cs.params',
        ),
        id='scm.cs',
        dock='horizontal',
        resizable=True,
        height=0.8,
        width=0.8)
示例#4
0
class CompositeCrackBridgeLoop(HasTraits):

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

    V_f_tot = Property(depends_on='reinforcement_lst+')

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

    E_c = Property(depends_on='reinforcement_lst+')

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

    sorted_theta = Property(depends_on='reinforcement_lst+')

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

    sorted_depsf = Property(depends_on='reinforcement_lst+')

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

    sorted_V_f = Property(depends_on='reinforcement_lst+')

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

    sorted_E_f = Property(depends_on='reinforcement_lst+')

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

    sorted_xi = Property(depends_on='reinforcement_lst+')

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

    sorted_stats_weights = Property(depends_on='reinforcement_lst+')

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

    sorted_nu_r = Property(depends_on='reinforcement_lst+')

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

    sorted_xi_cdf = Property(depends_on='reinforcement_lst+')

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

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

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

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

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

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

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

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

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

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

    _x_arr = Array

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

    _epsm_arr = Array

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

    _epsf0_arr = Array

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

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

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

    header = Str('''
Comparison of sampling structure
================================

The different types of sampling for sample size 100. Both variables are randomized with 
normal distribution. 
The exact solution is depicted with the black line. The gray lines indicate the sampling. 
The response diagram correspond to the sampling types (left to right):

Regular grid of random variables
Grid of constant probabilities
Monte Carlo sampling
Latin Hypercube Sampling 
    ''')

    demo_module = fiber_tt_2p

    #===========================================================================
    # Derived traits
    #===========================================================================
    demo_object = Property(depends_on='demo_module')

    @cached_property
    def _get_demo_object(self):
        return self.demo_module.create_demo_object()

    qname = Property(depends_on='demo_module')

    @cached_property
    def _get_qname(self):
        return self.demo_object.get_qname()

    output_dir = Property(depends_on='demo_module')

    @cached_property
    def _get_output_dir(self):
        return os.path.join(EX_OUTPUT_DIR, self.qname)

    rst_file_name = Property(depends_on='demo_module')

    @cached_property
    def _get_rst_file_name(self):
        return os.path.join(self.output_dir, 'index.rst')

    def generate_examples_sampling_structure(self):
        dobj = self.demo_object
        dobj.set(fig_output_dir=self.output_dir,
                 show_output=False,
                 dpi=70,
                 save_output=True,
                 plot_mode='figures')
        dobj.sampling_structure()

    def generate_examples_sampling_efficiency(self):
        dobj = self.demo_object
        dobj.set(fig_output_dir=self.output_dir,
                 show_output=False,
                 dpi=70,
                 save_output=True,
                 plot_mode='figures')
        dobj.sampling_efficiency()

    def generate_examples_language_efficiency(self):
        dobj = self.demo_object
        dobj.set(fig_output_dir=self.output_dir,
                 show_output=False,
                 dpi=70,
                 save_output=True,
                 plot_mode='figures')
        dobj.codegen_language_efficiency()

    def generate_examples(self):
        self.generate_examples_sampling_structure()
        self.generate_examples_sampling_efficiency()
        self.generate_examples_language_efficiency()

    def generate_html(self):

        print(('generating documentation for', self.qname, '...'))

        rst_text = '''
================================
Parametric study for %s
================================
        ''' % self.qname

        dobj = self.demo_object

        if dobj.s.q.__doc__ != None:
            rst_text += dobj.s.q.__doc__

        rst_text += self.header

        for st in dobj.sampling_types:
            rst_text += '''
            
.. image:: %s_%s.png
    :width: 24%%

            ''' % (self.qname, st)

        for st in dobj.sampling_types:
            rst_text += '''
                
.. image:: %s_sampling_%s.png
    :width: 24%%
    
            ''' % (self.qname, st)

        rst_text += '\nFollowing spirrid configuration has been used to produce the sampling figures:\n\n'
        rst_text += '\n>>> print demo_object\n' + str(dobj.s) + '\n'

        rst_text += '''
Comparison of execution time for different sampling types
=========================================================
Execution time evaluated for an increasing number of sampling points n_sim:
'''
        for basename in dobj.fnames_sampling_efficiency:
            rst_text += '''
        
.. image:: %s
    :width: 100%%

            ''' % basename
            print(('written file %s', basename))

        rst_text += '\n'

        rst_text += '''
Comparison of efficiency for different code types
=========================================================
Execution time evaluated for an numpy, weave and cython code:
'''
        for basename in dobj.fnames_language_efficiency:
            rst_text += '''
            
.. image:: %s
    :width: 100%%

            ''' % basename
            print(('written file %s', basename))

        rst_text += '\n'

        rst_file = open(self.rst_file_name, 'w')

        rst_file.write(rst_text)

        rst_file.close()
示例#6
0
class CompositeCrackBridgeView(ModelView):

    model = Instance(CompositeCrackBridge)
    results = Property(depends_on='model.E_m, model.w, model.Ll, model.Lr, model.reinforcement_lst+')
    @cached_property
    def _get_results(self):
        if self.model.w <= 0.0:
            self.model.w = 1e-15
        sigma_c = self.model.sigma_c
#         Kf_broken = np.sum(self.model.cont_fibers.sorted_V_f * self.model.cont_fibers.sorted_nu_r *
#                            self.model.cont_fibers.sorted_stats_weights * self.model.cont_fibers.sorted_E_f *
#                            self.model.cont_fibers.damage)
        if self.model.Ll > self.model.Lr:
            return -self.model._x_arr[::-1], self.model._epsm_arr[::-1], sigma_c, self.model._epsf_arr[::-1]
        else:
            return self.model._x_arr, self.model._epsm_arr, sigma_c, self.model._epsf_arr

    x_arr = Property(depends_on='model.E_m, model.w, model.Ll, model.Lr, model.reinforcement_lst+')
    @cached_property
    def _get_x_arr(self):
        return self.results[0]
 
    epsm_arr = Property(depends_on='model.E_m, model.w, model.Ll, model.Lr, model.reinforcement_lst+')
    @cached_property
    def _get_epsm_arr(self):
        return self.results[1]

    epsf_arr = Property(depends_on='model.E_m, model.w, model.Ll, model.Lr, model.reinforcement_lst+')
    @cached_property
    def _get_epsf_arr(self):
        return self.results[3]

    sigma_c = Property(depends_on='model.E_m, model.w, model.Ll, model.Lr, model.reinforcement_lst+')
    @cached_property
    def _get_sigma_c(self):
        return self.results[2]

    def sigma_c_arr(self, w_arr, u=False, damage=False):
        sigma_c_lst = []
        u_lst = []
        damage_lst = []
        for i, w in enumerate(w_arr):
            self.model.w = w
            sigma_c_lst.append(self.sigma_c)
            if u == True:
                u_lst.append(self.u_evaluated)
            if damage == True:
                damage_lst.append(np.sum(self.model.cont_fibers.damage *
                                         self.model.cont_fibers.sorted_stats_weights *
                                         self.model.cont_fibers.sorted_nu_r))
        if u == True or damage == True:
            return np.array(sigma_c_lst), np.array(u_lst), np.array(damage_lst)
        else:
            return np.array(sigma_c_lst)

    def secant_K(self, w_arr):
        secant_K_lst = []
        for w_i in w_arr:
            self.model.w = w_i
            secant_K_lst.append(self.model.secant_K)
        return np.array(secant_K_lst)

    u_evaluated = Property(depends_on='model.E_m, model.w, model.Ll, model.Lr, model.reinforcement_lst+')
    @cached_property
    def _get_u_evaluated(self):
        return self.model.w + np.trapz(self.epsm_arr, self.x_arr)

    sigma_c_max = Property(depends_on='model.E_m, model.w, model.Ll, model.Lr, model.reinforcement_lst+')
    @cached_property
    def _get_sigma_c_max(self):
        def minfunc_sigma(w):
            self.model.w = w
            stiffness_loss = np.sum(self.model.cont_fibers.Kf * self.model.cont_fibers.damage) / np.sum(self.model.cont_fibers.Kf)
            if stiffness_loss > 0.90:
                return 1. + w
            #plt.plot(w, self.sigma_c, 'ro')
            return -self.sigma_c
        def residuum_stiffness(w):
            self.model.w = w
            stiffness_loss = np.sum(self.model.Kf * self.model.damage) / np.sum(self.model.Kf)
            if stiffness_loss > 0.90:
                return 1. + w
            if stiffness_loss < 0.65 and stiffness_loss > 0.45:
                residuum = 0.0
            else:
                residuum = stiffness_loss - 0.5
            return residuum

        if len(self.model.sorted_reinf_lst[0]) == 0:
            # there are only short fibers
            def minfunc_short_fibers(w):
                self.model.w = w
                return -self.sigma_c
            w_max = fminbound(minfunc_short_fibers, 0.0, 3.0, maxfun=10, disp=0)
            return self.sigma_c, w_max
        else:
            # continuous or mixed fibers
            try:
                w_max = brentq(residuum_stiffness, 0.0, min(0.1 * (self.model.Ll + self.model.Lr), 20.))
            except:
                w_max = 0.03 * (self.model.Ll + self.model.Lr)
            w_points = np.linspace(0, w_max, len(self.model.reinforcement_lst) + 1)
            w_maxima = []
            sigma_maxima = []
            for i, w in enumerate(w_points[1:]):
                w_maxima.append(fminbound(minfunc_sigma, w_points[i], w_points[i + 1], maxfun=10, disp=0))
                sigma_maxima.append(self.sigma_c)
            return sigma_maxima[np.argmax(np.array(sigma_maxima))], w_maxima[np.argmax(np.array(sigma_maxima))]

    def apply_load(self, sigma):
        if sigma > self.sigma_c_max[0]:
            raise ValueError('applied load ', sigma , 'MPa is larger than composite strength ', self.sigma_c_max[0], 'MPa')
        else:
            def residuum(w):
                self.model.w = float(w)
                return sigma - self.sigma_c
            brentq(residuum, 0.0, min(self.sigma_c_max[1], 20.))

    def sigma_f_lst(self, w_arr):
        sigma_f_arr = np.zeros(len(w_arr) * 
                               len(self.model.reinforcement_lst)).reshape(len(w_arr),
                                len(self.model.reinforcement_lst))
        masks = [((self.model.sorted_xi == reinf.xi) * 
                          (self.model.sorted_E_f == reinf.E_f) * 
                          (self.model.sorted_V_f == reinf.V_f))
                 for reinf in self.model.reinforcement_lst]
        for i, w in enumerate(w_arr):
            if w == 0.0:
                self.model.w = 1e-15
            else:
                self.model.w = w
            self.model.damage
            for j, reinf in enumerate(self.model.reinforcement_lst):
                sigma_fi = np.sum(self.model._epsf0_arr * self.model.sorted_stats_weights * self.model.sorted_nu_r * 
                              self.model.sorted_E_f * (1. - self.model.damage) * masks[j])
                sigma_f_arr[i, j] = sigma_fi
        return sigma_f_arr

    Welm = Property(depends_on='model.E_m, model.w, model.Ll, model.Lr, model.reinforcement_lst+')
    @cached_property
    def _get_Welm(self):
        Km = self.results[4]
        bonded_l = self.epsm_arr[0] ** 2 * Km * (self.model.Ll - np.abs(self.x_arr[0]))
        bonded_r = self.epsm_arr[-1] ** 2 * Km * (self.model.Lr - np.abs(self.x_arr[-1]))
        return 0.5 * (np.trapz(self.epsm_arr ** 2 * Km, self.x_arr) + bonded_l + bonded_r) 

    Welf = Property(depends_on='model.E_m, model.w, model.Ll, model.Lr, model.reinforcement_lst+')
    @cached_property
    def _get_Welf(self):
        Kf = self.model.E_c - self.results[4]
        bonded_l = self.mu_epsf_arr[0] ** 2 * Kf * (self.model.Ll - np.abs(self.x_arr[0]))
        bonded_r = self.mu_epsf_arr[-1] ** 2 * Kf * (self.model.Lr - np.abs(self.x_arr[-1]))
        return 0.5 * (np.trapz(self.mu_epsf_arr ** 2 * Kf, self.x_arr) + bonded_l + bonded_r)

    W_el_tot = Property(depends_on='model.E_m, model.w, model.Ll, model.Lr, model.reinforcement_lst+')
    @cached_property
    def _get_W_el_tot(self):
        '''total elastic energy stored in the specimen'''
        return self.Welf + self.Welm

    W_inel_tot = Property(depends_on='model.E_m, model.w, model.Ll, model.Lr, model.reinforcement_lst+')
    @cached_property
    def _get_W_inel_tot(self):
        '''total inelastic energy dissipated during loading up to w'''
        return self.U - self.W_el_tot

    U_line = Property(depends_on='model.E_m, model.Ll, model.Lr, model.reinforcement_lst+, w_arr_energy')
    @cached_property
    def _get_U_line(self):
        '''work done by external force - mfn_line'''
        w_arr = self.w_arr_energy
        u_lst = []
        F_lst = []
        for w in w_arr:
            self.model.w = w
            u_lst.append(self.u_evaluated)
            F_lst.append(self.sigma_c)
        u_arr = np.array(u_lst)
        F_arr = np.array(F_lst)
        U_line = MFnLineArray(xdata=w_arr, ydata=np.hstack((0, cumtrapz(F_arr, u_arr))))
        return U_line

    U = Property(depends_on='model.E_m, model.Ll, model.Lr, model.reinforcement_lst+, model.w')
    @cached_property
    def _get_U(self):
        '''work done by external force U(w)'''
        return self.U_line.get_values(self.model.w)

    w_arr_energy = Array

    def get_sigma_m_x_input(self, sigma):
        self.apply_load(sigma)
        line = MFnLineArray(xdata=self.x_arr,
                            ydata=self.epsm_arr)
        return line.get_values(self.x_input)
示例#7
0
文件: rv_view.py 项目: simvisage/bmcs
class RIDVariable(HasTraits):
    """
    Association between a random variable and distribution.
    """

    title = Str('RIDvarible')

    s = WeakRef

    rf = WeakRef

    n_int = Int(20,
                enter_set=True,
                auto_set=False,
                desc='Number of integration points')

    def _n_int_changed(self):
        if self.pd:
            self.pd.n_segments = self.n_int

    # should this variable be randomized

    random = Bool(False, randomization_changed=True)

    def _random_changed(self):
        # get the default distribution
        if self.random:
            self.s.rv_dict[self.varname] = RV(pd=self.pd,
                                              name=self.varname,
                                              n_int=self.n_int)
        else:
            del self.s.rv_dict[self.varname]

    # name of the random variable (within the response function)
    #
    varname = String

    source_trait = Trait

    trait_value = Float

    pd = Property(Instance(IPDistrib), depends_on='random')

    @cached_property
    def _get_pd(self):
        if self.random:
            tr = self.rf.trait(self.varname)
            pd = PDistrib(distr_choice=tr.distr[0], n_segments=self.n_int)
            trait = self.rf.trait(self.varname)

            # get the distribution parameters from the metadata
            #
            distr_params = {
                'scale': trait.scale,
                'loc': trait.loc,
                'shape': trait.shape
            }
            dparams = {}
            for key, val in list(distr_params.items()):
                if val:
                    dparams[key] = val

            pd.distr_type.set(**dparams)
            return pd
        else:
            return None

    value = Property

    def _get_value(self):
        if self.random:
            return ''
        else:
            return '%g' % self.trait_value

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

    # default view specification
    def default_traits_view(self):
        return View(HGroup(Item(
            'n_int',
            visible_when='random',
            label='NIP',
        ),
                           Spring(),
                           show_border=True,
                           label='Variable name: %s' % self.varname),
                    Item('pd@', show_label=False),
                    resizable=True,
                    id='rid_variable',
                    height=800)
示例#8
0
class ECBLMNDiagram(HasTraits):

    # calibrator supplying the effective material law
    calib = Instance(ECBLCalib)

    def _calib_default(self):
        return ECBLCalib(notify_change=self.set_modified)

    def _calib_changed(self):
        self.calib.notify_change = self.set_modified

    modified = Event

    def set_modified(self):
        print 'MN:set_modifeid'
        self.modified = True

    # cross section
    cs = DelegatesTo('calib')

    calibrated_ecb_law = Property(depends_on='modified')

    @cached_property
    def _get_calibrated_ecb_law(self):
        print 'NEW CALIBRATION'
        return self.calib.calibrated_ecb_law

    eps_cu = Property()

    def _get_eps_cu(self):
        return -self.cs.cc_law.eps_c_u

    eps_tu = Property()

    def _get_eps_tu(self):
        return self.calibrated_ecb_law.eps_tex_u

    n_eps = Int(5, auto_set=False, enter_set=True)
    eps_range = Property(depends_on='n_eps')

    @cached_property
    def _get_eps_range(self):
        eps_c_space = np.linspace(self.eps_cu, 0, self.n_eps)
        eps_t_space = np.linspace(0, self.eps_tu, self.n_eps)

        eps_ccu = 0.8 * self.eps_cu

        #eps_cc = self.eps_cu * np.ones_like(eps_c_space)
        eps_cc = np.linspace(eps_ccu, self.eps_cu, self.n_eps)
        eps_ct = self.eps_cu * np.ones_like(eps_t_space)
        eps_tc = self.eps_tu * np.ones_like(eps_c_space)
        eps_tt = self.eps_tu * np.ones_like(eps_t_space)

        eps1 = np.vstack([eps_c_space, eps_cc])
        eps2 = np.vstack([eps_t_space, eps_ct])
        eps3 = np.vstack([eps_tc, eps_c_space])
        eps4 = np.vstack([eps_tt, eps_t_space])

        return np.hstack([eps1, eps2, eps3, eps4])

    n_eps_range = Property(depends_on='n_eps')

    @cached_property
    def _get_n_eps_range(self):
        return self.eps_range.shape[1]

    #===========================================================================
    # MN Diagram
    #===========================================================================

    def _get_MN_fn(self, eps_lo, eps_up):
        self.cs.set(eps_lo=eps_lo, eps_up=eps_up)
        return (self.cs.M, self.cs.N)

    MN_vct = Property(depends_on='modified')

    def _get_MN_vct(self):
        return np.vectorize(self._get_MN_fn)

    MN_arr = Property(depends_on='modified')

    @cached_property
    def _get_MN_arr(self):
        return self.MN_vct(self.eps_range[0, :], self.eps_range[1, :])

    #===========================================================================
    # f_eps Diagram
    #===========================================================================

    current_eps_idx = Int(0)  # , auto_set = False, enter_set = True)

    def _current_eps_idx_changed(self):
        self._clear_fired()
        self._replot_fired()

    current_eps = Property(depends_on='current_eps_idx')

    @cached_property
    def _get_current_eps(self):
        return self.eps_range[(0, 1), self.current_eps_idx]

    current_MN = Property(depends_on='current_eps_idx')

    @cached_property
    def _get_current_MN(self):
        return self._get_MN_fn(*self.current_eps)

    #===========================================================================
    # Plotting
    #===========================================================================

    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

    clear = Button

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

    replot = Button

    def _replot_fired(self):

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

        ax.plot(-self.eps_range, [0, 0.06], color='black')

        ax.plot(-self.current_eps, [0, 0.06], lw=3, color='red')

        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')

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

        ax.plot(self.MN_arr[0], -self.MN_arr[1], lw=2, color='blue')

        ax.plot(self.current_MN[0],
                -self.current_MN[1],
                'g.',
                markersize=20.0,
                color='red')

        ax.spines['left'].set_position('zero')
        ax.spines['bottom'].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')
        ax.grid(b=None, which='major')

        self.cs.set(eps_lo=self.current_eps[0], eps_up=self.current_eps[1])

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

        self.cs.plot_eps(ax)

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

        self.cs.plot_sig(ax)

        self.data_changed = True

    view = View(HSplit(
        Group(
            HGroup(
                Group(Item('n_eps', springy=True),
                      label='Discretization',
                      springy=True),
                springy=True,
            ),
            HGroup(
                Group(VGroup(
                    Item(
                        'cs',
                        label='Cross section',
                        show_label=False,
                        springy=True,
                        editor=InstanceEditor(kind='live'),
                    ),
                    Item(
                        'calib',
                        label='Calibration',
                        show_label=False,
                        springy=True,
                        editor=InstanceEditor(kind='live'),
                    ),
                    springy=True,
                ),
                      label='Cross sectoin',
                      springy=True),
                springy=True,
            ),
            scrollable=True,
        ),
        Group(
            HGroup(
                Item('replot', show_label=False),
                Item('clear', show_label=False),
            ),
            Item(
                'current_eps_idx',
                editor=RangeEditor(
                    low=0,
                    high_name='n_eps_range',
                    format='(%s)',
                    mode='slider',
                    auto_set=False,
                    enter_set=False,
                ),
                show_label=False,
            ),
            Item('figure',
                 editor=MPLFigureEditor(),
                 resizable=True,
                 show_label=False),
            id='simexdb.plot_sheet',
            label='plot sheet',
            dock='tab',
        ),
    ),
                width=1.0,
                height=0.8,
                resizable=True,
                buttons=['OK', 'Cancel'])
示例#9
0
class CompositeCrackBridge(HasTraits):

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

    V_f_tot = Property(depends_on='reinforcement_lst+')

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

    E_c = Property(depends_on='reinforcement_lst+')

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

    sorted_theta = Property(depends_on='reinforcement_lst+')

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

    sorted_depsf = Property(depends_on='reinforcement_lst+')

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

    sorted_V_f = Property(depends_on='reinforcement_lst+')

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

    sorted_E_f = Property(depends_on='reinforcement_lst+')

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

    sorted_xi = Property(depends_on='reinforcement_lst+')

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

    sorted_stats_weights = Property(depends_on='reinforcement_lst+')

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

    sorted_nu_r = Property(depends_on='reinforcement_lst+')

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

    sorted_masks = Property(depends_on='reinforcement_lst+')

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

    sorted_r = Property(depends_on='reinforcement_lst+')

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

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

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

    Kf = Property(depends_on='reinforcement_lst+')

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

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

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

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

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

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

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

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

    _x_arr = Array

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

    _epsm_arr = Array

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

    _epsf0_arr = Array

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

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

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

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

    qname = Property

    def _get_qname(self):
        return self.__class__.__name__

    comment = Property

    @cached_property
    def _get_comment(self):
        return self.__doc__

    rf_args = Property(Tuple)

    @cached_property
    def _get_rf_args(self):
        '''
        Extract the traits that are floating points and can be associated 
        with a statistical distribution.
        '''
        # Get the parameters of the obligatory call method

        argspec_list = getargspec(self.__call__).args[1:]

        # this line extracts the traits having the 'distr' metadata

        # containers for control variables
        ctrl_trait_keys = self.traits(ctrl_range=lambda x: x != None)
        ctrl_keys = []
        ctrl_traits = []
        ctrl_values = []

        # containers for parameters
        param_trait_keys = self.traits(distr=lambda x: x != None)
        param_keys = []
        param_traits = []
        param_values = []

        # iterate through the arguments of the call function to get
        # and store them in the corresponding list.
        #
        for argspec in argspec_list:
            if argspec in param_trait_keys:
                param_keys.append(argspec)
                param_traits.append(self.trait(argspec))
                param_values.append(getattr(self, argspec))
            elif argspec in ctrl_trait_keys:
                ctrl_keys.append(argspec)
                ctrl_traits.append(self.trait(argspec))
                ctrl_values.append(getattr(self, argspec))
            else:
                raise RuntimeError('parameter %s not declared as a trait in the response function %s' % \
                    (argspec, self.__class__))
        return (ctrl_keys, ctrl_traits, ctrl_values, param_keys, param_traits,
                param_values)

    #--------------------------------------------------------------------
    # FUNCTION PARAMETERS
    #--------------------------------------------------------------------
    # The declaration of parameters that can be randomized
    # (design parameters)
    param_keys = Property(List)

    def _get_param_keys(self):
        return self.rf_args[3]

    param_traits = Property(List)

    def _get_param_traits(self):
        return self.rf_args[4]

    param_values = Property(List)

    def _get_param_values(self):
        return self.rf_args[5]

    #--------------------------------------------------------------------
    # FUNCTION CONTROL VARIABLES
    #--------------------------------------------------------------------
    ctrl_keys = Property(List)

    def _get_ctrl_keys(self):
        return self.rf_args[0]

    ctrl_traits = Property(List)

    def _get_ctrl_traits(self):
        return self.rf_args[1]

    ctrl_values = Property(List)

    def _get_ctrl_values(self):
        return self.rf_args[2]

    changed = Event

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

    #@todo: delete - this is motivated by views and interactive editing
    # - shall be done later.

    listener_string = Str('')

    def add_listeners(self):
        self.on_trait_change(self.get_value, self.listener_string)

    def remove_listeners(self):
        self.on_trait_change(self.get_value, self.listener_string, remove=True)

    def default_traits_view(self):
        '''
        Generates the view from the param items.
        '''
        param_items = [Item(name) for name in self.param_keys]
        ctrl_items = [Item(name) for name in self.ctrl_keys]
        view = View(VGroup(*param_items, id='stats.spirrid_bak.rf.params'),
                    VGroup(*ctrl_items, id='stats.spirrid_bak.rf.ctrl'),
                    kind='modal',
                    height=0.3,
                    width=0.2,
                    scrollable=True,
                    resizable=True,
                    buttons=['OK', 'Cancel'],
                    id='stats.spirrid_bak.rf')
        return view

    def plot(self, p, ctrl_idx=0, **kw):
        X = np.linspace(*self.ctrl_traits[ctrl_idx].ctrl_range)
        Y = self(X, *self.param_values)
        p.plot(X, Y, **kw)
        p.xlabel(self.x_label)
        p.ylabel(self.y_label)
        p.legend(loc='best')
        p.title(self.title)

    def plot3d(self, p, ctrl_idx=[0, 1], **kw):
        X = np.linspace(*self.ctrl_traits[ctrl_idx[0]].ctrl_range)
        Y = np.linspace(*self.ctrl_traits[ctrl_idx[1]].ctrl_range)
        Z = self(X, Y, *self.param_values)
        p.surf(X, Y, Z, **kw)

    def __str__(self):
        ctrl_list = ['%s' % nm for nm in self.ctrl_keys]
        param_list = [
            '%s = %g' % (nm, v)
            for nm, v in zip(self.param_keys, self.param_values)
        ]
        ctrl = string.join(ctrl_list, ', ')
        params = string.join(param_list, ', ')
        return '%s\n%s' % (ctrl, params)
示例#11
0
class RV(HasStrictTraits):
    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))

    n_int = Int(None)
    '''Number of integration points
    '''

    loc = Float
    '''Location parameter.
    '''

    scale = Float
    '''Scale parameter.
    '''

    shape = Float
    '''Shape parameter.
    '''

    type = Str
    '''Type specifier.
    '''

    args = Tuple
    '''Generic arguments.
    '''

    kw = Dict
    '''Generic keyword arguments.
    '''

    _distr = Property(depends_on='mu,std,loc,type')
    '''Construct a distribution.
    hidden property instance of the scipy stats distribution
    '''

    @cached_property
    def _get__distr(self):
        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)

    def cdf(self, x):
        return self._distr.cdf(x)
示例#12
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 )
示例#13
0
class Randomization( HasTraits ):
    '''Multidimensional statistical integration.
    
    Its name SPIRRID is an acronym for 
    Set of Parallel Independent Random Responses with Identical Distributions
    
    The package implements the evaluation of an integral over a set of 
    random variables affecting a response function RF and distributed 
    according to a probabilistic distribution PDistrib.
    
    The input parameters are devided in four categories in order
    to define state consistency of the evaluation. The outputs 
    are define as cached properties that are reevaluated in response
    to changes in the inputs.
    
    The following events accummulate changes in the input parameters of spirrid:
    rf_change - change in the response function
    rand_change - change in the randomization
    conf_change - change in the configuration of the algorithm
    eps_change - change in the studied range of the process control variable       
    '''
    #--------------------------------------------------------------------
    # Response function 
    #--------------------------------------------------------------------
    #
    rf = Instance( IRF )
    def _rf_changed( self ):
        self.on_trait_change( self._set_rf_change, 'rf.changed' )
        self.rv_dict = {}
    #--------------------------------------------------------------------
    # Specification of random parameters 
    #--------------------------------------------------------------------
    # 
    rv_dict = Dict
    def add_rv( self, variable, distribution = 'uniform', discr_type = 'T grid',
                loc = 0., scale = 1., shape = 1., n_int = 30 ):
        '''Declare a variable as random 
        '''
        if variable not in self.rf.param_keys:
            raise AssertionError, 'parameter %s not defined by the response function' \
                % variable

        params_with_distr = self.rf.traits( distr = lambda x: type( x ) == ListType
                                            and distribution in x )
        if variable not in params_with_distr:
            raise AssertionError, 'distribution type %s not allowed for parameter %s' \
                % ( distribution, variable )

        # @todo - let the RV take care of PDistrib specification.
        # isolate the dirty two-step definition of the distrib from spirrid 
        #
        pd = PDistrib( distr_choice = distribution, n_segments = n_int )
        pd.distr_type.set( scale = scale, shape = shape, loc = loc )
        self.rv_dict[variable] = RV( name = variable, discr_type = discr_type,
                                     pd = pd, n_int = n_int )

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

    def clear_rv( self ):
        self.rv_dict = {}

    # subsidiary methods for sorted access to the random variables.
    # (note dictionary has not defined order of its items)
    rv_keys = Property( List, depends_on = 'rv_dict' )
    @cached_property
    def _get_rv_keys( self ):
        rv_keys = sorted( self.rv_dict.keys() )
        # the random variable gets an index based on the 
        # sorted keys
        for idx, key in enumerate( rv_keys ):
            self.rv_dict[ key ].idx = idx
        return rv_keys

    rv_list = Property( List, depends_on = 'rv_dict' )
    @cached_property
    def _get_rv_list( self ):
        return map( self.rv_dict.get, self.rv_keys )

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

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

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

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

    # Dictionary with key = rf parameters
    # and values = default param values for the resp func 
    #
    param_dict = Property( Dict, depends_on = 'rf_change, rand_change' )
    @cached_property
    def _get_param_dict( self ):
        '''Gather all the traits with the metadata distr specified.
        '''
        dict = {}
        for name, value in zip( self.rf.param_keys, self.rf.param_values ):
            rv = self.rv_dict.get( name, None )
            if rv == None:
                dict[ name ] = value
            else:
                dict[ name ] = self.theta_ogrid[ rv.idx ]
        return dict

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

    # Constant parameters
    #
    const_param_dict = Property( Dict, depends_on = 'rf_change, rand_change' )
    @cached_property
    def _get_const_param_dict( self ):
        const_param_dict = {}
        for name, v in zip( self.rf.param_keys, self.rf.param_values ):
            if name not in self.rv_keys:
                const_param_dict[ name ] = v
        return const_param_dict

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

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

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

    #---------------------------------------------------------------------------------
    # PDF grid - mutually multiplied arrays of PDF
    #---------------------------------------------------------------------------------
    dG_grid = Property( depends_on = 'rf_change, rand_change' )
    @cached_property
    def _get_dG_grid( self ):
        if len( self.dG_ogrid ):
            return reduce( lambda x, y: x * y, self.dG_ogrid )
        else:
            return 1.0
示例#14
0
class RepresentativeCB(HasTraits):
    CB_model = Instance(CompositeCrackBridge)
    n_w = Int
    n_BC = Int
    load_sigma_c_arr = Array
    length = Float
    CB_model_view = Property(Instance(CompositeCrackBridgeView),
                             depends_on='CB_model')

    @cached_property
    def _get_CB_model_view(self):
        return CompositeCrackBridgeView(model=self.CB_model)

    def max_sigma_w(self, Ll, Lr):
        self.CB_model_view.model.Ll = Ll
        self.CB_model_view.model.Lr = Lr
        max_sigma_c, max_w = self.CB_model_view.sigma_c_max
        if max_sigma_c < self.load_sigma_c_arr[-1]:
            return max_sigma_c, max_w
        else:
            self.CB_model_view.apply_load(self.load_sigma_c_arr[-1] - 1e-10)
            return self.load_sigma_c_arr[-1] - 1e-10, self.CB_model_view.model.w

    BC_range = Property(depends_on='n_BC, CB_model')

    @cached_property
    def _get_BC_range(self):
        self.max_sigma_w(1e5, 1e5)
        Lmax = min(self.CB_model_view.x_arr[-2], self.length)
        bc_range = np.logspace(np.log10(1.0), np.log10(Lmax), self.n_BC)
        return bc_range

    def w_x_res(self, w_arr, ll, lr):
        self.CB_model_view.model.Ll = ll
        self.CB_model_view.model.Lr = lr
        cb_epsm_interpolators_lst = [
            MFnLineArray(xdata=np.linspace(-1e5, 1e5, 5), ydata=np.zeros(5))
        ]
        cb_epsf_interpolators_lst = [
            MFnLineArray(xdata=np.linspace(-1e5, 1e5, 5), ydata=np.zeros(5))
        ]
        sigma_c_lst = [0.0]
        w_lst = [0.0]
        for w in w_arr:
            self.CB_model_view.model.w = w
            if self.CB_model_view.sigma_c > sigma_c_lst[-1]:
                w_lst.append(w)
                sigma_c_lst.append(self.CB_model_view.sigma_c)
                x_i = np.hstack((-self.length - 1e-1, self.CB_model_view.x_arr,
                                 self.length + 1e-1))
                epsm_i = np.hstack((self.CB_model_view.epsm_arr[0],
                                    self.CB_model_view.epsm_arr,
                                    self.CB_model_view.epsm_arr[-1]))
                epsf_i = np.hstack((self.CB_model_view.epsf_arr[0],
                                    self.CB_model_view.epsf_arr,
                                    self.CB_model_view.epsf_arr[-1]))
                cb_epsm_interpolators_lst.append(
                    MFnLineArray(xdata=x_i, ydata=epsm_i))
                cb_epsf_interpolators_lst.append(
                    MFnLineArray(xdata=x_i, ydata=epsf_i))
        w_interpolator = MFnLineArray(xdata=np.array(sigma_c_lst),
                                      ydata=np.array(w_lst))
        return w_interpolator, [sigma_c_lst, cb_epsm_interpolators_lst
                                ], [sigma_c_lst, cb_epsf_interpolators_lst]

    interpolator_lists = Property(
        Array, depends_on='CB_model, load_sigma_c_arr, n_w, n_x, n_BC')

    @cached_property
    def _get_interpolator_lists(self):
        epsm_interpolators = np.zeros((self.n_BC, self.n_BC), dtype=np.object)
        epsf_interpolators = np.zeros((self.n_BC, self.n_BC), dtype=np.object)
        w_interpolators = np.zeros((self.n_BC, self.n_BC), dtype=np.object)
        loops_tot = self.n_BC**2
        max_sigma_c_arr = np.zeros((self.n_BC, self.n_BC))
        for i, ll in enumerate(self.BC_range):
            for j, lr in enumerate(self.BC_range):
                if j >= i:
                    # find maximum
                    sigma_c_max, wmax = self.max_sigma_w(ll, lr)
                    # print 'Ll, Lr, sigmacmax: ', ll, lr, sigma_c_max
                    max_sigma_c_arr[i, j] = max_sigma_c_arr[j, i] = sigma_c_max
                    w_arr0 = np.linspace(1e-10, wmax, self.n_w)
                    w_interpolator, epsm_interp_lst, epsf_interp_lst = self.w_x_res(
                        w_arr0, ll, lr)
                    epsm_interpolators[i, j] = epsm_interpolators[
                        j, i] = epsm_interp_lst
                    epsf_interpolators[i, j] = epsf_interpolators[
                        j, i] = epsf_interp_lst
                    w_interpolators[i, j] = w_interpolators[j,
                                                            i] = w_interpolator
                current_loop = i * len(self.BC_range) + j + 1
                print 'progress: %2.1f %%' % \
                    (current_loop / float(loops_tot) * 100.)
        interp_max_sigma_c = interp2d(self.BC_range,
                                      self.BC_range,
                                      max_sigma_c_arr,
                                      fill_value=None)
        return interp_max_sigma_c, epsm_interpolators, w_interpolators, epsf_interpolators

    def get_BC_idxs(self, Ll, Lr):
        if Ll >= self.BC_range[-1]:
            ll_idx_high = -1
            ll_idx_low = -1
        elif Ll <= self.BC_range[0]:
            ll_idx_high = 0
            ll_idx_low = 0
        else:
            ll_idx_high = np.argwhere(Ll <= self.BC_range)[0][0]
            ll_idx_low = np.argwhere(Ll >= self.BC_range)[-1][0]
        if Lr > self.BC_range[-1]:
            lr_idx_high = -1
            lr_idx_low = -1
        elif Lr <= self.BC_range[0]:
            lr_idx_high = 0
            lr_idx_low = 0
        else:
            lr_idx_high = np.argwhere(Lr <= self.BC_range)[0][0]
            lr_idx_low = np.argwhere(Lr >= self.BC_range)[-1][0]
        return ll_idx_high, lr_idx_high, ll_idx_low, lr_idx_low

    def interpolate_max_sigma_c(self, Ll, Lr):
        return self.interpolator_lists[0](Ll, Lr)

    def interpolate_epsm(self, Ll, Lr, sigma_c, x_arr):
        ll_idx_high, lr_idx_high, ll_idx_low, lr_idx_low = self.get_BC_idxs(
            Ll, Lr)
        epsm_interpolator_lst = self.interpolator_lists[1][ll_idx_high,
                                                           lr_idx_high]
        sigc = np.array(epsm_interpolator_lst[0])
        if sigma_c > sigc[-1]:
            # applied stress is higher than crack bridge strength
            return np.repeat(np.nan, len(x_arr))
        else:
            sigc_high = np.argwhere(sigc > sigma_c)[0][0]
            sigc_low = np.argwhere(sigc < sigma_c)[-1][0]
            coeff_low = (sigc[sigc_high] - sigma_c) / \
                (sigc[sigc_high] - sigc[sigc_low])
            coeff_high = (sigma_c - sigc[sigc_low]) / (sigc[sigc_high] -
                                                       sigc[sigc_low])
            if Lr >= Ll:
                epsm = epsm_interpolator_lst[1][sigc_low].get_values(x_arr) * coeff_low + \
                    epsm_interpolator_lst[1][
                        sigc_high].get_values(x_arr) * coeff_high
            else:
                import matplotlib.pyplot as plt
                epsm = epsm_interpolator_lst[1][sigc_low].get_values(-x_arr[::-1]) * coeff_low + \
                    epsm_interpolator_lst[1][
                        sigc_high].get_values(-x_arr[::-1]) * coeff_high
                epsm = epsm[::-1]
            return epsm

    def interpolate_epsf(self, Ll, Lr, sigma_c, x_arr):
        ll_idx_high, lr_idx_high, ll_idx_low, lr_idx_low = self.get_BC_idxs(
            Ll, Lr)
        epsf_interpolator_lst = self.interpolator_lists[3][ll_idx_high,
                                                           lr_idx_high]
        sigc = np.array(epsf_interpolator_lst[0])
        if sigma_c > sigc[-1]:
            # applied stress is higher than crack bridge strength
            return np.repeat(np.nan, len(x_arr))
        else:
            sigc_high = np.argwhere(sigc > sigma_c)[0][0]
            sigc_low = np.argwhere(sigc < sigma_c)[-1][0]
            coeff_low = (sigc[sigc_high] - sigma_c) / \
                (sigc[sigc_high] - sigc[sigc_low])
            coeff_high = (sigma_c - sigc[sigc_low]) / (sigc[sigc_high] -
                                                       sigc[sigc_low])
            if Lr >= Ll:
                epsf = epsf_interpolator_lst[1][sigc_low].get_values(x_arr) * coeff_low + \
                    epsf_interpolator_lst[1][
                        sigc_high].get_values(x_arr) * coeff_high
            else:
                epsf = epsf_interpolator_lst[1][sigc_low].get_values(-x_arr[::-1]) * coeff_low + \
                    epsf_interpolator_lst[1][
                        sigc_high].get_values(-x_arr[::-1]) * coeff_high
                epsf = epsf[::-1]
            return epsf

    def interpolate_w(self, Ll, Lr, sigma_c):
        '''
        interpolation of w using the approach of interpolation on a 4-node rectangular finite element
        '''
        ll_idx_high, lr_idx_high, ll_idx_low, lr_idx_low = self.get_BC_idxs(
            Ll, Lr)
        ll_low, ll_high, lr_low, lr_high = self.BC_range[
            ll_idx_low], self.BC_range[ll_idx_high], self.BC_range[
                lr_idx_low], self.BC_range[lr_idx_high]
        # evaluating nodal values / note that w2 = w3
        w1 = self.interpolator_lists[2][ll_idx_low, lr_idx_low].get_values(
            np.array([sigma_c]))
        w2 = self.interpolator_lists[2][ll_idx_low, lr_idx_high].get_values(
            np.array([sigma_c]))
        w3 = self.interpolator_lists[2][ll_idx_high, lr_idx_low].get_values(
            np.array([sigma_c]))
        w4 = self.interpolator_lists[2][ll_idx_high, lr_idx_high].get_values(
            np.array([sigma_c]))
        nodal_values = [w1, w2, w3, w4]
        # shape functions
        if ll_idx_low == ll_idx_high:
            if lr_idx_low == lr_idx_high:
                # no interpolation
                return w1
            else:
                # 1D interpolation
                a = lr_high - lr_low
                N1 = lambda x: -(x - lr_high) / a
                N2 = lambda x: (x - lr_low) / a
                return w1 * N1(Lr) + w2 * N2(Lr)
        else:
            if lr_idx_low == lr_idx_high:
                # 1D interpolation
                a = ll_high - ll_low
                N1 = lambda x: -(x - ll_high) / a
                N2 = lambda x: (x - ll_low) / a
                return w2 * N1(Ll) + w3 * N2(Ll)
            else:
                # 2D interpolation
                ab = (ll_high - ll_low) * (lr_high - lr_low)
                N1 = lambda x, y: (x - ll_high) * (y - lr_high) / ab
                N2 = lambda x, y: -(x - ll_low) * (y - lr_high) / ab
                N3 = lambda x, y: (x - ll_low) * (y - lr_low) / ab
                N4 = lambda x, y: -(x - ll_high) * (y - lr_low) / ab
                shape_functions = [N1, N2, N3, N4]
                # interpolate w
                w_interpolated = 0.0
                for i, Ni in enumerate(shape_functions):
                    w_interpolated += nodal_values[i] * Ni(Ll, Lr)
                return w_interpolated
示例#15
0
class YMBCrossCorrel(HasTraits):

    data = Instance(IYMBData)

    # convert the dictionary keys to an ordered list.
    var_name_list = Property(List)

    @cached_property
    def _get_var_name_list(self):
        return sorted(var_dict.keys())

    # list of data arrays in the order of the var_name_list
    var_arr_list = Property(List, depends_on='data.input_change')

    @cached_property
    def _get_var_arr_list(self):
        return [
            getattr(self.data, var_dict[var_name]).flatten()[:, None]
            for var_name in self.var_name_list
        ]

    corr_arr = Property(Array, depends_on='data.input_change')

    @cached_property
    def _get_corr_arr(self):
        print 'redrawing cross correl'
        # get the list of names and sort them alphabetically
        corr_data = ma.hstack(self.var_arr_list)
        # @kelidas: return small differences between ma and numpy corrcoef
        # return ma.corrcoef( corr_data, rowvar = False, allow_masked = True )
        return MatSpearman(corr_data)

    figure = Instance(Figure)

    def _figure_default(self):
        figure = Figure()
        figure.add_axes([0.1, 0.1, 0.8, 0.8])
        return figure

    data_changed = Event(True)

    @on_trait_change('data, data.input_change')
    def _redraw(self):
        figure = self.figure
        figure.clear()
        var_data = self.corr_arr

        figure.add_axes([0.1, 0.1, 0.8, 0.8])
        axes = figure.axes[0]
        axes.clear()
        x_coor = arange(var_data.shape[1])
        axes.grid()
        for i in range(0, var_data.shape[1]):
            axes.plot(x_coor[i:] - x_coor[i], var_data[i, (i):], '-x')
        axes.set_xlabel('$\mathrm{x}\, [\mu\mathrm{m}]$', fontsize=16)
        axes.set_ylabel('$\mathrm{correlation}$', fontsize=16)
        axes.set_ylim(-1, 1)

        self.data_changed = True

    traits_view_mpl = View(
        Group(
            #                       Group( Item( 'figure', style = 'custom',
            #                              editor = MPLFigureEditor(),
            #                              show_label = False )
            #                              , id = 'figure.view' ),
            Item('corr_arr',
                 show_label=False,
                 style='readonly',
                 editor=TabularEditor(adapter=ArrayAdapter()))),
        resizable=True,
    )

    traits_view = View(Item('corr_arr',
                            editor=tabular_editor,
                            show_label=False),
                       resizable=True,
                       scrollable=True,
                       buttons=['OK', 'Cancel'],
                       width=1.0,
                       height=0.5)
示例#16
0
class SFBMushRoofModel(IBVModel):
    '''SFB - Demontrator model specification.
    '''
    implements(ISimModel)

    # number of elements in all dims

    n_elems_xy = Int(10, ps_levels=(20, 80, 3))

    n_dofs_xy = Property(Int, depends_on='+ps_levels')

    def _get_n_dofs_xy(self):
        if self.fets == self.fe_2D_linear:
            return self.n_elems_xy + 1
        elif self.fets == self.fe_2D_quadratic:
            return int(self.n_elems_xy * 2)
        else:
            raise ValueError

    rtrace_list = Property(List, depends_on='+ps_levels')

    @cached_property
    def _get_rtrace_list(self):
        return [self.max_princ_stress, self.sig_app, self.u]


#    sig_trace = RTraceDomainListField( name = 'Stress' ,
#                               var = 'sig_app', warp = False,
#                               record_on = 'update' )
#    eps_trace = RTraceDomainListField( name = 'Epsilon' ,
#                                       var = 'eps_app', warp = True,
#                                       record_on = 'update' )
#    eps0_trace = RTraceDomainListField( name = 'Epsilon 0' ,
#                                       var = 'eps0_app', warp = True,
#                                       record_on = 'update' )
#    eps1t_trace = RTraceDomainListField( name = 'Epsilon 1-t' ,
#                                       var = 'eps1t_app', warp = True,
#                                       record_on = 'update' )
#    u_trace = RTraceDomainListField( name = 'Displacement' ,
#                                       var = 'u', warp = True,
#                                       record_on = 'update' )

# dimensions of the shell structure

    length_xy = Float(1.)  # [m]

    E = Float(30000)  # [MPa]
    nu = Float(0.2)  # [-]
    alpha = Float(1e-3)
    # variable type of the finite element
    fets = Instance(FETSEval, ps_levels=['fe_2D_linear', 'fe_2D_quadratic'])

    def _fets_default(self):
        return self.fe_2D_quadratic

    mats = Instance(MATS2DElastic)

    def _mats_default(self):
        return MATS2DElastic(E=self.E,
                             nu=self.nu,
                             initial_strain=TemperatureLinFn(
                                 length=self.length_xy,
                                 n_dims=2,
                                 T_right=50,
                                 T_left=50,
                                 offset=0.5,
                                 alpha=self.alpha))

    fe_2D_linear = Instance(FETSEval, transient=True)

    def _fe_2D_linear_default(self):
        return FETS2D4Q(mats_eval=self.mats)

    fe_2D_quadratic = Instance(FETSEval, transient=True)

    def _fe_2D_quadratic_default(self):
        return FETS2D4Q8U(mats_eval=self.mats)

    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='max principle stress', unit='MPa'),
            SimOut(name='max sig_yy', unit='MPa'),
            SimOut(name='max sig_xx', unit='MPa'),
        ]

    def peval(self):
        '''
        Evaluate the model and return the array of results specified
        in the method get_sim_outputs.
        '''
        U = self.tloop.eval()
        u_corner = U[self.center_top_dof][-1, -1, 0]
        max_princ_stress = max(
            self.max_princ_stress._get_field_data().flatten())

        max_sig_yy = max(self.sig_app._get_field_data()[:, 4])
        max_sig_xx = max(self.sig_app._get_field_data()[:, 0])

        return array([u_corner, max_princ_stress, max_sig_yy, max_sig_xx],
                     dtype='float_')

    tline = Instance(TLine)

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

    max_princ_stress = Property(Instance(RTraceDomainListField),
                                depends_on='+ps_levels')

    @cached_property
    def _get_max_princ_stress(self):
        return RTraceDomainListField(
            name='max principle stress',
            idx=0,
            #                                   position = 'int_pnts',
            var='max_principle_sig',
            record_on='update',
        )

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

    @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')

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

    #[ self.sig_trace, self.eps_trace, self.eps0_trace, self.eps1t_trace, self.u_trace]#, self.f_w_diagram ]

    fe_grid = Property(Instance(FEGrid), depends_on='+ps_levels')

    def _get_fe_grid(self):
        return FEGrid(coord_min=(0.0, 0.0),
                      coord_max=(1.0, 1.0),
                      shape=(self.n_elems_xy, self.n_elems_xy),
                      fets_eval=self.fets)

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

    @cached_property
    def _get_tloop(self):

        self.fets.vtk_r *= 0.95

        domain = self.fe_grid

        self.center_top_dof = domain[-1, -1, -1, -1].dofs

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

        #        upper_surface = domain[:, :, -1, :, :, -1]
        #        whole_domain = domain[:, :, :, :, :, :]

        bcond_list = [
            BCSlice(var='u', dims=[0, 1], slice=domain[0, 0, 0, 0], value=0),
            BCSlice(var='u', dims=[0], slice=domain[0, -1, 0, -1], value=0),
        ]

        #       w_z = domain[-1, -1, -1, -1].dofs[0]

        #       self.f_w_diagram = RTraceGraph( name = 'load - corner deflection',
        #                                           var_x = 'U_k', idx_x = w_z,
        #                                           var_y = 'time', idx_y = 0,
        #                                           record_on = 'update' )
        #        rtrace_list = self.rtrace_list#[ self.f_w_diagram ] + self.rtrace_list

        ts = TS(sdomain=[domain],
                dof_resultants=True,
                bcond_list=bcond_list,
                rtrace_list=self.rtrace_list)
        # Add the time-loop control
        tloop = TLoop(tstepper=ts, tolerance=1e-4, tline=self.tline)
        return tloop
示例#17
0
class RFView3D(ModelView):

    model = Instance(IRF)

    scalar_arr = Property(depends_on='var_enum')

    @cached_property
    def _get_scalar_arr(self):
        return getattr(self.data, self.var_enum_)

    color_map = Str('blue-red')

    scene = Instance(MlabSceneModel, ())
    plot = Instance(PipelineBase)

    # When the scene is activated or parameters change the scene is updated
    @on_trait_change('model.')
    def update_plot(self):

        x_arrr, y_arrr, z_arrr = self.data.cut_data[0:3]
        scalar_arrr = self.scalar_arr

        mask = y_arrr > -1

        x = x_arrr[mask]
        y = y_arrr[mask]
        z = z_arrr[mask]
        scalar = scalar_arrr[mask]

        connections = -ones_like(x_arrr)
        mesk = x_arrr.filled() > -1
        connections[mesk] = list(range(0, len(connections[mesk])))
        connections = connections[self.start_fib:self.end_fib + 1, :].filled()
        connection = connections.astype(int).copy()
        connection = connection.tolist()

        # TODO: better
        for i in range(0, self.data.n_cols + 1):
            for item in connection:
                try:
                    item.remove(-1)
                except:
                    pass

        if self.plot is None:
            print('plot 3d -- 1')
            #self.scene.parallel_projection = False
            pts = self.scene.mlab.pipeline.scalar_scatter(
                array(x), array(y), array(z), array(scalar))
            pts.mlab_source.dataset.lines = connection
            self.plot = self.scene.mlab.pipeline.surface(
                self.scene.mlab.pipeline.tube(
                    #                        fig.scene.mlab.pipeline.stripper(
                    pts,
                    figure=self.scene.mayavi_scene,
                    #                        ),
                    tube_sides=10,
                    tube_radius=0.015,
                ), )
            self.plot.actor.mapper.interpolate_scalars_before_mapping = True
            self.plot.module_manager.scalar_lut_manager.show_scalar_bar = True
            self.plot.module_manager.scalar_lut_manager.show_legend = True
            self.plot.module_manager.scalar_lut_manager.shadow = True
            self.plot.module_manager.scalar_lut_manager.label_text_property.italic = False

            self.plot.module_manager.scalar_lut_manager.scalar_bar.orientation = 'horizontal'
            self.plot.module_manager.scalar_lut_manager.scalar_bar_representation.position2 = array(
                [0.61775334, 0.17])
            self.plot.module_manager.scalar_lut_manager.scalar_bar_representation.position = array(
                [0.18606834, 0.08273163])
            self.plot.module_manager.scalar_lut_manager.scalar_bar.width = 0.17000000000000004

            self.plot.module_manager.scalar_lut_manager.lut_mode = self.color_map  #'black-white'
            self.plot.module_manager.scalar_lut_manager.data_name = self.var_enum
            self.plot.module_manager.scalar_lut_manager.label_text_property.font_family = 'times'
            self.plot.module_manager.scalar_lut_manager.label_text_property.shadow = True
            self.plot.module_manager.scalar_lut_manager.title_text_property.color = (
                0.0, 0.0, 0.0)
            self.plot.module_manager.scalar_lut_manager.label_text_property.color = (
                0.0, 0.0, 0.0)
            self.plot.module_manager.scalar_lut_manager.title_text_property.font_family = 'times'
            self.plot.module_manager.scalar_lut_manager.title_text_property.shadow = True

            #fig.scene.parallel_projection = True
            self.scene.scene.background = (1.0, 1.0, 1.0)
            self.scene.scene.camera.position = [
                16.319534155794827, 10.477447863842627, 6.1717943847883232
            ]
            self.scene.scene.camera.focal_point = [
                3.8980860486356859, 2.4731178194274621, 0.14856957086692035
            ]
            self.scene.scene.camera.view_angle = 30.0
            self.scene.scene.camera.view_up = [
                -0.27676100729835512, -0.26547169369097656, 0.92354107904740446
            ]
            self.scene.scene.camera.clipping_range = [
                7.7372124315754673, 26.343575352248056
            ]
            self.scene.scene.camera.compute_view_plane_normal()
            #fig.scene.reset_zoom()

            axes = Axes()
            self.scene.engine.add_filter(axes, self.plot)
            axes.label_text_property.font_family = 'times'
            axes.label_text_property.shadow = True
            axes.title_text_property.font_family = 'times'
            axes.title_text_property.shadow = True
            axes.property.color = (0.0, 0.0, 0.0)
            axes.title_text_property.color = (0.0, 0.0, 0.0)
            axes.label_text_property.color = (0.0, 0.0, 0.0)
            axes.axes.corner_offset = .1
            axes.axes.x_label = 'x'
            axes.axes.y_label = 'y'
            axes.axes.z_label = 'z'
        else:
            print('plot 3d -- 2')
            #self.plot.mlab_source.dataset.reset()
            #self.plot.mlab_source.set( x = x, y = y, z = z, scalars = scalar )
            #self.plot.mlab_source.dataset.points = array( [x, y, z] ).T
            self.plot.mlab_source.scalars = scalar
            self.plot.mlab_source.dataset.lines = connection
            self.plot.module_manager.scalar_lut_manager.data_name = self.var_enum

    # The layout of the dialog created
    view = View(
        Item('scene',
             editor=SceneEditor(scene_class=MayaviScene),
             height=250,
             width=300,
             show_label=False),
        Group(
            '_',
            'start_fib',
            'end_fib',
            'var_enum',
        ),
        resizable=True,
    )
示例#18
0
class Randomization( HasTraits ):
    '''Multidimensional statistical integration.
    
    Its name SPIRRID is an acronym for 
    Set of Parallel Independent Random Responses with Identical Distributions
    
    The package implements the evaluation of an integral over a set of 
    random variables affecting a response function RF and distributed 
    according to a probabilistic distribution PDistrib.
    
    The input parameters are devided in four categories in order
    to define state consistency of the evaluation. The outputs 
    are define as cached properties that are reevaluated in response
    to changes in the inputs.
    
    The following events accummulate changes in the input parameters of spirrid:
    rf_change - change in the response function
    rand_change - change in the randomization
    conf_change - change in the configuration of the algorithm
    eps_change - change in the studied range of the process control variable       
    '''
    #--------------------------------------------------------------------
    # Response function 
    #--------------------------------------------------------------------
    #
    rf = Instance( IRF )
    def _rf_changed( self ):
        self.on_trait_change( self._set_rf_change, 'rf.changed' )

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    #---------------------------------------------------------------------------------
    # PDF grid - mutually multiplied arrays of PDF
    #---------------------------------------------------------------------------------
    dG_grid = Property( depends_on = 'rf_change, rand_change' )
    @cached_property
    def _get_dG_grid( self ):
        if len( self.dG_ogrid ):
            return reduce( lambda x, y: x * y, self.dG_ogrid )
        else:
            return 1.0
示例#19
0
class NIDOrderStats( HasTraits ):

    distr_list = List( desc = 'NID distributions' )

    n = Property( Int, depends_on = 'distr_list',
            desc = 'number of realizations' )
    def _get_n( self ):
        return len( self.distr_list )

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

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

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

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

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

    def kth_pdf( self ):
        '''evaluates the PDF of the kth entry; cases k = 1 and k > 1 are distinguished
            The most general formula is used here. For higher performance use CIDOrderStats'''
        if len( self.distr_list ) == self.n:
            n = self.n
            k = self.k
            if n >= k:
                fct = sp.misc.factorial
                # the constant actually tells how many redundances are present in the summation
                constant = 1. / ( fct( k - 1 ) * fct( n - k ) )
                summation = np.zeros( len( self.x_arr ) )
                permutations = it.permutations( range( n ), n )
                loop_run = True
                t = time.clock()
                while loop_run == True:
                    try:
                        idx = list( permutations.next() )
                        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 ) )
示例#20
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_random_keys ] ) + \
                       ');\n'
        else: # qg
            code_str = '\tdouble pdf = ' + \
                       '*'.join( [ ' *( %s_pdf + i_%s)' % ( name, name )
                                  for name in self.rv_random_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, rv in self.rv_dict.items():
            if not rv.random:
                code_str += 'double %s = %g;\n' % ( name, rv.trait_value )

        # generate loops over random params

        for rv in self.rv_list:

            # skip the terministic variable
            if not rv.random:
                continue

            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 self.n_rv > 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_random_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 = sysclock()

        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.theta_ogrid )

                    # 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 = sysclock() - 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,
                        )
示例#21
0
class YMBFieldVar(HasTraits):
    data = Instance(IYMBData)

    n_cols = Property()

    def _get_n_cols(self):
        return self.data.n_cuts

    var_enum = Trait('radius', var_dict, modified=True)
    scalar_arr = Property(depends_on='var_enum')

    def _get_scalar_arr(self):
        return getattr(self.data, self.var_enum_)

    sorted_on = Bool(False, modified=True)

    scalar_arr_sorted = Property(depends_on='var_enum')

    def _get_scalar_arr_sorted(self):
        ''' Return scalar array sorted by the shortest distance from the edge
        '''
        scalar_arr = zeros_like(getattr(self.data, self.var_enum_))
        scalar_mask_arr = zeros_like(getattr(self.data, self.var_enum_))
        distance_arr = self.data.edge_distance.filled()
        for i in range(0, self.n_cols):
            scalar_mask_arr[:, i] = zip(
                *sorted(zip(distance_arr[:, i],
                            getattr(self.data, self.var_enum_).mask[:, i]),
                        reverse=True))[1]
            scalar_arr[:, i] = zip(
                *sorted(zip(distance_arr[:, i],
                            getattr(self.data, self.var_enum_).filled()[:, i]),
                        reverse=True))[1]
        return ma.array(scalar_arr, mask=array(scalar_mask_arr, dtype=bool))

    figure = Instance(Figure, ())

    def _figure_default(self):
        figure = Figure()
        figure.add_axes([0.1, 0.1, 0.8, 0.8])
        return figure

    data_changed = Event(True)

    @on_trait_change('+modified, data')
    def _redraw(self):
        self.figure.clear()
        self.figure.add_axes([0.1, 0.1, 0.8, 0.8])
        figure = self.figure
        axes = figure.axes[0]
        axes.clear()

        if self.sorted_on == True:
            scalar_arr = self.scalar_arr_sorted
        else:
            scalar_arr = self.scalar_arr

        xi = linspace(min(self.data.cut_x), max(self.data.cut_x), 100)

        x = (ones_like(scalar_arr) * self.data.cut_x).flatten()
        ny_row = scalar_arr.shape[0]
        dy = max(diff(self.data.cut_x))
        yi = linspace(0, ny_row * dy, ny_row)
        y = (ones_like(scalar_arr).T *
             linspace(0, ny_row * dy, ny_row)).T.flatten()
        z = scalar_arr.flatten()
        zi = griddata(x, y, z, xi, yi, interp='nn')

        # contour the gridded data, plotting dots at the nonuniform data points
        # axes.contour( xi, yi, zi, 20, linewidths = .5, colors = 'k' )
        # plotting filled contour
        axes.contourf(xi, yi, zi, 200, cmap=my_cmap_lin)  # my_cmap_lin
        scat = axes.scatter(x,
                            y,
                            marker='o',
                            c=z,
                            s=20,
                            linewidths=0,
                            cmap=my_cmap_lin)
        figure.colorbar(scat)

        self.data_changed = True

    view = View('var_enum',
                'sorted_on',
                Item('figure',
                     style='custom',
                     editor=MPLFigureEditor(),
                     show_label=False),
                id='yarn_structure_view',
                resizable=True,
                scrollable=True,
                dock='tab',
                width=0.8,
                height=0.4)
示例#22
0
class RandomVariable( HasTraits ):
    '''Class representing the definition and discretization of a random variable.
    '''
    trait_value = Float

    source_trait = CTrait

    # name of the parameter
    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

    # Switch the parameter random 
    random = Bool( False, changed = True )

    def set_random( self, distribution = 'uniform', discr_type = 'T grid',
                    loc = 0., scale = 1., shape = 1., n_int = 30 ):

        possible_distr = self.source_trait.distr
        if distribution and distribution not in possible_distr:
            raise AssertionError, 'distribution type %s not allowed for parameter %s' \
                % ( distribution, self.name )

        self.pd = PDistrib( distr_choice = distribution, n_segments = n_int )
        self.pd.distr_type.set( scale = scale, shape = shape, loc = loc )

        self.n_int = n_int
        self.discr_type = discr_type
        self.random = True

    def unset_random( self ):
        self.random = False

    # Number of integration points (relevant only for grid based methods)
    _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

    # type of the RandomVariable 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 not self.random:
            return array( [ self.trait_value ], dtype = float )

        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 not self.random:
            return array( [ 1.0 ], dtype = float )

        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 ):
        if self.random:
            return self.pd.get_rvs_array( n_samples )
        else:
            return array( [self.trait_value], float )
示例#23
0
class ExpEM(ExType):
    '''Experiment: Elastic Modulus Test
    '''
    #    label = Str('three point bending test')

    implements(IExType)

    file_ext = 'TRA'

    #--------------------------------------------------------------------
    # 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(0.06,
                        unit='m',
                        input=True,
                        table_field=True,
                        auto_set=False,
                        enter_set=True)
    height = Float(0.12,
                   unit='m',
                   input=True,
                   table_field=True,
                   auto_set=False,
                   enter_set=True)
    gauge_length = Float(0.10,
                         unit='m',
                         input=True,
                         table_field=True,
                         auto_set=False,
                         enter_set=True)

    # age of the concrete at the time of testing
    age = Int(39,
              unit='d',
              input=True,
              table_field=True,
              auto_set=False,
              enter_set=True)
    loading_rate = Float(0.6,
                         unit='MPa/s',
                         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'
        fabric_layout_key = '2D-05-11'
        #        concrete_mixture_key = 'PZ-0708-1'
        concrete_mixture_key = 'FIL-10-09'
        orientation_fn_key = 'all0'
        #        orientation_fn_key = 'all90'
        #        orientation_fn_key = '90_0'
        n_layers = 12
        s_tex_z = 0.060 / (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
    #--------------------------------------------------------------------------------

    def _read_data_array(self):
        ''' Read the experiment data. 
        '''
        print 'READ FILE'
        _data_array = np.loadtxt(self.data_file,
                                 delimiter=';',
                                 skiprows=2,
                                 usecols=(4, 5, 10, 17, 20))
        self.data_array = _data_array

    names_and_units = Property

    @cached_property
    def _get_names_and_units(self):
        ''' Set the names and units of the measured data.
        '''
        names = ['delta_u1', 'delta_u2', 'w', 'F', 'time']
        units = ['mm', 'mm', 'mm', 'kN', 's']
        return names, units


#0#"Arbeit";
#1#"Dehn. abs";
#2#"Dehn. abs (2. Kanal)";
#3#"Dehnung";

#4#"Dehnung (1. Kanal)";
#5#"Dehnung (2. Kanal)";

#6#"Dehnung nominell";
#7#"DeltaE";
#8#"E1 korr";
#9#"E2 korr";

#10#"Kolbenweg";

#11#"Kolbenweg abs.";
#12#"Lastrahmen";
#13#"LE-Kanal";
#14#"PrXXXfzeit";
#15#"Querdehnung";
#16#"S korr";
#17#"Standardkraft";
#18#"Vorlaufzeit";
#19#"Weg";
#20#"Zeit";
#21#"Zyklus"

#
#"Nm";
#"mm";
#"mm";
#"mm";
#"mm";
#"mm";
#"mm";
#"%";
#"mm";
#" ";
#"mm";
#"mm";
#" ";
#"mm";
#"s";
#"mm";
#" ";
#"N";
#"s";
#"mm";
#"s";
#" "

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

    plot_templates = {
        'force / displacement': '_plot_force_displacement',
        'stress / strain': '_plot_stress_strain',
        'stress / time': '_plot_stress_time',
    }

    default_plot_template = 'force / displacement'

    def _plot_force_displacement(self, axes):
        xkey = 'deflection [mm]'
        ykey = 'force [kN]'
        xdata = self.w
        ydata = self.F / 1000.  # convert from [N] to [kN]
        axes.set_xlabel('%s' % (xkey, ))
        axes.set_ylabel('%s' % (ykey, ))
        axes.plot(xdata, ydata
                  # color = c, linewidth = w, linestyle = s
                  )

    def _plot_stress_strain(self, axes):
        sig = (self.F / 1000000.) / (self.edge_length**2
                                     )  # convert from [N] to [MN]
        eps1 = (self.delta_u1 / 1000.) / self.gauge_length
        eps2 = (self.delta_u2 / 1000.) / self.gauge_length
        eps_m = (eps1 + eps2) / 2.
        axes.plot(eps_m, sig, color='blue', linewidth=2)

    def _plot_stress_time(self, axes):
        sig = (self.F / 1000000.) / (self.edge_length**2
                                     )  # convert from [N] to [MN]
        axes.plot(self.time, sig, color='blue', linewidth=2)

    def _plot_displ_time(self, axes):
        axes.plot(self.time, self.displ, color='blue', linewidth=2)

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

    traits_view = View(VGroup(
        Group(Item('edge_length', format_str="%.3f"),
              Item('height', format_str="%.3f"),
              Item('gauge_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)
示例#24
0
class MFnLineArray(HasTraits):

    # Public Traits
    xdata = Array(float, value = [0.0, 1.0])
    def _xdata_default(self):
        '''
        convenience default - when xdata not defined created automatically as
        an array of integers with the same shape as ydata
        '''
        return np.arange(self.ydata.shape[0])

    ydata = Array(float, value = [0.0, 1.0])

    extrapolate = Enum('constant', 'exception', 'diff', 'zero')

    # alternative vectorized interpolation using scipy.interpolate   
    def get_values(self, x, k = 1):
        '''
        vectorized interpolation, k is the spline order, default set to 1 (linear)
        '''
        tck = ip.splrep(self.xdata, self.ydata, s = 0, k = k)

        x = np.array([x]).flatten()

        if self.extrapolate == 'diff':
            values = ip.splev(x, tck, der = 0)
        elif self.extrapolate == 'exception':
            if x.all() < self.xdata[0] and x.all() > self.xdata[-1]:
                values = values = ip.splev(x, tck, der = 0)
            else:
                raise ValueError('value(s) outside interpolation range')

        elif self.extrapolate == 'constant':
            mask = x >= self.xdata[0]
            mask *= x <= self.xdata[-1]
            l_mask = x < self.xdata[0]
            r_mask = x > self.xdata[-1]
            extrapol_left = np.repeat(ip.splev(self.xdata[0], tck, der = 0), len(x)) * l_mask
            extrapol_right = np.repeat(ip.splev(self.xdata[-1], tck, der = 0), len(x)) * r_mask
            extrapol = extrapol_left + extrapol_right
            values = ip.splev(x, tck, der = 0) * mask + extrapol
        elif self.extrapolate == 'zero':
            mask = x >= self.xdata[0]
            mask *= x <= self.xdata[-1]
            mask_extrapol = mask == False
            extrapol = np.zeros(len(x)) * mask_extrapol
            values = ip.splev(x, tck, der = 0) * mask + extrapol
        return values

    def get_value(self, x):
        x2idx = self.xdata.searchsorted(x)
        if x2idx == len(self.xdata):
            x2idx -= 1
        x1idx = x2idx - 1
        x1 = self.xdata[ x1idx ]
        x2 = self.xdata[ x2idx ]
        dx = x2 - x1
        y1 = self.ydata[ x1idx ]
        y2 = self.ydata[ x2idx ]
        dy = y2 - y1
        y = y1 + dy / dx * (x - x1)
        return y

    data_changed = Event

    def get_diffs(self, x, k = 1, der = 1):
        '''
        vectorized interpolation, der is the nth derivative, default set to 1;
        k is the spline order of the data inetrpolation, default set to 1 (linear)
        '''
        xdata = np.sort(np.hstack((self.xdata, x)))
        idx = np.argwhere(np.diff(xdata) == 0).flatten()
        xdata = np.delete(xdata, idx)
        tck = ip.splrep(xdata, self.get_values(xdata, k = k), s = 0, k = k)
        return ip.splev(x, tck, der = der)

    def get_diff(self, x):
        x2idx = self.xdata.searchsorted(x)
        if x2idx == len(self.xdata):
            x2idx -= 1
        x1idx = x2idx - 1
        x1 = self.xdata[ x1idx ]
        x2 = self.xdata[ x2idx ]
        dx = x2 - x1
        y1 = self.ydata[ x1idx ]
        y2 = self.ydata[ x2idx ]
        dy = y2 - y1
        return dy / dx

    dump_button = ToolbarButton('Print data',
                                style = 'toolbar')
    @on_trait_change('dump_button')
    def print_data(self, event = None):
        print 'x = ', repr(self.xdata)
        print 'y = ', repr(self.ydata)

    integ_value = Property(Float(), depends_on = 'ydata')
    @cached_property
    def _get_integ_value(self):
        _xdata = self.xdata
        _ydata = self.ydata
        # integral under the stress strain curve
        E_t = np.trapz(_ydata, _xdata)
        # area of the stored elastic energy  
        U_t = 0.0
        if len(_xdata) != 0:
            U_t = 0.5 * _ydata[-1] * _xdata[-1]
        return E_t - U_t

    def clear(self):
        self.xdata = np.array([])
        self.ydata = np.array([])

    def plot(self, axes, *args, **kw):
        self.mpl_plot(axes, *args, **kw)

    def mpl_plot(self, axes, *args, **kw):
        '''plot within matplotlib window'''
        axes.plot(self.xdata, self.ydata, *args, **kw)
示例#25
0
class RVTransformation(HasTraits):

    x_values = Array
    pdf_x = Array
    # TODO: the possibility to work with CDFs
    cdf_x = Array

    PDFx = Property(depends_on='x_values, pdf_x')

    @cached_property
    def _get_PDFx(self):
        pdfx_line = MFnLineArray(xdata=self.x_values, ydata=self.pdf_x)
        return pdfx_line

    transf_eqn = Callable

    def _transf_eqn_default(self):
        # define simple linear transfomation function
        return lambda x: x

    y_values = Property(Array, depends_on='x_values, transf_eqn')

    @cached_property
    def _get_y_values(self):
        y = self.transf_eqn(self.x_values)
        y = np.linspace(y.min(), y.max(), len(self.x_values))
        return y

    transf_line = Property(depends_on='x_values, pdf_x, transf_eqn')

    @cached_property
    def _get_transf_line(self):
        x = np.linspace(self.x_values[0], self.x_values[-1], 500)
        y = self.transf_eqn(x)
        return MFnLineArray(xdata=x, ydata=y, extrapolate='diff')

    def transf_diff(self, x):
        return self.transf_line.get_diffs(x, k=1, der=1)

    def transf_inv_scalar(self, y):
        x = np.linspace(self.x_values[0], self.x_values[-1], 500)
        s = sp.interpolate.InterpolatedUnivariateSpline(
            x,
            self.transf_eqn(x) - y)
        roots = s.roots()
        return roots

    def transf_inv_vect(self, y):
        res = []
        y_val = []
        for yi in y:
            value = self.transf_inv_scalar(yi)
            if len(value) != 0:
                res.append(value)
                y_val.append(yi)
        return res, y_val

    PDFy = Property(depends_on='x_values, pdf_x, transf_eqn')

    @cached_property
    def _get_PDFy(self):
        x, y = self.transf_inv_vect(self.y_values)
        xdata = []
        PDFy = []
        for i, xi in enumerate(x):
            if np.abs(self.transf_diff(np.array(xi))).all() > 1e-15:
                PDFy_arr = self.PDFx.get_values(np.array(xi), k=1) / np.abs(
                    self.transf_diff(np.array(xi)))
                PDFy.append(np.sum(PDFy_arr))
                xdata.append(y[i])
        return MFnLineArray(xdata=xdata, ydata=PDFy)
示例#26
0
class SimCrackLoc(IBVModel):
    '''Model assembling the components for studying the restrained crack localization.
    '''

    geo_transform = Instance(FlawCenteredGeoTransform)

    def _geo_transform_default(self):
        return FlawCenteredGeoTransform()

    shape = Int(10,
                desc='Number of finite elements',
                ps_levsls=(10, 40, 4),
                input=True)

    length = Float(1000,
                   desc='Length of the simulated region',
                   unit='mm',
                   input=True)

    flaw_position = Float(500, input=True, unit='mm')

    flaw_radius = Float(100, input=True, unit='mm')

    reduction_factor = Float(0.9, input=True)

    elastic_fraction = Float(0.9, input=True)

    avg_radius = Float(400, input=True, unit='mm')

    # tensile strength of concrete
    f_m_t = Float(3.0, input=True, unit='MPa')

    epsilon_0 = Property(unit='-')

    def _get_epsilon_0(self):
        return self.f_m_t / self.E_m

    epsilon_f = Float(10, input=True, unit='-')

    h_m = Float(10, input=True, unit='mm')

    b_m = Float(8, input=True, unit='mm')

    A_m = Property(unit='m^2')

    def _get_A_m(self):
        return self.b_m * self.h_m

    E_m = Float(30.0e5, input=True, unit='MPa')

    E_f = Float(70.0e6, input=True, unit='MPa')

    A_f = Float(1.0, input=True, unit='mm^2')

    s_crit = Float(0.009, input=True, unit='mm')

    P_f = Property(depends_on='+input')

    @cached_property
    def _get_P_f(self):
        return sqrt(4 * self.A_f * pi)

    K_b = Property(depends_on='+input')

    @cached_property
    def _get_K_b(self):
        return self.T_max / self.s_crit

    tau_max = Float(0.0, input=True, unit='MPa')

    T_max = Property(depends_on='+input', unit='N/mm')

    @cached_property
    def _get_T_max(self):
        return self.tau_max * self.P_f

    rho = Property(depends_on='+input')

    @cached_property
    def _get_rho(self):
        return self.A_f / (self.A_f + self.A_m)

    #-------------------------------------------------------
    # Material model for the matrix
    #-------------------------------------------------------
    mats_m = Property(Instance(MATS1DDamageWithFlaw), depends_on='+input')

    @cached_property
    def _get_mats_m(self):
        mats_m = MATS1DDamageWithFlaw(E=self.E_m * self.A_m,
                                      flaw_position=self.flaw_position,
                                      flaw_radius=self.flaw_radius,
                                      reduction_factor=self.reduction_factor,
                                      epsilon_0=self.epsilon_0,
                                      epsilon_f=self.epsilon_f)
        return mats_m

    mats_f = Instance(MATS1DElastic)

    def _mats_f_default(self):
        mats_f = MATS1DElastic(E=self.E_f * self.A_f)
        return mats_f

    mats_b = Instance(MATS1DEval)

    def _mats_b_default(self):
        mats_b = MATS1DElastic(E=self.K_b)
        mats_b = MATS1DPlastic(E=self.K_b,
                               sigma_y=self.T_max,
                               K_bar=0.,
                               H_bar=0.)  # plastic function of slip
        return mats_b

    mats_fb = Property(Instance(MATS1D5Bond), depends_on='+input')

    @cached_property
    def _get_mats_fb(self):

        # Material model construction
        return MATS1D5Bond(
            mats_phase1=MATS1DElastic(E=0),
            mats_phase2=self.mats_f,
            mats_ifslip=self.mats_b,
            mats_ifopen=MATS1DElastic(
                E=0)  # elastic function of open - inactive
        )

    #-------------------------------------------------------
    # Finite element type
    #-------------------------------------------------------
    fets_m = Property(depends_on='+input')

    @cached_property
    def _get_fets_m(self):
        fets_eval = FETS1D2L(mats_eval=self.mats_m)
        #fets_eval = FETS1D2L3U( mats_eval = self.mats_m )
        return fets_eval

    fets_fb = Property(depends_on='+input')

    @cached_property
    def _get_fets_fb(self):
        return FETS1D52L4ULRH(mats_eval=self.mats_fb)
        #return FETS1D52L6ULRH( mats_eval = self.mats_fb )
        #return FETS1D52L8ULRH( mats_eval = self.mats_fb )

    #--------------------------------------------------------------------------------------
    # Mesh integrator
    #--------------------------------------------------------------------------------------
    fe_domain_structure = Property(depends_on='+input')

    @cached_property
    def _get_fe_domain_structure(self):
        '''Root of the domain hierarchy
        '''
        elem_length = self.length / float(self.shape)

        fe_domain = FEDomain()

        fe_m_level = FERefinementGrid(name='matrix domain',
                                      domain=fe_domain,
                                      fets_eval=self.fets_m)

        fe_grid_m = FEGrid(name='matrix grid',
                           coord_max=(self.length, ),
                           shape=(self.shape, ),
                           level=fe_m_level,
                           fets_eval=self.fets_m,
                           geo_transform=self.geo_transform)

        fe_fb_level = FERefinementGrid(name='fiber bond domain',
                                       domain=fe_domain,
                                       fets_eval=self.fets_fb)

        fe_grid_fb = FEGrid(coord_min=(0., length / 5.),
                            coord_max=(length, 0.),
                            shape=(self.shape, 1),
                            level=fe_fb_level,
                            fets_eval=self.fets_fb,
                            geo_transform=self.geo_transform)

        return fe_domain, fe_grid_m, fe_grid_fb, fe_m_level, fe_fb_level

    fe_domain = Property

    def _get_fe_domain(self):
        return self.fe_domain_structure[0]

    fe_grid_m = Property

    def _get_fe_grid_m(self):
        return self.fe_domain_structure[1]

    fe_grid_fb = Property

    def _get_fe_grid_fb(self):
        return self.fe_domain_structure[2]

    fe_m_level = Property

    def _get_fe_m_level(self):
        return self.fe_domain_structure[3]

    fe_fb_level = Property

    def _get_fe_fb_level(self):
        return self.fe_domain_structure[4]

    #---------------------------------------------------------------------------
    # Load scaling adapted to the elastic and inelastic regime
    #---------------------------------------------------------------------------
    final_displ = Property(depends_on='+input')

    @cached_property
    def _get_final_displ(self):
        damage_onset_displ = self.mats_m.epsilon_0 * self.length
        return damage_onset_displ / self.elastic_fraction

    step_size = Property(depends_on='+input')

    @cached_property
    def _get_step_size(self):
        n_steps = self.n_steps
        return 1.0 / float(n_steps)

    time_function = Property(depends_on='+input')

    @cached_property
    def _get_time_function(self):
        '''Get the time function so that the elastic regime 
        is skipped in a single step.
        '''
        step_size = self.step_size

        elastic_value = self.elastic_fraction * 0.98 * self.reduction_factor
        inelastic_value = 1.0 - elastic_value

        def ls(t):
            if t <= step_size:
                return (elastic_value / step_size) * t
            else:
                return elastic_value + (t - step_size) * (inelastic_value) / (
                    1 - step_size)

        return ls

    def plot_time_function(self, p):
        '''Plot the time function.
        '''
        n_steps = self.n_steps
        mats = self.mats
        step_size = self.step_size

        ls_t = linspace(0, step_size * n_steps, n_steps + 1)
        ls_fn = frompyfunc(self.time_function, 1, 1)
        ls_v = ls_fn(ls_t)

        p.subplot(321)
        p.plot(ls_t, ls_v, 'ro-')

        final_epsilon = self.final_displ / self.length

        kappa = linspace(mats.epsilon_0, final_epsilon, 10)
        omega_fn = frompyfunc(lambda kappa: mats._get_omega(None, kappa), 1, 1)
        omega = omega_fn(kappa)
        kappa_scaled = (step_size + (1 - step_size) *
                        (kappa - mats.epsilon_0) /
                        (final_epsilon - mats.epsilon_0))
        xdata = hstack([array([0.0], dtype=float), kappa_scaled])
        ydata = hstack([array([0.0], dtype=float), omega])
        p.plot(xdata, ydata, 'g')
        p.xlabel('regular time [-]')
        p.ylabel('scaled time [-]')

    run = Button

    @on_trait_change('run')
    def peval(self):
        '''Evaluation procedure.
        '''
        #mv = MATS1DDamageView( model = mats_eval )
        #mv.configure_traits()

        right_dof_m = self.fe_grid_m[-1, -1].dofs[0, 0, 0]

        right_dof_fb = self.fe_grid_fb[-1, -1, -1, -1].dofs[0, 0, 0]
        # Response tracers
        A = self.A_m + self.A_f
        self.sig_eps_m = RTraceGraph(name='F_u_m',
                                     var_y='F_int',
                                     idx_y=right_dof_m,
                                     var_x='U_k',
                                     idx_x=right_dof_m,
                                     transform_y='y / %g' % A)

        # Response tracers
        self.sig_eps_f = RTraceGraph(name='F_u_f',
                                     var_y='F_int',
                                     idx_y=right_dof_fb,
                                     var_x='U_k',
                                     idx_x=right_dof_fb,
                                     transform_y='y / %g' % A)

        self.eps_m_field = RTraceDomainListField(name='eps_m',
                                                 position='int_pnts',
                                                 var='eps_app',
                                                 warp=False)

        self.eps_f_field = RTraceDomainListField(name='eps_f',
                                                 position='int_pnts',
                                                 var='mats_phase2_eps_app',
                                                 warp=False)
        # Response tracers
        self.sig_m_field = RTraceDomainListField(name='sig_m',
                                                 position='int_pnts',
                                                 var='sig_app')

        self.sig_f_field = RTraceDomainListField(name='sig_f',
                                                 position='int_pnts',
                                                 var='mats_phase2_sig_app')

        self.omega_m_field = RTraceDomainListField(name='omega_m',
                                                   position='int_pnts',
                                                   var='omega',
                                                   warp=False)

        self.shear_flow_field = RTraceDomainListField(name='shear flow',
                                                      position='int_pnts',
                                                      var='shear_flow',
                                                      warp=False)

        self.slip_field = RTraceDomainListField(name='slip',
                                                position='int_pnts',
                                                var='slip',
                                                warp=False)

        avg_processor = None
        if self.avg_radius > 0.0:
            n_dofs = self.fe_domain.n_dofs
            avg_processor = RTUAvg(sd=self.fe_m_level,
                                   n_dofs=n_dofs,
                                   avg_fn=QuarticAF(radius=self.avg_radius))

        ts = TStepper(
            u_processor=avg_processor,
            dof_resultants=True,
            sdomain=self.fe_domain,
            bcond_list=[  # define the left clamping 
                BCSlice(var='u',
                        value=0.,
                        dims=[0],
                        slice=self.fe_grid_fb[0, 0, 0, :]),
                #                                BCSlice( var = 'u', value = 0., dims = [0], slice = self.fe_grid_m[ 0, 0 ] ),
                # loading at the right edge
                #                                 BCSlice( var = 'f', value = 1, dims = [0], slice = domain[-1, -1, -1, 0],
                #                                         time_function = ls ),
                BCSlice(var='u',
                        value=self.final_displ,
                        dims=[0],
                        slice=self.fe_grid_fb[-1, -1, -1, :],
                        time_function=self.time_function),
                #                                 BCSlice( var = 'u', value = self.final_displ, dims = [0], slice = self.fe_grid_m[-1, -1],
                #                                         time_function = self.time_function ),
                # fix horizontal displacement in the top layer
                #                                 BCSlice( var = 'u', value = 0., dims = [0], slice = domain[:, -1, :, -1] ),
                # fix the vertical displacement all over the domain
                BCSlice(var='u',
                        value=0.,
                        dims=[1],
                        slice=self.fe_grid_fb[:, :, :, :]),
                #                            # Connect bond and matrix domains
                BCDofGroup(var='u',
                           value=0.,
                           dims=[0],
                           get_link_dof_method=self.fe_grid_fb.get_bottom_dofs,
                           get_dof_method=self.fe_grid_m.get_all_dofs,
                           link_coeffs=[1.])
            ],
            rtrace_list=[
                self.sig_eps_m,
                self.sig_eps_f,
                self.eps_m_field,
                self.eps_f_field,
                self.sig_m_field,
                self.sig_f_field,
                self.omega_m_field,
                self.shear_flow_field,
                self.slip_field,
            ])

        # Add the time-loop control
        tloop = TLoop(tstepper=ts,
                      KMAX=300,
                      tolerance=1e-5,
                      debug=False,
                      verbose_iteration=True,
                      verbose_time=False,
                      tline=TLine(min=0.0, step=self.step_size, max=1.0))

        tloop.on_accept_time_step = self.plot

        U = tloop.eval()

        self.sig_eps_f.refresh()
        max_sig_m = max(self.sig_eps_m.trace.ydata)
        return array([U[right_dof_m], max_sig_m], dtype='float_')

    #--------------------------------------------------------------------------------------
    # Tracers
    #--------------------------------------------------------------------------------------

    def plot_sig_eps(self, p):
        p.set_xlabel('control displacement [mm]')
        p.set_ylabel('stress [MPa]')

        self.sig_eps_m.refresh()
        self.sig_eps_m.trace.plot(p, 'o-')

        self.sig_eps_f.refresh()
        self.sig_eps_f.trace.plot(p, 'o-')

        p.plot(self.sig_eps_m.trace.xdata,
               self.sig_eps_m.trace.ydata + self.sig_eps_f.trace.ydata, 'o-')

    def plot_eps(self, p):
        eps_m = self.eps_m_field.subfields[0]
        xdata = eps_m.vtk_X[:, 0]
        ydata = eps_m.field_arr[:, 0, 0]
        idata = argsort(xdata)
        p.plot(xdata[idata], ydata[idata], 'o-')

        eps_f = self.eps_f_field.subfields[1]
        xdata = eps_f.vtk_X[:, 0]
        ydata = eps_f.field_arr[:, 0, 0]
        idata = argsort(xdata)
        p.plot(xdata[idata], ydata[idata], 'o-')

        p.set_ylim(ymin=0)
        p.set_xlabel('bar axis [mm]')
        p.set_ylabel('strain [-]')

    def plot_omega(self, p):
        omega_m = self.omega_m_field.subfields[0]
        xdata = omega_m.vtk_X[:, 0]
        ydata = omega_m.field_arr[:]
        idata = argsort(xdata)
        p.fill(xdata[idata], ydata[idata], facecolor='gray', alpha=0.2)

        print 'max omega', max(ydata[idata])

        p.set_ylim(ymin=0, ymax=1.0)
        p.set_xlabel('bar axis [mm]')
        p.set_ylabel('omega [-]')

    def plot_sig(self, p):
        sig_m = self.sig_m_field.subfields[0]
        xdata = sig_m.vtk_X[:, 0]
        ydata = sig_m.field_arr[:, 0, 0]
        idata = argsort(xdata)
        ymax = max(ydata)
        p.plot(xdata[idata], ydata[idata], 'o-')

        sig_f = self.sig_f_field.subfields[1]
        xdata = sig_f.vtk_X[:, 0]
        ydata = sig_f.field_arr[:, 0, 0]
        idata = argsort(xdata)
        p.plot(xdata[idata], ydata[idata], 'o-')

        xdata = sig_f.vtk_X[:, 0]
        ydata = sig_f.field_arr[:, 0, 0] + sig_m.field_arr[:, 0, 0]
        p.plot(xdata[idata], ydata[idata], 'ro-')

        p.set_ylim(ymin=0)  # , ymax = 1.2 * ymax )
        p.set_xlabel('bar axis [mm]')
        p.set_ylabel('stress [MPa]')

    def plot_shear_flow(self, p):
        shear_flow = self.shear_flow_field.subfields[1]
        xdata = shear_flow.vtk_X[:, 0]
        ydata = shear_flow.field_arr[:, 0] / self.P_f
        idata = argsort(xdata)
        ymax = max(ydata)
        p.plot(xdata[idata], ydata[idata], 'o-')

        p.set_xlabel('bar axis [mm]')
        p.set_ylabel('shear flow [N/m]')

    def plot_slip(self, p):
        slip = self.slip_field.subfields[1]
        xdata = slip.vtk_X[:, 0]
        ydata = slip.field_arr[:, 0]
        idata = argsort(xdata)
        ymax = max(ydata)
        p.plot(xdata[idata], ydata[idata], 'ro-')

        p.set_xlabel('bar axis [mm]')
        p.set_ylabel('slip [N/m]')

    def plot_tracers(self, p=p):

        p.subplot(221)
        self.plot_sig_eps(p)

        p.subplot(223)
        self.plot_eps(p)

        p.subplot(224)
        self.plot_sig(p)

    #---------------------------------------------------------------
    # PLOT OBJECT
    #-------------------------------------------------------------------
    figure_ld = Instance(Figure)

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

    #---------------------------------------------------------------
    # PLOT OBJECT
    #-------------------------------------------------------------------
    figure_eps = Instance(Figure)

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

    #---------------------------------------------------------------
    # PLOT OBJECT
    #-------------------------------------------------------------------
    figure_shear_flow = Instance(Figure)

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

    #---------------------------------------------------------------
    # PLOT OBJECT
    #-------------------------------------------------------------------
    figure_sig = Instance(Figure)

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

    #---------------------------------------------------------------
    # PLOT OBJECT
    #-------------------------------------------------------------------
    figure_shear_flow = Instance(Figure)

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

    def plot(self):

        self.figure_ld.clear()
        ax = self.figure_ld.gca()
        self.plot_sig_eps(ax)

        self.figure_eps.clear()
        ax = self.figure_eps.gca()
        self.plot_eps(ax)
        ax2 = ax.twinx()
        self.plot_omega(ax2)

        self.figure_sig.clear()
        ax = self.figure_sig.gca()
        self.plot_sig(ax)
        ax2 = ax.twinx()
        self.plot_omega(ax2)

        self.figure_shear_flow.clear()
        ax = self.figure_shear_flow.gca()
        self.plot_shear_flow(ax)
        ax2 = ax.twinx()
        self.plot_slip(ax2)

        self.data_changed = True

    def get_sim_outputs(self):
        '''
        Specifies the results and their order returned by the model
        evaluation.
        '''
        return [
            SimOut(name='right end displacement', unit='m'),
            SimOut(name='peak load', uni='MPa')
        ]

    data_changed = Event

    toolbar = ToolBar(Action(name="Run",
                             tooltip='Start computation',
                             image=ImageResource('kt-start'),
                             action="start_study"),
                      Action(name="Pause",
                             tooltip='Pause computation',
                             image=ImageResource('kt-pause'),
                             action="pause_study"),
                      Action(name="Stop",
                             tooltip='Stop computation',
                             image=ImageResource('kt-stop'),
                             action="stop_study"),
                      image_size=(32, 32),
                      show_tool_names=False,
                      show_divider=True,
                      name='view_toolbar'),

    traits_view = View(HSplit(
        VSplit(
            Item('run', show_label=False),
            VGroup(
                Item('shape'),
                Item('n_steps'),
                Item('length'),
                label='parameters',
                id='crackloc.viewmodel.factor.geometry',
                dock='tab',
                scrollable=True,
            ),
            VGroup(Item('E_m'),
                   Item('f_m_t'),
                   Item('avg_radius'),
                   Item('h_m'),
                   Item('b_m'),
                   Item('A_m', style='readonly'),
                   Item('mats_m', show_label=False),
                   label='Matrix',
                   dock='tab',
                   id='crackloc.viewmodel.factor.matrix',
                   scrollable=True),
            VGroup(Item('E_f'),
                   Item('A_f'),
                   Item('mats_f', show_label=False),
                   label='Fiber',
                   dock='tab',
                   id='crackloc.viewmodel.factor.fiber',
                   scrollable=True),
            VGroup(Group(
                Item('tau_max'),
                Item('s_crit'),
                Item('P_f', style='readonly', show_label=True),
                Item('K_b', style='readonly', show_label=True),
                Item('T_max', style='readonly', show_label=True),
            ),
                   Item('mats_b', show_label=False),
                   label='Bond',
                   dock='tab',
                   id='crackloc.viewmodel.factor.bond',
                   scrollable=True),
            VGroup(Item('rho', style='readonly', show_label=True),
                   label='Composite',
                   dock='tab',
                   id='crackloc.viewmodel.factor.jcomposite',
                   scrollable=True),
            id='crackloc.viewmodel.left',
            label='studied factors',
            layout='tabbed',
            dock='tab',
        ),
        VSplit(
            VGroup(
                Item('figure_ld',
                     editor=MPLFigureEditor(),
                     resizable=True,
                     show_label=False),
                label='stress-strain',
                id='crackloc.viewmode.figure_ld_window',
                dock='tab',
            ),
            VGroup(
                Item('figure_eps',
                     editor=MPLFigureEditor(),
                     resizable=True,
                     show_label=False),
                label='strains profile',
                id='crackloc.viewmode.figure_eps_window',
                dock='tab',
            ),
            VGroup(
                Item('figure_sig',
                     editor=MPLFigureEditor(),
                     resizable=True,
                     show_label=False),
                label='stress profile',
                id='crackloc.viewmode.figure_sig_window',
                dock='tab',
            ),
            VGroup(
                Item('figure_shear_flow',
                     editor=MPLFigureEditor(),
                     resizable=True,
                     show_label=False),
                label='bond shear and slip profiles',
                id='crackloc.viewmode.figure_shear_flow_window',
                dock='tab',
            ),
            id='crackloc.viewmodel.right',
        ),
        id='crackloc.viewmodel.splitter',
    ),
                       title='SimVisage Component: Crack localization',
                       id='crackloc.viewmodel',
                       dock='tab',
                       resizable=True,
                       height=0.8,
                       width=0.8,
                       buttons=[OKButton])
示例#27
0
class ExpBT3PT(ExType):
    '''Experiment: Bending Test Three Point
    '''
    #    label = Str('three point bending test')

    implements(IExType)

    file_ext = 'raw'

    #--------------------------------------------------------------------
    # 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:
    #--------------------------------------------------------------------------------

    length = Float(0.46,
                   unit='m',
                   input=True,
                   table_field=True,
                   auto_set=False,
                   enter_set=True)
    width = Float(0.1,
                  unit='m',
                  input=True,
                  table_field=True,
                  auto_set=False,
                  enter_set=True)
    thickness = Float(0.02,
                      unit='m',
                      input=True,
                      table_field=True,
                      auto_set=False,
                      enter_set=True)

    # age of the concrete at the time of testing
    age = Int(33,
              unit='d',
              input=True,
              table_field=True,
              auto_set=False,
              enter_set=True)
    loading_rate = Float(4.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
        '''
        #        fabric_layout_key = 'MAG-07-03'
        #        fabric_layout_key = '2D-02-06a'
        fabric_layout_key = '2D-05-11'
        #        fabric_layout_key = '2D-09-12'
        #        concrete_mixture_key = 'PZ-0708-1'
        #        concrete_mixture_key = 'FIL-10-09'
        concrete_mixture_key = 'barrelshell'
        orientation_fn_key = 'all0'
        #        orientation_fn_key = 'all90'
        #        orientation_fn_key = '90_0'
        n_layers = 6
        s_tex_z = 0.020 / (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
    #--------------------------------------------------------------------------------

    # flag distinguishes weather data from a displacement gauge is available
    # stored in a separate ASC-file with a corresponding file name
    #
    flag_ASC_file = Bool(False)

    def _read_data_array(self):
        ''' Read the experiment data.
        '''
        if exists(self.data_file):

            print 'READ FILE'
            file_split = self.data_file.split('.')

            # first check if a '.csv' file exists. If yes use the
            # data stored in the '.csv'-file and ignore
            # the data in the '.raw' file!
            #
            file_name = file_split[0] + '.csv'
            if not os.path.exists(file_name):
                file_name = file_split[0] + '.raw'
                if not os.path.exists(file_name):
                    raise IOError, 'file %s does not exist' % file_name

            print 'file_name', file_name
            _data_array = loadtxt_bending(file_name)
            self.data_array = _data_array

            # check if a '.ASC'-file exists. If yes append this information
            # to the data array.
            #
            file_name = file_split[0] + '.ASC'
            if not os.path.exists(file_name):
                print 'NOTE: no data from displacement gauge is available (no .ASC file)'
                self.flag_ASC_file = False
            else:
                print 'NOTE: additional data from displacement gauge for center deflection is available (.ASC-file loaded)!'
                self.flag_ASC_file = True
                # add data array read in from .ASC-file; the values are assigned by '_set_array_attribs' based on the
                # read in values in 'names_and_units' read in from the corresponding .DAT-file
                #
                self.data_array_ASC = loadtxt(file_name, delimiter=';')
        else:
            print 'WARNING: data_file with path %s does not exist == False' % (
                self.data_file)

    names_and_units = Property(depends_on='data_file')

    @cached_property
    def _get_names_and_units(self):
        '''names and units corresponding to the returned '_data_array' by 'loadtxt_bending'
        '''
        names = ['w_raw', 'eps_c_raw', 'F_raw']
        units = ['mm', '1*E-3', 'N']
        print 'names, units from .raw-file', names, units
        return names, units

    names_and_units_ASC = Property(depends_on='data_file')

    @cached_property
    def _get_names_and_units_ASC(self):
        ''' Extract the names and units of the measured data.
        The order of the names in the .DAT-file corresponds
        to the order of the .ASC-file.
        '''
        file_split = self.data_file.split('.')
        file_name = file_split[0] + '.DAT'
        data_file = open(file_name, 'r')
        lines = data_file.read().split()
        names = []
        units = []
        for i in range(len(lines)):
            if lines[i] == '#BEGINCHANNELHEADER':
                name = lines[i + 1].split(',')[1]
                unit = lines[i + 3].split(',')[1]
                names.append(name)
                units.append(unit)

        print 'names, units extracted from .DAT-file', names, units
        return names, units

    factor_list_ASC = Property(depends_on='data_file')

    def _get_factor_list_ASC(self):
        return self.names_and_units_ASC[0]

    def _set_array_attribs(self):
        '''Set the measured data as named attributes defining slices into
        the processed data array.
        '''
        for i, factor in enumerate(self.factor_list):
            self.add_trait(
                factor,
                Array(value=self.processed_data_array[:, i], transient=True))

        if self.flag_ASC_file:
            for i, factor in enumerate(self.factor_list_ASC):
                self.add_trait(
                    factor,
                    Array(value=self.data_array_ASC[:, i], transient=True))

    elastomer_law = Property(depends_on='input_change')

    @cached_property
    def _get_elastomer_law(self):

        elastomer_path = os.path.join(simdb.exdata_dir, 'bending_tests',
                                      'three_point',
                                      '2011-06-10_BT-3PT-12c-6cm-0-TU_ZiE',
                                      'elastomer_f-w.raw')
        _data_array_elastomer = loadtxt_bending(elastomer_path)

        # force [kN]:
        # NOTE: after conversion 'F_elastomer' is a positive value
        #
        F_elastomer = -0.001 * _data_array_elastomer[:, 2].flatten()

        # displacement [mm]:
        # NOTE: after conversion 'w_elastomer' is a positive value
        #
        w_elastomer = -1.0 * _data_array_elastomer[:, 0].flatten()

        mfn_displacement_elastomer = MFnLineArray(xdata=F_elastomer,
                                                  ydata=w_elastomer)
        return frompyfunc(mfn_displacement_elastomer.get_value, 1, 1)

    w_wo_elast = Property(depends_on='input_change')

    @cached_property
    def _get_w_wo_elast(self):
        # use the machine displacement for the center displacement:
        # subtract the deformation of the elastomer cushion between the cylinder
        # and change sign in positive values for vertical displacement [mm]
        #
        return self.w_raw - self.elastomer_law(self.F_raw)

    M_ASC = Property(Array('float_'), depends_on='input_change')

    @cached_property
    def _get_M_ASC(self):
        return self.F_ASC * self.length / 4.0

    M_raw = Property(Array('float_'), depends_on='input_change')

    @cached_property
    def _get_M_raw(self):
        return self.F_raw * self.length / 4.0

#    # 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]

    K_bending_elast = Property(Array('float_'), depends_on='input_change')

    @cached_property
    def _get_K_bending_elast(self):
        '''calculate the analytical bending stiffness of the beam (3 point bending)
        '''
        t = self.thickness
        w = self.width
        L = self.length

        # coposite E-modulus
        #
        E_c = self.E_c

        # moment of inertia
        #
        I_yy = t**3 * w / 12.

        delta_11 = (L**3) / 48 / E_c / I_yy

        # [MN/m]=[kN/mm] bending stiffness with respect to a force applied at center of the beam
        #
        K_bending_elast = 1 / delta_11
        #         print 'K_bending_elast', K_bending_elast

        return K_bending_elast

    F_cr = Property(Array('float_'), depends_on='input_change')

    @cached_property
    def _get_F_cr(self):
        '''calculate the analytical cracking load of the beam
        '''
        t = self.thickness
        w = self.width
        L = self.length

        # approx. flectural tensile strength
        #
        f_cfl = 6.  # MPa

        # resistant moment
        #
        W_yy = t**2 * w / 6.

        # analytical cracking load of the beam
        # corresponds to l = 0.46m and f_cfl = approx. 8.4 MPa#
        #
        F_cr = W_yy * f_cfl * 1000. / L  # [kN]

        return F_cr

    def process_source_data(self):
        '''read in the measured data from file and assign
        attributes after array processing.
        '''
        super(ExpBT3PT, self).process_source_data()

        #---------------------------------------------
        # process data from .raw file (machine data)
        #---------------------------------------------

        # convert machine force [N] to [kN] and return only positive values
        #
        self.F_raw *= -0.001

        # convert machine displacement [mm] to positive values
        # and remove offset
        #
        self.w_raw *= -1.0
        self.w_raw -= self.w_raw[0]

        # convert [permille] to [-] and return only positive values
        #
        self.eps_c_raw *= -0.001

        # access the derived arrays to initiate their processing
        #
        self.w_wo_elast
        self.M_raw

        #---------------------------------------------
        # process data from .ASC file (displacement gauge)
        #---------------------------------------------

        # only if separate ASC.-file with force-displacement data from displacement gauge is available
        #
        if self.flag_ASC_file == True:

            self.F_ASC = -1.0 * self.Kraft

            # remove offset and change sign to return positive displacement values
            #
            if hasattr(self, "WA50"):
                self.WA50 *= -1
                self.WA50 -= self.WA50[0]
                WA50_avg = np.average(self.WA50)

            if hasattr(self, "W10_u"):
                self.W10_u *= -1
                self.W10_u -= self.W10_u[0]
                W10_u_avg = np.average(self.W10_u)

            # check which displacement gauge has been used depending on weather two names are listed in .DAT file or only one
            # and assign values to 'w_ASC'
            #
            if hasattr(self, "W10_u") and hasattr(self, "WA50"):
                if W10_u_avg > WA50_avg:
                    self.w_ASC = self.W10_u
                    print 'self.W10_u assigned to self.w_ASC'
                else:
                    self.w_ASC = self.WA50
                    print 'self.WA50 assigned to self.w_ASC'
            elif hasattr(self, "W10_u"):
                self.w_ASC = self.W10_u
                print 'self.W10_u assigned to self.w_ASC'
            elif hasattr(self, "WA50"):
                self.w_ASC = self.WA50
                print 'self.WA50 assigned to self.w_ASC'

            # convert strain from [permille] to [-],
            # switch to positive values for compressive strains
            # and remove offset
            #
            self.eps_c_ASC = -0.001 * self.DMS_l
            self.eps_c_ASC -= self.eps_c_ASC[0]

            # access the derived arrays to initiate their processing
            #
            self.M_ASC

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

    plot_templates = {
        'force / machine displacement (incl. w_elast)':
        '_plot_force_machine_displacement',
        'force / machine displacement (without w_elast)':
        '_plot_force_machine_displacement_wo_elast',
        'force / machine displacement (without w_elast, interpolated)':
        '_plot_force_machine_displacement_wo_elast_interpolated',
        'force / machine displacement (analytical offset)':
        '_plot_force_machine_displacement_wo_elast_analytical_offset',
        'force / gauge displacement': '_plot_force_gauge_displacement',
        'force / gauge displacement (analytical offset)':
        '_plot_force_gauge_displacement_with_analytical_offset',
        'force / gauge displacement (interpolated)':
        '_plot_force_gauge_displacement_interpolated',

        #                       'smoothed force / gauge displacement'            : '_plot_smoothed_force_gauge_displacement',
        #                       'smoothed force / machine displacement'          : '_plot_smoothed_force_machine_displacement_wo_elast',
        #
        'moment / eps_c (ASC)': '_plot_moment_eps_c_ASC',
        'moment / eps_c (raw)': '_plot_moment_eps_c_raw',
        #
        #                       'smoothed moment / eps_c (ASC)'                  : '_plot_smoothed_moment_eps_c_ASC',
        #                       'smoothed moment / eps_c (raw)'                  : '_plot_smoothed_moment_eps_c_raw',
        #
        #                       'analytical bending stiffness'                   :  '_plot_analytical_bending_stiffness'
    }

    default_plot_template = 'force / deflection (displacement gauge)'

    def _plot_analytical_bending_stiffness(self,
                                           axes,
                                           color='red',
                                           linewidth=1.,
                                           linestyle='--'):
        '''plot the analytical bending stiffness of the beam (3 point bending)
        '''
        t = self.thickness
        w = self.width
        L = self.length

        # composite E-modulus
        #
        E_c = self.E_c

        # moment of inertia
        #
        I_yy = t**3 * w / 12.

        delta_11 = L**3 / 48 / E_c / I_yy
        K_linear = 1 / delta_11  # [MN/m] bending stiffness with respect to a force applied at center of the beam
        w_linear = 2 * np.array([0., 1.])
        F_linear = 2 * np.array([0., K_linear])
        axes.plot(w_linear, F_linear, linestyle='--')

    def _plot_force_machine_displacement_wo_elast(self,
                                                  axes,
                                                  color='blue',
                                                  linewidth=1.,
                                                  linestyle='-'):

        # get the index of the maximum stress
        #
        max_force_idx = argmax(self.F_raw)

        # get only the ascending branch of the response curve
        #
        f_asc = self.F_raw[:max_force_idx + 1]
        w_asc = self.w_wo_elast[:max_force_idx + 1]
        axes.plot(w_asc,
                  f_asc,
                  color=color,
                  linewidth=linewidth,
                  linestyle=linestyle)
        # plot analytical bending stiffness
        #
        w_linear = 2 * np.array([0., 1.])
        F_linear = 2 * np.array([0., self.K_bending_elast])
        axes.plot(w_linear, F_linear, linestyle='--')
#        xkey = 'deflection [mm]'
#        ykey = 'force [kN]'
#        axes.set_xlabel('%s' % (xkey,))
#        axes.set_ylabel('%s' % (ykey,))

    def _plot_force_machine_displacement_wo_elast_interpolated(
            self, axes, color='green', linewidth=1., linestyle='-'):

        # get the index of the maximum stress
        #
        max_force_idx = argmax(self.F_raw)

        # get only the ascending branch of the response curve
        #
        f_asc = self.F_raw[:max_force_idx + 1]
        w_asc = np.copy(self.w_wo_elast[:max_force_idx + 1])

        # interpolate the starting point of the center deflection curve based on the slope of the curve
        # (remove offset in measured displacement where there is still no force measured)
        #
        idx_10 = np.where(f_asc > f_asc[-1] * 0.10)[0][0]
        idx_8 = np.where(f_asc > f_asc[-1] * 0.08)[0][0]
        f8 = f_asc[idx_8]
        f10 = f_asc[idx_10]
        w8 = w_asc[idx_8]
        w10 = w_asc[idx_10]
        m = (f10 - f8) / (w10 - w8)
        delta_w = f8 / m
        w0 = w8 - delta_w * 0.9
        #         print 'w0', w0
        f_asc_interpolated = np.hstack([0., f_asc[idx_8:]])
        w_asc_interpolated = np.hstack([w0, w_asc[idx_8:]])
        #         print 'type( w_asc_interpolated )', type(w_asc_interpolated)
        w_asc_interpolated -= float(w0)
        axes.plot(w_asc_interpolated,
                  f_asc_interpolated,
                  color=color,
                  linewidth=linewidth,
                  linestyle=linestyle)

        #        fw_arr = np.hstack([f_asc_interpolated[:, None], w_asc_interpolated[:, None]])
        #        print 'fw_arr.shape', fw_arr.shape
        #        np.savetxt('BT-3PT-12c-6cm-TU_f-w_interpolated.csv', fw_arr, delimiter=';')

        # plot analytical bending stiffness
        #
        w_linear = 2 * np.array([0., 1.])
        F_linear = 2 * np.array([0., self.K_bending_elast])
        axes.plot(w_linear, F_linear, linestyle='--')

    def _plot_force_machine_displacement_wo_elast_analytical_offset(
            self, axes, color='green', linewidth=1., linestyle='-'):

        # get the index of the maximum stress
        #
        max_force_idx = argmax(self.F_raw)

        # get only the ascending branch of the response curve
        #
        f_asc = self.F_raw[:max_force_idx + 1]
        w_asc = np.copy(self.w_wo_elast[:max_force_idx + 1])

        M_asc = f_asc * self.length / 4.
        eps_c_asc = self.eps_c_raw[:max_force_idx + 1]

        t = self.thickness
        w = self.width

        # coposite E-modulus
        #
        E_c = self.E_c

        # resistant moment
        #
        W_yy = t**2 * w / 6.

        K_I_analytic = W_yy * E_c  # [MN/m] bending stiffness with respect to center moment
        K_I_analytic *= 1000.  # [kN/m] bending stiffness with respect to center moment

        # interpolate the starting point of the center deflection curve based on the slope of the curve
        # (remove offset in measured displacement where there is still no force measured)
        #
        idx_lin = np.where(M_asc <= K_I_analytic * eps_c_asc)[0][0]
        idx_lin = int(idx_lin * 0.7)
        #         idx_lin = 50

        #        idx_lin = np.where(M_asc - M_asc[0] / eps_c_asc <= 0.90 * K_I_analytic)[0][0]
        print 'idx_lin', idx_lin
        print 'F_asc[idx_lin]', f_asc[idx_lin]
        print 'M_asc[idx_lin]', M_asc[idx_lin]
        print 'w_asc[idx_lin]', w_asc[idx_lin]

        w_lin_epsc = w_asc[idx_lin]

        w_lin_analytic = f_asc[idx_lin] / self.K_bending_elast

        f_asc_offset_analytic = f_asc[idx_lin:]
        w_asc_offset_analytic = w_asc[idx_lin:]
        w_asc_offset_analytic -= np.array([w_lin_epsc])
        w_asc_offset_analytic += np.array([w_lin_analytic])

        axes.plot(w_asc_offset_analytic,
                  f_asc_offset_analytic,
                  color=color,
                  linewidth=linewidth,
                  linestyle=linestyle)
        # plot analytical bending stiffness
        #
        w_linear = 2 * np.array([0., 1.])
        F_linear = 2 * np.array([0., self.K_bending_elast])
        axes.plot(w_linear, F_linear, linestyle='--')

    def _plot_force_machine_displacement(self,
                                         axes,
                                         color='black',
                                         linewidth=1.,
                                         linestyle='-'):
        xdata = self.w_raw
        ydata = self.F_raw
        axes.plot(xdata,
                  ydata,
                  color=color,
                  linewidth=linewidth,
                  linestyle=linestyle)
        #        xkey = 'deflection [mm]'
        #        ykey = 'force [kN]'
        #        axes.set_xlabel('%s' % (xkey,))
        #        axes.set_ylabel('%s' % (ykey,))
        # plot analytical bending stiffness
        #
        w_linear = 2 * np.array([0., 1.])
        F_linear = 2 * np.array([0., self.K_bending_elast])
        axes.plot(w_linear, F_linear, linestyle='--')

    def _plot_force_gauge_displacement_with_analytical_offset(
            self, axes, color='black', linewidth=1., linestyle='-'):

        # skip the first values (= first seconds of testing)
        # and start with the analytical bending stiffness instead to avoid artificial offset of F-w-diagram
        #
        #         w_max = np.max(self.w_ASC)
        #         cut_idx = np.where(self.w_ASC > 0.001 * w_max)[0]

        cut_idx = np.where(self.w_ASC > 0.01)[0]

        print 'F_cr ', self.F_cr
        #         cut_idx = np.where(self.F_ASC > 0.6 * self.F_cr)[0]

        print 'cut_idx', cut_idx[0]
        print 'w_ASC[cut_idx[0]]', self.w_ASC[cut_idx[0]]
        xdata = np.copy(self.w_ASC[cut_idx])
        ydata = np.copy(self.F_ASC[cut_idx])

        # specify offset if force does not start at the origin with value 0.
        F_0 = ydata[0]
        print 'F_0 ', F_0
        offset_w = F_0 / self.K_bending_elast
        xdata -= xdata[0]
        xdata += offset_w

        f_asc_interpolated = np.hstack([0, ydata])
        w_asc_interpolated = np.hstack([0, xdata])

        #        fw_arr = np.hstack([f_asc_interpolated[:, None], w_asc_interpolated[:, None]])
        #        print 'fw_arr.shape', fw_arr.shape
        #        np.savetxt('BT-3PT-6c-2cm-TU_f-w_interpolated.csv', fw_arr, delimiter=';')

        xdata = self.w_raw
        ydata = self.F_raw
        axes.plot(xdata,
                  ydata,
                  color='blue',
                  linewidth=linewidth,
                  linestyle=linestyle)

        axes.plot(w_asc_interpolated,
                  f_asc_interpolated,
                  color=color,
                  linewidth=linewidth,
                  linestyle=linestyle)
        #        xkey = 'deflection [mm]'
        #        ykey = 'force [kN]'
        #        axes.set_xlabel('%s' % (xkey,))
        #        axes.set_ylabel('%s' % (ykey,))
        # plot analytical bending stiffness
        #
        w_linear = 2 * np.array([0., 1.])
        F_linear = 2 * np.array([0., self.K_bending_elast])
        axes.plot(w_linear, F_linear, linestyle='--')

    def _plot_force_gauge_displacement(self,
                                       axes,
                                       offset_w=0.,
                                       color='black',
                                       linewidth=1.,
                                       linestyle='-'):
        xdata = self.w_ASC
        ydata = self.F_ASC

        # specify offset if force does not start at the origin
        xdata += offset_w

        axes.plot(xdata,
                  ydata,
                  color=color,
                  linewidth=linewidth,
                  linestyle=linestyle)
        #        xkey = 'deflection [mm]'
        #        ykey = 'force [kN]'
        #        axes.set_xlabel('%s' % (xkey,))
        #        axes.set_ylabel('%s' % (ykey,))

        #        fw_arr = np.hstack([xdata[:, None], ydata[:, None]])
        #        print 'fw_arr.shape', fw_arr.shape
        #        np.savetxt('BT-3PT-6c-2cm-TU-80cm-V3_f-w_asc.csv', fw_arr, delimiter=';')

        # plot analytical bending stiffness
        #
        w_linear = 2 * np.array([0., 1.])
        F_linear = 2 * np.array([0., self.K_bending_elast])
        axes.plot(w_linear, F_linear, linestyle='--')

    def _plot_smoothed_force_gauge_displacement(self, axes):

        # get the index of the maximum stress
        #
        max_force_idx = argmax(self.F_ASC)

        # get only the ascending branch of the response curve
        #
        F_asc = self.F_ASC[:max_force_idx + 1]
        w_asc = self.w_ASC[:max_force_idx + 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)

    def _plot_force_gauge_displacement_interpolated(self,
                                                    axes,
                                                    color='green',
                                                    linewidth=1.,
                                                    linestyle='-'):
        '''get only the ascending branch of the meassured load-displacement curve)'''

        # get the index of the maximum stress
        #
        max_force_idx = argmax(self.F_ASC)

        # get only the ascending branch of the response curve
        #
        f_asc = self.F_ASC[:max_force_idx + 1]
        w_asc = self.w_ASC[:max_force_idx + 1]

        # interpolate the starting point of the center deflection curve based on the slope of the curve
        # (remove offset in measured displacement where there is still no force measured)
        #
        idx_10 = np.where(f_asc > f_asc[-1] * 0.10)[0][0]
        idx_8 = np.where(f_asc > f_asc[-1] * 0.08)[0][0]
        f8 = f_asc[idx_8]
        f10 = f_asc[idx_10]
        w8 = w_asc[idx_8]
        w10 = w_asc[idx_10]
        m = (f10 - f8) / (w10 - w8)
        delta_w = f8 / m
        w0 = w8 - delta_w * 0.9
        print 'w0', w0

        f_asc_interpolated = np.hstack([0., f_asc[idx_8:]])
        w_asc_interpolated = np.hstack([w0, w_asc[idx_8:]])
        print 'type( w_asc_interpolated )', type(w_asc_interpolated)
        w_asc_interpolated -= float(w0)

        #        w_offset = f_asc[idx_10] / self.K_bending_elast
        #        f_asc_interpolated = np.hstack([0., f_asc[ idx_10: ]])
        #        w_asc_interpolated = np.hstack([0, w_asc[ idx_10: ] - w_asc[idx_10] + w_offset])

        axes.plot(w_asc_interpolated,
                  f_asc_interpolated,
                  color=color,
                  linewidth=linewidth,
                  linestyle=linestyle)

        # plot analytical bending stiffness
        #
        w_linear = 2 * np.array([0., 1.])
        F_linear = 2 * np.array([0., self.K_bending_elast])
        axes.plot(w_linear, F_linear, linestyle='--')

    def _plot_smoothed_force_machine_displacement_wo_elast(self, axes):

        # get the index of the maximum stress
        #
        max_force_idx = argmax(self.F_raw)

        # get only the ascending branch of the response curve
        #
        F_asc = self.F_raw[:max_force_idx + 1]
        w_asc = self.w_wo_elast[:max_force_idx + 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)

        # plot analytical bending stiffness
        #
        w_linear = 2 * np.array([0., 1.])
        F_linear = 2 * np.array([0., self.K_bending_elast])
        axes.plot(w_linear, F_linear, linestyle='--')


#        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_moment_eps_c_ASC(self, axes):
        xkey = 'compressive strain [1*E-3]'
        ykey = 'moment [kNm]'
        xdata = self.eps_c_ASC
        ydata = self.M_ASC
        axes.set_xlabel('%s' % (xkey, ))
        axes.set_ylabel('%s' % (ykey, ))
        axes.plot(xdata, ydata)
        # plot stiffness in uncracked state
        t = self.thickness
        w = self.width
        # composite E-modulus
        #
        E_c = self.E_c

        # resistant moment
        #
        W_yy = t**2 * w / 6.

        max_M = np.max(self.M_raw)

        K_linear = W_yy * E_c  # [MN/m] bending stiffness with respect to center moment
        K_linear *= 1000.  # [kN/m] bending stiffness with respect to center moment
        w_linear = np.array([0., max_M / K_linear])
        M_linear = np.array([0., max_M])
        axes.plot(w_linear, M_linear, linestyle='--')

    def _plot_moment_eps_c_raw(self,
                               axes,
                               color='black',
                               linewidth=1.5,
                               linestyle='-'):
        xkey = 'compressive strain [1*E-3]'
        ykey = 'moment [kNm]'
        xdata = self.eps_c_raw
        ydata = self.M_raw
        axes.set_xlabel('%s' % (xkey, ))
        axes.set_ylabel('%s' % (ykey, ))
        axes.plot(xdata,
                  ydata,
                  color=color,
                  linewidth=linewidth,
                  linestyle=linestyle)
        # plot stiffness in uncracked state
        t = self.thickness
        w = self.width
        # composite E-modulus
        #
        E_c = self.E_c

        # resistant moment
        #
        W_yy = t**2 * w / 6.

        max_M = np.max(self.M_raw)

        K_linear = W_yy * E_c  # [MN/m] bending stiffness with respect to center moment
        K_linear *= 1000.  # [kN/m] bending stiffness with respect to center moment
        w_linear = np.array([0., max_M / K_linear])
        M_linear = np.array([0., max_M])
        axes.plot(w_linear, M_linear, linestyle='--')

    n_fit_window_fraction = Float(0.1)

    smoothed_M_eps_c_ASC = Property(depends_on='input_change')

    @cached_property
    def _get_smoothed_M_eps_c_ASC(self):
        # get the index of the maximum stress
        max_idx = argmax(self.M_ASC)
        # get only the ascending branch of the response curve
        m_asc = self.M_ASC[:max_idx + 1]
        eps_c_asc = self.eps_c_ASC[:max_idx + 1]
        n_points = int(self.n_fit_window_fraction * len(eps_c_asc))
        m_smoothed = smooth(m_asc, n_points, 'flat')
        eps_c_smoothed = smooth(eps_c_asc, n_points, 'flat')
        return m_smoothed, eps_c_smoothed

    smoothed_eps_c_ASC = Property

    def _get_smoothed_eps_c_ASC(self):
        return self.smoothed_M_eps_c_ASC[1]

    smoothed_M_ASC = Property

    def _get_smoothed_M_ASC(self):
        return self.smoothed_M_eps_c_ASC[0]

    def _plot_smoothed_moment_eps_c_ASC(self, axes):
        axes.plot(self.smoothed_eps_c_ASC,
                  self.smoothed_M_ASC,
                  color='blue',
                  linewidth=2)

    smoothed_M_eps_c_raw = Property(depends_on='input_change')

    @cached_property
    def _get_smoothed_M_eps_c_raw(self):
        # get the index of the maximum stress
        max_idx = argmax(self.M_raw)
        # get only the ascending branch of the response curve
        m_asc = self.M_raw[:max_idx + 1]
        eps_c_asc = self.eps_c_raw[:max_idx + 1]
        n_points = int(self.n_fit_window_fraction * len(eps_c_asc))
        m_smoothed = smooth(m_asc, n_points, 'flat')
        eps_c_smoothed = smooth(eps_c_asc, n_points, 'flat')
        return m_smoothed, eps_c_smoothed

    smoothed_eps_c_raw = Property

    def _get_smoothed_eps_c_raw(self):
        return self.smoothed_M_eps_c_raw[1]

    smoothed_M_raw = Property

    def _get_smoothed_M_raw(self):
        return self.smoothed_M_eps_c_raw[0]

    def _plot_smoothed_moment_eps_c_raw(self, axes):
        axes.plot(self.smoothed_eps_c_raw,
                  self.smoothed_M_raw,
                  color='blue',
                  linewidth=2)

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

    traits_view = View(VGroup(
        Group(Item('length', format_str="%.3f"),
              Item('width', format_str="%.3f"),
              Item('thickness', 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)
示例#28
0
class Model(HasTraits):

    test_xdata = Array
    test_ydata = Array
    sV0 = Float(auto_set=False, enter_set=True, params=True)
    m = Float(auto_set=False, enter_set=True, params=True)
    w_min = Float(auto_set=False, enter_set=True, params=True)
    w_max = Float(auto_set=False, enter_set=True, params=True)
    w_pts = Int(auto_set=False, enter_set=True, params=True)
    n_int = Int(auto_set=False, enter_set=True, params=True)
    w2_min = Float(auto_set=False, enter_set=True, params=True)
    w2_max = Float(auto_set=False, enter_set=True, params=True)
    w2_pts = Int(auto_set=False, enter_set=True, params=True)
    tau_scale = Float(auto_set=False, enter_set=True, params=True)
    tau_loc = Float(auto_set=False, enter_set=True, params=True)
    tau_shape = Float(auto_set=False, enter_set=True, params=True)
    Ef = Float(auto_set=False, enter_set=True, params=True)
    lm = Float(auto_set=False, enter_set=True, params=True)
    V_f = Float(.01, params=True)
    r = Float(3.5e-3, params=True)

    w = Property(Array)

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

    w2 = Property(Array)

    def _get_w2(self):
        return np.linspace(self.w2_min, self.w2_max, self.w2_pts)

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

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

    model_rand = Property(Array)

    def _get_model_rand(self):
        cb = CBClampedRandXi(pullout=False)
        spirrid = SPIRRID(q=cb, sampling_type='LHS')
        sV0 = self.sV0
        tau_scale = self.tau_scale
        V_f = 1.0
        r = 3.5e-3
        m = self.m
        tau = RV('gamma',
                 shape=self.tau_shape,
                 scale=tau_scale,
                 loc=self.tau_loc)
        n_int = self.n_int
        w = self.w
        lm = 1000.
        spirrid.eps_vars = dict(w=w)
        spirrid.theta_vars = dict(tau=tau,
                                  E_f=self.Ef,
                                  V_f=V_f,
                                  r=r,
                                  m=m,
                                  sV0=sV0,
                                  lm=lm)
        spirrid.n_int = n_int
        sigma_c = spirrid.mu_q_arr / self.r**2
        return sigma_c

    model_extrapolate = Property(Array)

    def _get_model_extrapolate(self):
        cb = CBClampedRandXi(pullout=False)
        spirrid = SPIRRID(q=cb, sampling_type='LHS')
        sV0 = self.sV0
        V_f = 1.0
        r = 3.5e-3
        m = self.m
        tau = RV('gamma',
                 shape=self.tau_shape,
                 scale=self.tau_scale,
                 loc=self.tau_loc)
        n_int = self.n_int
        w = self.w2
        lm = self.lm
        spirrid.eps_vars = dict(w=w)
        spirrid.theta_vars = dict(tau=tau,
                                  E_f=self.Ef,
                                  V_f=V_f,
                                  r=r,
                                  m=m,
                                  sV0=sV0,
                                  lm=lm)
        spirrid.n_int = n_int
        sigma_c = spirrid.mu_q_arr / self.r**2
        return sigma_c
示例#29
0
class TSCrackLoc( TStepper ):
    '''Modified time stepper with adjusted predictor and corrector.
    
    The management of the shared variable omega_0 is done before
    calling the standard corrector predictor. The strain state
    at the x = 0 is evaluated and provided to the MATS1DCrackLoc
    material model in order to evaluate the next trial damage state.
    
    During the corrpred call, the material model then uses these
    variables during the stress and stiffness integration.
    '''
    mats_eval = Property( Instance( MATS1DCrackLoc ) )
    def _get_mats_eval( self ):
        return self.subdomains[0].fets_eval.mats_eval.mats_phase1

    on_update = Callable

    fe_grid = Property( Instance( FEGrid ) )
    @cached_property
    def _get_fe_grid( self ):
        # get the single subgrid in the first subdomain.
        return self.subdomains[0].fe_subgrids[0]

    concrete_dofs = Property( Array( Float ) )
    @cached_property
    def _get_concrete_dofs( self ):
        # get the dofs associated with the bottom layer - concrete
        return self.fe_grid[:, 0, :, 0].dofs[:, :, 0]

    # specialize the 
    #
    def eval( self, step_flag, U_k, d_U, t_n, t_n1 ):

        print 'concrete dofs'
        print self.concrete_dofs

        if step_flag == 'corrector':

            # when in the corrector - switch the trial to accepted
            #
            self.mats_eval.update_state()
            self.on_update()

            #print 'E', self.subdomains[0].dots.state_array

        #----------------------------------
        # calculate the epxilon_0 at x = 0 
        #----------------------------------
        fe_grid = self.subdomains[0]
        # pick the first element
        elem_0 = fe_grid.elements[0]
        fets_eval = fe_grid.fets_eval
        # get the displacement vector in the first element
        u = U_k[ elem_0.get_dof_map() ]
        # and the coordinates
        # set the spatial context
        self.sctx.X = elem_0.get_X_mtx()
        self.sctx.x = elem_0.get_x_mtx()
        self.sctx.loc = array( [0], dtype = 'float_' )
        # get epsilon
        eps = fets_eval.get_eps_eng( self.sctx, u )
        # set the trial state for the obtained strain
        self.mats_eval.set_trial_state( eps )

        print 'BEGIN TS'
        # run the standard calculation
        return super( TSCrackLoc, self ).eval( step_flag, U_k, d_U, t_n, t_n1 )
示例#30
0
class GenDistr( HasTraits ):

    x_values = Array
    pdf_values = Array
    cdf_values = Array

    def check( self ):
        if len( self.x_values ) == 0:
            raise ValueError, 'x_values not defined'
        if len( self.pdf_values ) == 0 and len( self.cdf_values ) == 0:
            raise ValueError, 'either pdf_values or cdf_values have to be given'
        else:
            pass

    cached_pdf = Property( depends_on = 'x_values, pdf_values, cdf_values' )
    @cached_property
    def _get_cached_pdf( self ):
        if len( self.pdf_values ) == 0:
            cdf_line = MFnLineArray( xdata = self.x_values, ydata = self.cdf_values )
            pdf = []
            for x in self.x_values:
                pdf.append( cdf_line.get_diff( x ) )
            return MFnLineArray( xdata = self.x_values, ydata = pdf )
        else:
            return MFnLineArray( xdata = self.x_values, ydata = self.pdf_values )

    def pdf( self, x ):
        self.check()
        return self.cached_pdf.get_values( x )

    cached_cdf = Property( depends_on = 'x_values, pdf_values, cdf_values' )
    @cached_property
    def _get_cached_cdf( self ):
        if len( self.cdf_values ) == 0:
            cdf = []
            for i in range( len( self.x_values ) ):
                cdf.append( np.trapz( self.pdf_values[:i], self.x_values[:i] ) )
            return MFnLineArray( xdata = self.x_values, ydata = cdf )
        else:
            return MFnLineArray( xdata = self.x_values, ydata = self.cdf_values )

    def cdf( self, x ):
        self.check()
        return self.cached_cdf.get_values( x )

    def sf( self, x ):
        self.check()
        return 1 - self.cdf( x )

    def ppf( self, x ):
        self.check()
        if len( self.cdf_values ) != 0:
            xx, cdf = self.x_values, self.cdf_values
        else:
            xx, cdf = self.x_values, self.cdf( self.x_values )
        ppf_mfn_line = MFnLineArray( xdata = cdf, ydata = xx )
        return ppf_mfn_line.get_values( x )

    def stats( self, str ):
        self.check()
        if str == 'm':
            return self.mean()
        elif str == 'v':
            return self.var()
        elif str == 'mv':
            return ( self.mean(), self.var() )

    def median( self ):
        self.check()
        return self.ppf( 0.5 )

    def mean( self ):
        self.check()
        if len( self.pdf_values ) != 0:
            x, pdf = self.x_values, self.pdf_values
        else:
            x, pdf = self.x_values, self.pdf( self.x_values )
        return np.trapz( x * pdf , x )

    def var( self ):
        self.check()
        if len( self.pdf_values ) != 0:
            x, pdf = self.x_values, self.pdf_values
        else:
            x, pdf = self.x_values, self.pdf( self.x_values )
        mu = self.mean()
        return np.trapz( ( x ** 2 - mu ) * pdf , x )

    def std( self ):
        self.check()
        return np.sqrt( self.var() )