Example #1
0
    class CBClampedFiberSP(CBClampedFiber):
        '''
        stress profile for a crack bridged by a short fiber with constant
        frictional interface to the matrix; clamped fiber end
        '''

        x = Float(0.0,
                  auto_set=False,
                  enter_set=True,
                  input=True,
                  distr=['uniform'],
                  desc='distance from crack')

        x_label = Str('position [mm]')
        y_label = Str('force [N]')

        C_code = Str('')

        def __call__(self, w, x, tau, l, D_f, E_f, theta, xi, phi, Ll, Lr):

            T = tau * phi * D_f * pi

            q = super(CBClampedFiberSP, self).__call__(w, tau, l, D_f, E_f,
                                                       theta, xi, phi, Ll, Lr)
            q_x = q * Heaviside(l / 2. - abs(x)) + (
                q - T * (abs(x) - l / 2.)) * Heaviside(abs(x) - l / 2.)
            q_x = q_x * Heaviside(x + Ll) * Heaviside(Lr - x)
            q_x = q_x * Heaviside(q_x)

            return q_x
Example #2
0
class POClampedFiber(RF):
    '''
    Pullout of fiber from a stiff matrix;
    stress criterion for debonding, fixed fiber end
    '''

    implements(IRF)

    title = Str('pullout - clamped fiber with constant friction')
    image = Image('pics/cb_short_fiber.jpg', size=2)

    xi = Float(0.0179, auto_set=False, enter_set=True, input=True,
                distr=['weibull_min', 'uniform'])

    tau = Float(2.5, auto_set=False, enter_set=True, input=True,
                distr=['uniform', 'norm'])

    l = Float(0.0, auto_set=False, enter_set=True, input=True,
              distr=['uniform'], desc='free length')

    D_f = Float(26e-3, auto_set=False, input=True,
              enter_set=True, distr=['uniform', 'weibull_min'])

    E_f = Float(72.0e3, auto_set=False, enter_set=True, input=True,
                  distr=['uniform'])

    theta = Float(0.01, auto_set=False, enter_set=True, input=True,
                  distr=['uniform', 'norm'], desc='slack')

    phi = Float(1., auto_set=False, enter_set=True, input=True,
                  distr=['uniform', 'norm'], desc='bond quality')

    L = Float(1., auto_set=False, enter_set=True, input=True,
              distr=['uniform'], desc='embedded length')

    u = Float(auto_set=False, enter_set=True,
               ctrl_range=(0.0, 0.02, 100))

    x_label = Str('displacement [mm]')
    y_label = Str('force [N]')

    C_code = Str('')

    def __call__(self, u, tau, l, D_f, E_f, theta, xi, phi, L):

        A = pi * D_f ** 2 / 4.
        l = l * (1 + theta)
        u = u - theta * l
        T = tau * phi * D_f * pi
        q = (-l * T + sqrt(l ** 2 * T ** 2 + 2 * u * H(u) * E_f * A * T))

        # displacement at which the debonding is finished
        u0 = L * T * (L + 2 * l) / 2 / E_f / A
        q = q * H(T * L - q) + (T * L + (u - u0) / (l + L) * A * E_f) * H(q - T * L)

            # ----------------------------------
        q = q * H(A * E_f * xi - q)
        return q
Example #3
0
class RVModelView(ModelView):
    '''
    ModelView class for displaying the table of parameters and
    set the distribution parameters of random variables
    '''

    title = Str('randomization setup')

    model = Instance(SPIRRID)

    rv_list = List(RIDVariable)

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

    selected_var = Instance(RIDVariable)

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

    title = Str('random variable editor')

    selected_var = Instance(RIDVariable)

    traits_view = View(VSplit(
        HGroup(
            Item('rv_list', editor=rv_list_editor, show_label=False),
            id='rid.tview.randomization.rv',
            label='Model variables',
        ),
        HGroup(
            Item('selected_var@', show_label=False, resizable=True),
            id='rid.tview.randomization.distr',
            label='Distribution',
        ),
        scrollable=True,
        id='rid.tview.tabs',
        dock='tab',
    ),
                       title='RANDOM VARIABLES',
                       id='rid.ridview',
                       dock='tab',
                       resizable=True,
                       height=1.0,
                       width=1.0)
