def __init__(self, parent=None, **traits): super(MFnChacoEditorToolbar, self).__init__(**traits) factory = self.editor.factory actions = [self.save_data, self.save_fig] toolbar = ToolBar(image_size=(16, 16), show_tool_names=False, show_divider=False, *actions) self.control = toolbar.create_tool_bar(parent, self) self.control.SetBackgroundColour(parent.GetBackgroundColour()) # fixme: Why do we have to explictly set the size of the toolbar? # Is there some method that needs to be called to do the # layout? self.control.SetSize(wx.Size(23 * len(actions), 16))
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 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) return ctt.eps_c_interpolated_smoothed, ctt.sig_c_interpolated_smoothed # smoothed data without jumps with interpolated starting point in the origin # 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 = hstack([ self.fitted_phi_fn.xdata[:], current_time + self.step_size ]) y = 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('') 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 = 1.0e-6 phi_new = brentq(self.get_lack_of_fit, 0., phi_old, 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 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 # 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 = hstack([ self.fitted_phi_fn.xdata[:], current_time + self.step_size ]) y = 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 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, map(lambda x: "%.0f" % x, locs), fontproperties=font) locs, labels = p.yticks() p.yticks(locs, map(lambda x: "%.0f" % x, 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, map(lambda x: "%.0f" % x, locs), fontproperties=font) locs, labels = p.yticks() p.yticks(locs, map(lambda x: "%.1f" % x, 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, map(lambda x: "%.0f" % x, locs), fontproperties=font) locs, labels = p.yticks() p.yticks(locs, map(lambda x: "%.0f" % x, 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, map(lambda x: "%.0f" % x, locs), fontproperties=font) locs, labels = p.yticks() p.yticks(locs, map(lambda x: "%.1f" % x, 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 = str(self.composite_tensile_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() #----------------------------------------------------------------------------------------- # 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 SimPStudy(HasTraits): """ The main application window. """ def __init__(self, **kw): super(SimPStudy, self).__init__(**kw) # The initialization should not be considered dirty # therefore set the flag to indicate unsaved study to false # self.dirty = False sim_array = Instance(SimArray) def _sim_array_default(self): return SimArray() sim_model = Property() def _set_sim_model(self, value): self.sim_array.sim_model = value def __getitem__(self, factor_slices): '''Direct access to the sim_array. ''' return self.sim_array[factor_slices] #--------------------------------------------------------------- # PERSISTENCY #------------------------------------------------------------------- file_base_name = Property() def _get_file_base_name(self): return self.sim_model.__class__.__name__ file_path = Str('') dirty = False @on_trait_change('sim_array.changed') def _set_dirty(self): self.dirty = True def new(self): sim_model = self.sim_array.sim_model self.sim_array = SimArray(sim_model=sim_model) self.dirty = False def load(self, file_name): file = open(file_name, 'r') self.sim_array = pickle.load(file) file.close() self.dirty = False def save(self, file_name): file = open(file_name, 'w') pickle.dump(self.sim_array, file) file.close() self.dirty = False def clear_cache(self): self.sim_array.clear_cache() toolbar = ToolBar(Action(name="New Study", tooltip='Create a new study', image=ImageResource('New-32'), action="new_study"), Action(name="Open Study", tooltip='Open a study', image=ImageResource('fileopen-32'), action="open_study"), Action(name="Save Study", tooltip='Save study', image=ImageResource('save'), action="save_study"), Action(name="New View", tooltip='Create new view', image=ImageResource('new_view'), action="new_view"), Action(name="Clear Cache", tooltip='Reset cache', image=ImageResource('reset'), action="clear_cache"), image_size=(22, 22), show_tool_names=False, show_divider=True, name='study_toolbar') menubar = MenuBar( Menu(Action(name="&New", action="new_study"), Action(name="&Open", action="open_study"), Action(name="&Save", action="save_study"), Action(name="Save &As", action="save_study_as"), Action(name="&Exit", action="exit_study"), name="&File"), Menu(Action(name="&New View", action="new_view"), name="&View"), Menu(Action(name="&Clear Cache", action="clear_cache"), name="&Data"), Menu(Action(name="About PStudy", action="about_pstudy"), HelpAction, name="Help")) view = View( Item('sim_array@', show_label=False), id='simvisage.simiter.pstudy', dock='tab', menubar=menubar, toolbar=toolbar, resizable=True, width=0.8, height=0.8, title='SimVisage: Parametric Study', handler=SimPStudyController, )