def test_without_time_mixin_prob(self): """ Test that non time dependent problems return true. """ prob = SimpleSteadyState(mesh=self.m, V=self.V) solver = Solver(prob) self.assertTrue(solver.is_steady_state())
def test_creates_files_time_dep(self): """ Test that the solve method creates the expected files for a time dependent problem. """ prob = SimpleTimeDep(mesh=self.m, V=self.V) file_path = os.path.join(self.out_dir.name, 'out.pvd') prob.set_function('K', Constant(1)) prob.set_function('S', Constant(0)) prob.set_no_boundary() num_steps = 5 prob.set_timescale(steps=num_steps, dt=0.1) prob.set_method('BackwardEuler') solver = Solver(prob) solver.u.assign(10) solver.solve(file_path=file_path) flist = os.listdir(self.out_dir.name) self.assertEqual(len(flist), num_steps + 2) self.assertIn('out.pvd', flist) for i in range(num_steps): self.assertIn('out_{}.vtu'.format(i), flist)
def test_with_time_mixin_prob_true(self): """ Test that a time dependant problem returns true if no time set. """ prob = SimpleTimeDep(mesh=self.m, V=self.V) solver = Solver(prob) self.assertTrue(solver.is_steady_state())
def test_with_time_mixin_prob_false(self): """ Test that the time dependant problem returns false if time set. """ prob = SimpleTimeDep(mesh=self.m, V=self.V) prob.set_timescale(dt=1.0, steps=5) solver = Solver(prob) self.assertFalse(solver.is_steady_state())
def test_time_dependant_result_sine(self): """ Test that the solve creates a correct result for a time dependant problem with a sine wave initial value. T(x,0) = 10*sin(3*pi*x) T(0,t) = T(1,t) = 0 Analytic solution: T(x, t) = 10*sin(3*pi*x)*exp(-pi*pi*9*t) """ m = UnitIntervalMesh(500) V = FunctionSpace(m, 'CG', 2) prob = SimpleTimeDep(mesh=m, V=V) file_path = os.path.join(self.out_dir.name, 'out.pvd') prob.set_function('C', Constant(1)) prob.set_function('K', Constant(1)) prob.set_function('S', Constant(0)) prob.set_timescale(steps=100, dt=0.00001) prob.add_boundary('dirichlet', g=0, surface='all') x = SpatialCoordinate(m) prob.T_.interpolate(10 * sin(x[0] * pi * 3)) prob.T.assign(prob.T_) prob.set_method('CrankNicolson') solver = Solver(prob) def analytical(x, t): return 10 * np.sin(3 * np.pi * x) * np.exp(-np.pi * np.pi * 9 * t) coords = np.array([i / 10 for i in range(11)]) t = 0 for i in range(10): t = prob.dt * (i + 1) * prob.steps solver.solve(file_path=file_path) value = solver.u.at(coords) expected = analytical(coords, t) print(value) print(expected) self.assertTrue(np.isclose(value, expected).all())
def test_creates_files_steady(self): """ Test that the solve method creates the expected files for a steady state problem. """ prob = SimpleSteadyState(mesh=self.m, V=self.V) file_path = os.path.join(self.out_dir.name, 'out.pvd') prob._update_func('K', Constant(1)) prob.set_function('S', Constant(0)) prob.set_no_boundary() solver = Solver(prob) solver.u.assign(10) solver.solve(file_path=file_path) flist = os.listdir(self.out_dir.name) self.assertEqual(len(flist), 3) self.assertIn('out.pvd', flist) self.assertIn('out_0.vtu', flist) self.assertIn('out_1.vtu', flist)
def test_steady_state_result_uniform(self): """ Test that the solve creates a correct uniform result for a simple steady state problem. """ prob = SimpleSteadyState(mesh=self.m, V=self.V) file_path = os.path.join(self.out_dir.name, 'out.pvd') prob.set_function('K', Constant(1)) prob.set_function('S', Constant(0)) prob.add_boundary('dirichlet', g=10, surface='all') solver = Solver(prob) solver.u.assign(100) solver.solve(file_path=file_path) expected = 10 coords = [[i / 10, j / 10, k / 10] for i in range(11) for j in range(11) for k in range(11)] value = solver.u.at(coords) self.assertTrue(np.isclose(value, expected).all())
def run(config_file, debug=False): """ Run the solve on the given problem definition config file. Args: config_file (string): The path to the config file to run. debug (bool, optional): Print debug output. Defaults to False. """ # pylint: disable=too-many-locals logger = setup_logger(debug=debug) logger.info('Running TTiP on %s', config_file) config = Config(config_file) logger.info('Setting up the problem.') start_time = time.time() logger.debug('Building mesh..') # Setup mesh and function space mesh, V = config.get_mesh() # Get parameters params = config.get_parameters() constant_ionisation = 'ionisation' in params logger.debug('Setting timescales..') # Set up timescale steps, dt, max_t = config.get_time() time_dep = (steps is not None or dt is not None or max_t is not None) limit_conductivity, limit_flux = config.get_physics_settings() ProblemClass = create_problem_class( time_dep=time_dep, sh_conductivity=True, constant_ionisation=constant_ionisation, limit_flux=limit_flux, limit_conductivity=limit_conductivity) problem = ProblemClass(mesh, V) if time_dep: problem.set_timescale(steps=steps, dt=dt, max_t=max_t) # Set up parameters ignored = [] for name, value in params.items(): try: problem.set_function(name, value) except AttributeError: ignored.append(name) if ignored: logger.info('Ignoring unnecesary parameters: %s', ', '.join(ignored)) logger.debug('Building sources..') # Set up source source = config.get_sources() problem.set_function('S', source) logger.debug('Building boundary conditions..') # Set up boundary conditions bcs = config.get_boundary_conds() for bc in bcs: problem.add_boundary(**bc) if not bcs: problem.set_no_boundary() logger.debug('Building initial value..') # Set up initial value initial_val = config.get_initial_val() problem.T.assign(initial_val) logger.info('Problem set up (%.1fs)', time.time() - start_time) logger.info('Running the solve.') start_time = time.time() # Solve file_path, method, params = config.get_solver_params() try: problem.set_method(method, **params) except AttributeError: pass solver = Solver(problem) solver.solve(file_path=file_path) logger.info('Success (%.1fs) - Results are stored in: %s', time.time() - start_time, file_path)