Example #4
0
class fiber_tt_2p(RF):
    r'''
Response Function with two-parameters.
======================================
    
The function describes a linear dependency with a coefficient :math:`\lambda` 
up to the threshold :math:`\xi` and zero value beyond the threshold: 
    
..    math::
       q( \varepsilon; \theta, \lambda ) = \lambda \varepsilon H( \xi - \varepsilon )

where the variables :math:`\lambda=` stiffness parameter and :math:`\xi=` 
breaking strain are considered random and normally distributed. The function 
:math:`H(\eta)` represents the Heaviside function with values 0 for 
:math:`\eta < 0` and 1 for :math:`\eta > 0`.
   
    '''
    implements(IRF)

    title = Str('brittle filament')

    def __call__(self, e, la, xi):
        ''' Response function of a single fiber '''
        return la * e * Heaviside(xi - e)

    cython_code = '''
            # Computation of the q( ... ) function
            if eps < 0 or eps > xi:
                q = 0.0
            else:
                q = la * eps
            '''

    c_code = '''
class ConstantFrictionAndFreeLength(RF):
    '''
    '''

    implements(IRF)

    title = Str('pull-out with constant friction and free length ')

    tau = Float(8, auto_set=False, enter_set=True, distr=['uniform'])

    # free length
    l = Float(1, auto_set=False, enter_set=True, distr=['uniform', 'norm'])

    E = Float(70e9, auto_set=False, enter_set=True, distr=['uniform'])

    A = Float(5.30929158457e-10,
              auto_set=False,
              enter_set=True,
              distr=['uniform', 'weibull_min'])

    # waviness in strains
    slack = Float(0.1, auto_set=False, enter_set=True, distr=['uniform'])

    u = Float(auto_set=False, enter_set=True, ctrl_range=(0.0, 1.0, 10))

    def __call__(self, u, tau, l, E, A, slack):
        return -l * (1 + slack) * tau * Heaviside(u - l * (slack)) + \
                + sqrt((l * (1 + slack) * tau) ** 2 \
                + 2 * E * A * (u - (l * slack)) * Heaviside(u - l * (slack)))
class RFSumParams(RF):

    implements(IRF)

    title = Str('RFSumParams')

    a = Float(1, auto_set=False, enter_set=True,
                distr=['uniform'],
                loc=1.0, scale=0.1, shape=0.1)

    b = Float(1, auto_set=False, enter_set=True,
                distr=['uniform'],
                loc=1.0, scale=0.1, shape=0.1)

    c = Float(1, auto_set=False, enter_set=True,
                distr=['uniform'],
                loc=1.0, scale=0.1, shape=0.1)

    d = Float(1, auto_set=False, enter_set=True,
                distr=['uniform'],
                loc=1.0, scale=0.1, shape=0.1)

    ee = Float(1, auto_set=False, enter_set=True,
                distr=['uniform'],
                loc=1.0, scale=0.1, shape=0.1)

    f = Float(1, auto_set=False, enter_set=True,
                distr=['uniform'],
                loc=1.0, scale=0.1, shape=0.1)

    g = Float(1, auto_set=False, enter_set=True,
                distr=['uniform'],
                loc=1.0, scale=0.1, shape=0.1)

    h = Float(1, auto_set=False, enter_set=True,
                distr=['uniform'],
                loc=1.0, scale=0.1, shape=0.1)

    i = Float(1, auto_set=False, enter_set=True,
                distr=['uniform'],
                loc=1.0, scale=0.1, shape=0.1)

    eps = Float(0, ctrl_range=(0, 0.2, 10))

    C_code = '''
            // Computation of the q( ... ) function
            //q = ( cos( a ) + cos( b ) + cos( c ) + cos( d ) + cos( ee ) + cos( f ) + cos( g ) + cos( h ) + cos( i )) * eps;
             q = ( ( a ) + ( b ) + ( c ) + ( d ) + ( ee ) + ( f ) + ( g ) + ( h ) + ( i )) * eps;
        '''

    def __call__(self, eps, a, b, c, d, ee, f, g, h, i):
        '''
        Implements the response function with arrays as variables.
        first extract the variable discretizations from the orthogonal grid.
        '''
        # broadcast eps also in the xi - dimension 
        # (by multiplying with array containing ones with the same shape as xi )
        #
        # return ( cos( a ) + cos( b ) + cos( c ) + cos( d ) + cos( ee ) + cos( f ) + cos( g ) + cos( h ) + cos( i ) ) * eps
        return ((a) + (b) + (c) + (d) + (ee) + (f) + (g) + (h) + (i)) * eps;
Example #7
0
class S(YMBSource):

    yarn_type = Enum('__TEST__',
                     changed_source=True,
                     editor=EnumEditor(values=['__TEST__']))
    root_dir = Str('')

    view = View(Item('yarn_type'))
Example #8
0
    class Preprocessor(HasTraits):
        title = Str('preprocessor')
        prep_components = Property(List)

        def _get_prep_components(self):
            rf_view = RFModelView(model=default_rf, child=spirrid)
            rf_view._redraw()
            rv_view = RVModelView(model=spirrid)
            return [rf_view, rv_view]
class ConstantFrictionFreeLengthFiniteFiber(RF):
    '''
    '''

    implements(IRF)

    title = Str('pull-out with constant friction and free length ')

    tau = Float(0.5e6,
                auto_set=False,
                enter_set=True,
                distr=['uniform', 'weibull_min', 'norm'])

    # free length
    l = Float(0.01, auto_set=False, enter_set=True, distr=['uniform', 'norm'])

    E = Float(70e9, auto_set=False, enter_set=True, distr=['uniform'])

    A = Float(5.30929158457e-10,
              auto_set=False,
              enter_set=True,
              distr=['uniform', 'weibull_min'])

    # waviness in strains
    slack = Float(0.0, auto_set=False, enter_set=True, distr=['uniform'])

    # embedded length
    L = Float(0.03, auto_set=False, enter_set=True, distr=['uniform'])

    # breking stress
    sigma_fu = Float(1200.e6,
                     auto_set=False,
                     enter_set=True,
                     distr=['uniform'])

    u = Float(auto_set=False, enter_set=True, ctrl_range=(0.0, 1.0, 10))

    #

    def __call__(self, u, tau, l, E, A, slack, L, sigma_fu):
        ''' method for evaluating the u-F diagram for
        pullout with constant friction at the interface and
        free fiber length sticking out of the matrix '''
        # defining tau as length dependent
        tau = tau * sqrt(4 * A * pi)
        # constitutive law for a pullout without free length
        q = ( -l * ( 1 + slack ) * tau * Heaviside( u / 2 - l * ( slack ) ) + \
                + sqrt( ( l * ( 1 + slack ) * tau ) ** 2 * Heaviside( u / 2 - l * ( slack ) ) \
                + 2 * E * A * ( u / 2 - ( l * slack ) ) * Heaviside( u / 2 - l * ( slack ) ) ) )

        # deformation of the free length added
        continuous = q * Heaviside( L - l - q / tau )\
                + ( L - l ) * tau * Heaviside( l + q / tau - L )

        # a check whether the fiber has reached the breaking stress
        return continuous * Heaviside(sigma_fu - continuous / A)
Example #10
0
class fiber_tt_2p(RF):
    '''Linear elastic, brittle filament.
    '''
    implements(IRF)

    title = Str('brittle filament')

    def __call__(self, e, la, xi):
        ''' Response function of a single fiber '''
        return la * e * Heaviside(xi - e)

    C_code = '''
