def approximate_exponential(x, y): r""" Approximate :math:`y = f(x)` by :math:`y_a = c_1 exp(- c_2 x)`. Initial guess is given by assuming y has already the required exponential form. """ from scipy.optimize import leastsq ## weights = nm.abs(y) ## weights = weights / weights.sum() weights = nm.ones_like(y) def fun(c, x, y): val = weights * (y - eval_exponential(c, x)) return val c1 = y[0] c2 = -nm.log(y[1] / c1) / (x[1] - x[0]) coefs, ier = leastsq(fun, nm.array([c1, c2]), args=(x, y)) if ier != 1: print(c1, c2) print(coefs, ier) pause('exponential fit failed!') return coefs
def check_gradient(xit, aofg, fn_of, delta, check): dofg = nm.zeros_like(aofg) xd = xit.copy() for ii in xrange(xit.shape[0]): xd[ii] = xit[ii] + delta ofp = fn_of(xd) xd[ii] = xit[ii] - delta ofm = fn_of(xd) xd[ii] = xit[ii] dofg[ii] = 0.5 * (ofp - ofm) / delta output('**********', ii, aofg[ii], dofg[ii]) diff = abs(aofg - dofg) aux = nm.concatenate( (aofg[:, nm.newaxis], dofg[:, nm.newaxis], diff[:, nm.newaxis]), 1) output(aux) output(nla.norm(diff, nm.Inf)) aofg.tofile('aofg.txt', ' ') dofg.tofile('dofg.txt', ' ') diff.tofile('diff.txt', ' ') if check == 2: import pylab pylab.plot(aofg) pylab.plot(dofg) pylab.legend(('analytical', 'finite difference')) pylab.show() pause('gradient checking done')
def approximate_exponential(x, y): r""" Approximate :math:`y = f(x)` by :math:`y_a = c_1 exp(- c_2 x)`. Initial guess is given by assuming y has already the required exponential form. """ from scipy.optimize import leastsq ## weights = nm.abs(y) ## weights = weights / weights.sum() weights = nm.ones_like(y) def fun(c, x, y): val = weights * (y - eval_exponential(c, x)) return val c1 = y[0] c2 = - nm.log(y[1] / c1) / (x[1] - x[0]) coefs, ier = leastsq(fun, nm.array([c1, c2]), args=(x, y)) if ier != 1: print c1, c2 print coefs, ier pause('exponential fit failed!') return coefs
def check_gradient( xit, aofg, fn_of, delta, check ): dofg = nm.zeros_like( aofg ) xd = xit.copy() for ii in xrange( xit.shape[0] ): xd[ii] = xit[ii] + delta ofp = fn_of( xd ) xd[ii] = xit[ii] - delta ofm = fn_of( xd ) xd[ii] = xit[ii] dofg[ii] = 0.5 * (ofp - ofm) / delta output( '**********', ii, aofg[ii], dofg[ii] ) diff = abs( aofg - dofg ) aux = nm.concatenate( (aofg[:,nm.newaxis], dofg[:,nm.newaxis], diff[:,nm.newaxis]), 1 ) output( aux ) output( nla.norm( diff, nm.Inf ) ) aofg.tofile( 'aofg.txt', ' ' ) dofg.tofile( 'dofg.txt', ' ' ) diff.tofile( 'diff.txt', ' ' ) if check == 2: import pylab pylab.plot( aofg ) pylab.plot( dofg ) pylab.legend( ('analytical', 'finite difference') ) pylab.show() pause( 'gradient checking done' )
def vary_incident_wave_dir( problem ): default_printer.prefix = 'vary_incident_wave_dir:' log_conf = { 'is_plot' : True, 'yscales' : ['linear'], 'xaxes' : ['incident wave angle [degrees]'], 'yaxes' : ['phase velocity [m/s]'], } dim = problem.domain.mesh.dim log = Log.from_conf( log_conf, ['phase velocity %d' % ii for ii in range( dim )] ) alphas = nm.linspace( 0.0, 360.0, 37 ) output( 'running for angles:', alphas ) pause() for ii, alpha in enumerate( alphas ): output( 'iteration %d: alpha %2f' % (ii, alpha) ) opts = problem.conf.options ra = nm.pi * alpha / 180.0 iwd = nm.zeros( (dim,), dtype = nm.float64 ) iwd[0:2] = [nm.cos( ra ), nm.sin( ra )] opts.incident_wave_dir = iwd out = [] yield problem, out #You have: sqrt( 10^10Pa / 10^4kg * m^3 ) #You want: #Definition: 1000 m / s convert_to_ms = 1000.0 phase_velocity = out[0] * convert_to_ms # to m/s. log( x = [alpha], *phase_velocity ) output( 'phase velocity [m/s]:', phase_velocity ) if opts.homogeneous: mat = problem.materials['matrix'] # dilatation wave: vp = \sqrt{ (\lambda + 2\mu) / \rho } vd = nm.sqrt( (mat.D[0,0]) / mat.density) * convert_to_ms # shear wave: vs = \sqrt{ \mu / \rho } vs = nm.sqrt( mat.D[-1,-1] / mat.density ) * convert_to_ms output( 'analytical dilatation: %f, shear: %f' % (vd, vs) ) # pause() yield None print log pause() if opts.homogeneous: name = 'homogeneous' else: name = 'perforated' fig_name = os.path.join( problem.output_dir, 'phase_velocity_%s%s' % (name, opts.fig_suffix) ) log( save_figure = fig_name, finished = True )
def main(): cwd = os.path.split(os.path.join(os.getcwd(), __file__))[0] log = Log((['sin(x) + i sin(x**2)', 'cos(x)'], ['exp(x)']), yscales=['linear', 'log'], xlabels=['angle', None], ylabels=[None, 'a function'], aggregate=1000, sleep=0.05, log_filename=os.path.join(cwd, 'live_plot.log')) log2 = Log([['x^3']], yscales=['linear'], xlabels=['x'], ylabels=['a cubic function'], aggregate=1000, sleep=0.05, log_filename=os.path.join(cwd, 'live_plot2.log'), formats=[['{:.5e}']]) added = 0 for x in nm.linspace(0, 4.0 * nm.pi, 200): output('x: ', x) if x < (2.0 * nm.pi): log(nm.sin(x) + 1j * nm.sin(x**2), nm.cos(x), nm.exp(x), x=[x, None]) else: if added: log(nm.sin(x) + 1j * nm.sin(x**2), nm.cos(x), nm.exp(x), x**2, x=[x, None, x]) else: log.plot_vlines(color='r', linewidth=2) log.add_group(['x^2'], yscale='linear', xlabel='new x', ylabel='square', formats=['%+g']) added += 1 if (added == 20) or (added == 50): log.plot_vlines([2], color='g', linewidth=2) log2(x * x * x, x=[x]) print(log) print(log2) pause() log(finished=True) log2(finished=True)
def main(): cwd = os.path.split(os.path.join(os.getcwd(), __file__))[0] log = Log( (["sin(x)", "cos(x)"], ["exp(x)"]), yscales=["linear", "log"], xlabels=["angle", None], ylabels=[None, "a function"], log_filename=os.path.join(cwd, "live_plot.log"), ) log2 = Log( [["x^3"]], yscales=["linear"], xlabels=["x"], ylabels=["a cubic function"], log_filename=os.path.join(cwd, "live_plot2.log"), ) added = 0 for x in nm.linspace(0, 4.0 * nm.pi, 200): output("x: ", x) if x < (2.0 * nm.pi): log(nm.sin(x), nm.cos(x), nm.exp(x), x=[x, None]) else: if added: log(nm.sin(x), nm.cos(x), nm.exp(x), x ** 2, x=[x, None, x]) else: log.plot_vlines(color="r", linewidth=2) log.add_group(["x^2"], "linear", "new x", "square", formats=["%+g"]) added += 1 if (added == 20) or (added == 50): log.plot_vlines([2], color="g", linewidth=2) log2(x * x * x, x=[x]) print log print log2 pause() log(finished=True) log2(finished=True)
def check_sensitivity(self, idsgs, delta, dp_var_data, state_ap): a_grad = self.sensitivity(dp_var_data, state_ap, select=idsgs) output( a_grad ) d_grad = [] dpb = self.dpb dim = self.sp_boxes.dim n_mesh_nod = dpb.domain.shape.n_nod coors0 = dpb.get_mesh_coors().copy() for nu in self.generate_mesh_velocity( (n_mesh_nod, dim), idsgs ): coorsp = coors0 + delta * nu dpb.set_mesh_coors( coorsp, update_fields=True ) dpb.time_update() state_dp = dpb.solve() valp = self.obj_fun(state_dp) output( 'obj_fun+:', valp ) coorsm = coors0 - delta * nu dpb.set_mesh_coors( coorsm, update_fields=True ) dpb.time_update() state_dp = dpb.solve() valm = self.obj_fun(state_dp) output( 'obj_fun-:', valm ) d_grad.append( 0.5 * (valp - valm) / delta ) ## # Restore original mesh coordinates. dpb.set_mesh_coors( coors0, update_fields=True ) d_grad = nm.array( d_grad, nm.float64 ) output( 'a: %.8e' % a_grad ) output( 'd: %.8e' % d_grad ) output( a_grad / d_grad ) pause()
def main(): cwd = os.path.split(os.path.join(os.getcwd(), __file__))[0] log = Log((['sin(x) + i sin(x**2)', 'cos(x)'], ['exp(x)']), yscales=['linear', 'log'], xlabels=['angle', None], ylabels=[None, 'a function'], log_filename=os.path.join(cwd, 'live_plot.log')) log2 = Log([['x^3']], yscales=['linear'], xlabels=['x'], ylabels=['a cubic function'], aggregate=50, sleep=0.05, log_filename=os.path.join(cwd, 'live_plot2.log'), formats=[['{:.5e}']]) added = 0 for x in nm.linspace(0, 4.0 * nm.pi, 200): output('x: ', x) if x < (2.0 * nm.pi): log(nm.sin(x)+1j*nm.sin(x**2), nm.cos(x), nm.exp(x), x=[x, None]) else: if added: log(nm.sin(x)+1j*nm.sin(x**2), nm.cos(x), nm.exp(x), x**2, x=[x, None, x]) else: log.plot_vlines(color='r', linewidth=2) log.add_group(['x^2'], yscale='linear', xlabel='new x', ylabel='square', formats=['%+g']) added += 1 if (added == 20) or (added == 50): log.plot_vlines([2], color='g', linewidth=2) log2(x*x*x, x=[x]) print(log) print(log2) pause() log(finished=True) log2(finished=True)
def __call__(self, vec_x0, conf=None, fun=None, fun_grad=None, lin_solver=None, iter_hook=None, status=None): """ Nonlinear system solver call. Solves a nonlinear system :math:`f(x) = 0` using the Newton method with backtracking line-search, starting with an initial guess :math:`x^0`. Parameters ---------- vec_x0 : array The initial guess vector :math:`x_0`. conf : Struct instance, optional The solver configuration parameters, fun : function, optional The function :math:`f(x)` whose zero is sought - the residual. fun_grad : function, optional The gradient of :math:`f(x)` - the tangent matrix. lin_solver : LinearSolver instance, optional The linear solver for each nonlinear iteration. iter_hook : function, optional User-supplied function to call before each iteration. status : dict-like, optional The user-supplied object to hold convergence statistics. Notes ----- * The optional parameters except `iter_hook` and `status` need to be given either here or upon `Newton` construction. * Setting `conf.problem == 'linear'` means a pre-assembled and possibly pre-solved matrix. This is mostly useful for linear time-dependent problems. """ import sfepy.base.plotutils as plu conf = get_default( conf, self.conf ) fun = get_default( fun, self.fun ) fun_grad = get_default( fun_grad, self.fun_grad ) lin_solver = get_default( lin_solver, self.lin_solver ) iter_hook = get_default(iter_hook, self.iter_hook) status = get_default( status, self.status ) ls_eps_a, ls_eps_r = lin_solver.get_tolerance() eps_a = get_default(ls_eps_a, 1.0) eps_r = get_default(ls_eps_r, 1.0) lin_red = conf.eps_a * conf.lin_red time_stats = {} vec_x = vec_x0.copy() vec_x_last = vec_x0.copy() vec_dx = None if self.log is not None: self.log.plot_vlines(color='r', linewidth=1.0) err = err0 = -1.0 err_last = -1.0 it = 0 while 1: if iter_hook is not None: iter_hook(self, vec_x, it, err, err0) ls = 1.0 vec_dx0 = vec_dx; while 1: tt = time.clock() try: vec_r = fun( vec_x ) except ValueError: if (it == 0) or (ls < conf.ls_min): output('giving up!') raise else: ok = False else: ok = True time_stats['rezidual'] = time.clock() - tt if ok: try: err = nla.norm( vec_r ) except: output( 'infs or nans in the residual:', vec_r ) output( nm.isfinite( vec_r ).all() ) debug() if self.log is not None: self.log(err, it) if it == 0: err0 = err; break if err < (err_last * conf.ls_on): break red = conf.ls_red; output( 'linesearch: iter %d, (%.5e < %.5e) (new ls: %e)'\ % (it, err, err_last * conf.ls_on, red * ls) ) else: # Failure. if conf.give_up_warp: output('giving up!') break red = conf.ls_red_warp; output( 'rezidual computation failed for iter %d' ' (new ls: %e)!' % (it, red * ls) ) if ls < conf.ls_min: output( 'linesearch failed, continuing anyway' ) break ls *= red; vec_dx = ls * vec_dx0; vec_x = vec_x_last.copy() - vec_dx # End residual loop. if self.log is not None: self.log.plot_vlines([1], color='g', linewidth=0.5) err_last = err; vec_x_last = vec_x.copy() condition = conv_test( conf, it, err, err0 ) if condition >= 0: break if (not ok) and conf.give_up_warp: condition = 2 break tt = time.clock() if conf.problem == 'nonlinear': mtx_a = fun_grad(vec_x) else: mtx_a = fun_grad( 'linear' ) time_stats['matrix'] = time.clock() - tt if conf.check: tt = time.clock() wt = check_tangent_matrix( conf, vec_x, fun, fun_grad ) time_stats['check'] = time.clock() - tt - wt if conf.lin_precision is not None: if ls_eps_a is not None: eps_a = max(err * conf.lin_precision, ls_eps_a) elif ls_eps_r is not None: eps_r = max(conf.lin_precision, ls_eps_r) lin_red = max(eps_a, err * eps_r) if conf.verbose: output('solving linear system...') tt = time.clock() vec_dx = lin_solver(vec_r, x0=vec_x, eps_a=eps_a, eps_r=eps_r, mtx=mtx_a) time_stats['solve'] = time.clock() - tt if conf.verbose: output('...done') for kv in time_stats.iteritems(): output( '%10s: %7.2f [s]' % kv ) vec_e = mtx_a * vec_dx - vec_r lerr = nla.norm( vec_e ) if lerr > lin_red: output('linear system not solved! (err = %e < %e)' % (lerr, lin_red)) vec_x -= vec_dx if conf.is_plot: plu.plt.ion() plu.plt.gcf().clear() plu.plt.subplot( 2, 2, 1 ) plu.plt.plot( vec_x_last ) plu.plt.ylabel( r'$x_{i-1}$' ) plu.plt.subplot( 2, 2, 2 ) plu.plt.plot( vec_r ) plu.plt.ylabel( r'$r$' ) plu.plt.subplot( 2, 2, 4 ) plu.plt.plot( vec_dx ) plu.plt.ylabel( r'$\_delta x$' ) plu.plt.subplot( 2, 2, 3 ) plu.plt.plot( vec_x ) plu.plt.ylabel( r'$x_i$' ) plu.plt.draw() plu.plt.ioff() pause() it += 1 if status is not None: status['time_stats'] = time_stats status['err0'] = err0 status['err'] = err status['n_iter'] = it status['condition'] = condition if conf.log.plot is not None: if self.log is not None: self.log(save_figure=conf.log.plot) return vec_x
def plot_matrix_diff(mtx1, mtx2, delta, legend, mode): eps = 1e-16 print(nm.amin(mtx1.data), nm.amin(mtx2.data)) print(nm.amax(mtx1.data), nm.amax(mtx2.data)) mtx_da = mtx1.copy() # To preserve structure of mtx1. mtx_da.data[:] = nm.abs(mtx1.data - mtx2.data) mtx_dr = mtx_da.copy() mtx_dr.data[:] = -1 iin = nm.where(nm.abs(mtx1.data) > eps)[0] mtx_dr.data[iin] = mtx_da.data[iin] / nm.abs(mtx1.data[iin]) print(nm.amin(mtx_da.data), nm.amax(mtx_da.data)) print(nm.amin(mtx_dr.data), nm.amax(mtx_dr.data)) epsilon = max(1e-5, 10 * delta) print('epsilon:', epsilon) pause() ija = nm.where(mtx_da.data > epsilon)[0] print_matrix_diff('--- absolute diff', legend, mtx1, mtx2, mtx_da, mtx_dr, ija) pause() iin = nm.where(nm.abs(mtx1.data) > epsilon)[0] ij = nm.where(nm.abs(mtx_dr.data[iin]) > epsilon)[0] ij = iin[ij] print_matrix_diff('--- relative diff', legend, mtx1, mtx2, mtx_da, mtx_dr, ij) pause() ijb = nm.intersect1d(ija, ij) print_matrix_diff('--- a-r', legend, mtx1, mtx2, mtx_da, mtx_dr, ijb) pause() ii = nm.argsort(mtx_dr.data[ijb]) n_s = min(20, len(ii)) ijbs = ijb[ii[-1:-n_s-1:-1]] print_matrix_diff('--- a-r 20 biggest (by r)', legend, mtx1, mtx2, mtx_da, mtx_dr, ijbs) pause() if mode < 2: return h = 100 plt.figure(h); plt.clf() plt.axes([0.04, 0.6, 0.3, 0.3], frameon=True) spy(mtx_da, epsilon) plt.title('absolute diff') plt.axes([0.68, 0.6, 0.3, 0.3], frameon=True) iia = nm.where(mtx_dr.data)[0] mtx_dr.data[nm.setdiff1d(iia, iin)] = 0.0 spy(mtx_dr, epsilon) plt.title('relative diff') plt.axes([0.36, 0.6, 0.3, 0.3], frameon=True) mtx = mtx_dr.copy() mtx.data[:] = 0.0 ii = nm.intersect1d(nm.where(mtx_dr.data > epsilon)[0], nm.where(mtx_da.data > epsilon)[0]) mtx.data[ii] = 1.0 spy(mtx, epsilon) plt.title('a-r intersection') plt.axes([0.04, 0.08, 0.42, 0.42], frameon=True) spy(mtx1, epsilon) plt.title(legend[0]) plt.axes([0.54, 0.08, 0.42, 0.42], frameon=True) spy(mtx2, epsilon) plt.title(legend[1]) plt.show()
def iplot(*args, **kwargs): plt.ion() plt.plot(*args, **kwargs) plt.draw() plt.ioff() pause()
def plot_matrix_diff(mtx1, mtx2, delta, legend, mode): eps = 1e-16 print nm.amin(mtx1.data), nm.amin(mtx2.data) print nm.amax(mtx1.data), nm.amax(mtx2.data) mtx_da = mtx1.copy() # To preserve structure of mtx1. mtx_da.data[:] = nm.abs(mtx1.data - mtx2.data) mtx_dr = mtx_da.copy() mtx_dr.data[:] = -1 iin = nm.where(nm.abs(mtx1.data) > eps)[0] mtx_dr.data[iin] = mtx_da.data[iin] / nm.abs(mtx1.data[iin]) print nm.amin(mtx_da.data), nm.amax(mtx_da.data) print nm.amin(mtx_dr.data), nm.amax(mtx_dr.data) epsilon = max(1e-5, 10 * delta) print 'epsilon:', epsilon pause() ija = nm.where(mtx_da.data > epsilon)[0] print_matrix_diff('--- absolute diff', legend, mtx1, mtx2, mtx_da, mtx_dr, ija) pause() iin = nm.where(nm.abs(mtx1.data) > epsilon)[0] ij = nm.where(nm.abs(mtx_dr.data[iin]) > epsilon)[0] ij = iin[ij] print_matrix_diff('--- relative diff', legend, mtx1, mtx2, mtx_da, mtx_dr, ij) pause() ijb = nm.intersect1d(ija, ij) print_matrix_diff('--- a-r', legend, mtx1, mtx2, mtx_da, mtx_dr, ijb) pause() ii = nm.argsort(mtx_dr.data[ijb]) n_s = min(20, len(ii)) ijbs = ijb[ii[-1:-n_s - 1:-1]] print_matrix_diff('--- a-r 20 biggest (by r)', legend, mtx1, mtx2, mtx_da, mtx_dr, ijbs) pause() if mode < 2: return h = 100 plt.figure(h) plt.clf() plt.axes([0.04, 0.6, 0.3, 0.3], frameon=True) spy(mtx_da, epsilon) plt.title('absolute diff') plt.axes([0.68, 0.6, 0.3, 0.3], frameon=True) iia = nm.where(mtx_dr.data)[0] mtx_dr.data[nm.setdiff1d(iia, iin)] = 0.0 spy(mtx_dr, epsilon) plt.title('relative diff') plt.axes([0.36, 0.6, 0.3, 0.3], frameon=True) mtx = mtx_dr.copy() mtx.data[:] = 0.0 ii = nm.intersect1d( nm.where(mtx_dr.data > epsilon)[0], nm.where(mtx_da.data > epsilon)[0]) mtx.data[ii] = 1.0 spy(mtx, epsilon) plt.title('a-r intersection') plt.axes([0.04, 0.08, 0.42, 0.42], frameon=True) spy(mtx1, epsilon) plt.title(legend[0]) plt.axes([0.54, 0.08, 0.42, 0.42], frameon=True) spy(mtx2, epsilon) plt.title(legend[1]) plt.show()
def __call__( self, vec_x0, conf = None, fun = None, fun_grad = None, lin_solver = None, status = None, problem = None ): """ Oseen solver is problem-specific - it requires a Problem instance. """ import sfepy.base.plotutils as plu conf = get_default( conf, self.conf ) fun = get_default( fun, self.fun ) fun_grad = get_default( fun_grad, self.fun_grad ) lin_solver = get_default( lin_solver, self.lin_solver ) status = get_default( status, self.status ) problem = get_default( problem, self.problem ) if problem is None: msg = 'set solver option "needs_problem_instance" to True!' raise ValueError(msg) time_stats = {} stabil = problem.get_materials()[conf.stabil_mat] ns, ii = stabil.function.function.get_maps() variables = problem.get_variables() update_var = variables.set_data_from_state make_full_vec = variables.make_full_vec print 'problem size:' print ' velocity: %s' % ii['us'] print ' pressure: %s' % ii['ps'] vec_x = vec_x0.copy() vec_x_prev = vec_x0.copy() vec_dx = None if self.log is not None: self.log.plot_vlines(color='r', linewidth=1.0) err0 = -1.0 it = 0 while 1: vec_x_prev_f = make_full_vec( vec_x_prev ) update_var( ns['b'], vec_x_prev_f, ns['u'] ) vec_b = vec_x_prev_f[ii['u']] b_norm = nla.norm( vec_b, nm.inf ) print '|b|_max: %.12e' % b_norm vec_x_f = make_full_vec( vec_x ) vec_u = vec_x_f[ii['u']] u_norm = nla.norm( vec_u, nm.inf ) print '|u|_max: %.2e' % u_norm stabil.function.set_extra_args(b_norm=b_norm) stabil.time_update(None, problem.equations, mode='force', problem=problem) max_pars = stabil.reduce_on_datas( lambda a, b: max( a, b.max() ) ) print 'stabilization parameters:' print ' gamma: %.12e' % max_pars[ns['gamma']] print ' max( delta ): %.12e' % max_pars[ns['delta']] print ' max( tau ): %.12e' % max_pars[ns['tau']] if (not are_close( b_norm, 1.0 )) and conf.adimensionalize: adimensionalize = True else: adimensionalize = False tt = time.clock() try: vec_r = fun( vec_x ) except ValueError: ok = False else: ok = True time_stats['rezidual'] = time.clock() - tt if ok: err = nla.norm( vec_r ) if it == 0: err0 = err; else: err += nla.norm( vec_dx ) else: # Failure. output( 'rezidual computation failed for iter %d!' % it ) raise RuntimeError( 'giving up...' ) if self.log is not None: self.log(err, it, max_pars[ns['gamma']], max_pars[ns['delta']], max_pars[ns['tau']]) condition = conv_test( conf, it, err, err0 ) if condition >= 0: break if adimensionalize: output( 'adimensionalizing' ) ## mat.viscosity = viscosity / b_norm ## vec_r[indx_us] /= b_norm tt = time.clock() try: mtx_a = fun_grad( vec_x ) except ValueError: ok = False else: ok = True time_stats['matrix'] = time.clock() - tt if not ok: raise RuntimeError( 'giving up...' ) tt = time.clock() vec_dx = lin_solver(vec_r, x0=vec_x, mtx=mtx_a) time_stats['solve'] = time.clock() - tt vec_e = mtx_a * vec_dx - vec_r lerr = nla.norm( vec_e ) if lerr > (conf.eps_a * conf.lin_red): output( 'linear system not solved! (err = %e)' % lerr ) if adimensionalize: output( 'restoring pressure...' ) ## vec_dx[indx_ps] *= b_norm dx_norm = nla.norm( vec_dx ) output( '||dx||: %.2e' % dx_norm ) for kv in time_stats.iteritems(): output( '%10s: %7.2f [s]' % kv ) vec_x_prev = vec_x.copy() vec_x -= vec_dx if conf.is_plot: plu.plt.ion() plu.plt.gcf().clear() plu.plt.subplot( 2, 2, 1 ) plu.plt.plot( vec_x_prev ) plu.plt.ylabel( r'$x_{i-1}$' ) plu.plt.subplot( 2, 2, 2 ) plu.plt.plot( vec_r ) plu.plt.ylabel( r'$r$' ) plu.plt.subplot( 2, 2, 4 ) plu.plt.plot( vec_dx ) plu.plt.ylabel( r'$\_delta x$' ) plu.plt.subplot( 2, 2, 3 ) plu.plt.plot( vec_x ) plu.plt.ylabel( r'$x_i$' ) plu.plt.draw() plu.plt.ioff() pause() it += 1 if conf.check_navier_stokes_rezidual: t1 = '+ dw_div_grad.%s.%s( %s.viscosity, %s, %s )' \ % (ns['i2'], ns['omega'], ns['fluid'], ns['v'], ns['u']) ## t2 = '+ dw_lin_convect.%s( %s, %s, %s )' % (ns['omega'], ## ns['v'], b_name, ns['u']) t2 = '+ dw_convect.%s.%s( %s, %s )' % (ns['i2'], ns['omega'], ns['v'], ns['u']) t3 = '- dw_stokes.%s.%s( %s, %s )' % (ns['i1'], ns['omega'], ns['v'], ns['p']) t4 = 'dw_stokes.%s.%s( %s, %s )' % (ns['i1'], ns['omega'], ns['u'], ns['q']) equations = { 'balance' : ' '.join( (t1, t2, t3) ), 'incompressibility' : t4, } problem.set_equations( equations ) try: vec_rns0 = fun( vec_x0 ) vec_rns = fun( vec_x ) except ValueError: ok = False else: ok = True if not ok: print 'Navier-Stokes rezidual computation failed!' err_ns = err_ns0 = None else: err_ns0 = nla.norm( vec_rns0 ) err_ns = nla.norm( vec_rns ) print 'Navier-Stokes rezidual0: %.8e' % err_ns0 print 'Navier-Stokes rezidual : %.8e' % err_ns print 'b - u: %.8e' % nla.norm( vec_b - vec_u ) print condition ## print vec_rns - vec_rns1 plu.plt.ion() plu.plt.gcf().clear() plu.plt.plot( vec_rns ) ## plu.plt.gcf().clear() ## plu.plt.plot( vec_rns1 ) plu.plt.draw() plu.plt.ioff() pause() else: err_ns = None if status is not None: status['time_stats'] = time_stats status['err0'] = err0 status['err'] = err status['err_ns'] = err_ns status['condition'] = condition if conf.log.plot is not None: if self.log is not None: self.log(save_figure=conf.log.plot) return vec_x
def __call__(self, vec_x0, conf=None, fun=None, fun_grad=None, lin_solver=None, status=None, problem=None): """Oseen solver is problem-specific - it requires a ProblemDefinition instance.""" import sfepy.base.plotutils as plu conf = get_default(conf, self.conf) fun = get_default(fun, self.fun) fun_grad = get_default(fun_grad, self.fun_grad) lin_solver = get_default(lin_solver, self.lin_solver) status = get_default(status, self.status) problem = get_default(problem, self.problem) if problem is None: msg = 'set solver option "needs_problem_instance" to True!' raise ValueError(msg) time_stats = {} stabil = problem.get_materials()[conf.stabil_mat] ns, ii = stabil.function.function.get_maps() variables = problem.get_variables() update_var = variables.non_state_data_from_state make_full_vec = variables.make_full_vec print 'problem size:' print ' velocity: %s' % ii['us'] print ' pressure: %s' % ii['ps'] vec_x = vec_x0.copy() vec_x_prev = vec_x0.copy() vec_dx = None if self.log is not None: self.log.plot_vlines(color='r', linewidth=1.0) err0 = -1.0 it = 0 while 1: vec_x_prev_f = make_full_vec(vec_x_prev) update_var(ns['b'], vec_x_prev_f, ns['u']) vec_b = vec_x_prev_f[ii['u']] b_norm = nla.norm(vec_b, nm.inf) print '|b|_max: %.12e' % b_norm vec_x_f = make_full_vec(vec_x) vec_u = vec_x_f[ii['u']] u_norm = nla.norm(vec_u, nm.inf) print '|u|_max: %.2e' % u_norm stabil.function.set_extra_args(b_norm=b_norm) stabil.time_update(None, problem.equations, problem) max_pars = stabil.reduce_on_datas(lambda a, b: max(a, b.max())) print 'stabilization parameters:' print ' gamma: %.12e' % max_pars[ns['gamma']] print ' max( delta ): %.12e' % max_pars[ns['delta']] print ' max( tau ): %.12e' % max_pars[ns['tau']] if (not are_close(b_norm, 1.0)) and conf.adimensionalize: adimensionalize = True else: adimensionalize = False tt = time.clock() try: vec_r = fun(vec_x) except ValueError: ok = False else: ok = True time_stats['rezidual'] = time.clock() - tt if ok: err = nla.norm(vec_r) if it == 0: err0 = err else: err += nla.norm(vec_dx) else: # Failure. output('rezidual computation failed for iter %d!' % it) raise RuntimeError('giving up...') if self.log is not None: self.log(err, it, max_pars[ns['gamma']], max_pars[ns['delta']], max_pars[ns['tau']]) condition = conv_test(conf, it, err, err0) if condition >= 0: break if adimensionalize: output('adimensionalizing') ## mat.viscosity = viscosity / b_norm ## vec_r[indx_us] /= b_norm tt = time.clock() try: mtx_a = fun_grad(vec_x) except ValueError: ok = False else: ok = True time_stats['matrix'] = time.clock() - tt if not ok: raise RuntimeError('giving up...') tt = time.clock() vec_dx = lin_solver(vec_r, x0=vec_x, mtx=mtx_a) time_stats['solve'] = time.clock() - tt vec_e = mtx_a * vec_dx - vec_r lerr = nla.norm(vec_e) if lerr > (conf.eps_a * conf.lin_red): output('linear system not solved! (err = %e)' % lerr) if adimensionalize: output('restoring pressure...') ## vec_dx[indx_ps] *= b_norm dx_norm = nla.norm(vec_dx) output('||dx||: %.2e' % dx_norm) for kv in time_stats.iteritems(): output('%10s: %7.2f [s]' % kv) vec_x_prev = vec_x.copy() vec_x -= vec_dx if conf.is_plot: plu.plt.ion() plu.plt.gcf().clear() plu.plt.subplot(2, 2, 1) plu.plt.plot(vec_x_prev) plu.plt.ylabel(r'$x_{i-1}$') plu.plt.subplot(2, 2, 2) plu.plt.plot(vec_r) plu.plt.ylabel(r'$r$') plu.plt.subplot(2, 2, 4) plu.plt.plot(vec_dx) plu.plt.ylabel(r'$\_delta x$') plu.plt.subplot(2, 2, 3) plu.plt.plot(vec_x) plu.plt.ylabel(r'$x_i$') plu.plt.draw() plu.plt.ioff() pause() it += 1 if conf.check_navier_stokes_rezidual: t1 = '+ dw_div_grad.%s.%s( %s.viscosity, %s, %s )' \ % (ns['i2'], ns['omega'], ns['fluid'], ns['v'], ns['u']) ## t2 = '+ dw_lin_convect.%s( %s, %s, %s )' % (ns['omega'], ## ns['v'], b_name, ns['u']) t2 = '+ dw_convect.%s.%s( %s, %s )' % (ns['i2'], ns['omega'], ns['v'], ns['u']) t3 = '- dw_stokes.%s.%s( %s, %s )' % (ns['i1'], ns['omega'], ns['v'], ns['p']) t4 = 'dw_stokes.%s.%s( %s, %s )' % (ns['i1'], ns['omega'], ns['u'], ns['q']) equations = { 'balance': ' '.join((t1, t2, t3)), 'incompressibility': t4, } problem.set_equations(equations) try: vec_rns0 = fun(vec_x0) vec_rns = fun(vec_x) except ValueError: ok = False else: ok = True if not ok: print 'Navier-Stokes rezidual computation failed!' err_ns = err_ns0 = None else: err_ns0 = nla.norm(vec_rns0) err_ns = nla.norm(vec_rns) print 'Navier-Stokes rezidual0: %.8e' % err_ns0 print 'Navier-Stokes rezidual : %.8e' % err_ns print 'b - u: %.8e' % nla.norm(vec_b - vec_u) print condition ## print vec_rns - vec_rns1 plu.plt.ion() plu.plt.gcf().clear() plu.plt.plot(vec_rns) ## plu.plt.gcf().clear() ## plu.plt.plot( vec_rns1 ) plu.plt.draw() plu.plt.ioff() pause() else: err_ns = None if status is not None: status['time_stats'] = time_stats status['err0'] = err0 status['err'] = err status['err_ns'] = err_ns status['condition'] = condition if conf.log.plot is not None: if self.log is not None: self.log(save_figure=conf.log.plot) return vec_x
def check_custom_sensitivity(self, term_desc, idsg, delta, dp_var_data, state_ap): pb = self.apb domain = pb.domain possible_mat_names = get_expression_arg_names(term_desc) materials = self.dpb.create_materials(possible_mat_names).as_dict() variables = self.ofg_equations.variables aux = self.dpb.create_evaluable(term_desc, try_equations=False, var_dict=variables, verbose=False, **materials) check0_equations, check0_variables = aux aux = self.dpb.create_evaluable(term_desc, try_equations=False, var_dict=variables, verbose=False, **materials) check1_equations, check1_variables = aux var_data = state_ap.get_parts() var_data.update(dp_var_data) check0_equations.set_data(var_data, ignore_unknown=True) check1_equations.set_data(var_data, ignore_unknown=True) dim = self.sp_boxes.dim n_mesh_nod = domain.shape.n_nod a_grad = [] d_grad = [] coors0 = domain.mesh.coors for nu in self.generate_mesh_velocity( (n_mesh_nod, dim), [idsg] ): check1_variables['Nu'].set_data(nu.ravel()) aux = eval_equations(check1_equations, check1_variables, term_mode=1) a_grad.append( aux ) coorsp = coors0 + delta * nu pb.set_mesh_coors( coorsp, update_fields=True ) valp = eval_equations(check0_equations, check0_variables, term_mode=0) coorsm = coors0 - delta * nu pb.set_mesh_coors( coorsm, update_fields=True ) valm = eval_equations(check0_equations, check0_variables, term_mode=0) d_grad.append( 0.5 * (valp - valm) / delta ) pb.set_mesh_coors( coors0, update_fields=True ) a_grad = nm.array( a_grad, nm.float64 ) d_grad = nm.array( d_grad, nm.float64 ) output( term_desc + ':' ) output( ' a: %.8e' % a_grad ) output( ' d: %.8e' % d_grad ) output( '-> ratio:', a_grad / d_grad ) pause()