def __init__(self, problem, pdofs, drange, is_overlap, psol, comm, matrix_hook=None, verbose=False): BasicEvaluator.__init__(self, problem, matrix_hook=matrix_hook) Struct.__init__(self, pdofs=pdofs, drange=drange, is_overlap=is_overlap, comm=comm, verbose=verbose) variables = problem.get_variables() di = variables.di ebc_rows = [] for ii, variable in enumerate(variables.iter_state(ordered=True)): eq_map = variable.eq_map ebc_rows.append(eq_map.eq_ebc + di.ptr[ii]) self.ebc_rows = nm.concatenate(ebc_rows) self.psol_i = pp.create_local_petsc_vector(pdofs) self.gather, self.scatter = pp.create_gather_scatter(pdofs, self.psol_i, psol, comm=comm)
def test_boundary_fluxes( self ): import os.path as op from sfepy.linalg import rotation_matrix2d from sfepy.discrete.evaluate import BasicEvaluator from sfepy.discrete import Material problem = self.problem angles = [0, 30, 45] region_names = ['Left', 'Right', 'Gamma'] values = [5.0, -5.0, 0.0] variables = problem.get_variables() get_state = variables.get_state_part_view state = self.state.copy(deep=True) problem.time_update(ebcs={}, epbcs={}) # problem.save_ebc( 'aux.vtk' ) state.apply_ebc() ev = BasicEvaluator( problem ) aux = ev.eval_residual(state()) field = variables['t'].field conf_m = problem.conf.get_item_by_name('materials', 'm') m = Material.from_conf(conf_m, problem.functions) name = op.join( self.options.out_dir, op.split( problem.domain.mesh.name )[1] + '_%02d.mesh' ) orig_coors = problem.get_mesh_coors().copy() ok = True for ia, angle in enumerate( angles ): self.report( '%d: mesh rotation %d degrees' % (ia, angle) ) problem.domain.mesh.transform_coors( rotation_matrix2d( angle ), ref_coors = orig_coors ) problem.set_mesh_coors(problem.domain.mesh.coors, update_fields=True) problem.domain.mesh.write( name % angle, io = 'auto' ) for ii, region_name in enumerate( region_names ): flux_term = 'd_surface_flux.i.%s( m.K, t )' % region_name val1 = problem.evaluate(flux_term, t=variables['t'], m=m) rvec = get_state( aux, 't', True ) reg = problem.domain.regions[region_name] nods = field.get_dofs_in_region(reg, merge=True) val2 = rvec[nods].sum() # Assume 1 dof per node. ok = ok and ((abs( val1 - values[ii] ) < 1e-10) and (abs( val2 - values[ii] ) < 1e-10)) self.report( ' %d. %s: %e == %e == %e'\ % (ii, region_name, val1, val2, values[ii]) ) # Restore original coordinates. problem.domain.mesh.transform_coors(rotation_matrix2d(0), ref_coors=orig_coors) problem.set_mesh_coors(problem.domain.mesh.coors, update_fields=True) return ok
def test_boundary_fluxes(self): import os.path as op from sfepy.linalg import rotation_matrix2d from sfepy.discrete.evaluate import BasicEvaluator from sfepy.discrete import Material problem = self.problem angles = [0, 30, 45] region_names = ['Left', 'Right', 'Gamma'] values = [5.0, -5.0, 0.0] variables = problem.get_variables() get_state = variables.get_state_part_view state = self.state.copy(deep=True) problem.time_update(ebcs={}, epbcs={}) # problem.save_ebc( 'aux.vtk' ) state.apply_ebc() ev = BasicEvaluator(problem) aux = ev.eval_residual(state()) field = variables['t'].field conf_m = problem.conf.get_item_by_name('materials', 'm') m = Material.from_conf(conf_m, problem.functions) name = op.join(self.options.out_dir, op.split(problem.domain.mesh.name)[1] + '_%02d.mesh') orig_coors = problem.get_mesh_coors().copy() ok = True for ia, angle in enumerate(angles): self.report('%d: mesh rotation %d degrees' % (ia, angle)) problem.domain.mesh.transform_coors(rotation_matrix2d(angle), ref_coors=orig_coors) problem.set_mesh_coors(problem.domain.mesh.coors, update_fields=True) problem.domain.mesh.write(name % angle, io='auto') for ii, region_name in enumerate(region_names): flux_term = 'd_surface_flux.i.%s( m.K, t )' % region_name val1 = problem.evaluate(flux_term, t=variables['t'], m=m) rvec = get_state(aux, 't', True) reg = problem.domain.regions[region_name] nods = field.get_dofs_in_region(reg, merge=True) val2 = rvec[nods].sum() # Assume 1 dof per node. ok = ok and ((abs(val1 - values[ii]) < 1e-10) and (abs(val2 - values[ii]) < 1e-10)) self.report( ' %d. %s: %e == %e == %e'\ % (ii, region_name, val1, val2, values[ii]) ) # Restore original coordinates. problem.domain.mesh.transform_coors(rotation_matrix2d(0), ref_coors=orig_coors) problem.set_mesh_coors(problem.domain.mesh.coors, update_fields=True) return ok
def eval_residual(self, snes, psol, prhs): self.scatter(self.psol_i, psol) rhs_if = BasicEvaluator.eval_residual(self, self.psol_i[...], is_full=True) pp.assemble_rhs_to_petsc( prhs, rhs_if, self.pdofs, self.drange, self.is_overlap, self.comm, verbose=self.verbose )
def eval_tangent_matrix(self, snes, psol, pmtx, ppmtx): self.scatter(self.psol_i, psol) mtx_if = BasicEvaluator.eval_tangent_matrix(self, self.psol_i[...], is_full=True) pp.apply_ebc_to_matrix(mtx_if, self.ebc_rows) pp.assemble_mtx_to_petsc( pmtx, mtx_if, self.pdofs, self.drange, self.is_overlap, self.comm, verbose=self.verbose )
def test_boundary_fluxes( self ): from sfepy.discrete.evaluate import BasicEvaluator from sfepy.discrete import Material problem = self.problem region_names = ['Gamma'] variables = problem.get_variables() get_state = variables.get_state_part_view state = self.state.copy(deep=True) problem.time_update(ebcs={}, epbcs={}) ## problem.save_ebc( 'aux.vtk' ) state.apply_ebc() ev = BasicEvaluator( problem ) aux = ev.eval_residual(state()) field = variables['t'].field conf_m = problem.conf.get_item_by_name('materials', 'm') m = Material.from_conf(conf_m, problem.functions) ok = True for ii, region_name in enumerate( region_names ): flux_term = 'd_surface_flux.1.%s( m.K, t )' % region_name val1 = problem.evaluate(flux_term, t=variables['t'], m=m) rvec = get_state( aux, 't', True ) reg = problem.domain.regions[region_name] nods = field.get_dofs_in_region(reg, merge=True) val2 = rvec[nods].sum() # Assume 1 dof per node. eps = 1e-2 ok = ok and ((abs( val1 - val2 ) < eps)) self.report( '%d. %s: |%e - %e| = %e < %.2e'\ % (ii, region_name, val1, val2, abs( val1 - val2 ), eps) ) return ok
def test_boundary_fluxes(self): from sfepy.discrete.evaluate import BasicEvaluator from sfepy.discrete import Material problem = self.problem region_names = ['Gamma'] variables = problem.get_variables() get_state = variables.get_state_part_view state = self.state.copy(deep=True) problem.time_update(ebcs={}, epbcs={}) ## problem.save_ebc( 'aux.vtk' ) state.apply_ebc() ev = BasicEvaluator(problem) aux = ev.eval_residual(state()) field = variables['t'].field conf_m = problem.conf.get_item_by_name('materials', 'm') m = Material.from_conf(conf_m, problem.functions) ok = True for ii, region_name in enumerate(region_names): flux_term = 'd_surface_flux.1.%s( m.K, t )' % region_name val1 = problem.evaluate(flux_term, t=variables['t'], m=m) rvec = get_state(aux, 't', True) reg = problem.domain.regions[region_name] nods = field.get_dofs_in_region(reg, merge=True) val2 = rvec[nods].sum() # Assume 1 dof per node. eps = 1e-2 ok = ok and ((abs(val1 - val2) < eps)) self.report( '%d. %s: |%e - %e| = %e < %.2e'\ % (ii, region_name, val1, val2, abs( val1 - val2 ), eps) ) return ok
def eval_tangent_matrix(self, snes, psol, pmtx, ppmtx): self.scatter(self.psol_i, psol) mtx_if = BasicEvaluator.eval_tangent_matrix(self, self.psol_i[...], is_full=True) pp.assemble_mtx_to_petsc(pmtx, mtx_if, self.pdofs, self.drange, self.is_overlap, self.comm, verbose=self.verbose)
def eval_residual(self, snes, psol, prhs): self.scatter(self.psol_i, psol) rhs_if = BasicEvaluator.eval_residual(self, self.psol_i[...], is_full=True) pp.assemble_rhs_to_petsc(prhs, rhs_if, self.pdofs, self.drange, self.is_overlap, self.comm, verbose=self.verbose)
def __init__(self, problem, pdofs, drange, is_overlap, psol, comm, matrix_hook=None, verbose=False): BasicEvaluator.__init__(self, problem, matrix_hook=matrix_hook) Struct.__init__(self, pdofs=pdofs, drange=drange, is_overlap=is_overlap, comm=comm, verbose=verbose) self.psol_i = pp.create_local_petsc_vector(pdofs) self.gather, self.scatter = pp.create_gather_scatter(pdofs, self.psol_i, psol, comm=comm)
def get_evaluator(self, reuse=False): """ Either create a new Evaluator instance (reuse == False), or return an existing instance, created in a preceding call to Problem.init_solvers(). """ if reuse: try: ev = self.evaluator except AttributeError: raise AttributeError('call Problem.init_solvers() or'\ ' set reuse to False!') else: if self.equations.variables.has_lcbc: ev = LCBCEvaluator(self, matrix_hook=self.matrix_hook) else: ev = BasicEvaluator(self, matrix_hook=self.matrix_hook) self.evaluator = ev return ev
def solve_navier_stokes(conf, options): opts = conf.options dpb = Problem.from_conf(conf, init_equations=False) equations = getattr(conf, '_'.join(('equations_direct', opts.problem))) dpb.set_equations(equations) ls_conf = dpb.get_solver_conf(opts.ls) nls_conf = dpb.get_solver_conf(opts.nls_direct) method = opts.direct_method if method == 'stationary': data = {} dpb.time_update(None) state_dp = dpb.solve(nls_conf=nls_conf) elif method == 'transient': ls = Solver.any_from_conf(ls_conf) ts_conf = dpb.get_solver_conf(opts.ts_direct) data = {'ts': Struct(dt=ts_conf.dt)} # Plug in mass term. mequations = {} for key, eq in equations.iteritems(): if 'dw_div_grad' in eq: eq = '+'.join((ts_conf.mass_term, eq)).replace('++', '+') mequations[key] = eq if ts_conf.stokes_init: state_dp0 = solve_stokes(dpb, conf.equations_direct_stokes, nls_conf) dpb.set_equations(mequations) else: dpb.set_equations(mequations) state_dp0 = dpb.create_state() dpb.time_update(None) state_dp0.apply_ebc() from sfepy.base.log import Log log = Log.from_conf(Struct(is_plot=True), ([r'$||u||$'], [r'$||p||$'])) output('Navier-Stokes...') ev = BasicEvaluator(dpb, ts=Struct(dt=ts_conf.dt)) nls = Solver.any_from_conf(nls_conf, evaluator=ev, lin_solver=ls) n_step = ts_conf.n_step step = 0 while 1: for ii in xrange(n_step): output(step) vec_u = state_dp0('w') vec_p = state_dp0('r') log(nm.linalg.norm(vec_u), nm.linalg.norm(vec_p)) dpb.variables.set_data_from_state('w_0', state_dp0(), 'w') vec_dp = nls(state_dp0()) step += 1 state_dp = state_dp0.copy() state_dp.set_reduced(vec_dp) state_dp0 = state_dp if ts_conf.interactive: try: n_step = int(raw_input('continue: ')) if n_step <= 0: break except: break vec_u = state_dp('w') vec_p = state_dp('r') log(nm.linalg.norm(vec_u), nm.linalg.norm(vec_p), finished=True) else: raise 'unknown Navier-Stokes solution method (%s)!' % method return dpb, state_dp, data