def default_traits_view(self): ''' Generates the view from the param items. ''' #rf_param_items = [ Item( 'model.' + name, format_str = '%g' ) for name in self.model.param_keys ] D2_plot_param_items = [ VGroup(Item('max_x', label='max x value'), Item('x_points', label='No of plot points')) ] if hasattr(self.rf, 'get_q_x'): D3_plot_param_items = [ VGroup(Item('min_x', label='min x value'), Item('max_x', label='max x value'), Item('min_y', label='min y value'), Item('max_y', label='max y value')) ] else: D3_plot_param_items = [] control_items = [ Item('show', show_label=False), Item('clear', show_label=False), ] view = View( HSplit( VGroup(Item('@rf', show_label=False), label='Function parameters', id='stats.spirrid_bak.rf_model_view.rf_params', scrollable=True), VGroup(HGroup(*D2_plot_param_items), label='plot parameters', id='stats.spirrid_bak.rf_model_view.2Dplot_params'), # VGroup( HGroup( *D3_plot_param_items ), # label = '3D plot parameters', # id = 'stats.spirrid_bak.rf_model_view.3Dplot_params' ), VGroup( Item('model.comment', show_label=False, style='readonly'), label='Comment', id='stats.spirrid_bak.rf_model_view.comment', scrollable=True, ), VGroup(HGroup(*control_items), Item('figure', editor=MPLFigureEditor(), resizable=True, show_label=False), label='Plot', id='stats.spirrid_bak.rf_model_view.plot'), dock='tab', id='stats.spirrid_bak.rf_model_view.split'), kind='modal', resizable=True, dock='tab', buttons=[OKButton], id='stats.spirrid_bak.rf_model_view') return view
class ECBLCalibStateModelView(ModelView): '''Model in a viewable window. ''' model = Instance(ECBLCalibState) def _model_default(self): return ECBLCalibState() cs_state = Property(Instance(ECBCrossSectionState), depends_on = 'model') @cached_property def _get_cs_state(self): return self.model.cs_state data_changed = Event figure = Instance(Figure) def _figure_default(self): figure = Figure(facecolor = 'white') return figure replot = Button() def _replot_fired(self): ax = self.figure.add_subplot(1, 1, 1) self.model.calibrated_ecb_law.plot(ax) self.data_changed = True clear = Button() def _clear_fired(self): self.figure.clear() self.data_changed = True calibrated_ecb_law = Property(Instance(ECBLBase), depends_on = 'model') @cached_property def _get_calibrated_ecb_law(self): return self.model.calibrated_ecb_law view = View(HSplit(VGroup( Item('cs_state', label = 'Cross section', show_label = False), Item('model@', show_label = False), Item('calibrated_ecb_law@', show_label = False, resizable = True), ), Group(HGroup( Item('replot', show_label = False), Item('clear', show_label = False), ), Item('figure', editor = MPLFigureEditor(), resizable = True, show_label = False), id = 'simexdb.plot_sheet', label = 'plot sheet', dock = 'tab', ), ), width = 0.5, height = 0.4, buttons = ['OK', 'Cancel'], resizable = True)
def default_traits_view(self): return View( HSplit( VSplit( Item('data_file@', editor=FileEditor(filter_name='filter'), show_label=False), Group( Item('figure', editor=MPLFigureEditor(), resizable=True, show_label=False), id='simexdb.plot_sheet', label='plot sheet', dock='tab', ), Group( Item('plot_template'), columns=1, label='plot parameters', id='simexdb.plot_params', dock='tab', ), id='simexdb.plot.vsplit', dock='tab', ), VSplit( Item('model@', id='simexdb.run.split', dock='tab', resizable=True, label='experiment run', show_label=False), id='simexdb.mode_plot_data.vsplit', dock='tab', scrollable=True ), id='simexdb.hsplit', dock='tab', ), key_bindings=self.key_bindings, menubar=self.default_menubar(), toolbar=self.default_toolbar(), resizable=True, title='Simvisage: experiment database browser', id='simexdb', dock='tab', buttons=['Ok'], height=1.0, width=1.0 )
class ConstitutiveLawModelView(ModelView): model = Instance(CLBase) data_changed = Event figure = Instance(Figure) def _figure_default(self): figure = Figure(facecolor='white') return figure replot = Button() def _replot_fired(self): ax = self.figure.add_subplot(1, 1, 1) self.model.plot(ax) self.data_changed = True clear = Button() def _clear_fired(self): self.figure.clear() self.data_changed = True traits_view = View(HSplit( Group( Item('model', style='custom', show_label=False, resizable=True), scrollable=True, ), Group( HGroup( Item('replot', show_label=False), Item('clear', show_label=False), ), Item('figure', editor=MPLFigureEditor(), resizable=True, show_label=False), id='simexdb.plot_sheet', label='plot sheet', dock='tab', ), ), width=0.5, height=0.4, resizable=True, buttons=['OK', 'Cancel'])
def default_traits_view(self): ''' Generates the view from the param items. ''' rf_param_items = [ Item('model.' + name, format_str='%g') for name in self.model.param_keys ] plot_param_items = [ Item('eps_max'), Item('n_eps'), Item('x_name', label='x-axis'), Item('y_name', label='y-axis') ] control_items = [ Item('show', show_label=False), Item('clear', show_label=False), ] view = View(HSplit( VGroup(*rf_param_items, label='Function Parameters', id='stats.spirrid_bak.rf_model_view.rf_params', scrollable=True), VGroup(*plot_param_items, label='Plot Parameters', id='stats.spirrid_bak.rf_model_view.plot_params'), VGroup( Item('model.comment', show_label=False, style='readonly'), label='Comment', id='stats.spirrid_bak.rf_model_view.comment', scrollable=True, ), VGroup(HGroup(*control_items), Item('figure', editor=MPLFigureEditor(), resizable=True, show_label=False), label='Plot', id='stats.spirrid_bak.rf_model_view.plot'), dock='tab', id='stats.spirrid_bak.rf_model_view.split'), kind='modal', resizable=True, dock='tab', buttons=['Ok', 'Cancel'], id='stats.spirrid_bak.rf_model_view') return view
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'])
class ECBReinfTexUniform(ECBReinfComponent): '''Cross section characteristics needed for tensile specimens ''' height = DelegatesTo('matrix_cs') '''height of reinforced cross section ''' n_layers = Int(12, auto_set=False, enter_set=True, geo_input=True) '''total number of reinforcement layers [-] ''' n_rovings = Int(23, auto_set=False, enter_set=True, geo_input=True) '''number of rovings in 0-direction of one composite layer of the bending test [-]: ''' A_roving = Float(0.461, auto_set=False, enter_set=True, geo_input=True) '''cross section of one roving [mm**2]''' def convert_eps_tex_u_2_lo(self, eps_tex_u): '''Convert the strain in the lowest reinforcement layer at failure to the strain at the bottom of the cross section''' eps_up = self.state.eps_up return eps_up + (eps_tex_u - eps_up) / self.z_ti_arr[0] * self.height def convert_eps_lo_2_tex_u(self, eps_lo): '''Convert the strain at the bottom of the cross section to the strain in the lowest reinforcement layer at failure''' eps_up = self.state.eps_up return (eps_up + (eps_lo - eps_up) / self.height * self.z_ti_arr[0]) '''Convert the MN to kN ''' #=========================================================================== # material properties #=========================================================================== sig_tex_u = Float(1216., auto_set=False, enter_set=True, tt_input=True) '''Ultimate textile stress measured in the tensile test [MPa] ''' #=========================================================================== # Distribution of reinforcement #=========================================================================== s_tex_z = Property(depends_on=ECB_COMPONENT_AND_EPS_CHANGE) '''spacing between the layers [m]''' @cached_property def _get_s_tex_z(self): return self.height / (self.n_layers + 1) z_ti_arr = Property(depends_on=ECB_COMPONENT_AND_EPS_CHANGE) '''property: distance of each reinforcement layer from the top [m]: ''' @cached_property def _get_z_ti_arr(self): return np.array([ self.height - (i + 1) * self.s_tex_z for i in range(self.n_layers) ], dtype=float) zz_ti_arr = Property '''property: distance of reinforcement layers from the bottom ''' def _get_zz_ti_arr(self): return self.height - self.z_ti_arr #=========================================================================== # Discretization conform to the tex layers #=========================================================================== eps_i_arr = Property(depends_on=ECB_COMPONENT_AND_EPS_CHANGE) '''Strain at the level of the i-th reinforcement layer ''' @cached_property def _get_eps_i_arr(self): # ------------------------------------------------------------------------ # geometric params independent from the value for 'eps_t' # ------------------------------------------------------------------------ height = self.height eps_lo = self.state.eps_lo eps_up = self.state.eps_up # strain at the height of each reinforcement layer [-]: # return eps_up + (eps_lo - eps_up) * self.z_ti_arr / height eps_ti_arr = Property(depends_on=ECB_COMPONENT_AND_EPS_CHANGE) '''Tension strain at the level of the i-th layer of the fabrics ''' @cached_property def _get_eps_ti_arr(self): return (np.fabs(self.eps_i_arr) + self.eps_i_arr) / 2.0 eps_ci_arr = Property(depends_on=ECB_COMPONENT_AND_EPS_CHANGE) '''Compression strain at the level of the i-th layer. ''' @cached_property def _get_eps_ci_arr(self): return (-np.fabs(self.eps_i_arr) + self.eps_i_arr) / 2.0 #=========================================================================== # Effective crack bridge law #=========================================================================== ecb_law_type = Trait('fbm', dict(fbm=ECBLFBM, cubic=ECBLCubic, linear=ECBLLinear, bilinear=ECBLBilinear), tt_input=True) '''Selector of the effective crack bridge law type ['fbm', 'cubic', 'linear', 'bilinear']''' ecb_law = Property(Instance(ECBLBase), depends_on='+tt_input') '''Effective crack bridge law corresponding to ecb_law_type''' @cached_property def _get_ecb_law(self): return self.ecb_law_type_(sig_tex_u=self.sig_tex_u, cs=self) show_ecb_law = Button '''Button launching a separate view of the effective crack bridge law. ''' def _show_ecb_law_fired(self): ecb_law_mw = ConstitutiveLawModelView(model=self.ecb_law) ecb_law_mw.edit_traits(kind='live') return tt_modified = Event sig_ti_arr = Property(depends_on=ECB_COMPONENT_AND_EPS_CHANGE) '''Stresses at the i-th fabric layer. ''' @cached_property def _get_sig_ti_arr(self): return self.ecb_law.mfn_vct(self.eps_ti_arr) f_ti_arr = Property(depends_on=ECB_COMPONENT_AND_EPS_CHANGE) '''force at the height of each reinforcement layer [kN]: ''' @cached_property def _get_f_ti_arr(self): sig_ti_arr = self.sig_ti_arr n_rovings = self.n_rovings A_roving = self.A_roving return sig_ti_arr * n_rovings * A_roving / self.unit_conversion_factor figure = Instance(Figure) def _figure_default(self): figure = Figure(facecolor='white') figure.add_axes([0.08, 0.13, 0.85, 0.74]) return figure data_changed = Event replot = Button def _replot_fired(self): self.figure.clear() ax = self.figure.add_subplot(2, 2, 1) self.plot_eps(ax) ax = self.figure.add_subplot(2, 2, 2) self.plot_sig(ax) ax = self.figure.add_subplot(2, 2, 3) self.cc_law.plot(ax) ax = self.figure.add_subplot(2, 2, 4) self.ecb_law.plot(ax) self.data_changed = True def plot_eps(self, ax): #ax = self.figure.gca() d = self.height # eps ti ax.plot([-self.eps_lo, -self.eps_up], [0, self.height], color='black') ax.hlines(self.zz_ti_arr, [0], -self.eps_ti_arr, lw=4, color='red') # eps cj ec = np.hstack([self.eps_cj_arr] + [0, 0]) zz = np.hstack([self.zz_cj_arr] + [0, self.height]) ax.fill(-ec, zz, color='blue') # reinforcement layers eps_range = np.array([max(0.0, self.eps_lo), min(0.0, self.eps_up)], dtype='float') z_ti_arr = np.ones_like(eps_range)[:, None] * self.z_ti_arr[None, :] ax.plot(-eps_range, z_ti_arr, 'k--', color='black') # neutral axis ax.plot(-eps_range, [d, d], 'k--', color='green', lw=2) ax.spines['left'].set_position('zero') ax.spines['right'].set_color('none') ax.spines['top'].set_color('none') ax.spines['left'].set_smart_bounds(True) ax.spines['bottom'].set_smart_bounds(True) ax.xaxis.set_ticks_position('bottom') ax.yaxis.set_ticks_position('left') def plot_sig(self, ax): d = self.height # f ti ax.hlines(self.zz_ti_arr, [0], -self.f_ti_arr, lw=4, color='red') # f cj f_c = np.hstack([self.f_cj_arr] + [0, 0]) zz = np.hstack([self.zz_cj_arr] + [0, self.height]) ax.fill(-f_c, zz, color='blue') f_range = np.array( [np.max(self.f_ti_arr), np.min(f_c)], dtype='float_') # neutral axis ax.plot(-f_range, [d, d], 'k--', color='green', lw=2) ax.spines['left'].set_position('zero') ax.spines['right'].set_color('none') ax.spines['top'].set_color('none') ax.spines['left'].set_smart_bounds(True) ax.spines['bottom'].set_smart_bounds(True) ax.xaxis.set_ticks_position('bottom') ax.yaxis.set_ticks_position('left') view = View(HSplit( Group( HGroup( Group(Item('height', springy=True), Item('width'), Item('n_layers'), Item('n_rovings'), Item('A_roving'), label='Geometry', springy=True), Group(Item('eps_up', label='Upper strain', springy=True), Item('eps_lo', label='Lower strain'), label='Strain', springy=True), springy=True, ), HGroup( Group(VGroup(Item('cc_law_type', show_label=False, springy=True), Item('cc_law', label='Edit', show_label=False, springy=True), Item('show_cc_law', label='Show', show_label=False, springy=True), springy=True), Item('f_ck', label='Compressive strength'), Item('n_cj', label='Discretization'), label='Concrete', springy=True), Group(VGroup( Item('ecb_law_type', show_label=False, springy=True), Item('ecb_law', label='Edit', show_label=False, springy=True), Item('show_ecb_law', label='Show', show_label=False, springy=True), springy=True, ), label='Reinforcement', springy=True), springy=True, ), Group( Item('s_tex_z', label='vertical spacing', style='readonly'), label='Layout', ), Group(HGroup( Item('M', springy=True, style='readonly'), Item('N', springy=True, style='readonly'), ), label='Stress resultants'), scrollable=True, ), Group( Item('replot', show_label=False), Item('figure', editor=MPLFigureEditor(), resizable=True, show_label=False), id='simexdb.plot_sheet', label='plot sheet', dock='tab', ), ), width=0.8, height=0.7, resizable=True, buttons=['OK', 'Cancel'])
class CSModelView(ModelView): model = Instance(ClampSetup) def _model_default(self): return ClampSetup() 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 @on_trait_change('model.+modified') def refresh(self): figure = self.figure axes = figure.gca() axes.clear() cs = self.model xu, u, xe, e = cs.get_values() axes.set_xlabel('position on yarn', weight='semibold') axes.set_axis_bgcolor(color='white') axes.ticklabel_format(scilimits=(-3., 4.)) axes.grid(color='gray', linestyle='--', linewidth=0.5, alpha=0.7) if cs.switch == 'strains': axes.plot(xe, e, lw=2, color='blue') axes.set_ylabel('strains [-]', weight='semibold') axes.plot(array([cs.l1, cs.l1]), array([0, max(e)]), lw=2, color='red', linestyle='dashed') axes.plot(array([cs.l1 + cs.L, cs.l1 + cs.L]), array([0, max(e)]), lw=2, color='red', linestyle='dashed') axes.text(cs.l1 + cs.L / 2, max(e) * 0.95, 'clamp', size='large', ha='center') axes.text(cs.l1 + cs.L + cs.lt / 2, max(e) * 0.95, 'tested length', size='large', ha='center') elif cs.switch == 'displacement': axes.plot(xu, u, lw=2, color='blue') axes.set_ylabel('displacement [m]', weight='semibold') axes.plot(array([cs.l1, cs.l1]), array([0, max(u)]), lw=2, color='red', linestyle='dashed') axes.plot(array([cs.l1 + cs.L, cs.l1 + cs.L]), array([0, max(u)]), lw=2, color='red', linestyle='dashed') axes.text(cs.l1 + cs.L / 2, max(u) * 0.95, 'clamp', size='large', ha='center') axes.text(cs.l1 + cs.L + cs.lt / 2, max(u) * 0.95, 'tested length', size='large', ha='center') else: print 'NOT YET IMPLEMENTED' # axes.plot(xslip, yslip, lw = 2, color = 'blue') # axes.set_ylabel('slip in clamp [m]', weight = 'semibold') # axes.set_xlabel('position in clamp [mm]', weight = 'semibold') self.data_changed = True traits_view = View(HSplit( VGroup( Item('model@', show_label=False, resizable=True), label='Material parameters', id='cs.viewmodel.model', dock='tab', ), VSplit( VGroup( Item('figure', editor=MPLFigureEditor(), resizable=True, show_label=False), label='yarn displacement', id='cs.viewmodel.plot_window', dock='tab', ), id='cs.viewmodel.right', ), id='cs.viewmodel.splitter', ), title='tested yarn', id='cs.viewmodel', dock='tab', resizable=True, buttons=[OKButton], height=0.8, width=0.8)
class PDistribView(ModelView): def __init__(self, **kw): super(PDistribView, self).__init__(**kw) self.on_trait_change( self.refresh, 'model.distr_type.changed, model.quantile, model.n_segments') self.refresh() model = Instance(PDistrib) figure = Instance(Figure) def _figure_default(self): figure = Figure(facecolor='white') return figure data_changed = Event def plot(self, fig): figure = fig figure.clear() axes = figure.gca() # plot PDF axes.plot(self.model.x_array, self.model.pdf_array, lw=1.0, color='blue', label='PDF') axes2 = axes.twinx() # plot CDF on a separate axis (tick labels left) axes2.plot(self.model.x_array, self.model.cdf_array, lw=2, color='red', label='CDF') # fill the unity area given by integrating PDF along the X-axis axes.fill_between(self.model.x_array, 0, self.model.pdf_array, color='lightblue', alpha=0.8, linewidth=2) # plot mean mean = self.model.distr_type.distr.stats('m') axes.plot([mean, mean], [0.0, self.model.distr_type.distr.pdf(mean)], lw=1.5, color='black', linestyle='-') # plot stdev stdev = sqrt(self.model.distr_type.distr.stats('v')) axes.plot([mean - stdev, mean - stdev], [0.0, self.model.distr_type.distr.pdf(mean - stdev)], lw=1.5, color='black', linestyle='--') axes.plot([mean + stdev, mean + stdev], [0.0, self.model.distr_type.distr.pdf(mean + stdev)], lw=1.5, color='black', linestyle='--') axes.legend(loc='center left') axes2.legend(loc='center right') axes.ticklabel_format(scilimits=(-3., 4.)) axes2.ticklabel_format(scilimits=(-3., 4.)) # plot limits on X and Y axes axes.set_ylim(0.0, max(self.model.pdf_array) * 1.15) axes2.set_ylim(0.0, 1.15) range = self.model.range[1] - self.model.range[0] axes.set_xlim(self.model.x_array[0] - 0.05 * range, self.model.x_array[-1] + 0.05 * range) axes2.set_xlim(self.model.x_array[0] - 0.05 * range, self.model.x_array[-1] + 0.05 * range) def refresh(self): self.plot(self.figure) self.data_changed = True icon = Property( Instance(ImageResource), depends_on='model.distr_type.changed, model.quantile, model.n_segments' ) @cached_property def _get_icon(self): import matplotlib.pyplot as plt fig = plt.figure(figsize=(4, 4), facecolor='white') self.plot(fig) tf_handle, tf_name = tempfile.mkstemp('.png') fig.savefig(tf_name, dpi=35) return ImageResource(name=tf_name) traits_view = View(HSplit(VGroup( Group( Item('model.distr_choice', show_label=False), Item('@model.distr_type', show_label=False), ), id='pdistrib.distr_type.pltctrls', label='Distribution parameters', scrollable=True, ), Tabbed( Group( Item('figure', editor=MPLFigureEditor(), show_label=False, resizable=True), scrollable=True, label='Plot', ), Group(Item('model.quantile', label='quantile'), Item('model.n_segments', label='plot points'), label='Plot parameters'), label='Plot', id='pdistrib.figure.params', dock='tab', ), dock='tab', id='pdistrib.figure.view'), id='pdistrib.view', dock='tab', title='Statistical distribution', buttons=[OKButton, CancelButton], scrollable=True, resizable=True, width=600, height=400)
class YMBAutoCorrelView(HasTraits): correl_data = Instance(YMBAutoCorrel) axes_adjust = List([0.1, 0.1, 0.8, 0.8]) data = Property def _get_data(self): return self.correl_data.data zero = Constant(0) slider_max = Property() def _get_slider_max(self): return self.data.n_cuts - 1 cut_slider = Range('zero', 'slider_max', mode='slider', auto_set=False, enter_set=True, modified=True) vcut_slider = Range('zero', 'slider_max', mode='slider', auto_set=False, enter_set=True, modified=True) cut_slider_on = Bool(False, modified=True) color = Str('blue') figure = Instance(Figure) def _figure_default(self): figure = Figure() figure.add_axes(self.axes_adjust) return figure data_changed = Event(True) @on_trait_change('correl_data.input_change, +modified') def _redraw(self): # TODO: set correct ranges, fix axis range (axes.xlim) print 'redrawing xxxx' figure = self.figure figure.clear() var_data = self.correl_data.corr_arr id = self.cut_slider if self.cut_slider_on == True: i = self.cut_slider j = self.vcut_slider plot_data = getattr(self.data, self.correl_data.var_enum_) # plot_data = vstack( [plot_data[:, i], plot_data[:, j]] ).T # plot only values > -1 # plot_data = plot_data[prod( plot_data >= 0, axis = 1, dtype = bool )] plot_data_x = plot_data[:, i] plot_data_y = plot_data[:, j] plot_data_corr = min(corrcoef(plot_data_x, plot_data_y)) plot_data_corr_spear = spearmanr(plot_data_x, plot_data_y)[0] left, width = 0.1, 0.65 bottom, height = 0.1, 0.65 bottom_h = left_h = left + width + 0.02 rect_scatter = [left, bottom, width, height] rect_histx = [left, bottom_h, width, 0.2] rect_histy = [left_h, bottom, 0.2, height] axScatter = figure.add_axes(rect_scatter) axHistx = figure.add_axes(rect_histx) axHisty = figure.add_axes(rect_histy) axScatter.clear() axHistx.clear() axHisty.clear() from matplotlib.ticker import NullFormatter axHistx.xaxis.set_major_formatter(NullFormatter()) axHisty.yaxis.set_major_formatter(NullFormatter()) axScatter.scatter(plot_data_x, plot_data_y) # binwidth = 0.25 # xymax = max( [max( abs( self.data.cf[:, j] ) ), max( abs( self.data.cf[:, i] ) )] ) # lim = ( int( xymax / binwidth ) + 1 ) * binwidth # axScatter.set_xlim( ( -lim, lim ) ) # axScatter.set_ylim( ( -lim, lim ) ) # bins = arange( -lim, lim + binwidth, binwidth ) axHistx.hist(plot_data_x.compressed(), bins=40) axHisty.hist(plot_data_y.compressed(), bins=40, orientation='horizontal') axHistx.set_xlim(axScatter.get_xlim()) axHisty.set_ylim(axScatter.get_ylim()) axScatter.set_xlabel('$\mathrm{cut\, %i}$' % self.cut_slider, fontsize=16) axScatter.set_ylabel('$\mathrm{cut\, %i}$' % self.vcut_slider, fontsize=16) axScatter.text(axScatter.get_xlim()[0], axScatter.get_ylim()[0], 'actual set correlation %.3f (Pearson), %.3f (Spearman)' % (plot_data_corr, plot_data_corr_spear), color='r') if self.cut_slider_on == False: figure.add_axes(self.axes_adjust) axes = figure.axes[0] axes.clear() x_coor = self.data.x_coord axes.grid() for i in range(0, var_data.shape[1]): axes.plot(x_coor[i:] - x_coor[i], var_data[i, (i):], '-x', color=self.color) # approximate by the polynomial (of the i-th order) # axes.plot( x_coor, self.correl_data.peval( x_coor, self.correl_data.fit_correl ), 'b', linewidth = 3 ) setp(axes.get_xticklabels(), position=(0, -.025)) axes.set_xlabel('$x \, [\mathrm{mm}]$', fontsize=15) axes.set_ylabel('$\mathrm{correlation}$', fontsize=15) axes.set_ylim(-1, 1) self.data_changed = True traits_view = View(Group(Item('correl_data', show_label=False, style='custom'), HGroup( Item('cut_slider_on', label='Scatter'), Item('cut_slider', show_label=False, springy=True, enabled_when='cut_slider_on == True'), Item('vcut_slider', show_label=False, springy=True, enabled_when='cut_slider_on == True'), ), Group(Item('figure', style='custom', editor=MPLFigureEditor(), show_label=False) , id='figure.view'), ), resizable=True, )
class YSEModelView(ModelView): ''' Size effect depending on the yarn length ''' model = Instance(YSE) def _model_default(self): return YSE() l_plot = DelegatesTo('model') min_plot_length = DelegatesTo('model') n_points = DelegatesTo('model') test_2_on = Bool(True, modified=True) test_3_on = Bool(True, modified=True) Asymp = Bool(True, modified=True) Gauss = Bool(True, modified=True) stdev = Bool(False, modified=True) mean_app = Bool(False, modified=True) figure = Instance(Figure) def _figure_default(self): figure = Figure(facecolor='white') figure.add_axes([0.08, 0.13, 0.85, 0.74]) return figure test_length_r = DelegatesTo('model') test_length_f = DelegatesTo('model') data_changed = Event(True) @on_trait_change('+modified,model.+modified') def _redraw(self): data = self.model._get_values() xdata = [] ydata = [] linecolor = [] linewidth = [] linestyle = [] legend = [] if self.Gauss is True: xdata.append(data[0]) ydata.append(data[2]) linecolor.append('blue') linewidth.append(2) linestyle.append('solid') legend.append('median Gauss') if self.Asymp is True: xdata.append(data[1]) ydata.append(data[3]) linecolor.append('black') linewidth.append(1) linestyle.append('dashed') legend.append('asymptotes') if self.test_2_on: xdata.append(self.test_length_r[0]) ydata.append(self.test_length_r[1]) linecolor.append('red') linewidth.append(1) linestyle.append('dashed') legend.append('test - single bundle') if self.test_3_on: xdata.append(self.test_length_f[0]) ydata.append(self.test_length_f[1]) linecolor.append('red') linewidth.append(1) linestyle.append('dashed') legend.append('test - chain of bundles') if self.mean_app is True: xdata.append(data[7]) xdata.append(data[7]) xdata.append(data[7]) ydata.append(data[8]) ydata.append(data[9]) ydata.append(data[10]) linecolor.append('red') linecolor.append('black') linecolor.append('green') linewidth.append(1) linewidth.append(1) linewidth.append(1) linestyle.append('dashed') linestyle.append('dotted') linestyle.append('solid') legend.append('mean Mirek') legend.append('mean Gumbel') legend.append('median Gumbel') if self.stdev and self.Gauss is True: xdata.append(data[4]) xdata.append(data[4]) ydata.append(data[5]) ydata.append(data[6]) linecolor.append('lightblue') linecolor.append('lightblue') linewidth.append(2) linewidth.append(2) linestyle.append('solid') linestyle.append('solid') legend.append('st. deviation') test_on = True if self.stdev is False or self.Gauss is False: test_on = False figure = self.figure figure.clear() axes = figure.gca() for x, y, c, w, s in zip(xdata[:], ydata[:], linecolor[:], linewidth[:], linestyle[:]): axes.plot(x, y, color=c, linewidth=w, linestyle=s) if test_on is True: axes.fill_between( xdata[-1], ydata[len(ydata) - 1], ydata[len(xdata) - 2], color='lightblue', ) else: pass axes.set_xlabel('length [m]', weight='semibold') axes.set_ylabel('stress [MPa]', weight='semibold') axes.set_title('strength size effect', size='large', color='black', weight='bold', position=(.5, 1.03)) axes.set_axis_bgcolor(color='white') axes.ticklabel_format(scilimits=(-3., 4.)) axes.grid(color='gray', linestyle='--', linewidth=0.1, alpha=0.4) axes.legend((legend), loc='best') axes.set_xscale('log') # , subsx = [0, 1, 2, 3 ] ) axes.set_yscale('log') # , subsy = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] ) # axes.set_xlim(10.e-4) limits = max(ydata[:][0]) - min(ydata[:][0]) # annotations # x, y = self.min_plot_length, self.model.mu_sigma_0 axes.annotate( '%.1f' % y, xy=(x, y), xytext=(x * 1.1, y + limits * 0.08), # fontsize=18,family='serif', ) x, y = self.model.l_b, self.model.mu_b axes.annotate( '[%.3f,%.1f]' % (x, y), xy=(x, y), # fontsize=18,family='serif', xytext=(x * 1.1, y + limits * 0.08), arrowprops=dict(facecolor='blue', shrink=0.01)) axes.set_ylim( min(ydata[:][0]) - limits * 0.15, max(ydata[:][0]) + limits * 0.30) self.data_changed = True traits_view = View(HSplit( VGroup( Item('model@', show_label=False, resizable=True), label='data sheet', id='yse.viewmodel.model', dock='tab', ), VSplit( VGroup( Item('figure', editor=MPLFigureEditor(), resizable=True, show_label=False), label='plot sheet', id='yse.viewmodel.figure_window', dock='tab', ), VGroup( HGroup( Item('min_plot_length', label='minimum [m]', springy=True), Item('l_plot', label='maximum [m]', springy=True), Item('n_points', label='plot points', springy=True), ), VGroup( Item('test_2_on', label='I. test'), Item('Asymp', label='asymptotes'), Item('Gauss', label='Gauss'), Item('test_3_on', label='II. test'), Item('stdev', label='st. deviadion'), Item('mean_app', label='mean approx.'), columns=3, ), label='plot parameters', id='yse.viewmodel.view_params', dock='tab', ), id='yse.viewmodel.right', ), id='yse.viewmodel.splitter', ), title='Yarn Size Effect', id='yse.viewmodel', dock='tab', resizable=True, height=0.8, width=0.8, buttons=[OKButton])
class DoublePulloutSym(RF): implements(IRF) title = Str('symetrical yarn pullout') xi = Float(0.0179, auto_set=False, enter_set=True, input=True, distr=['weibull_min', 'uniform']) tau_fr = Float(2.5, auto_set=False, enter_set=True, input=True, distr=['uniform', 'norm']) # free length l = Float(0.0, auto_set=False, enter_set=True, input=True, distr=['uniform']) d = Float(26e-3, auto_set=False, input=True, enter_set=True, distr=['uniform', 'weibull_min']) E_mod = Float(72.0e3, auto_set=False, enter_set=True, input=True, distr=['uniform']) # slack theta = Float(0.01, auto_set=False, enter_set=True, input=True, distr=['uniform', 'norm']) phi = Float(1., auto_set=False, enter_set=True, input=True, distr=['uniform', 'norm']) # embedded length L = Float(1., auto_set=False, enter_set=True, input=True, distr=['uniform']) free_fiber_end = Bool(True, input=True) w = Float(enter_set=True, input=True, ctrl_range=(0, 1, 10)) weave_code = ''' ''' def __call__(self, w, tau_fr, l, d, E_mod, theta, xi, phi, L): '''Return the force for a prescribed crack opening displacement w. ''' A = pi * d**2 / 4. l = l * (1 + theta) w = w - theta * l Tau = tau_fr * phi * d * pi P_ = 0.5 * (-l * Tau + sqrt(l**2 * Tau**2 + 4 * w * H(w) * E_mod * A * Tau)) # one sided pullout P_ = ( -l * Tau + sqrt( l ** 2 * Tau ** 2 + 2 * w * H( w ) * E_mod * A * Tau ) ) if self.free_fiber_end: # ------ FREE LENGTH ------- # frictional force along the bond length P_fr = Tau * (L - l) # if pullout_criterion positive - embedded # otherwise pulled out # pull_out_criterion = P_fr - P_ P_ = P_ * H(pull_out_criterion) + P_fr * H(-pull_out_criterion) else: # -------------------------- # ------ clamped fiber end --------- v = L * (l * Tau + Tau * L) / E_mod / A P_ = P_ * H(Tau * L - P_) + (Tau * L + (w - v) / (l + 2 * L) * A * E_mod) * H(P_ - Tau * L) # ---------------------------------- P = P_ * H(A * E_mod * xi - P_) return P figure = Instance(Figure) def _figure_default(self): figure = Figure(facecolor='white') return figure changed = Event @on_trait_change('+input') def _set_changed(self): self.changed = True data_changed = Event @on_trait_change('+input') def refresh(self): figure = self.figure figure.clear() axes = figure.gca() P_fn = lambda w: self.__call__(w, self.tau_fr, self.l, self.d, self. E_mod, self.theta, self.xi, self.phi, self.L) pyF = frompyfunc(P_fn, 1, 1) w_arr = linspace(0.0, 1.0, 100) P_arr = array(pyF(w_arr), dtype='float_') axes.plot(w_arr, P_arr, lw=1.0, color='blue') self.data_changed = True group_attribs = VGroup( Item('tau_fr'), Item('l'), Item('d'), Item('E_mod'), Item('theta'), Item('xi'), Item('phi'), Item('L'), Item('free_fiber_end'), ), traits_view = View( group_attribs, scrollable=True, resizable=True, id='mk.figure.attribs', dock='tab', ) traits_view_diag = View(HSplit( group_attribs, VGroup(Item('figure', editor=MPLFigureEditor(), show_label=False, resizable=True), id='mk.figure.view'), ), id='mk.view', buttons=['OK', 'Cancel'], resizable=True, width=600, height=400)
class YMBView2D(HasTraits): data = Instance(YMBData) zero = Constant(0) slider_max = Property() def _get_slider_max(self): return self.data.n_cuts - 1 var_enum = Trait('radius', var_dict, modified=True) cut_slider = Range('zero', 'slider_max', mode='slider', auto_set=False, enter_set=True, modified=True) circle_diameter = Float(20, enter_set=True, auto_set=False, modified=True) underlay = Bool(False, modified=True) variable = Property(Array, depends_on='var_enum') @cached_property def _get_variable(self): return getattr(self.data, self.var_enum_) 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.input_changed') def _redraw(self): # TODO: set correct ranges, fix axis range (axes.xlim) self.figure.clear() self.figure.add_axes([0.1, 0.1, 0.8, 0.8]) figure = self.figure axes = figure.axes[0] axes.clear() y_arr, z_arr = self.data.cut_data[1:3] y_raw_arr, z_raw_arr = self.data.cut_raw_data[0:2] offset = hstack([0, self.data.cut_raw_data[5]]) scalar_arr = self.variable mask = y_arr[:, self.cut_slider] > -1 axes.scatter( y_raw_arr[offset[self.cut_slider]:offset[self.cut_slider + 1]], z_raw_arr[offset[self.cut_slider]:offset[self.cut_slider + 1]], s=self.circle_diameter, color='k', marker='x', label='identified filament in cut') scat = axes.scatter(y_arr[:, self.cut_slider][mask], z_arr[:, self.cut_slider][mask], s=self.circle_diameter, c=scalar_arr[:, self.cut_slider][mask], cmap=my_cmap_lin, label='connected filaments') axes.set_xlabel('$y\, [\mathrm{mm}]$', fontsize=16) axes.set_ylabel('$z\, [\mathrm{mm}]$', fontsize=16) axes.set_xlim([0, ceil(max(y_arr))]) axes.set_ylim([0, ceil(max(z_arr))]) axes.legend() figure.colorbar(scat) if self.underlay == True: axes.text(axes.get_xlim()[0], axes.get_ylim()[0], 'That\'s all at this moment :-)', color='red', fontsize=20) self.data_changed = True traits_view = View( Group( Item('var_enum'), Item('cut_slider', springy=True), Item('circle_diameter', springy=True), Item('underlay', springy=True), ), Item('figure', style='custom', editor=MPLFigureEditor(), show_label=False), resizable=True, )
class ImageProcessing(HasTraits): def __init__(self, **kw): super(ImageProcessing, self).__init__(**kw) self.on_trait_change(self.refresh, '+params') self.refresh() image_path = Str def rgb2gray(self, rgb): return np.dot(rgb[..., :3], [0.299, 0.587, 0.144]) filter = Bool(False, params=True) block_size = Range(1, 100, params=True) offset = Range(1, 20, params=True) denoise = Bool(False, params=True) denoise_spatial = Range(1, 100, params=True) processed_image = Property def _get_processed_image(self): # read image image = mpimg.imread(self.image_path) mask = image[:, :, 1] > 150. image[mask] = 255. #plt.imshow(image) #plt.show() # convert to grayscale image = self.rgb2gray(image) # crop image image = image[100:1000, 200:1100] mask = mask[100:1000, 200:1100] image = image - np.min(image) image[mask] *= 255. / np.max(image[mask]) if self.filter == True: image = denoise_bilateral(image, sigma_spatial=self.denoise_spatial) if self.denoise == True: image = threshold_adaptive(image, self.block_size, offset=self.offset) return image, mask edge_detection_method = Enum('canny', 'sobel', 'roberts', params=True) canny_sigma = Range(2.832, 5, params=True) canny_low = Range(5.92, 100, params=True) canny_high = Range(0.1, 100, params=True) edges = Property def _get_edges(self): img_edg, mask = self.processed_image if self.edge_detection_method == 'canny': img_edg = canny(img_edg, sigma=self.canny_sigma, low_threshold=self.canny_low, high_threshold=self.canny_high) elif self.edge_detection_method == 'roberts': img_edg = roberts(img_edg) elif self.edge_detection_method == 'sobel': img_edg = sobel(img_edg) img_edg = img_edg > 0.0 return img_edg radii = Int(80, params=True) radius_low = Int(40, params=True) radius_high = Int(120, params=True) step = Int(2, params=True) hough_circles = Property def _get_hough_circles(self): hough_radii = np.arange(self.radius_low, self.radius_high, self.step)[::-1] hough_res = hough_circle(self.edges, hough_radii) centers = [] accums = [] radii = [] # For each radius, extract num_peaks circles num_peaks = 3 for radius, h in zip(hough_radii, hough_res): peaks = peak_local_max(h, num_peaks=num_peaks) centers.extend(peaks) print 'circle centers = ', peaks accums.extend(h[peaks[:, 0], peaks[:, 1]]) radii.extend([radius] * num_peaks) im = mpimg.imread(self.image_path) # crop image im = im[100:1000, 200:1100] for idx in np.arange(len(centers)): center_x, center_y = centers[idx] radius = radii[idx] cx, cy = circle_perimeter(center_y, center_x, radius) mask = (cx < im.shape[0]) * (cy < im.shape[1]) im[cy[mask], cx[mask]] = (220., 20., 20.) return im eval_edges = Button def _eval_edges_fired(self): edges = self.figure_edges edges.clear() axes_edges = edges.gca() axes_edges.imshow(self.edges, plt.gray()) self.data_changed = True eval_circles = Button def _eval_circles_fired(self): circles = self.figure_circles circles.clear() axes_circles = circles.gca() axes_circles.imshow(self.hough_circles, plt.gray()) self.data_changed = True figure = Instance(Figure) def _figure_default(self): figure = Figure(facecolor='white') return figure figure_edges = Instance(Figure) def _figure_edges_default(self): figure = Figure(facecolor='white') return figure figure_circles = Instance(Figure) def _figure_circles_default(self): figure = Figure(facecolor='white') return figure data_changed = Event def plot(self, fig, fig2): figure = fig figure.clear() axes = figure.gca() img, mask = self.processed_image axes.imshow(img, plt.gray()) def refresh(self): self.plot(self.figure, self.figure_edges) self.data_changed = True traits_view = View(HGroup( Group(Item('filter', label='filter'), Item('block_size'), Item('offset'), Item('denoise', label='denoise'), Item('denoise_spatial'), label='Filters'), Group( Item('figure', editor=MPLFigureEditor(), show_label=False, resizable=True), scrollable=True, label='Plot', ), ), Tabbed( VGroup(Item('edge_detection_method'), Item('canny_sigma'), Item('canny_low'), Item('canny_high'), Item('eval_edges', label='Evaluate'), Item('figure_edges', editor=MPLFigureEditor(), show_label=False, resizable=True), scrollable=True, label='Plot_edges'), ), Tabbed( VGroup(Item('radii'), Item('radius_low'), Item('radius_high'), Item('step'), Item('eval_circles'), Item('figure_circles', editor=MPLFigureEditor(), show_label=False, resizable=True), scrollable=True, label='Plot_circles'), ), id='imview', dock='tab', title='Image processing', scrollable=True, resizable=True, width=600, height=400)
class SPIRRIDModelView(ModelView): ''' Size effect depending on the yarn length ''' model = Instance(SPIRRID) def _model_changed(self): self.model.rf = self.rf rf_values = List(IRF) def _rf_values_default(self): return [ Filament() ] rf = Enum(values = 'rf_values') def _rf_default(self): return self.rf_values[0] def _rf_changed(self): # reset the rf in the spirrid model and in the rf_modelview self.model.rf = self.rf self.rf_model_view = RFModelView(model = self.rf) # actually, the view should be reusable but the model switch # did not work for whatever reason # the binding of the view generated by edit_traits does not # react to the change in the 'model' attribute. # # Remember - we are implementing a handler here # that has an associated view. # # self.rf.model_view.model = self.rf rf_model_view = Instance(RFModelView) def _rf_model_view_default(self): return RFModelView(model = self.rf) rv_list = Property(List(RIDVariable), depends_on = 'rf') @cached_property def _get_rv_list(self): return [ RIDVariable(spirrid = self.model, rf = self.rf, varname = nm, trait_value = st) for nm, st in zip(self.rf.param_keys, self.rf.param_values) ] selected_var = Instance(RIDVariable) def _selected_var_default(self): return self.rv_list[0] run = Button(desc = 'Run the computation') def _run_fired(self): self._redraw() sample = Button(desc = 'Show samples') def _sample_fired(self): n_samples = 50 self.model.set( min_eps = 0.00, max_eps = self.max_eps, n_eps = self.n_eps, ) # get the parameter combinations for plotting rvs_theta_arr = self.model.get_rvs_theta_arr(n_samples) eps_arr = self.model.eps_arr figure = self.figure axes = figure.gca() for theta_arr in rvs_theta_arr.T: q_arr = self.rf(eps_arr, *theta_arr) axes.plot(eps_arr, q_arr, color = 'grey') self.data_changed = True run_legend = Str('', desc = 'Legend to be added to the plot of the results') clear = Button def _clear_fired(self): axes = self.figure.axes[0] axes.clear() self.data_changed = True min_eps = Float(0.0, desc = 'minimum value of the control variable') max_eps = Float(1.0, desc = 'maximum value of the control variable') n_eps = Int(100, desc = 'resolution of the control variable') label_eps = Str('epsilon', desc = 'label of the horizontal axis') label_sig = Str('sigma', desc = 'label of the vertical axis') 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) def _redraw(self): figure = self.figure axes = figure.gca() self.model.set( min_eps = 0.00, max_eps = self.max_eps, n_eps = self.n_eps, ) mc = self.model.mean_curve axes.plot(mc.xdata, mc.ydata, linewidth = 2, label = self.run_legend) axes.set_xlabel(self.label_eps) axes.set_ylabel(self.label_sig) axes.legend(loc = 'best') self.data_changed = True traits_view_tabbed = View( VGroup( HGroup( Item('run_legend', resizable = False, label = 'Run label', width = 80, springy = False), Item('run', show_label = False, resizable = False), Item('sample', show_label = False, resizable = False), Item('clear', show_label = False, resizable = False, springy = False) ), Tabbed( VGroup( Item('rf', show_label = False), Item('rf_model_view@', show_label = False, resizable = True), label = 'Deterministic model', id = 'spirrid.tview.model', ), Group( Item('rv_list', editor = rv_list_editor, show_label = False), id = 'spirrid.tview.randomization.rv', label = 'Model variables', ), Group( Item('selected_var@', show_label = False, resizable = True), id = 'spirrid.tview.randomization.distr', label = 'Distribution', ), VGroup( Item('model.cached_dG' , label = 'Cached weight factors', resizable = False, springy = False), Item('model.compiled_QdG_loop' , label = 'Compiled loop over the integration product', springy = False), Item('model.compiled_eps_loop' , enabled_when = 'model.compiled_QdG_loop', label = 'Compiled loop over the control variable', springy = False), scrollable = True, label = 'Execution configuration', id = 'spirrid.tview.exec_params', dock = 'tab', ), VGroup( HGroup( Item('min_eps' , label = 'Min', springy = False, resizable = False), Item('max_eps' , label = 'Max', springy = False, resizable = False), Item('n_eps' , label = 'N', springy = False, resizable = False), label = 'Simulation range', show_border = True ), VGroup( Item('label_eps' , label = 'x', resizable = False, springy = False), Item('label_sig' , label = 'y', resizable = False, springy = False), label = 'Axes labels', show_border = True, scrollable = True, ), label = 'Execution control', id = 'spirrid.tview.view_params', dock = 'tab', ), VGroup( Item('figure', editor = MPLFigureEditor(), resizable = True, show_label = False), label = 'Plot sheet', id = 'spirrid.tview.figure_window', dock = 'tab', scrollable = True, ), scrollable = True, id = 'spirrid.tview.tabs', dock = 'tab', ), ), title = 'SPIRRID', id = 'spirrid.viewmodel', dock = 'tab', resizable = True, height = 1.0, width = 1.0 )
class SimCrackLoc( IBVModel ): '''Model assembling the components for studying the restrained crack localization. ''' shape = Int( 1, desc = 'Number of finite elements', ps_levsls = ( 10, 40, 4 ) ) length = Float( 1, desc = 'Length of the simulated region' ) #------------------------------------------------------- # Material model for the matrix #------------------------------------------------------- mats_m = Instance( MATS1DCrackLoc ) def _mats_m_default( self ): E_m = 1 mats_m = MATS1DCrackLoc( E = E_m, R = 0.5, epsilon_0 = 0.001, epsilon_f = 0.01 ) return mats_m mats_f = Instance( MATS1DElastic ) def _mats_f_default( self ): E_f = 0 mats_f = MATS1DElastic( E = E_f ) return mats_f mats_b = Instance( MATS1DElastic ) def _mats_b_default( self ): E_b = 0 mats_b = MATS1DElastic( E = E_b ) return mats_b mats = Instance( MATS1D5Bond ) def _mats_default( self ): # Material model construction mats = MATS1D5Bond( mats_phase1 = self.mats_m, mats_phase2 = self.mats_f, mats_ifslip = self.mats_b, mats_ifopen = MATS1DElastic( E = 0 ) # elastic function of open - inactive ) return mats #------------------------------------------------------- # Finite element type #------------------------------------------------------- fets = Instance( FETSEval ) def _fets_default( self ): #return FETS1D52L8ULRH( mats_eval = self.mats ) return FETS1D52L4ULRH( mats_eval = self.mats ) #return FETS1D2L3U( mats_eval = self.mats ) run = Button @on_trait_change( 'run' ) def peval( self ): '''Evaluation procedure. ''' #mv = MATS1DDamageView( model = mats_eval ) #mv.configure_traits() self.mats_m.reset_state() # Discretization # length = self.length domain = FEGrid( coord_min = ( 0., length / 5. ), coord_max = ( length, 0. ), shape = ( self.shape, 1 ), fets_eval = self.fets ) right_dofs = domain[-1, -1, -1, :].dofs[0, :, 0] print 'concrete_dofs', id( domain ), domain[:, 0, :, 0].dofs # Response tracers self.stress_strain = RTraceGraph( name = 'Fi,right over u_right (iteration)' , var_y = 'F_int', idx_y = right_dofs[0], var_x = 'U_k', idx_x = right_dofs[0] ) self.eps_m_field = RTraceDomainListField( name = 'eps_m' , position = 'int_pnts', var = 'eps1', idx = 0, warp = True ) self.eps_f_field = RTraceDomainListField( name = 'eps_f' , position = 'int_pnts', var = 'eps2', idx = 0, warp = True ) # Response tracers self.sig_m_field = RTraceDomainListField( name = 'sig_m' , position = 'int_pnts', var = 'mats_phase1_sig_app', idx = 0 ) self.sig_f_field = RTraceDomainListField( name = 'sig_f' , position = 'int_pnts', var = 'mats_phase2_sig_app', idx = 0 ) self.omega_m_field = RTraceDomainListField( name = 'omega_m' , position = 'int_pnts', var = 'mats_phase1_omega', idx = 0, warp = True ) # damage_onset_displ = self.mats_m.epsilon_0 * self.length go_behind = 1.5 finish_displ = go_behind * damage_onset_displ n_steps = 20 step_size = ( finish_displ - damage_onset_displ ) / n_steps tmax = 1 + n_steps def ls( t ): if t <= 1: return t else: return 1.0 + ( t - 1.0 ) / n_steps * ( go_behind - 1 ) ts = TSCrackLoc( dof_resultants = True, on_update = self.plot, sdomain = domain, bcond_list = [# define the left clamping BCSlice( var = 'u', value = 0., dims = [0], slice = domain[ 0, 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 = finish_displ, dims = [0], slice = domain[-1,-1,-1, 0], # time_function = ls ), # 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 = domain[ :, :, :, :] ) ], rtrace_list = [ self.stress_strain, self.eps_m_field, self.eps_f_field, self.sig_m_field, self.sig_f_field, self.omega_m_field ] ) # Add the time-loop control tloop = TLoop( tstepper = ts, KMAX = 200, debug = True, tolerance = 1e-5, tline = TLine( min = 0.0, step = 1.0, max = 1.0 ) ) print ts.rte_dict.keys() U = tloop.eval() self.plot() return array( [ U[right_dofs[-1]] ], dtype = 'float_' ) #--------------------------------------------------------------- # 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_omega = Instance( Figure ) def _figure_omega_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 def plot( self ): self.stress_strain.refresh() t = self.stress_strain.trace ax = self.figure_ld.axes[0] ax.clear() ax.plot( t.xdata, t.ydata, linewidth = 2, color = 'blue' ) ax = self.figure_eps.axes[0] ax.clear() ef = self.eps_m_field.subfields[0] xdata = ef.vtk_X[:, 0] ydata = ef.field_arr[:, 0] idata = argsort( xdata ) ax.plot( xdata[idata], ydata[idata], linewidth = 2, color = 'grey' ) ef = self.eps_f_field.subfields[0] xdata = ef.vtk_X[:, 0] ydata = ef.field_arr[:, 0] idata = argsort( xdata ) ax.plot( xdata[idata], ydata[idata], linewidth = 2, color = 'red' ) ax.legend( ['eps_m', 'eps_f'] ) ax = self.figure_sig.axes[0] ax.clear() ef = self.sig_m_field.subfields[0] xdata = ef.vtk_X[:, 0] ydata = ef.field_arr[:, 0] idata = argsort( xdata ) ax.plot( xdata[idata], ydata[idata], linewidth = 2, color = 'grey' ) ef = self.sig_f_field.subfields[0] xdata = ef.vtk_X[:, 0] ydata = ef.field_arr[:, 0] idata = argsort( xdata ) ax.plot( xdata[idata], ydata[idata], linewidth = 2, color = 'red' ) ax.legend( ['sig_m', 'sig_f'] ) ax = self.figure_omega.axes[0] ax.clear() ef = self.omega_m_field.subfields[0] xdata = ef.vtk_X[:, 0] ydata = ef.field_arr[:, 0] idata = argsort( xdata ) ax.plot( xdata[idata], ydata[idata], linewidth = 2, color = 'brown' ) ax.legend( ['omega_m'] ) 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' ) ] 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_sjteps' ), Item( 'length' ), label = 'parameters', id = 'crackloc.viewmodel.factor.geometry', dock = 'tab', scrollable = True, ), VGroup( Item( 'mats_m@', show_label = False ), label = 'Matrix', dock = 'tab', id = 'crackloc.viewmodel.factor.matrix', scrollable = True ), VGroup( Item( 'mats_f@', show_label = False ), label = 'Fiber', dock = 'tab', id = 'crackloc.viewmodel.factor.fiber', scrollable = True ), VGroup( Item( 'mats_b@', show_label = False ), label = 'Bond', dock = 'tab', id = 'crackloc.viewmodel.factor.bond', 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_omega', editor = MPLFigureEditor(), resizable = True, show_label = False ), label = 'omega profile', id = 'crackloc.viewmode.figure_omega_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] )
class CHOBModelView(ModelView): ''' Size effect depending on the yarn length ''' model = Instance(CHOB) def _model_default(self): return CHOB() 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) @on_trait_change('model.+input') def refresh(self): distribs = self.model.distribs xdata = [] ydata = [] legend = [] if self.model.fiber_total is True: xdata.append(distribs[0].x) ydata.append(distribs[0].pdf) legend.append('fiber $l_t$') if self.model.bundle_total is True: xdata.append(distribs[1].x) ydata.append(distribs[1].pdf) legend.append('bundle $l_t$') if self.model.fiber_bundle is True: xdata.append(distribs[2].x) ydata.append(distribs[2].pdf) legend.append('fiber $l_b$') if self.model.bundle_bundle is True: xdata.append(distribs[3].x) ydata.append(distribs[3].pdf) legend.append('bundle $l_b$') if self.model.yarn_total is True: xdata.append(distribs[4].x) ydata.append(distribs[4].pdf) legend.append('yarn $l_t$') figure = self.figure figure.clear() axes = figure.gca() for x, y, l in zip(xdata[:], ydata[:], legend[:]): axes.plot(x, y, linewidth=2, label=l) axes.set_xlabel('strength', weight='semibold') axes.set_ylabel('PDF', weight='semibold') axes.set_title('chain of bundles analysis', size='large', color='black', weight='bold') axes.set_axis_bgcolor(color='white') axes.ticklabel_format(scilimits=(-3., 4.)) axes.grid(color='gray', linestyle='--', linewidth=0.1, alpha=0.4) axes.legend(loc='best') self.data_changed = True traits_view = View(VSplit(HGroup( Item('model@', show_label=False, resizable=True), label='data sheet', id='chob.viewmodel.model', dock='tab', ), HGroup( Item('figure', editor=MPLFigureEditor(), resizable=True, show_label=False), label='plot sheet', id='chob.viewmodel.figure_window', dock='tab', ), id='chob.vsplit'), title='chain of bundles', id='chob.viewmodel', dock='tab', resizable=True, buttons=[OKButton], height=0.8, width=0.8)
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'])
class SCMModelView(ModelView): model = Instance(SCM) def _model_default(self): return SCM() # Number of all curves which can be plotted by this module n_curves = Int(6) # switches between stresses with respect to area of composite and # reinforcement, respectively stresses = Enum('composite', 'reinforcement') csf = Bool(True) 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 @on_trait_change( 'model.+modified, model.reinf_ratio.+modified, stresses, csf') def refresh(self): figure = self.figure figure.clear() axes = figure.gca() scm = self.model epsilon_c_arr = scm.sig_eps_fn[0] sigma_c_arr = scm.sig_eps_fn[1] sigma_f_arr = scm.sig_eps_fn[2] sigma_fiber = scm.sig_eps_fn[3] epsilon_csf = scm.csf[0] sigma_csf = scm.csf[1] axes.set_xlabel('strain', weight='semibold') axes.set_ylabel('stress [MPa]', weight='semibold') axes.set_axis_bgcolor(color='white') axes.ticklabel_format(scilimits=(-3., 4.)) axes.grid(color='gray', linestyle='--', linewidth=0.5, alpha=0.7) if self.stresses == 'composite': axes.plot(epsilon_c_arr, sigma_c_arr, lw=2, color='blue') axes.plot(epsilon_c_arr[[0, -1]], sigma_fiber, lw=2, color='grey') legend = ['composite', 'reference stiffness'] if self.csf: axes.plot(epsilon_csf, sigma_csf, lw=1, color='green', linestyle='dotted') legend.append('strain at $CS_f$') axes.legend(legend, 'upper left') else: axes.plot(epsilon_c_arr, sigma_f_arr, lw=2, color='red') axes.plot(epsilon_c_arr[[0, -1]], sigma_fiber / scm.rho, lw=2, color='grey') legend = ['reinforcement', 'reference stiffness'] if self.csf: axes.plot(epsilon_csf, sigma_csf / scm.rho, lw=1, color='green', linestyle='dotted') legend.append('strain at $CS_f$') axes.legend(legend, 'upper left') self.data_changed = True traits_view = View(HSplit( VGroup( Item('model@', show_label=False, springy=True, width=400), label='Material parameters', id='scm.viewmodel.model', dock='tab', ), VSplit( VGroup( Item('figure', editor=MPLFigureEditor(), springy=True, resizable=True, show_label=False), label='Strain hardening response', id='scm.viewmodel.plot_window', dock='tab', ), HGroup( VGroup(Item('stresses', label='stress refered to cross-sectional area of', resizable=False, height=30), scrollable=False), VGroup(Item('csf', label='show csf'), scrollable=False), VGroup(Item('model.Pf', label='probability for csf'), scrollable=False), label='plot parameters', id='scm.viewmodel.plot_params', group_theme='blue', ), id='scm.viewmodel.right', ), id='scm.viewmodel.splitter', ), title='Stochastic Cracking Model', id='scm.viewmodel', dock='tab', resizable=True, buttons=[OKButton], height=0.8, width=0.8)
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])
class MATSCalibDamageFn(MATSExplore): ''' Fitting algorithm for the damage function of the quasi-ductile anisotropic material model. The algorithm uses the TLoop instance to proceed step by step with the computation. The value of the damage function for the time step t_n is identified iteratively by adjusting the values and evaluating the corresponding equilibrated stresses. The control parameters of the algorithm are: @param step_size: time step for fitting the damage parameter. @param tmax: end time for fitting, it might be also be set implicitly for integrity = 1 - full damage of the material. ''' # store the fitted 'PhiFn' in the data base, i.e. 'CCSUniteCell' store_fitted_phi_fn = Bool(True) # default settings are overloaded with settings specified in 'ec_config' max_eps = Property(Float) def _get_max_eps(self): # return 0.007 # set explicit value when calibration is aborted (mean # value of strain) return self.mfn_line_array_target.xdata[-1] n_steps = Int(1) log = Bool(False) # TLine parameter # KMAX = Int tolerance = Float RESETMAX = Float step_size = Property(Float, depends_on='max_eps,n_steps') @cached_property def _get_step_size(self): print('step_size = ', self.max_eps / self.n_steps) return self.max_eps / self.n_steps def run_through(self): '''Run the computation without fitting from the start to the end ''' self.tloop.tline.max = self.tmax self.tloop.tline.step = self.step_size self.tloop.eval() print('ending time', self.tloop.t_n1) # show the response def run_step_by_step(self): '''Run the computation step by step from the start to the end ''' n_steps = int(self.tmax / self.step_size) self.tloop.tline.step = self.step_size current_time = 0. tmax = 0. for i in range(n_steps): print('STEP', i) self.run_one_step() def run_trial_step(self): '''Run the computation one step starting from the current time t_n to iterate the value for phi_new which gives a fit with macroscopic stress curve. NOTE: The trial step does not update 'U_n' or 't_n'! ''' if self.log: print('--------- run trial step: --------- ') if len(self.tloop.U_n) == 0: current_U_n = self.tloop.tstepper.new_cntl_var() print('U_n = None: tloop.tstepper.new_cntl_var()', self.tloop.tstepper.new_cntl_var()) else: current_U_n = self.tloop.U_n[:] current_time = self.tloop.t_n self.run_one_step() # reset the current time back self.tloop.t_n = current_time self.tloop.U_n[:] = current_U_n[:] if self.log: print('--------- end of trial step --------- ') self.tloop.tstepper.sctx.update_state_on = False def run_one_step(self): '''Run the computation one step starting from the current time t_n with the iterated value for phi_new in order to update TLoop and save the new phi value in the array ydata of PhiFnGeneral NOTE: The calculated step does update 'U_n' or 't_n'! ''' self.tloop.tline.step = self.step_size current_time = self.tloop.t_n tmax = current_time + self.step_size self.tloop.tline.max = tmax self.tloop.eval() self.update_e_max_value_new = True #-------------------------------------------------- # Data source for calibration within simdb #-------------------------------------------------- ex_run = Instance(ExRun) composite_tensile_test = Property def _get_composite_tensile_test(self): return self.ex_run.ex_type composite_cross_section = Property def _get_composite_cross_section(self): return self.composite_tensile_test.ccs def get_target_data_exdb_tensile_test(self): '''Use the data from the ExDB ''' ctt = self.composite_tensile_test # save 'sig_eps_arr' in directory "/simdb/simdata/mats_calib_damage_fn" simdata_dir = os.path.join(simdb.simdata_dir, 'mats_calib_damage_fn') if os.path.isdir(simdata_dir) == False: os.makedirs(simdata_dir) ctt_key = str(self.composite_tensile_test.key) filename = os.path.join(simdata_dir, 'eps-sig-arr_' + ctt_key + '.csv') xdata, ydata = ctt.eps_c_interpolated_smoothed[:, None], \ ctt.sig_c_interpolated_smoothed[:, None] eps_sig_arr = np.hstack([xdata, ydata]) print('eps_sig_arr') np.savetxt(filename, eps_sig_arr, delimiter=';') print('eps-sig-data saved to file %s' % (filename)) # smoothed data without jumps with interpolated starting point in the # origin return ctt.eps_c_interpolated_smoothed, ctt.sig_c_interpolated_smoothed # return ctt.eps_c_interpolated, ctt.sig_c_interpolated # original data without jumps with interpolated starting point in the origin # return ctt.eps_ironed, ctt.sig_c_ironed # original data without smoothing (without jumps) # return ctt.eps_smooth, ctt.sig_c_smooth #smoothed data #-------------------------------------------------- # interpolation function for fitting data: #-------------------------------------------------- mfn_line_array_target = Property(Instance(MFnLineArray), depends_on='ex_run') @cached_property def _get_mfn_line_array_target(self): xdata, ydata = self.get_target_data_exdb_tensile_test() print('xdata[-1]', xdata[-1]) return MFnLineArray(xdata=xdata, ydata=ydata) fitted_phi_fn = Instance(MFnLineArray) #--------------------------------------------------------------- # PLOT OBJECT #------------------------------------------------------------------- figure = Instance(Figure) def _figure_default(self): figure = Figure(facecolor='white') figure.add_axes([0.12, 0.13, 0.85, 0.74]) return figure data_changed = Event def init(self): #-------------------------------------------------- # for fitting use 'General'-function for 'phi_fn': #-------------------------------------------------- # The value pair for the piecewise linear definition # of 'phi_fn' value consists of current strain and the # iterated 'phi_value'. The microplanes with a lower # microplane strain level use an interpolated value # for 'phi' self.fitted_phi_fn = self.dim.mats_eval.phi_fn.mfn self.fitted_phi_fn.xdata = [0] self.fitted_phi_fn.ydata = [1] self.fitted_phi_fn.data_changed = True # initialize TLoop parameters: self.tloop.setup() self.tloop.tstepper.sctx.mats_state_array[:] = 0.0 self.tloop.U_n[:] = 0.0 self.tloop.rtrace_mngr.clear() self.tloop.verbose_iteration = False self.tloop.verbose_load_step = False self.tloop.verbose_time = False # set TLine parameters self.tloop.tline.KMAX = self.KMAX self.tloop.tline.tolerance = self.tolerance self.tloop.tline.RESETMAX = self.RESETMAX # store trial step data in the lists if trial steps are to be stored # for the plotting method 'plot_trail_steps' # rec_trial_steps = True phi_trial_list_i = [] sig_trial_list_i = [] phi_trial_list_n = [] sig_trial_list_n = [] def get_lack_of_fit(self, phi_trial): '''Return the difference between the macroscopic stress calculated based on the value of phi_trial (damage at the next step) and the macroscopic stress defined as target data (=fitting curve) ''' if self.log: print('\n') print("#'get_lack_of_fit' for the trial value # START") print(' phi_trial = ', phi_trial) # value of the principle macroscopic strain corresponds to control # variable current_time = self.tloop.t_n if self.log: print(' current_time = ', current_time) print(' step_size = ', self.step_size) # ------------------------------------ # add new pair in fitted_phi_fn # ------------------------------------ # consisting of 'e_max_value_new' and 'phi_trial' x = np.hstack( [self.fitted_phi_fn.xdata[:], current_time + self.step_size]) y = np.hstack([self.fitted_phi_fn.ydata[:], phi_trial]) self.fitted_phi_fn.set(xdata=x, ydata=y) self.fitted_phi_fn.data_changed = True # ------------------------------------ # get state array before trial: # ------------------------------------ mats_state_array_old = copy(self.tloop.tstepper.sctx.mats_state_array) # ------------------------------------ # run trial step: # ------------------------------------ if self.log: print(' reset current_U_n =', self.tloop.U_n) print('CURRENT PHI', self.dim.mats_eval.phi_fn.mfn.ydata) # try the next equilibrium self.run_trial_step() # ------------------------------------ # reset mats_state_array: # ------------------------------------ # Note: the material state array (i.e. the maximum microstrains) are # updated within the iterations of each trial step, therefore a reset # is necessary in order to start each trial step with the same state # variables self.tloop.tstepper.sctx.mats_state_array[:] = mats_state_array_old[:] if self.log: print(' reset state array') # ------------------------------------ # remove trial value in fitted_phi_fn # ------------------------------------ x = self.fitted_phi_fn.xdata[:-1] y = self.fitted_phi_fn.ydata[:-1] self.fitted_phi_fn.set(xdata=x, ydata=y) self.fitted_phi_fn.data_changed = True # ------------------------------------ # get the lack of fit # ------------------------------------ # get calculated value for 'sig_app' based on the current value of 'phi_trial': # and evaluate the difference between the obtained stress and the # measured response self.tloop.rtrace_mngr.rtrace_bound_list[0].redraw() sig_app_trial = self.tloop.rtrace_mngr.rtrace_bound_list[ 0].trace.ydata[-1] # get corresponding value from the target data: sig_app_target = self.mfn_line_array_target.get_value(current_time + self.step_size) # absolut error: lack_of_fit_absolut = sig_app_trial - sig_app_target # relative error: lack_of_fit_relative = lack_of_fit_absolut / sig_app_target if self.log: print(' sig_app_trial ', sig_app_trial) print(' sig_app_target', sig_app_target) print(' lack_of_fit_absolute ', lack_of_fit_absolut) print(' lack_of_fit_relative ', lack_of_fit_relative) print('# get_lack_of_fit # END ') if self.rec_trial_steps: # store all trial values of 'phi_trail' and 'sig_app_trail' within each iteration to a global list # self.phi_trial_list_i.append(phi_trial) self.sig_trial_list_i.append(sig_app_trial) return lack_of_fit_relative param_key = Str('') phi_max_factor = Float(1.0) xtol = Float(1e-6, label='lack-of-fit tolerance') def fit_response(self): '''iterate phi_trial in each incremental step such that the lack of fit between the calculated stress and the target curve is smaller then xtol defined in function 'brentq'. NOTE: the method 'get_lack_of_fit' returns the relative error. ''' self.tloop.reset() phi_old = 1.0 # map the array dimensions to the plot axes # figure = self.figure axes = figure.axes[0] print('n_steps', self.n_steps) for n in range(self.n_steps): axes.clear() phi_new = phi_old # use scipy-functionality to get the iterated value of phi_new # If the trial value calculated with phi_trial = phi_old # is smaller then target value get_lack_of_fit has no sign change # for phi_trial = phi_old and phi_trial = 0. which is a requirement # for the function call 'brentq'. In this case the old value # for phi_trial is used and tloop moves on one step try: # 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 # # Here xtol is used to specify the allowed RELATIVE error! # therefore the relative lack of fit is returned in # method 'get_lack_of_fit' _xtol = self.xtol phi_max = min(1.0, phi_old * self.phi_max_factor) phi_min = phi_old * 0.2 # 0.0 # phi_old * 0.3 phi_new = brentq(self.get_lack_of_fit, phi_min, phi_max, xtol=_xtol) # @todo: check if 'brenth' gives better fitting results; faster? # phi_new = brenth( self.get_lack_of_fit, 0., phi_old ) print('(#) n = ', n, phi_new, phi_max, phi_old, phi_old - phi_new) except ValueError: if self.log: lof_0 = self.get_lack_of_fit(0.) lof_phi_old = self.get_lack_of_fit(phi_old) print('No sign change between get_lack_of_fit(phi_old) = ', lof_phi_old, ' and ') print('get_lack_of_fit(0.) = ', lof_0) print('Use old value for phi_trial. phi_old = ', phi_old) else: print('(!) n = ', n, phi_new, phi_max, phi_old, phi_old - phi_new) phi_new = phi_old # current time corresponds to the current strain applied # current_time = self.tloop.t_n # replace old 'phi_value' with iterated value: # phi_old = phi_new # get mats_state_array: # mats_state_array = copy(self.tloop.tstepper.sctx.mats_state_array) # update phi_data: # x = np.hstack( [self.fitted_phi_fn.xdata[:], current_time + self.step_size]) y = np.hstack([self.fitted_phi_fn.ydata[:], phi_new]) axes.plot(x, y, color='blue', linewidth=2) self.data_changed = True self.fitted_phi_fn.set(xdata=x, ydata=y) self.fitted_phi_fn.data_changed = True # run one step with the iterated value for phi in order to # update the state array and to move forward one step: if self.log: print('\n') print('### run_one_step ###') print('### step', n, '###') print('### current time:', current_time) if self.rec_trial_steps: # add entries of the iterations ('i') in the current step ('n') # (yields a list of lists) # self.phi_trial_list_n.append(self.phi_trial_list_i) self.sig_trial_list_n.append(self.sig_trial_list_i) # delete the entries of the iterations ('i') in the last step ('n') # and fill it with the iterations of the next step ('n+1') # self.phi_trial_list_i = [] self.sig_trial_list_i = [] self.run_one_step() # print '(g%)' %(n) self.fitted_phi_fn.changed = True def store(self): mats_key = self.dim.mats_eval.__class__.__name__ ctt_key = str(self.composite_tensile_test.key) if self.store_fitted_phi_fn: print( "stored 'fitted_phi_fn' in CCSUnitCell with material model %s and calibration test %s" % (mats_key, ctt_key)) print('ctt_key + self.param_key', ctt_key + self.param_key) self.composite_cross_section.set_param( mats_key, ctt_key + self.param_key, # self.composite_cross_section.set_param(mats_key, # ctt_key, copy(self.fitted_phi_fn)) # save 'sig_eps_arr' in directory # "/simdb/simdata/mats_calib_damage_fn" simdata_dir = os.path.join(simdb.simdata_dir, 'mats_calib_damage_fn') if os.path.isdir(simdata_dir) == False: os.makedirs(simdata_dir) ctt_key = str(self.composite_tensile_test.key) filename = os.path.join( simdata_dir, 'eps-phi-arr_' + ctt_key + self.param_key + '.csv') xdata, ydata = self.fitted_phi_fn.xdata[:, None], self.fitted_phi_fn.ydata[:, None] eps_phi_arr = np.hstack([xdata, ydata]) np.savetxt(filename, eps_phi_arr, delimiter=';') print('eps-phi-data saved to file %s' % (filename)) format_ticks = Bool(False) def plot_trial_steps(self): '''Plot target (sig-eps-curve of the tensile test) and trial curves and corresponding phi function together with trail steps from the iteration process. NOTE: the global variable 'rec_trial_steps' must be set to 'True' in order to store the iteration values within the global variables 'phi_trial_list_n' and 'sig_trial_list_n' n - index of the time steps to be considered i - index of the iteration steps performed in order to fit the target curve ''' #------------------------------------------------------------------- # configure the style of the font to be used for labels and ticks #------------------------------------------------------------------- # from matplotlib.font_manager import FontProperties font = FontProperties() # font.serif : Times, Palatino, New Century Schoolbook, Bookman, Computer Modern Roman # font.sans-serif : Helvetica, Avant Garde, Computer Modern Sans serif # font.cursive : Zapf Chancery # font.monospace : Courier, Computer Modern Typewriter font.set_name('Script MT') # name = ['Times New Roman', 'Helvetica', 'Script MT'] #? font.set_family('serif') # family = ['serif', 'sans-serif', 'cursive', 'fantasy', 'monospace'] font.set_style('normal') # style = ['normal', 'italic', 'oblique'] font.set_size('small') # size = ['xx-small', 'x-small', 'small', 'medium', 'large', 'x-large', 'xx-large', '11'] font.set_variant('normal') # variant= ['normal', 'small-caps'] font.set_weight('medium') # weight = ['light', 'normal', 'medium', 'semibold', 'bold', 'heavy', 'black'] #------------------------------------------------------------------- p.figure(facecolor='white', dpi=600, figsize=(8, 6)) # white background # time list corresponding to the specified numbers of steps and step size # step_list = [n * self.step_size for n in range(self.n_steps + 1)] # get list of lists containing the trial values of 'sig_app' and 'phi_trail' # the lists are defined as global variables of 'MATSCalibDamageFn' and are filled # within the iteration process when the method 'get_lack_of_fit" is called # phi_trial_list_n = [[1.]] + self.phi_trial_list_n sig_trial_list_n = [[0.]] + self.sig_trial_list_n xrange = 10. # plotting range for strain [mm/m] yrange = 15. # plotting range for stress [MPa] for n in range(self.n_steps): for i in range(len(phi_trial_list_n[n + 1])): x = np.array([step_list[n], step_list[n + 1]]) eps = 1000. * x # plot strains in permil on the x-axis #-------------------------------------- # sig-eps trial #-------------------------------------- # plot the numerically calculated sig-eps-curve (tensile test) # (with trial steps) # sig_trail = np.array( [sig_trial_list_n[n][-1], sig_trial_list_n[n + 1][i]]) p.subplot(222) p.plot(eps, sig_trail, color='k', linewidth=1) p.xlabel(r'strain $\varepsilon$ [1E-3]', fontproperties=font) p.ylabel('stress $\sigma$ [MPa]', fontproperties=font) if self.format_ticks: # format ticks for plot p.axis([0, xrange, 0., yrange], fontproperties=font) locs, labels = p.xticks() p.xticks(locs, ["%.0f" % x for x in locs], fontproperties=font) locs, labels = p.yticks() p.yticks(locs, ["%.0f" % x for x in locs], fontproperties=font) #-------------------------------------- # phi_trail #-------------------------------------- # plot the fitted phi-function # (with trial steps) # p.subplot(224) phi_trail = np.array( [phi_trial_list_n[n][-1], phi_trial_list_n[n + 1][i]]) p.plot(eps, phi_trail, color='k', linewidth=1) p.xlabel(r'strain $\varepsilon$ [1E-3]', fontproperties=font) p.ylabel('integrity $\phi$ [-]', fontproperties=font) if self.format_ticks: # format ticks for plot p.yticks([0, 0.2, 0.4, 0.6, 0.8, 1.0]) p.axis([0, xrange, 0., 1.]) locs, labels = p.xticks() p.xticks(locs, ["%.0f" % x for x in locs], fontproperties=font) locs, labels = p.yticks() p.yticks(locs, ["%.1f" % x for x in locs], fontproperties=font) #-------------------------------------- # sig-eps target #-------------------------------------- # plot the sig-eps-target curve (tensile test) # p.subplot(221) eps = 1000. * self.mfn_line_array_target.xdata[:-1] sig_target = self.mfn_line_array_target.ydata[:-1] p.plot(eps, sig_target, color='black', linewidth=1) p.xlabel(r'strain $\varepsilon$ [1E-3]', fontproperties=font) p.ylabel('stress $\sigma$ [MPa]', fontproperties=font) if self.format_ticks: # format ticks for plot p.axis([0, xrange, 0., yrange]) locs, labels = p.xticks() p.xticks(locs, ["%.0f" % x for x in locs], fontproperties=font) locs, labels = p.yticks() p.yticks(locs, ["%.0f" % x for x in locs], fontproperties=font) #-------------------------------------- # phi_trail (final) #-------------------------------------- # plot the corresponding fitted phi-function # (without trial steps) # p.subplot(223) eps = 1000. * self.fitted_phi_fn.xdata[:-1] phi_fn = self.fitted_phi_fn.ydata[:-1] p.plot(eps, phi_fn, color='black', linewidth=1) p.xlabel(r'strain $\varepsilon$ [1E-3]', fontproperties=font) p.ylabel('integrity $\phi$ [-]', fontproperties=font) if self.format_ticks: # format ticks for plot p.yticks([0, 0.2, 0.4, 0.6, 0.8, 1.0]) p.axis([0, xrange, 0., 1.]) locs, labels = p.xticks() p.xticks(locs, ["%.0f" % x for x in locs], fontproperties=font) locs, labels = p.yticks() p.yticks(locs, ["%.1f" % x for x in locs], fontproperties=font) # save figure with calibration process in directory # "/simdb/simdata/lcc_table/output_images/save_fig_to_file.png" simdata_dir = os.path.join(simdb.simdata_dir, 'mats_calib_damage_fn') if os.path.isdir(simdata_dir) == False: os.makedirs(simdata_dir) ctt_key = self.test_key filename = os.path.join(simdata_dir, ctt_key + self.param_key + '.pdf') p.savefig(filename) print('plot_trail_steps.png saved to file %s' % (filename)) filename = os.path.join(simdata_dir, ctt_key + self.param_key + '.png') p.savefig(filename, dpi=600) print('plot_trail_steps.png saved to file %s' % (filename)) p.show() test_key = Property def _get_test_key(self): return str(self.composite_tensile_test.key) #------------------------------------------------------------------------- # User interaction #------------------------------------------------------------------------- toolbar = ToolBar(Action( name="Run Calibration", tooltip='Run damage function calibration for the current parameters', image=ImageResource('kt-start'), action="run_calibration"), image_size=(22, 22), show_tool_names=False, show_divider=True, name='calibration_toolbar') traits_view = View( HSplit( Item('ex_run@', show_label=False), VSplit( Item('dim@', id='mats_calib_damage_fn.run.split', dock='tab', resizable=True, label='experiment run', show_label=False), id='mats_calib_damage_fn.mode_plot_data.vsplit', dock='tab', ), VSplit( Group( Item('figure', editor=MPLFigureEditor(), resizable=True, show_label=False), id='mats_calib_damage_fn.plot_sheet', label='fitted damage function', dock='tab', ), id='mats_calib_damage_fn.plot.vsplit', dock='tab', ), id='mats_calib_damage_fn.hsplit', dock='tab', ), # menubar = self.default_menubar(), resizable=True, toolbar=toolbar, handler=MATSCalibDamageFnController(), title='Simvisage: damage function calibration', id='mats_calib_damage_fn', dock='tab', buttons=[OKButton, CancelButton], height=0.8, width=0.8)
class CBView(ModelView): def __init__(self, **kw): super(CBView, self).__init__(**kw) self.on_trait_change(self.refresh, 'model.+params') self.refresh() model = Instance(Model) figure = Instance(Figure) def _figure_default(self): figure = Figure(facecolor='white') return figure figure2 = Instance(Figure) def _figure2_default(self): figure = Figure(facecolor='white') return figure data_changed = Event def plot(self, fig, fig2): figure = fig figure.clear() axes = figure.gca() # plot PDF axes.plot(self.model.w, self.model.model_rand, lw=2.0, color='blue', \ label='model') axes.plot(self.model.w, self.model.interpolate_experiment(self.model.w), lw=1.0, color='black', \ label='experiment') axes.legend(loc='best') # figure2 = fig2 # figure2.clear() # axes = figure2.gca() # # plot PDF # axes.plot(self.model.w2, self.model.model_extrapolate, lw=2.0, color='red', \ # label='model') # axes.legend() def refresh(self): self.plot(self.figure, self.figure2) self.data_changed = True traits_view = View(HSplit(VGroup( Group( Item('model.tau_scale'), Item('model.tau_shape'), Item('model.tau_loc'), Item('model.m'), Item('model.sV0'), Item('model.Ef'), Item('model.w_min'), Item('model.w_max'), Item('model.w_pts'), Item('model.n_int'), Item('model.w2_min'), Item('model.w2_max'), Item('model.w2_pts'), Item('model.sigmamu'), ), id='pdistrib.distr_type.pltctrls', label='Distribution parameters', scrollable=True, ), Tabbed( Group( Item('figure', editor=MPLFigureEditor(), show_label=False, resizable=True), scrollable=True, label='Plot', ), label='Plot', id='pdistrib.figure.params', dock='tab', ), Tabbed( Group( Item('figure2', editor=MPLFigureEditor(), show_label=False, resizable=True), scrollable=True, label='Plot', ), label='Plot', id='pdistrib.figure2', dock='tab', ), dock='tab', id='pdistrib.figure.view'), id='pdistrib.view', dock='tab', title='Statistical distribution', buttons=[OKButton, CancelButton], scrollable=True, resizable=True, width=600, height=400)
class RespFuncView(ModelView): def __init__(self, **kw): super(RespFuncView, self).__init__(**kw) self._redraw() self.on_trait_change(self._redraw, 'model.values') model = Instance(RespFunc) def _model_default(self): return RespFunc() 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) count = Int def _redraw(self): self.count += 1 print('redraw', self.count) # data post-processing # xdata, ydata = self.model.values if self.model.approach.plot.yvalues == 'forces': ylabel = 'pull-out force [N]' else: ydata = ydata / self.model.approach.Af ylabel = 'pull-out stress [N/m2]' title = self.model.boundary.type.BC if title[0] == 'd': xlabel = 'crack opening [m]' else: xlabel = 'displacement [m]' figure = self.figure axes = figure.axes[0] axes.clear() axes.plot(xdata, ydata, color='blue', linewidth=2, linestyle='solid') axes.set_xlabel(xlabel, weight='semibold') axes.set_ylabel(ylabel, weight='semibold') axes.set_title( title, \ size='large', color='black', \ weight='bold', position=( .5, 1.03 ) ) axes.set_axis_bgcolor(color='white') axes.ticklabel_format(scilimits=(-3., 4.)) axes.grid(color='gray', linestyle='--', linewidth=0.1, alpha=0.4) self.data_changed = True plot_button = Button('Plot pull-out') def _plot_button_fired(self): self._redraw() traits_view = View( HSplit( VGroup( Item('@model.boundary', show_label=False), Item('@model.approach', show_label=False), id='rf.model', dock='tab', label='pull-out model', ), VGroup( Item('figure', editor=MPLFigureEditor(), resizable=True, show_label=False), #Item('plot_button', show_label = False), label='plot sheet', id='rf.figure_window', dock='tab', ), id='rf.viewmodel.hsplit', ), title='Response Function', id='rf.viewmodel', dock='tab', kind='live', resizable=True, height=0.8, width=0.8, buttons=[OKButton]) def open(self, uiinfo): file_name = open_file(filter=['*.pst'], extensions=[FileInfo(), TextInfo()]) if file_name == '': return file = open(file_name, 'r') self.model = pickle.load(file) file.close() def save(self, uiinfo): file_name = save_file(filter=['*.pst'], extensions=[FileInfo(), TextInfo()]) if file_name == '': return print('writing into', file_name) file = open(file_name, 'w') pickle.dump(self.model, file) file.close()
class ExRunClassExt(SimDBClassExt): category = Str('exdata') path = List([]) # dictionary of predefined inst_list - used for # debugging and early stages of class developmemnt. # klass = Type classname = Property(depends_on='klass') @cached_property def _get_classname(self): return self.klass.__name__ field_names = Property(depends_on='klass') @cached_property def _get_field_names(self): ''' Get the list of table fields. ''' return self.klass.class_trait_names(table_field=lambda x: x != None) # Get columns for the table editor # table_columns = Property(depends_on='klass') @cached_property def _get_table_columns(self): columns = [ ObjectColumn( name='key', editable=False, horizontal_alignment='center', ) ] columns += [ ObjectColumn( name=field_name, editable=False, horizontal_alignment='center', # width = 100 ) for field_name in self.field_names ] return columns dir = Directory def _dir_default(self): '''Name of the directory for the data of the class ''' full_path = (simdb.simdb_dir, self.category) path = os.path.join(*full_path) return path def _get_file_list(self): '''Populate the inst_list with the values ''' # walk through the directories and read the # values # print('file list', self.dir) for root, sub_folders, files in os.walk(self.dir): for folder in sub_folders: ex_type_file = os.path.join(root, folder, 'ex_type.cls') if os.path.exists(ex_type_file): # check if the class specification coincides with # the klass trait of this table # f = open(ex_type_file, 'r') ex_type_klass = f.read().split('\n')[0] # use trim here f.close() klass = _find_class(ex_type_klass) if klass and klass.__name__ == self.klass.__name__: file_ext = klass().file_ext ex_type_dir = os.path.join(root, folder) ex_type_files = os.listdir(ex_type_dir) for filename in fnmatch.filter(ex_type_files, '*.%s' % file_ext): yield os.path.join(ex_type_dir, filename) ex_run_list = List def _ex_run_list_default(self): print('file_list', self._get_file_list()) return [ExRun(ex_run_file) for ex_run_file in self._get_file_list()] inst_list = List def _inst_list_default(self): print('ex_run_list', self.ex_run_list) return [ex_run.ex_type for ex_run in self.ex_run_list] selected_inst_list = List def _selected_inst_list_default(self): return [] selected_instance = Property(Instance(ExType), depends_on='selected_inst_list[]') def _get_selected_instance(self): if len(self.selected_inst_list) > 0: return self.selected_inst_list[0] else: return None def export_inst_list(self): ex_table = [] for inst in self.inst_list: row = [getattr(inst, tcol) for tcol in self.table_columns] ex_table.append(row) print(ex_table) def keys(self): return list(self.inst_list.keys()) def get(self, name, Missing): it = self.inst_list.get(name, Missing) return it #------------------------------------------------------------------- # PLOT OBJECT #------------------------------------------------------------------- figure = Instance(Figure) def _figure_default(self): figure = Figure(facecolor='white') # figure.add_axes( [0.08, 0.13, 0.85, 0.74] ) figure.add_axes([0.15, 0.15, 0.75, 0.75]) return figure # event to trigger the replotting - used by the figure editor # data_changed = Event # selected plot template # plot_template = Enum(values='plot_template_list') # list of availble plot templates # (gets extracted from the model whenever it's been changed) # plot_template_list = Property(depends_on='klass') @cached_property def _get_plot_template_list(self): '''Change the selection list of plot templates. This method is called upon every change of the model. This makes the viewing of different experiment types possible. ''' return list(self.inst_list[0].plot_templates.keys()) @on_trait_change('selected_inst_list,plot_template') def redraw(self, ui_info=None): ''' Use the currently selected plot template to plot it in the Figure. ''' # map the array dimensions to the plot axes # figure = self.figure axes = figure.gca() axes.clear() # get the labels (keys) of the selected inst_list for # attibution of the legends in matplotlib: # for run in self.selected_inst_list: proc_name = run.plot_templates[self.plot_template] plot_processor = getattr(run, proc_name) plot_processor(axes) legend_names = [] for run in self.selected_inst_list: legend_names = legend_names + [run.key] if len(legend_names) > 0: axes.legend(legend_names, loc=7) self.data_changed = True #------------------------------------------------------------------------- # VIEW #------------------------------------------------------------------------- traits_view = View( HSplit( VSplit( VGroup( HGroup( Item('classname', emphasized=True, style='readonly', label='database extension class')), Item('inst_list', editor=exdb_table_editor, show_label=False, style='custom', resizable=True), ), label='experiment table', id='exdb.table.inst_list', dock='tab', scrollable=True, ), VGroup( VGroup( Item('selected_instance@', resizable=True, show_label=False), label='experiment', id='exdb.table.instance', dock='tab', scrollable=True, ), Group( Item('figure', editor=MPLFigureEditor(), resizable=True, show_label=False), id='exrun_table.plot_sheet', label='plot sheet', dock='tab', ), Group( Item('plot_template'), columns=1, label='plot parameters', id='exrun_table.plot_params', dock='tab', ), id='exdb.table.right', layout='split', label='selected instance', dock='tab', ), id='exdb.table.splitter', ), id='exdb.table', buttons=['OK', 'Cancel'], dock='tab', resizable=True, height=0.8, width=0.8, )
class SimArrayView(ModelView): ''' View into the parametric space constructed over the model. The is associated with the PStudySpace instance covering the factor ranges using an n-dimensional array. The view is responsible for transferring the response values into 2D and 3D plots. Depending on the current view specification it also initiates the calculation of response values in the currently viewed subspace of the study. ''' model = Instance(ISimArray) #--------------------------------------------------------------- # PARAMETER RANGE SPECIFICATION #------------------------------------------------------------------- factor_dict = DelegatesTo('model') # alphabetically ordered names of factors # factor_names = DelegatesTo('model') # alphabetically ordered list of factors # factor_list = DelegatesTo('model') #--------------------------------------------------------------- # X-PARAMETER RANGE SPECIFICATION #------------------------------------------------------------------- # Selected factor name for evalution along the X-axis # x_factor_name = Str(factors_modified=True) def _x_factor_name_default(self): return self.factor_names[0] def _x_factor_name_changed(self): if self.x_factor_name == self.y_factor_name: self.y_factor_name = '-' if self.x_factor_name == self.other_factor_name: self.other_factor_name = '-' self.x_factor = self.factor_dict[self.x_factor_name] x_factor = Instance(SimFactor) def _x_factor_default(self): return self.factor_dict[self.factor_names[0]] # index of the currently selected variable x_factor_idx = Property() def _get_x_factor_idx(self): return self.factor_names.index(self.x_factor_name) #--------------------------------------------------------------- # Y-PARAMETER RANGE SPECIFICATION #------------------------------------------------------------------- y_factor_names = Property(depends_on='x_factor_name') @cached_property def _get_y_factor_names(self): current_x_factor = self.x_factor_name current_x_factor_idx = self.factor_names.index(current_x_factor) y_factor_names = self.factor_names[:current_x_factor_idx] + \ self.factor_names[current_x_factor_idx+1:] return ['-'] + y_factor_names # # Selected factor name for evalution of multiple lines # y_factor_name = Str('-', factors_modified=True) def _y_factor_name_changed(self): if self.y_factor_name == self.other_factor_name: self.other_factor_name = '-' if self.y_factor_name == '-': self.y_factor = None else: self.y_factor = self.factor_dict[self.y_factor_name] y_factor = Instance(SimFactor) y_factor_idx = Property() def _get_y_factor_idx(self): return self.factor_names.index(self.y_factor_name) #------------------------------------------------------------------ # OTHER PARAM LEVELS #------------------------------------------------------------------ other_factor_names = Property(depends_on='x_factor_name, y_factor_name') @cached_property def _get_other_factor_names(self): x_factor_idx = self.factor_names.index(self.x_factor_name) y_factor_idx = x_factor_idx if self.y_factor_name != '-': y_factor_idx = self.factor_names.index(self.y_factor_name) ignore_idx = [x_factor_idx, y_factor_idx] ignore_idx.sort() other_factor_names = self.factor_names[:ignore_idx[0] ] + \ self.factor_names[ignore_idx[0]+1: ignore_idx[1]] + \ self.factor_names[ignore_idx[1]+1:] return ['-'] + other_factor_names # # Selected factor name for evalution of multiple lines # other_factor_name = Str('-', factors_modified=True) def _other_factor_name_changed(self): if self.other_factor_name == '-': self.other_factor_levels = [] else: levels = self.factor_dict[self.other_factor_name].level_list self.other_factor_levels = list(levels) other_factor_idx = self.factor_names.index(self.other_factor_name) other_factor_level_idx = self.frozen_factor_levels[ other_factor_idx] self.other_factor_level = self.other_factor_levels[ other_factor_level_idx] other_factor_levels = List other_factor_level = Any def _other_factor_level_changed(self): level_idx = self.other_factor_levels.index(self.other_factor_level) other_factor_idx = self.factor_names.index(self.other_factor_name) self.frozen_factor_levels[other_factor_idx] = level_idx frozen_factor_levels = Array def _frozen_factor_levels_default(self): return zeros(self.model.n_factors, dtype='int_') #--------------------------------------------------------------- # OUTPUT ARRAY SPECIFICATION #------------------------------------------------------------------- outputs = DelegatesTo('model') # extract the available names output_names = DelegatesTo('model') # active selection to be plotted output_name = Str def _output_name_default(self): return self.output_names[0] output_idx = Property(Int, depends_on='output_name') def _get_output_idx(self): return self.output_names.index(self.output_name) def _output_name_changed(self): self.output = self.outputs[self.output_idx] output = Instance(SimOut) def _output_default(self): return self.outputs[0] #--------------------------------------------------------------- # PLOT OBJECT #------------------------------------------------------------------- figure = Instance(Figure) def _figure_default(self): figure = Figure(facecolor='white') figure.add_axes([0.12, 0.13, 0.85, 0.74]) return figure #--------------------------------------------------------------------------- # Public Controller interface #--------------------------------------------------------------------------- def start_study(self, ui_info): self._start_study() def stop_study(self, ui_info): todo = ToDo() todo.configure_traits(kind='modal') def _start_study(self): # identify the runs to be performed # use slices along the varied factors # to obtain the indices of the values. # get the sliced dimensions # factor_levels = [level for level in self.frozen_factor_levels] factor_levels[self.x_factor_idx] = slice(None) if self.y_factor_name != '-': factor_levels[self.y_factor_idx] = slice(None) factor_slices = tuple(factor_levels) # get the response value for the given factor slices # output_array = self.model[factor_slices] # map the array dimensions to the plot axes # figure = self.figure axes = figure.axes[0] axes.clear() x_levels = self.x_factor.level_list if self.y_factor_name == '-': axes.plot(x_levels, output_array[:, self.output_idx] # color = c, linewidth = w, linestyle = s ) else: y_levels = self.y_factor.level_list for i_y, y_level in enumerate(y_levels): index = x_levels # The dimensions of the returned array are given # by the index of the factors within the pstudy # In other words, the subspace to be plotted has # the same order of factors as the original space. # The remapping of the axes must therefore respect # this order and take y data from the first dimension # if y_factor_idx is lower than y_factor_idx # if self.y_factor_idx > self.x_factor_idx: values = output_array[:, i_y, self.output_idx] else: values = output_array[i_y, :, self.output_idx] axes.plot(index, values # color = c, linewidth = w, linestyle = s ) legend = [str(level) for level in y_levels] axes.legend(legend, loc='best') axes.set_xlabel('%s [%s]' % (self.x_factor_name, self.x_factor.unit), weight='semibold') axes.set_ylabel('%s [%s]' % (self.output_name, self.output.unit), weight='semibold') # axes.set_title( 'strength size effect',\ # size = 'large', color = 'black',\ # weight = 'bold', position = (.5,1.03)) axes.set_axis_bgcolor(color='white') # axes.ticklabel_format(scilimits = (-3.,4.)) axes.grid(color='gray', linestyle='--', linewidth=0.1, alpha=0.4) # axes.legend(( legend ), loc = 'best') # axes.set_xscale('log' ) #, subsx = [0, 1, 2, 3 ] ) # axes.set_yscale('log' ) # , subsy = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] ) #axes.set_xlim(10.e-4) self.data_changed = True data_changed = Event traits_view = View( HSplit( VGroup( VGroup( Item('x_factor_name', editor=EnumEditor(name='factor_names'), label='horizontal axis'), Item('y_factor_name', editor=EnumEditor(name='y_factor_names'), label='depth axis'), Item('other_factor_name', editor=EnumEditor(name='other_factor_names'), label='other factors'), Item('other_factor_level', editor=EnumEditor(name='other_factor_levels'), label='viewed level'), label='viewed subspace', id='sim_pstudy.viewmodel.factor.subspace', dock='tab', scrollable=True, ), VGroup( Item('output_name', editor=EnumEditor(name='output_names'), show_label=False), Item('output@', show_label=False, springy=True), label='vertical axis', id='sim_psrudy.viewmodel.control', dock='tab', ), id='sim_pstudy.viewmodel.left', label='studied factors', layout='normal', dock='tab', ), VSplit( VGroup( Item('figure', editor=MPLFigureEditor(), resizable=True, show_label=False), label='plot sheet', id='sim_pstudy.viewmode.figure_window', dock='tab', ), id='sim_pstudy.viewmodel.right', ), id='sim_pstudy.viewmodel.splitter', #group_theme = '@G', #item_theme = '@B0B', #label_theme = '@BEA', ), 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'), title='SimVisage Component: Parametric Studies', id='sim_pstudy.viewmodel', dock='tab', resizable=True, height=0.8, width=0.8, buttons=[OKButton])
class DebonTrixWindow(HasStrictTraits): '''View object for a cross section state. ''' model = Instance(DebonTrixModel) w = Range(low=0.0, high=0.1, value=0.0, enter_set=True, auto_set=False) def _w_changed(self): self.model.w = self.w self.replot = True G = Range(low=0.1, high=100, value=0.1, enter_set=True, auto_set=False) def _G_changed(self): self.model.G = self.G self.replot = True eta = Range(low=0.01, high=100, value=0.1, enter_set=True, auto_set=False) def _eta_changed(self): self.model.eta = self.eta self.replot = True n_E = Range(low=3, high=100, value=10, enter_set=True, auto_set=False) def _n_E_changed(self): self.model.n_E = self.n_E self.replot = True figure = Instance(Figure) def _figure_default(self): figure = Figure() return figure data_changed = Event replot = Button def _replot_fired(self): self.figure.clear() self.model.plot(self.figure) self.data_changed = True clear = Button() def _clear_fired(self): self.figure.clear() self.data_changed = True view = View( HSplit( Group( Item('model', resizable=True, show_label=False, width=400, height=200), ), Group( HGroup(Item('replot', show_label=False), Item('clear', show_label=False)), Item('figure', editor=MPLFigureEditor(), resizable=True, show_label=False, springy=True), Item('n_E'), Item('G'), Item('eta'), Item('w'), # Item('self.root.time', label='t/T_max'), label='plot sheet', dock='tab', )), id='bmcstreeview_id', width=0.9, height=0.8, title='Debontrix BMCS App', resizable=True, # handler=BMCSTreeViewHandler(), # menubar=MenuBar(Menu(menu_exit, Separator(), # menu_save, menu_open, # name='File')) )
class ECBCrossSection(ECBCrossSectionState): '''Cross section characteristics needed for tensile specimens ''' matrix_cs = Instance(ECBMatrixCrossSection) def _matrix_cs_default(self): return ECBMatrixCrossSection() reinf = List(ECBReinfComponent) '''Components of the cross section including the matrix and reinforcement. ''' matrix_cs_with_state = Property(depends_on='matrix_cs') @cached_property def _get_matrix_cs_with_state(self): self.matrix_cs.state = self return self.matrix_cs reinf_components_with_state = Property(depends_on='reinf') '''Components linked to the strain state of the cross section ''' @cached_property def _get_reinf_components_with_state(self): for r in self.reinf: r.state = self r.matrix_cs = self.matrix_cs return self.reinf height = DelegatesTo('matrix_cs') unit_conversion_factor = Constant(1000.0) '''Convert the MN to kN ''' #=========================================================================== # State management #=========================================================================== changed = Event '''Notifier of a changed in some component of a cross section ''' @on_trait_change('+eps_input') def _notify_eps_change(self): self.changed = True self.matrix_cs.eps_changed = True for c in self.reinf: c.eps_changed = True #=========================================================================== # Cross-sectional stress resultants #=========================================================================== N = Property(depends_on='changed') '''Get the resulting normal force. ''' @cached_property def _get_N(self): N_matrix = self.matrix_cs_with_state.N return N_matrix + np.sum([c.N for c in self.reinf_components_with_state]) M = Property(depends_on='changed') '''Get the resulting moment. ''' @cached_property def _get_M(self): M_matrix = self.matrix_cs_with_state.M M = M_matrix + np.sum([c.M for c in self.reinf_components_with_state]) return M - self.N * self.height / 2. figure = Instance(Figure) def _figure_default(self): figure = Figure(facecolor='white') figure.add_axes([0.08, 0.13, 0.85, 0.74]) return figure data_changed = Event replot = Button def _replot_fired(self): self.figure.clear() ax = self.figure.add_subplot(2, 2, 1) self.plot_eps(ax) ax = self.figure.add_subplot(2, 2, 2) self.plot_sig(ax) ax = self.figure.add_subplot(2, 2, 3) self.cc_law.plot(ax) ax = self.figure.add_subplot(2, 2, 4) self.ecb_law.plot(ax) self.data_changed = True def plot_eps(self, ax): # ax = self.figure.gca() d = self.thickness # eps ti ax.plot([-self.eps_lo, -self.eps_up], [0, self.thickness], color='black') ax.hlines(self.zz_ti_arr, [0], -self.eps_ti_arr, lw=4, color='red') # eps cj ec = np.hstack([self.eps_cj_arr] + [0, 0]) zz = np.hstack([self.zz_cj_arr] + [0, self.thickness ]) ax.fill(-ec, zz, color='blue') # reinforcement layers eps_range = np.array([max(0.0, self.eps_lo), min(0.0, self.eps_up)], dtype='float') z_ti_arr = np.ones_like(eps_range)[:, None] * self.z_ti_arr[None, :] ax.plot(-eps_range, z_ti_arr, 'k--', color='black') # neutral axis ax.plot(-eps_range, [d, d], 'k--', color='green', lw=2) ax.spines['left'].set_position('zero') ax.spines['right'].set_color('none') ax.spines['top'].set_color('none') ax.spines['left'].set_smart_bounds(True) ax.spines['bottom'].set_smart_bounds(True) ax.xaxis.set_ticks_position('bottom') ax.yaxis.set_ticks_position('left') def plot_sig(self, ax): d = self.thickness # f ti ax.hlines(self.zz_ti_arr, [0], -self.f_ti_arr, lw=4, color='red') # f cj f_c = np.hstack([self.f_cj_arr] + [0, 0]) zz = np.hstack([self.zz_cj_arr] + [0, self.thickness ]) ax.fill(-f_c, zz, color='blue') f_range = np.array([np.max(self.f_ti_arr), np.min(f_c)], dtype='float_') # neutral axis ax.plot(-f_range, [d, d], 'k--', color='green', lw=2) ax.spines['left'].set_position('zero') ax.spines['right'].set_color('none') ax.spines['top'].set_color('none') ax.spines['left'].set_smart_bounds(True) ax.spines['bottom'].set_smart_bounds(True) ax.xaxis.set_ticks_position('bottom') ax.yaxis.set_ticks_position('left') view = View(HSplit(Group( HGroup( Group(Item('thickness', springy=True), Item('width'), Item('n_layers'), Item('n_rovings'), Item('A_roving'), label='Geometry', springy=True ), Group(Item('eps_up', label='Upper strain', springy=True), Item('eps_lo', label='Lower strain'), label='Strain', springy=True ), springy=True, ), HGroup( Group(VGroup( Item('cc_law_type', show_label=False, springy=True), Item('cc_law', label='Edit', show_label=False, springy=True), Item('show_cc_law', label='Show', show_label=False, springy=True), springy=True ), Item('f_ck', label='Compressive strength'), Item('n_cj', label='Discretization'), label='Concrete', springy=True ), Group(VGroup( Item('ecb_law_type', show_label=False, springy=True), Item('ecb_law', label='Edit', show_label=False, springy=True), Item('show_ecb_law', label='Show', show_label=False, springy=True), springy=True, ), label='Reinforcement', springy=True ), springy=True, ), Group(Item('s_tex_z', label='vertical spacing', style='readonly'), label='Layout', ), Group( HGroup(Item('M', springy=True, style='readonly'), Item('N', springy=True, style='readonly'), ), label='Stress resultants' ), scrollable=True, ), Group(Item('replot', show_label=False), Item('figure', editor=MPLFigureEditor(), resizable=True, show_label=False), id='simexdb.plot_sheet', label='plot sheet', dock='tab', ), ), width=0.8, height=0.7, resizable=True, buttons=['OK', 'Cancel'])
class MATS1DDamageView(ModelView): ''' View into the parametric space constructed over the model. The is associated with the PStudySpace instance covering the factor ranges using an n-dimensional array. The view is responsible for transferring the response values into 2D and 3D plots. Depending on the current view specification it also initiates the calculation of response values in the currently viewed subspace of the study. ''' model = Instance(MATS1DDamage) max_eps = Float(0.01, enter_set=True, auto_set=False, modified=True) n_points = Int(100, enter_set=True, auto_set=False, modified=True) data_changed = Event(True) @on_trait_change('+modified,model.+modified') def _redraw(self): get_omega = frompyfunc(self.model._get_omega, 1, 1) xdata = linspace(0, self.max_eps, self.n_points) ydata = get_omega(xdata) axes = self.figure.axes[0] axes.clear() axes.plot(xdata, ydata, color='blue', linewidth=3) self.data_changed = True #--------------------------------------------------------------- # PLOT OBJECT #------------------------------------------------------------------- figure = Instance(Figure) def _figure_default(self): figure = Figure(facecolor='white') figure.add_axes([0.12, 0.13, 0.85, 0.74]) return figure traits_view = View(HSplit( VGroup( Item('model@', show_label=False, resizable=True), label='material parameters', id='mats.viewmodel.model', dock='tab', ), VSplit( VGroup( Item('figure', editor=MPLFigureEditor(), resizable=True, show_label=False), label='plot sheet', id='mats.viewmodel.figure_window', dock='tab', ), VGroup( HGroup( Item('max_eps', label='maximum epsilon [-]', springy=True), Item('n_points', label='plot points', springy=True), ), label='plot parameters', id='mats.viewmodel.view_params', dock='tab', ), id='mats.viewmodel.right', ), id='mats.viewmodel.splitter', ), title='Yarn Size Effect', id='yse.viewmodel', dock='tab', resizable=True, height=0.8, width=0.8, buttons=[OKButton])
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()))
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)