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. """ 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 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 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 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, evaluator = None, lin_solver = None, status = None ): """""" conf = get_default( conf, self.conf ) evaluator = get_default( evaluator, self.evaluator ) lin_solver = get_default( lin_solver, self.lin_solver ) status = get_default( status, self.status ) if hasattr( conf, 'fixed_data' ): fixed_data = conf.fixed_data else: fixed_data = None time_stats = {} problem = evaluator.problem stabil, ns, ii = create_stabil_data( problem, conf.fluid_mat_name, conf.stabil_mat_name, conf.lin_convect_eq_name, conf.div_eq_name ) update_var = problem.variables.non_state_data_from_state 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 err0 = -1.0 it = 0 while 1: update_var( ns['b'], vec_x_prev, ns['u'] ) vec_b = vec_x_prev[ii['u']] b_norm = nla.norm( vec_b, nm.inf ) print '|b|_max: %.12e' % b_norm vec_u = vec_x[ii['u']] u_norm = nla.norm( vec_u, nm.inf ) print '|u|_max: %.2e' % u_norm stabil.time_update( None, None, problem.domain, b_norm = b_norm, fixed_data = fixed_data ) max_pars = stabil.reduce_on_datas( lambda a, b: max( a, b.max() ) ) print 'stabilization parameters:' print ' gamma: %.12e' % max_pars['gamma'] print ' max( delta ): %.12e' % max_pars['delta'] print ' max( tau ): %.12e' % max_pars['tau'] try: print ' max( h^2 ): %.12e' % max_pars['diameters2'] except: pass if (not are_close( b_norm, 1.0 )) and conf.adimensionalize: adimensionalize = True else: adimensionalize = False tt = time.clock() vec_r, ret = evaluator.eval_residual( vec_x ) time_stats['rezidual'] = time.clock() - tt if ret == 0: # OK. err = nla.norm( vec_r ) if it == 0: err0 = err; else: err += nla.norm( vec_dx ) else: # Failure. print 'rezidual computation failed for iter %d!' % it raise RuntimeError, 'giving up...' condition = conv_test( conf, it, err, err0 ) if condition >= 0: break if adimensionalize: print 'adimensionalizing' mat.viscosity = viscosity / b_norm vec_r[indx_us] /= b_norm tt = time.clock() mtx_a, ret = evaluator.eval_tangent_matrix( vec_x ) time_stats['matrix'] = time.clock() - tt if ret != 0: raise RuntimeError, 'giving up...' tt = time.clock() vec_dx = lin_solver( vec_r, 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): print 'linear system not solved! (err = %e)' % lerr # raise RuntimeError, 'linear system not solved! (err = %e)' % lerr if adimensionalize: print 'restoring pressure...' vec_dx[indx_ps] *= b_norm dx_norm = nla.norm( vec_dx ) print '||dx||: %.2e' % dx_norm for kv in time_stats.iteritems(): print '%10s: %7.2f [s]' % kv vec_x_prev = vec_x.copy() evaluator.update_vec( vec_x, vec_dx ) if conf.is_plot: plu.pylab.ion() plu.pylab.gcf().clear() plu.pylab.subplot( 2, 2, 1 ) plu.pylab.plot( vec_x_prev ) plu.pylab.ylabel( r'$x_{i-1}$' ) plu.pylab.subplot( 2, 2, 2 ) plu.pylab.plot( vec_r ) plu.pylab.ylabel( r'$r$' ) plu.pylab.subplot( 2, 2, 4 ) plu.pylab.plot( vec_dx ) plu.pylab.ylabel( r'$\_delta x$' ) plu.pylab.subplot( 2, 2, 3 ) plu.pylab.plot( vec_x ) plu.pylab.ylabel( r'$x_i$' ) plu.pylab.draw() plu.pylab.ioff() pause() it += 1 if conf.check_navier_stokes_rezidual: ## update_var( b_name, vec_x_prev, u_name ) ## # update_var( b_name, vec_x, u_name ) ## vec_rns1, ret = residual( vec_x, context ) ## err_ns = nla.norm( vec_rns1 ) ## print '"Oseen" rezidual: %.8e' % err_ns t1 = '+ dw_div_grad.%s( %s, %s, %s )' % (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 )' % (ns['omega'], ns['v'], ns['u']) t3 = '- dw_grad.%s( %s, %s )' % (ns['omega'], ns['v'], ns['p']) t4 = 'dw_div.%s( %s, %s )' % (ns['omega'], ns['q'], ns['u']) equations = { 'balance' : ' '.join( (t1, t2, t3) ), 'incompressibility' : t4, } problem.set_equations( equations ) vec_rns0, ret = evaluator.eval_residual( vec_x0 ) vec_rns, ret = evaluator.eval_residual( vec_x ) if ret: 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.pylab.ion() plu.pylab.gcf().clear() plu.pylab.plot( vec_rns ) ## plu.pylab.gcf().clear() ## plu.pylab.plot( vec_rns1 ) plu.pylab.draw() plu.pylab.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 return vec_x