Example #11
0
class CBEMClampedFiberStressSP(CBEMClampedFiberStress):
    '''
        stress profile for a crack bridged by a fiber with constant
        frictional interface to the matrix; clamped fiber end
        '''
    x = Float(0.0,
              auto_set=False,
              enter_set=True,
              input=True,
              distr=['uniform'],
              desc='distance from crack')

    x_label = Str('position [mm]')
    y_label = Str('force [N]')

    C_code = Str('')

    def __call__(self, w, x, tau, l, E_f, E_m, theta, xi, phi, Ll, Lr, V_f, r):
        T = 2. * tau * V_f / r
        q = super(CBEMClampedFiberStressSP,
                  self).__call__(w, tau, l, E_f, E_m, theta, xi, phi, Ll, Lr,
                                 V_f, r)
        # stress in the free length
        l = l * (1 + theta)
        q_l = q * H(l / 2 - abs(x))
        # stress in the part, where fiber transmits stress to the matrix
        q_e = (q - T / V_f * (abs(x) - l / 2.)) * H(abs(x) - l / 2.)
        # q_e = q_e * H(x + Ll) * H (Lr - x)

        # far field stress
        E_c = E_m * (1 - V_f) + E_f * V_f
        q_const = q * V_f * E_f / E_c

        # putting all parts together
        q_x = q_l + q_e
        q_x = np.maximum(q_x, q_const)
        return q_x
Example #12
0
class Reinforcement(HasTraits):
    '''common class for all reinforcement types'''
    label = Str('reinforcement')
    r = EitherType(klasses=[FloatType, RV])
    V_f = Float
    E_f = Float
    xi = EitherType(klasses=[FloatType, RV, WeibullFibers])
    tau = EitherType(klasses=[FloatType, RV])
    n_int = Int

    @on_trait_change('n_int')
    def check(self):
        if self.n_int < 50:
            print 'Warning: integration with', self.n_int, 'points might not be accurate enough'
            print 'a minimum of 50 integration points is recommended'
class CBEMClampedFiberSP(CBEMClampedFiber):
    '''
    stress profile for a crack bridged by a short fiber with constant
    frictional interface to the matrix; clamped fiber end
    '''

    x = Float(0.0,
              auto_set=False,
              enter_set=True,
              input=True,
              distr=['uniform'],
              desc='distance from crack')

    x_label = Str('position [mm]')
    y_label = Str('force [N]')

    C_code = Str('')

    def __call__(self, w, x, tau, l, A_r, E_f, A_m, E_m, theta, xi, phi, Ll,
                 Lr, Nf):

        D = sqrt(A_r * Nf / pi) * 2
        T = tau * phi * D * pi
        Km = A_m * E_m
        Kr = A_r * E_f

        q = super(CBEMClampedFiberSP,
                  self).__call__(w, tau, l, A_r, E_f, A_m, E_m, theta, xi, phi,
                                 Ll, Lr, Nf)
        q_x = q * H(l / 2. -
                    abs(x)) + (q - T * (abs(x) - l / 2.)) * H(abs(x) - l / 2.)
        # q_x = q_x * H(x + Ll) * H (Lr - x)
        a = q * Km / (T * (Km + Kr))
        q_const = (q - T * a)
        q_x = maximum(q_x, q_const)
        return q_x
Example #14
0
    class fiber_tt_5p_np(RF):
        ''' Response function of a single fiber '''
        implements(IRF)

        title = Str('brittle filament')

        def __call__(self, eps, lambd, xi, E_mod, theta, A):
            '''
            Implements the response function with arrays as variables.
            first extract the variable discretizations from the orthogonal grid.
            '''
            eps_ = (eps - theta * (1 + lambd)) / ((1 + theta) * (1 + lambd))

            eps_ *= Heaviside(eps_)
            eps_grid = eps_ * Heaviside(xi - eps_)
            q_grid = E_mod * A * eps_grid

            return q_grid
