def test_instruction_wrong_step_factor(): f = Frame() fi = Field(f, 0.) with pytest.raises(TypeError): i = Instruction(schemes.expl_1_euler, fi, fstep=None) with pytest.raises(ValueError): i = Instruction(schemes.expl_1_euler, fi, fstep=0.) with pytest.raises(ValueError): i = Instruction(schemes.expl_1_euler, fi, fstep=1.1)
def initialize(self): '''Function initializes the simulation frame. Function sets all fields that are None with a standard value. If the grids are not set, it will call ``Simulation.makegrids()`` first.''' if not isinstance(self.grid.Nm, Field) or not isinstance(self.grid.Nr, Field): self.makegrids() # INTEGRATION VARIABLE if self.t is None: self.t = IntVar(self, 0., description="Time [s]") self.t.cfl = 0.1 self.t.updater = std.sim.dt self.t.snapshots = np.logspace(3., 5., num=21, base=10.) * c.year # STELLAR QUANTITIES self._initializestar() # GRID QUANTITIES self._initializegrid() # GAS QUANTITIES self._initializegas() # DUST QUANTITIES self._initializedust() # INTEGRATOR if self.integrator is None: instructions = [ Instruction(std.dust.impl_1_direct, self.dust.Sigma, controller={"rhs": self.dust._rhs }, description="Dust: implicit 1st-order direct solver" ), Instruction(std.gas.impl_1_direct, self.gas.Sigma, controller={"rhs": self.gas._rhs }, description="Gas: implicit 1st-order direct solver" ), ] self.integrator = Integrator( self.t, description="Default integrator") self.integrator.instructions = instructions self.integrator.preparator = std.sim.prepare_implicit_dust self.integrator.finalizer = std.sim.finalize_implicit_dust # WRITER if self.writer is None: self.writer = hdf5writer() # Updating the entire Simulation object including integrator finalization self.integrator._finalize() self.update()
def test_expl_2_heun_euler_adaptive(): f = Frame() f.addfield("Y", 1.) def dYdx(f, x, Y): return -Y f.Y.differentiator = dYdx f.addintegrationvariable("x", 0.) def dx(f): return f.x.suggested f.x.updater = dx f.x.snapshots = [10.] f.x.suggest(0.1) f.integrator = Integrator(f.x) f.integrator.instructions = [ Instruction(schemes.expl_2_heun_euler_adptv, f.Y, controller={"eps": 1.e-3}) ] f.run() assert np.allclose(f.Y, 4.553150014598088e-05)
def test_impl_1_euler_gmres_fail(): f = Frame() f.addfield("Y", 1.) def jac(f, x): return np.array([-1.]) f.Y.jacobinator = jac f.addintegrationvariable("x", 0.) def dx(f): return 0.1 f.x.updater = dx f.x.snapshots = [10.] f.integrator = Integrator(f.x) f.integrator.instructions = [ Instruction(schemes.impl_1_euler_gmres, f.Y, controller={ "gmres_opt": { "atol": 0., "tol": 1.e-18, "maxiter": 1 } }) ] with pytest.raises(StopIteration): f.run()
def test_namespacewriter_simple(): f = Frame() f.addfield("Y", 1.) f.addgroup("A") f.A.addfield("B", 0.) def dYdx(f, x, Y): return -Y f.Y.differentiator = dYdx f.addintegrationvariable("x", 0.) def dx(f): return 1. f.x.updater = dx f.x.snapshots = [1.] f.integrator = Integrator(f.x) f.integrator.instructions = [Instruction(schemes.expl_1_euler, f.Y)] f.writer = writers.namespacewriter() f.writer.dumping = True f.run() Y = f.writer.read.sequence("Y") assert np.all(Y == [1., 0.]) x = f.writer.read.sequence("x") assert np.all(x == [0., 1.]) data = f.writer.read.all() assert np.all(data.Y == [1., 0.]) assert np.all(data.x == [0., 1.]) f.writer.reset()
def test_expl_5_dormand_prince_adptv(): f = Frame() f.addfield("Y", 1.) def dYdx(f, x, Y): return -Y f.Y.differentiator = dYdx f.addintegrationvariable("x", 0.) def dx(f): return f.x.suggested f.x.updater = dx f.x.snapshots = [10.] f.x.suggest(0.1) f.integrator = Integrator(f.x) f.integrator.instructions = [ Instruction(schemes.expl_5_dormand_prince_adptv, f.Y, controller={"eps": 1.e-2}) ] f.run() assert np.allclose(f.Y, 1.8016162079480785e-06)
def test_expl_5_cash_karp_adptv(): f = Frame() f.addfield("Y", 1.) def dYdx(f, x, Y): return -Y f.Y.differentiator = dYdx f.addintegrationvariable("x", 0.) def dx(f): return f.x.suggested f.x.updater = dx f.x.snapshots = [10.] f.x.suggest(0.1) f.integrator = Integrator(f.x) f.integrator.instructions = [ Instruction(schemes.expl_5_cash_karp_adptv, f.Y, controller={"eps": 1.e-3}) ] f.run() assert np.allclose(f.Y, 4.57114092616805e-05)
def test_expl_3_gottlieb_shu_adptv(): f = Frame() f.addfield("Y", 1.) def dYdx(f, x, Y): return -Y f.Y.differentiator = dYdx f.addintegrationvariable("x", 0.) def dx(f): return f.x.suggested f.x.updater = dx f.x.snapshots = [10.] f.x.suggest(0.1) f.integrator = Integrator(f.x) f.integrator.instructions = [ Instruction(schemes.expl_3_gottlieb_shu_adptv, f.Y, controller={"eps": 1.e-4}) ] f.run() assert np.allclose(f.Y, 4.5390485375346277e-05)
def test_adaptive_update(): f = Frame() f.addfield("Y", 1.) def dYdx(f, x, Y): return -Y f.Y.differentiator = dYdx f.addintegrationvariable("x", 0.) def dx(f): return f.x.suggested f.x.updater = dx f.x.snapshots = [10.] f.x.suggest(100.) f.integrator = Integrator(f.x) f.integrator.instructions = [Instruction(schemes.expl_5_cash_karp_adptv, f.Y), Instruction(schemes.update, f.Y)] f.run() assert f.Y == 5.34990702474703e-3
def test_simple_read_files(): f = Frame() f.addgroup("A") f.A.addfield("B", [0., 0.]) f.addfield("Y", 1.) def dYdx(f, x, Y): return -Y f.Y.differentiator = dYdx f.addintegrationvariable("x", 0.) def dx(f): return 1. f.x.updater = dx f.x.snapshots = [1.] f.integrator = Integrator(f.x) f.integrator.instructions = [Instruction(schemes.expl_1_euler, f.Y)] f.writer = writers.hdf5writer() f.run() x = f.writer.read.sequence("x") assert np.all(x == [0., 1.]) Y = f.writer.read.sequence("Y") assert np.all(Y == [1., 0.]) B = f.writer.read.sequence("A.B") assert np.all(B == [0., 0.]) with pytest.raises(TypeError): f.writer.read.sequence(1) data = f.writer.read.all() assert np.all(data.x == [0., 1.]) assert np.all(data.Y == [1., 0.]) assert np.all(data.A.B == [0., 0.]) data0000 = f.writer.read.output(0) assert np.all(data0000.x == 0.) assert np.all(data0000.Y == 1.) assert np.all(data0000.A.B == 0.) with pytest.raises(RuntimeError): f.writer.read.output(2) shutil.rmtree(f.writer.datadir) with pytest.raises(RuntimeError): f.writer.datadir = "temp" f.writer.read.all() with pytest.raises(RuntimeError): f.writer.read.sequence("x") f.writer.datadir = "data"
def test_simple(): f = Frame() f.addfield("Y", 1.) def dYdx(f, x, Y): return -Y f.Y.differentiator = dYdx f.addintegrationvariable("x", 0.) def dx(f): return 1. f.x.updater = dx f.x.snapshots = [1.] f.integrator = Integrator(f.x) f.integrator.instructions = [Instruction(schemes.expl_1_euler, f.Y)] f.run() assert f.Y == 0. assert f.x.prevstepsize == 1.
def test_expl_2_heun(): f = Frame() f.addfield("Y", 1.) def dYdx(f, x, Y): return -Y f.Y.differentiator = dYdx f.addintegrationvariable("x", 0.) def dx(f): return 0.1 f.x.updater = dx f.x.snapshots = [10.] f.integrator = Integrator(f.x) f.integrator.instructions = [Instruction(schemes.expl_2_heun, f.Y)] f.run() assert np.allclose(f.Y, 4.6222977814657625e-05)
def test_expl_4_runge_kutta(): f = Frame() f.addfield("Y", 1.) def dYdx(f, x, Y): return -Y f.Y.differentiator = dYdx f.addintegrationvariable("x", 0.) def dx(f): return 0.1 f.x.updater = dx f.x.snapshots = [10.] f.integrator = Integrator(f.x) f.integrator.instructions = [Instruction(schemes.expl_4_runge_kutta, f.Y)] f.run() assert np.allclose(f.Y, 4.540034101629485e-05)
def test_expl_1_euler(): f = Frame() f.addfield("Y", 1.) def dYdx(f, x, Y): return -Y f.Y.differentiator = dYdx f.addintegrationvariable("x", 0.) def dx(f): return 0.1 f.x.updater = dx f.x.snapshots = [10.] f.integrator = Integrator(f.x) f.integrator.instructions = [Instruction(schemes.expl_1_euler, f.Y)] f.run() assert np.allclose(f.Y, 2.656139888758694e-05)
def test_impl_1_euler_gmres(): f = Frame() f.addfield("Y", 1.) def jac(f, x): return np.array([-1.]) f.Y.jacobinator = jac f.addintegrationvariable("x", 0.) def dx(f): return 0.1 f.x.updater = dx f.x.snapshots = [10.] f.integrator = Integrator(f.x) f.integrator.instructions = [Instruction(schemes.impl_1_euler_gmres, f.Y)] f.run() assert np.allclose(f.Y, 7.256571590148018e-05)
def test_adaptive_fail(): f = Frame() f.addfield("Y", 1.) def dYdx(f, x, Y): return -Y f.Y.differentiator = dYdx f.addintegrationvariable("x", 0.) def dx(f): return f.x.suggested f.x.updater = dx f.x.snapshots = [10.] f.x.suggest(100.) f.integrator = Integrator(f.x) f.integrator.instructions = [Instruction( schemes.expl_5_cash_karp_adptv, f.Y)] f.integrator.maxit = 1 with pytest.raises(StopIteration): f.run()
def test_impl_2_midpoint_direct(): f = Frame() f.addfield("Y", 1.) def jac(f, x): return np.array([-1.]) f.Y.jacobinator = jac f.addintegrationvariable("x", 0.) def dx(f): return 0.1 f.x.updater = dx f.x.snapshots = [10.] f.integrator = Integrator(f.x) f.integrator.instructions = [ Instruction(schemes.impl_2_midpoint_direct, f.Y) ] f.run() assert np.allclose(f.Y, 4.5022605238147066e-05)
def test_instruction_no_field(): with pytest.raises(TypeError): i = Instruction(schemes.expl_1_euler, None)
def setdustintegrator(self, scheme="explicit", method="cash-karp"): """Function sets the dust integrator. Parameters ---------- scheme : string, optional, default : "explicit" Possible values {"explicit", "implicit"} method : string, optional, default : "cash-karp" Possible values for explicit integration {"cash-karp"} Possible values for implicit integration {"direct", "gmres", "bicgstab}""" if not isinstance(self.grid.Nm, Field) or not isinstance(self.grid.Nr, Field): raise RuntimeError( "The simulation frame has to be initialized before calling setdustimplicit().") # Get index of dust instruction for i, inst in enumerate(self.integrator.instructions): if inst.Y is self.dust.Sigma: break if scheme == "implicit": shape2ravel = (int(self.grid.Nr*self.grid.Nm)) # Hidden fields # We store the old values of the surface density in a hidden field # to calculate the fluxes through the boundaries in case of implicit integration. self.dust._SigmaOld = Field( self, self.dust.Sigma, description="Previous value of surface density [g/cm²]") # The right-hand side of the matrix equation is stored in a hidden field self.dust._rhs = Field(self, np.zeros( shape2ravel), description="Right-hand side of matrix equation [g/cm²]") # Setting the Jacobinator self.dust.Sigma.jacobinator = std.dust.jacobian # Time step routine self.t.updater = std.sim.dt # Updaters self.dust.v.updater = ["frag", "driftmax", "rel"] self.dust.updater = ["delta", "rhos", "fill", "a", "St", "H", "rho", "backreaction", "v", "D", "eps", "kernel", "p", "S"] self.dust.S.updater = ["ext", "tot"] # Preparation/Finalization self.integrator.preparator = std.sim.prepare_implicit_dust self.integrator.finalizer = std.sim.finalize_implicit_dust # Integrator if method == "direct": inst = Instruction(std.dust.impl_1_direct, self.dust.Sigma, controller={"rhs": self.dust._rhs }, description="Dust: implicit 1st-order direct solver" ) self.integrator.instructions[i] = inst elif method == "gmres": raise NotImplementedError( "GMRES method is not implemented, yet.") elif method == "bicgstab": raise NotImplementedError("BiCGSTAB is not implemented, yet.") else: raise RuntimeError("Invalid method for implicit integration.") elif scheme == "explicit": # Remove hidden fields if they exist if hasattr(self.dust, "_SigmaOld"): del self.dust._SigmaOld if hasattr(self.dust, "_rhs"): del self.dust._rhs # Unset Jacobian self.dust.Sigma.jacobinator = None # Updaters self.dust.v.updater = ["frag", "driftmax", "rad", "rel"] self.dust.updater = ["delta", "rhos", "fill", "a", "St", "H", "rho", "backreaction", "v", "D", "eps", "Fi", "kernel", "p", "S"] self.dust.S.updater = ["coag", "hyd", "ext", "tot"] # Preparation/Finalization self.integrator.preparator = std.sim.prepare_explicit_dust self.integrator.finalizer = std.sim.finalize_explicit_dust if method == "cash-karp": # Adaptive time step routine self.t.updater = std.sim.dt_adaptive # Instruction inst = Instruction(schemes.expl_5_cash_karp_adptv, self.dust.Sigma, controller={"dYdx": self.dust.S.tot, "eps": 0.1, "S": 0.9, }, description="Dust: explicit 5th-order adaptive Cash-Karp method" ) self.integrator.instructions[i] = inst self.t.suggest(1.*c.year) else: raise RuntimeError("Invalid method for explicit integration.") else: raise RuntimeError("Unknown integration scheme.") self.integrator._finalize() self.update() if self.verbosity > 0: msg = "Setting dust integrator\n scheme: {}\n method: {}".format( colorize(scheme, "blue"), colorize(method, "blue")) print(msg)