Example #15
0
class fiber_tt_2p(RF):
    '''Linear elastic, brittle filament.
    '''
    implements(IRF)

    title = Str('brittle filament')

    def __call__(self, e, la, xi):
        ''' Response function of a single fiber '''
        return la * e * Heaviside(xi - e)

    cython_code = '''
            # Computation of the q( ... ) function
            if eps < 0 or eps > xi:
                q = 0.0
            else:
                q = la * eps
            '''

    weave_code = '''
Example #16
0
    class fiber_tt_5p_ne(RF):
        ''' Response function of a single fiber '''
        implements(IRF)

        title = Str('brittle filament')

        def __call__(self, eps, lambd, xi, E_mod, theta, A):
            '''
            Implements the response function with arrays as variables.
            first extract the variable discretizations from the orthogonal grid.
            '''
            eps_ = ne.evaluate(
                "((eps - theta * (1 + lambd)) / ((1 + theta) * (1 + lambd)))")
            tmp = Heaviside_ne(eps_)
            eps_ = ne.evaluate('eps_*tmp')
            tmp = Heaviside_ne(ne.evaluate("(xi - eps_)"))
            eps_grid = ne.evaluate("eps_ * tmp")
            q_grid = ne.evaluate("E_mod * A * eps_grid")

            return q_grid
Example #17
0
class RFBase(RF):

    implements(IRF)

    title = Str('RFSumParams')

    a = Float(1,
              auto_set=False,
              enter_set=True,
              distr=['uniform'],
              loc=1.0,
              scale=0.1,
              shape=0.1)

    b = Float(1,
              auto_set=False,
              enter_set=True,
              distr=['uniform'],
              loc=1.0,
              scale=0.1,
              shape=0.1)

    c = Float(1,
              auto_set=False,
              enter_set=True,
              distr=['uniform'],
              loc=1.0,
              scale=0.1,
              shape=0.1)

    d = Float(1,
              auto_set=False,
              enter_set=True,
              distr=['uniform'],
              loc=1.0,
              scale=0.1,
              shape=0.1)

    ee = Float(1,
               auto_set=False,
               enter_set=True,
               distr=['uniform'],
               loc=1.0,
               scale=0.1,
               shape=0.1)

    f = Float(1,
              auto_set=False,
              enter_set=True,
              distr=['uniform'],
              loc=1.0,
              scale=0.1,
              shape=0.1)

    g = Float(1,
              auto_set=False,
              enter_set=True,
              distr=['uniform'],
              loc=1.0,
              scale=0.1,
              shape=0.1)

    h = Float(1,
              auto_set=False,
              enter_set=True,
              distr=['uniform'],
              loc=1.0,
              scale=0.1,
              shape=0.1)

    i = Float(1,
              auto_set=False,
              enter_set=True,
              distr=['uniform'],
              loc=1.0,
              scale=0.1,
              shape=0.1)

    k = Float(1,
              auto_set=False,
              enter_set=True,
              distr=['uniform'],
              loc=1.0,
              scale=0.1,
              shape=0.1)
Example #18
0
class RunTable(SimDBClass):
    '''Manage the combinations of exec configurations and randomization patterns.
    '''

    name = Str(simdb=True)

    memsize = Float(1e4, simdb=True)

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

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

    rf = Instance(IRF, simdb=True)

    config_list = List(config=True)

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

    config_dict = Property(depends_on='config_list')

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

    rand_list = List(rand=True)

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

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

        return array(run_table)

    exec_time_arr = Array
    n_int_arr = Array
    real_memsize_arr = Array

    calculate = Button()

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

    clear = Button()

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

    figure = Instance(Figure, transient=True)

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

    data_changed = Event(True)

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

    redraw = Button()

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

    redraw_in_window = Button()

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

    def plot(self, ax):

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    traits_view = View(Item('name'),
                       Item('memsize'),
                       Item('rf'),
                       Item('config_dict'),
                       Item('rand_list'),
                       HGroup(
                           Item('calculate', show_label=False),
                           Item('redraw', show_label=False),
                           Item('clear', show_label=False),
                           Item('redraw_in_window', show_label=False),
                       ),
                       Item('figure',
                            editor=MPLFigureEditor(),
                            resizable=True,
                            show_label=False),
                       buttons=['OK', 'Cancel'])
Example #19
0
class POShortFiber(RF):
    '''
    Pullout of fiber from a stiff matrix;
    stress criterion for debonding, free fiber end
    '''

    implements(IRF)

    title = Str('pullout - short fiber with constant friction')
    image = Image('pics/cb_short_fiber.jpg')

    xi = Float(0.0179,
               auto_set=False,
               enter_set=True,
               input=True,
               distr=['weibull_min', 'uniform'])

    E_f = Float(200e+3,
                auto_set=False,
                enter_set=True,
                desc='filament stiffness [N/mm2]',
                distr=['uniform', 'norm'],
                scale=210e3,
                shape=0)

    D_f = Float(0.3,
                auto_set=False,
                enter_set=True,
                desc='filament diameter [mm]',
                distr=['uniform', 'norm'],
                scale=0.5,
                shape=0)

    le = Float(8.5,
               auto_set=False,
               enter_set=True,
               desc='embedded lentgh [mm]',
               distr=['uniform'],
               scale=8.5,
               shape=0)

    L_f = Float(17.0,
                auto_set=False,
                enter_set=True,
                desc='fiber length [mm]',
                distr=['uniform', 'norm'],
                scale=30,
                shape=0)

    tau = Float(1.76,
                auto_set=False,
                enter_set=True,
                desc='bond shear stress [N/mm2]',
                distr=['norm', 'uniform'],
                scale=1.76,
                shape=0.5)

    f = Float(0.03,
              auto_set=False,
              enter_set=True,
              desc='snubbing coefficient',
              distr=['uniform', 'norm'],
              scale=0.05,
              shape=0)

    phi = Float(0.0,
                auto_set=False,
                enter_set=True,
                desc='inclination angle',
                distr=['sin2x', 'sin_distr'],
                scale=1.0,
                shape=0)

    l = Float(0.0,
              auto_set=False,
              enter_set=True,
              distr=['uniform'],
              desc='free length')

    theta = Float(0.01,
                  auto_set=False,
                  enter_set=True,
                  distr=['uniform', 'norm'],
                  desc='slack')

    u = Float(ctrl_range=(0, 0.01, 100), auto_set=False, enter_set=True)

    x_label = Str('displacement [mm]', enter_set=True, auto_set=False)
    y_label = Str('force [N]', enter_set=True, auto_set=False)

    C_code = ''

    def __call__(self, u, tau, L_f, D_f, E_f, le, phi, f, l, theta, xi):

        l = l * (1 + theta)
        u = u - theta * l
        T = tau * pi * D_f
        E = E_f
        A = D_f**2 / 4. * pi

        # debonding stage
        q_deb = -l * T + sqrt((l * T)**2 + 2 * E * A * T * u * H(u))

        # displacement at which debonding is finished
        u0 = le * T * (le + 2 * l) / 2 / E_f / A

        q_pull = le * T * ((u0 - u) / (le - u0) + 1)
        q = q_deb * H(le * T - q_deb) + q_pull * H(q_deb - le * T)

        # include inclination influence
        q = q * H(q) * e**(f * phi)

        # include breaking strain
        q = q * H(A * E_f * xi - q)
        return q

    def get_q_x(self, u, x, tau, L_f, D_f, E_f, z, phi, f, l, theta, xi):
        q = self.__call__(u, tau, L_f, D_f, E_f, z, phi, f, l, theta, xi)
        l = l * (1 + theta)
        T = tau * pi * D_f
        qfree = q
        qbond = q - T * (x - l)

        return qfree * H(l - x) + qbond * H(x - l)

    traits_view = View(Item('E_f', label='fiber E-mod'),
                       Item('D_f', label='fiber diameter'),
                       Item('f', label='snubbing coef.'),
                       Item('phi', label='inclination angle'),
                       Item('le', label='embedded length'),
                       Item('tau', label='frictional coef.'),
                       resizable=True,
                       scrollable=True,
                       height=0.8,
                       width=0.8,
                       buttons=[OKButton, CancelButton])
Example #20
0
    class CBClampedFiber(RF):
        '''
        Crack bridged by a short fiber with constant
        frictional interface to the matrix; clamped fiber end
        '''

        implements(IRF)

        title = Str('crack bridge - clamped fiber with constant friction')
        image = Image('pics/cb_short_fiber.jpg')

        xi = Float(0.0179,
                   auto_set=False,
                   enter_set=True,
                   input=True,
                   distr=['weibull_min', 'uniform'])

        tau = Float(2.5,
                    auto_set=False,
                    enter_set=True,
                    input=True,
                    distr=['uniform', 'norm'])

        l = Float(0.0,
                  auto_set=False,
                  enter_set=True,
                  input=True,
                  distr=['uniform'],
                  desc='free length')

        D_f = Float(26e-3,
                    auto_set=False,
                    input=True,
                    enter_set=True,
                    distr=['uniform', 'weibull_min'])

        E_f = Float(72.0e3,
                    auto_set=False,
                    enter_set=True,
                    input=True,
                    distr=['uniform'])

        theta = Float(0.01,
                      auto_set=False,
                      enter_set=True,
                      input=True,
                      distr=['uniform', 'norm'],
                      desc='slack')

        phi = Float(1.,
                    auto_set=False,
                    enter_set=True,
                    input=True,
                    distr=['uniform', 'norm'],
                    desc='bond quality')

        Ll = Float(1.,
                   auto_set=False,
                   enter_set=True,
                   input=True,
                   distr=['uniform'],
                   desc='embedded length - left')

        Lr = Float(.5,
                   auto_set=False,
                   enter_set=True,
                   input=True,
                   distr=['uniform'],
                   desc='embedded length - right')

        w = Float(auto_set=False,
                  enter_set=True,
                  input=True,
                  desc='crack width',
                  ctrl_range=(0, 0.01, 100))

        x_label = Str('crack opening [mm]')
        y_label = Str('force [N]')

        C_code = Str('')

        # TODO: case where Lmin is zero - gives a double sided pullout
        # should be one sided though
        def __call__(self, w, tau, l, D_f, E_f, theta, xi, phi, Ll, Lr):

            A = pi * D_f**2 / 4.
            Lmin = minimum(Ll, Lr)
            Lmax = maximum(Ll, Lr)

            Lmin = maximum(Lmin - l / 2., 0)
            Lmax = maximum(Lmax - l / 2., 0)

            l = minimum(Lr + Ll, l)

            l = l * (1 + theta)
            w = w - theta * l

            T = tau * phi * D_f * pi

            # double sided debonding
            l0 = l / 2.
            q0 = (-l0 * T + sqrt((l0 * T)**2 + w * Heaviside(w) * E_f * A * T))

            # displacement at which the debonding to the closer clamp is finished
            # the closer distance is min(L1,L2)

            w0 = Lmin * T * (Lmin + 2 * l0) / E_f / A

            # debonding from one side; the other side is clamped
            # equal to L1*T + one sided pullout with embedded length Lmax - Lmin and free length 2*L1 + l

            # force at w0
            Q0 = Lmin * T
            l1 = 2 * Lmin + l
            q1 = (-(l1) * T +
                  sqrt((l1 * T)**2 + 2 *
                       (w - w0) * Heaviside(w - w0) * E_f * A * T)) + Q0

            # displacement at debonding finished at both sides
            # equals a force of T*(larger clamp distance)

            # displacement, at which both sides are debonded
            w1 = w0 + (Lmax - Lmin) * T * ((Lmax - Lmin) + 2 *
                                           (l + 2 * Lmin)) / 2 / E_f / A
            # linear elastic response with stiffness EA/(clamp distance)
            q2 = E_f * A * (w - w1) / (Lmin + Lmax + l) + (Lmax) * T

            q0 = q0 * Heaviside(w0 - w)
            q1 = q1 * Heaviside(w - w0) * Heaviside(w1 - w)
            q2 = q2 * Heaviside(w - w1)

            q = q0 + q1 + q2

            # include breaking strain
            q = q * Heaviside(A * E_f * xi - q)
            #return q0, q1, q2 * Heaviside( A * E_f * xi - q2 ), w0 + theta * l, w1 + theta * l
            return q
Example #21
0
class MushRoofModelNonLin(MRquarter):
    '''Overload the nonlinear model.
    '''

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

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

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

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

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

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

    calibration_test = Str(input=True)

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

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

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

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

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

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

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

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

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

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

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

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

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

        return mats

    tline = Instance(TLine)

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

    rtrace_list = List

    def _rtrace_list_default(self):
        return [
            #                                 RTraceDomainListField( name = 'Displacement' ,
            #                                                var = 'u', idx = 0, warp = True ),
            #                                 RTraceDomainListField( name = 'Stress' ,
            #                                                var = 'sig_app', idx = 0, warp = True,
            #                                                record_on = 'update', ),
            #                    self.max_princ_stress,
            RTraceDomainListField(name='Damage',
                                  var='omega_mtx',
                                  idx=0,
                                  warp=True,
                                  record_on='update'),
        ]
Example #22
0
class SimBT4PTDB(SimBT4PT):

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

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

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

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

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

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

    calibration_test = Str(input=True)

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

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

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

    #-----------------
    # phi function extended:
    #-----------------
    #


#    phi_fn = Property(Instance(PhiFnGeneralExtended),
#                       depends_on = 'input_change,+ps_levels')
#    @cached_property
#    def _get_phi_fn(self):
#        return PhiFnGeneralExtended(mfn = self.damage_function,
#                                     factor_eps_fail = self.factor_eps_fail)

#-----------------
# phi function General:
#-----------------
#
# definition of 'phi_fn' in order to run scripting
# @todo: how can the implementation be changed in order to allow for parameter passing, e.g. 'factor_eps_fail', etc.
#
    phi_fn_class = Enum(
        PhiFnGeneral,
        [PhiFnGeneral, PhiFnGeneralExtended, PhiFnGeneralExtendedExp],
        input=True,
    )
    phi_fn = Property(Instance(phi_fn_class),
                      depends_on='phi_fn_class, input_change, +ps_levels')

    @cached_property
    def _get_phi_fn(self):
        return self.phi_fn_class(mfn=self.damage_function)

    #----------------------------------------------------------------------------------
    # material properties stored in 'ccs'
    #----------------------------------------------------------------------------------

    # concrete matrix E-modulus (taken from 'ccs_unit_cell')
    #
    E_m = Property(Float, depends_on='input_change')

    @cached_property
    def _get_E_m(self):
        E_m = self.ccs_unit_cell_ref.get_E_m_time(self.age)
        print 'E_m (from ccs)', E_m
        return E_m

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

    @cached_property
    def _get_E_c(self):
        E_c = self.ccs_unit_cell_ref.get_E_c_time(self.age)
        print 'E_c (from ccs)', E_c
        return E_c

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

    @cached_property
    def _get_nu(self):
        nu = self.ccs_unit_cell_ref.nu
        print 'nu (from ccs)', nu
        # set nu explicitly corresponding to settings in 'mats_calib_damage_fn'
        #
        print 'nu set explicitly to 0.20'
        nu = 0.2
        return nu
Example #23
0
class MRquarterDB(MRquarter):
    '''get 'phi_fn' as calibrated by the fitter and stored in the DB
    '''

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

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

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

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

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

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

    calibration_test = Str(input=True)

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

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

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

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

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


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

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

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

    age = Int(
        28,  # input = True
    )

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

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

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

    @cached_property
    def _get_nu(self):
        return self.ccs_unit_cell_ref.nu
Example #24
0
class ResultView(HasTraits):

    spirrid_view = Instance(SPIRRIDModelView)

    title = Str('result plot')

    n_samples = Int(10)

    figure = Instance(Figure)

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

    data_changed = Event(True)

    clear = Button

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

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

    sample = Button(desc='Show samples')

    def _sample_fired(self):
        n_samples = 20

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

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

        eps_arr = self.spirrid_view.model.eps_arr

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

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

        self.data_changed = True

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

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

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

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

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

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

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

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

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

        self.data_changed = True

    traits_view = View(
        HGroup(Item('n_samples', label='No of samples'),
               Item('sample', show_label=False, resizable=False),
               Item('clear', show_label=False, resizable=False,
                    springy=False)),
        Item('figure', show_label=False, editor=MPLFigureEditor()))
Example #25
0
class GenExampleDoc(HasTraits):

    header = Str('''
%s
================================

    ''')

    component_module = None

    #=========================================================================
    # Derived traits
    #=========================================================================
    component_obj = Property(depends_on='component_module')

    @cached_property
    def _get_component_obj(self):
        return self.component_module.create_doc_object()

    name = Property(depends_on='component_module')

    @cached_property
    def _get_name(self):
        return self.component_obj.__class__

    output_dir = Property(depends_on='component_module')

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

    rst_file_name = Property(depends_on='component_module')

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

    def generate_html(self):

        print 'generating documentation for', self.name, '...'

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

        dobj = self.component_obj

        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.name, st)

        for st in dobj.sampling_types:
            rst_text += '''

.. image:: %s_sampling_%s.png
    :width: 24%%

            ''' % (self.name, st)

        rst_text += '\nFollowing oricrete configuration has been used to produce the sampling figures:\n\n'
        rst_text += '\n>>> print component_obj\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()
Example #26
0
class CBEMClampedFiberStress(RF):
    '''
    Crack bridged by a fiber with constant
    frictional interface to the elastic matrix; clamped fiber end;
    Gives tension.
    '''

    implements(IRF)

    title = Str('crack bridge - clamped fiber with constant friction')

    xi = Float(0.0179,
               auto_set=False,
               enter_set=True,
               input=True,
               distr=['weibull_min', 'uniform'])

    tau = Float(2.5,
                auto_set=False,
                enter_set=True,
                input=True,
                distr=['uniform', 'norm'])

    l = Float(10.0,
              auto_set=False,
              enter_set=True,
              input=True,
              distr=['uniform'],
              desc='free length')

    r = Float(0.013,
              auto_set=False,
              input=True,
              enter_set=True,
              desc='fiber radius in mm')

    E_f = Float(72e3,
                auto_set=False,
                enter_set=True,
                input=True,
                distr=['uniform'])

    E_m = Float(30e3,
                auto_set=False,
                enter_set=True,
                input=True,
                distr=['uniform'])

    V_f = Float(0.0175,
                auto_set=False,
                enter_set=True,
                input=True,
                distr=['uniform'])

    theta = Float(0.01,
                  auto_set=False,
                  enter_set=True,
                  input=True,
                  distr=['uniform', 'norm'],
                  desc='slack')

    phi = Float(1.,
                auto_set=False,
                enter_set=True,
                input=True,
                distr=['uniform', 'norm'],
                desc='bond quality')

    Ll = Float(1.,
               auto_set=False,
               enter_set=True,
               input=True,
               distr=['uniform'],
               desc='embedded length - left',
               ctrl_range=(0.0, 1.0, 10))

    Lr = Float(.5,
               auto_set=False,
               enter_set=True,
               input=True,
               distr=['uniform'],
               desc='embedded length - right',
               ctrl_range=(0.0, 1.0, 10))

    w = Float(auto_set=False,
              enter_set=True,
              input=True,
              distr=['uniform'],
              desc='crack width',
              ctrl_range=(0.0, 1.0, 10))

    x = Float(auto_set=False,
              enter_set=True,
              input=True,
              distr=['uniform'],
              desc='crack width',
              ctrl_range=(0.0, 1.0, 10))

    x_label = Str('crack opening [mm]')
    y_label = Str('force [N]')

    C_code = Str('')

    def crackbridge(self, w, l, T, Kf, Km, Vf):
        # Phase A : Both sides debonding .
        Kc = Kf + Km
        c = Kc * T * l / 2.
        q0 = (np.sqrt(c**2 + w * Kf * Km * Kc * T) - c) / Km
        return q0 / Vf

    def pullout(self, w, l, T, Kf, Km, Vf, Lmin, Lmax):
        # Phase B : Debonding of shorter side is finished
        Kc = Kf + Km
        c = Kc * T * (Lmin + l)
        f = T**2 * Lmin**2 * Kc**2
        q1 = (np.sqrt(c**2. + f + 2 * w * Kc * T * Kf * Km) - c) / Km
        return q1 / Vf

    def linel(self, w, l, T, Kf, Km, Vf, Lmax, Lmin):
        # Phase C: Both sides debonded - linear elastic behavior.
        Kc = Kf + Km
        q2 = (2. * w * Kf * Km + T * Kc *
              (Lmin**2 + Lmax**2)) / (2. * Km * (Lmax + l + Lmin))
        return q2 / Vf

    def __call__(self, w, tau, l, E_f, E_m, theta, xi, phi, Ll, Lr, V_f, r):
        # assigning short and long embedded length
        Lmin = np.minimum(Ll, Lr)
        Lmax = np.maximum(Ll, Lr)

        Lmin = np.maximum(Lmin - l / 2., 1e-15)
        Lmax = np.maximum(Lmax - l / 2., 1e-15)

        # maximum condition for free length
        l = np.minimum(l / 2., Lr) + np.minimum(l / 2., Ll)

        # defining variables
        w = w - theta * l
        l = l * (1 + theta)
        w = H(w) * w
        T = 2. * tau * V_f / r
        Km = (1. - V_f) * E_m
        Kf = V_f * E_f
        Kc = Km + Kf

        # double sided debonding
        # q0 = self.crackbridge(w, l, T, Kr, Km, Lmin, Lmax)
        q0 = self.crackbridge(w, l, T, Kf, Km, V_f)

        # displacement at which the debonding to the closer clamp is finished
        w0 = (Lmin + l) * Lmin * Kc * T / Kf / Km

        # debonding of one side; the other side is clamped
        q1 = self.pullout(w, l, T, Kf, Km, V_f, Lmin, Lmax)

        # displacement at which the debonding is finished at both sides
        e1 = Lmax * Kc * T / Km / Kf
        w1 = e1 * (l + Lmax / 2.) + (e1 + e1 * Lmin / Lmax) * Lmin / 2.

        # debonding completed at both sides, response becomes linear elastic
        q2 = self.linel(w, l, T, Kf, Km, V_f, Lmax, Lmin)

        # cut out definition ranges
        q0 = H(w) * (q0 + 1e-15) * H(w0 - w)
        q1 = H(w - w0) * q1 * H(w1 - w)
        q2 = H(w - w1) * q2

        # add all parts
        q = q0 + q1 + q2
        # include breaking strain
        q = q * H(E_f * xi - q)
        return q
Example #27
0
class CBClamped(RF):
    '''
    Crack bridged by a fiber with constant
    frictional interface to rigid; free fiber end;
    '''

    implements(IRF)

    title = Str('crack bridge with rigid matrix')

    tau = Float(2.5,
                auto_set=False,
                enter_set=True,
                input=True,
                distr=['uniform', 'norm'])

    r = Float(0.013,
              auto_set=False,
              enter_set=True,
              input=True,
              distr=['uniform', 'norm'],
              desc='fiber radius')

    E_f = Float(72e3,
                auto_set=False,
                enter_set=True,
                input=True,
                distr=['uniform'])

    m = Float(5.,
              auto_set=False,
              enter_set=True,
              input=True,
              distr=['uniform'])

    sV0 = Float(3.e-3,
                auto_set=False,
                enter_set=True,
                input=True,
                distr=['uniform'])

    V_f = Float(0.0175,
                auto_set=False,
                enter_set=True,
                input=True,
                distr=['uniform'])

    lm = Float(np.inf,
               auto_set=False,
               enter_set=True,
               input=True,
               distr=['uniform'])

    w = Float(auto_set=False,
              enter_set=True,
              input=True,
              distr=['uniform'],
              desc='crack width',
              ctrl_range=(0.0, 1.0, 10))

    x_label = Str('crack opening [mm]')
    y_label = Str('composite stress [MPa]')

    C_code = Str('')

    def e_broken(self, Pf, depsf, r, m, sV0, mask):
        '''weibull_fibers_cdf_mc'''
        s_free = ((depsf * (m + 1.) * sV0**m) / (2. * pi * r**2.))**(1. /
                                                                     (m + 1.))
        xi_free = s_free * (-np.log(1. - Pf))**(1. / (m + 1))
        s_fixed = ((depsf * sV0**m) / (2. * pi * r**2.))**(1. / (m + 1.))
        xi_fixed = s_fixed * (-np.log(1. - Pf))**(1. / (m + 1))
        return xi_free, xi_fixed

    def __call__(self, w, tau, E_f, V_f, r, m, sV0, lm, Pf):
        '''free and fixed fibers combined'''
        T = 2. * tau / r
        k = np.sqrt(T / E_f)
        ef0cb = k * np.sqrt(w)
        ef0lin = w / lm + T * lm / 4. / E_f
        depsf = T / E_f
        a0 = ef0cb / depsf
        mask = a0 < lm / 2.0
        e_int = ef0cb * mask + ef0lin * (mask == False)
        xi_free, xi_fixed = self.e_broken(Pf, depsf, r, m, sV0, mask)
        axi = xi_free / depsf
        mask_xi = axi < lm / 2.
        e_broken = xi_free / (m + 1.) * (mask_xi) + xi_fixed / 2. * (mask_xi
                                                                     == False)
        xi = xi_free * (mask_xi) + xi_fixed * (mask_xi == False)
        e = e_int * (e_int < xi) + e_broken * (e_int > xi)
        return e * E_f * V_f * r**2

    def __call__2(self, w, tau, E_f, V_f, r, m, sV0, Pf):
        '''free debonding only = __call__ with lm=infty'''
        #strain and debonded length of intact fibers
        T = 2. * tau / r
        ef0_inf = np.sqrt(T * w / E_f)
        #scale parameter with respect to a reference volume
        s0 = ((T * (m + 1) * sV0**m) / (2. * E_f * pi * r**2))**(1. / (m + 1))
        # strain at fiber breakage
        ef0_break = s0 * (-np.log(1. - Pf))**(1. / (m + 1))
        # debonded length at fiber breakage
        a_break = ef0_break * E_f / T
        #mean pullout length of broken fibers
        mu_Lpo = a_break / (m + 1)
        # strain carried by broken fibers
        ef0_residual = T / E_f * mu_Lpo

        if self.include_pullout == True:
            ef0_tot = ef0_residual * H(ef0_inf - ef0_break) + ef0_inf * H(
                ef0_break - ef0_inf)
        else:
            ef0_tot = ef0_inf * H(ef0_break - ef0_inf)
        return ef0_tot * E_f * V_f * r**2
Example #28
0
class CBClampedRandXi(RF):
    '''
    Crack bridged by a fiber with constant
    frictional interface to rigid; free fiber end;
    '''

    implements(IRF)
    title = Str('crack bridge with rigid matrix')
    tau = Float(2.5,
                auto_set=False,
                enter_set=True,
                input=True,
                distr=['uniform', 'norm'])

    r = Float(0.013,
              auto_set=False,
              enter_set=True,
              input=True,
              distr=['uniform', 'norm'],
              desc='fiber radius')

    E_f = Float(72e3,
                auto_set=False,
                enter_set=True,
                input=True,
                distr=['uniform'])

    m = Float(5.,
              auto_set=False,
              enter_set=True,
              input=True,
              distr=['uniform'])

    sV0 = Float(3.e-3,
                auto_set=False,
                enter_set=True,
                input=True,
                distr=['uniform'])

    V_f = Float(0.0175,
                auto_set=False,
                enter_set=True,
                input=True,
                distr=['uniform'])

    lm = Float(np.inf,
               auto_set=False,
               enter_set=True,
               input=True,
               distr=['uniform'])

    w = Float(auto_set=False,
              enter_set=True,
              input=True,
              distr=['uniform'],
              desc='crack width',
              ctrl_range=(0.0, 1.0, 10))

    x_label = Str('crack opening [mm]')
    y_label = Str('composite stress [MPa]')

    C_code = Str('')

    def __call__(self, w, tau, E_f, V_f, r, m, sV0):
        '''free and fixed fibers combined
        the failure probability of fixed fibers
        is evaluated by integrating only
        between -lm/2 and lm/2.
        Only intact fibers are considered (no pullout contribution)'''
        T = 2. * tau / r + 1e-10
        k = np.sqrt(T / E_f)
        ef0cb = k * np.sqrt(w)
        s = ((T * (m + 1) * sV0**m) / (2. * E_f * pi * r**2))**(1. / (m + 1))
        Gxi_deb = 1 - np.exp(-(ef0cb / s)**(m + 1))
        if w == 1.00:
            a0 = ef0cb * E_f / T
            print np.sum(a0 > 500.) / float(np.sum(a0 > -0.1))
        return ef0cb * (1 - Gxi_deb) * E_f * V_f * r**2
Example #29
0
class SPIRRID( Randomization ):

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

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

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

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

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

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

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

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

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

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

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

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

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

        return arg_list

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

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

        code_str = ''
        if self.compiled_eps_loop:

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

            if self.cached_dG:

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

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

        else:

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

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

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

        # generate loops over random params

        for rv in self.rv_list:

            name = rv.name
            n_int = rv.n_int

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

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

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

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

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

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

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

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

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

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

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

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

        if self.compiled_eps_loop:

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

        if self.compiled_QdG_loop:

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

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

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

        t = time.clock()

        if self.compiled_eps_loop:

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

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

        else:

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

                if self.compiled_QdG_loop:

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

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

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

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

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

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

                if self.implicit_var_eval:
                    var_q_arr[idx] = var_q

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

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

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

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

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

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

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

        return self.results[1]

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

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

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

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

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

    traits_view = View( Item( 'rf@', show_label = False ),
                        width = 0.3, height = 0.3,
                        resizable = True,
                        scrollable = True,
                        )
Example #30
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 probabilities8
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):
        dm = self.demo_module
        return dm.create_demo_object()

    qname = Property(depends_on='demo_module')
    @cached_property
    def _get_qname(self):
        return self.demo_object.get_qname()

    ex_build_dir = Property(depends_on='demo_module')
    @cached_property
    def _get_ex_build_dir(self):
        # check if the directory exists
        out_dir = os.path.join(EX_BUILD_DIR, self.qname)
        if not os.path.exists(out_dir):
            os.makedirs(out_dir)
        return out_dir

    ex_cache_dir = Property(depends_on='demo_module')
    @cached_property
    def _get_ex_cache_dir(self):
        # check if the directory exists
        out_dir = os.path.join(EX_CACHE_DIR, self.qname)
        if not os.path.exists(out_dir):
            os.makedirs(out_dir)
        return out_dir

    fig_cache_dir = Property()
    @cached_property
    def _get_fig_cache_dir(self):
        # check if the directory exists
        out_dir = os.path.join(self.ex_cache_dir, 'fig')
        if not os.path.exists(out_dir):
            os.makedirs(out_dir)
        return out_dir

    rst_file_name = Property(depends_on='demo_module')
    @cached_property
    def _get_rst_file_name(self):
        return os.path.join(self.ex_cache_dir, 'index.rst')

    def generate_examples_sampling_structure(self):
        dobj = self.demo_object
        dobj.set(fig_output_dir=self.ex_cache_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.ex_cache_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.ex_cache_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_lst:
            rst_text += '''

.. image:: %s_%s.png
    :width: 24%%

            ''' % (self.qname, st)

        for st in dobj.sampling_lst:
            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'

        print 'writing rst file %s' % self.rst_file_name

        rst_file = open(self.rst_file_name, 'w')
        rst_file.write(rst_text)
        rst_file.close()