diff --git a/flowermd/library/simulations/tensile.py b/flowermd/library/simulations/tensile.py index 7b2b37ea..770ec9bc 100644 --- a/flowermd/library/simulations/tensile.py +++ b/flowermd/library/simulations/tensile.py @@ -78,25 +78,32 @@ def strain(self): ) return delta_L / self.initial_length - def run_tensile(self, strain, n_steps, kT, tau_kt, period): + def run_tensile(self, strain, duration, temperature, tau_kt, period): """Run a tensile test simulation. Parameters ---------- strain : float, required The strain to apply to the simulation. - n_steps : int, required - The number of steps to run the simulation for. + duration : int or flowermd.internal.Units, required + The number of steps or time length to run the simulation. If unitless, + the time is assumed to be the number of steps. + temperature : flowermd.internal.Units or float or int, required + The temperature to use during volume update. If no unit is provided, + the temperature is assumed to be kT (temperature times Boltzmann + constant). tau_kt : float, required Thermostat coupling period (in simulation time units). - period : int, required - The period of the strain application. + period : int or flowermd.internal.Units, required + The number of steps or time length between box updates. If no unit + is provided, the period is assumed to be the number of steps. """ current_length = self.box_lengths_reduced[self._axis_index] final_length = current_length * (1 + strain) final_box = np.copy(self.box_lengths_reduced) final_box[self._axis_index] = final_length + n_steps = self._setup_n_steps(duration) shift_by = (final_length - current_length) / (n_steps // period) resize_trigger = hoomd.trigger.Periodic(period) box_ramp = hoomd.variant.Ramp( @@ -120,4 +127,6 @@ def run_tensile(self, strain, n_steps, kT, tau_kt, period): ) self.operations.updaters.append(box_resizer) self.operations.updaters.append(particle_updater) - self.run_NVT(n_steps=n_steps + 1, kT=kT, tau_kt=tau_kt) + self.run_NVT( + n_steps=n_steps + 1, temperature=temperature, tau_kt=tau_kt + ) diff --git a/flowermd/modules/surface_wetting/surface_wetting.py b/flowermd/modules/surface_wetting/surface_wetting.py index 3f35383e..0466b14a 100644 --- a/flowermd/modules/surface_wetting/surface_wetting.py +++ b/flowermd/modules/surface_wetting/surface_wetting.py @@ -8,6 +8,7 @@ import unyt as u from flowermd.base import Simulation +from flowermd.internal import Units from flowermd.modules.surface_wetting.utils import combine_forces from flowermd.utils import HOOMDThermostats, get_target_box_mass_density @@ -45,15 +46,15 @@ def __init__( def run_droplet( self, - shrink_kT, - shrink_steps, + shrink_temperature, + shrink_duration, shrink_period, shrink_density, - expand_kT, - expand_steps, + expand_temperature, + expand_duration, expand_period, - hold_kT, - hold_steps, + hold_temperature, + hold_duration, final_density, tau_kt, ): @@ -61,61 +62,63 @@ def run_droplet( The steps for creating a droplet are: 1. Shrink the box to a high density (i.e. `shrink_density`) at a high - temperature (i.e. `shrink_kT`) to get the droplet to form. + temperature (i.e. `shrink_temperature`) to get the droplet to form. 2. Expand the box back to a low density (i.e. 'final_density') at a low - temperature (i.e. `expand_kT`). Keeping the temperature low will keep + temperature (i.e. `expand_temperature`). Keeping the temperature low will keep the droplet from falling apart. 3. Run the simulation at the `final_density` and low temperature - (i.e. `hold_kT`) to equilibrate the droplet. + (i.e. `hold_temperature`) to equilibrate the droplet. Parameters ---------- - shrink_kT : float or hoomd.variant.Ramp, required + shrink_temperature : float or flowermd.internal.Units or hoomd.variant.Ramp, required The temperature to run the simulation at while shrinking. - shrink_steps : int, required - The number of steps to run the simulation while shrinking. - shrink_period : int, required - The number of steps between updates to the box size while shrinking. - shrink_density : float, required + shrink_duration : int or flowermd.internal.Units, required + The number of steps (unitless) or time length (with units) to run the simulation while shrinking. + shrink_period : int or flowermd.internal.Units, required + The number of steps (unitless) or time length (with units) between updates to the box size while shrinking. + shrink_density : float or flowermd.internal.Units, required The high density to shrink the box to. - Note: the units of the density are in g/cm^3. - expand_kT : float or hoomd.variant.Ramp, required + Note: If unitless, the units of the density are in g/cm^3. + expand_temperature : float or flowermd.internal.Units or hoomd.variant.Ramp, required The temperature to run the simulation at while expanding. - expand_steps : int, required - The number of steps to run the simulation while expanding. - expand_period : int, required - The number of steps between updates to the box size while expanding. - hold_kT : float or hoomd.variant.Ramp, required + expand_duration : int or flowermd.internal.Units, required + The number of steps (unitless) or time length (with units) to run the simulation while expanding. + expand_period : int or flowermd.internal.Units, required + The number of steps (unitless) or time length (with units) between updates to the box size while expanding. + hold_temperature : float or flowermd.internal.Units or hoomd.variant.Ramp, required The temperature to run the simulation at while equilibrating. - hold_steps : int, required - The number of steps to run the simulation while equilibrating. - final_density : float, required + hold_duration : int or flowermd.internal.Units, required + The number of steps (unitless) or time length (with units) to run the simulation while equilibrating. + final_density : float or flowermd.internal.Units, required The low density to equilibrate the box to. - Note: the units of the density are in g/cm^3. + Note: If unitless, the units of the density are in g/cm^3. tau_kt : float, required The time constant for the thermostat. """ # Shrink down to high density if not isinstance( - shrink_density, u.array.unyt_quantity - ) and not isinstance(final_density, u.array.unyt_quantity): + shrink_density, (u.array.unyt_quantity, u.unyt_quantity, Units) + ) and not isinstance( + final_density, (u.array.unyt_quantity, u.unyt_quantity, Units) + ): warnings.warn( "Units for density were not given, assuming " "units of g/cm**3." ) target_box_shrink = get_target_box_mass_density( - density=shrink_density * (u.g / (u.cm**3)), + density=shrink_density * Units.g_cm3, mass=self.mass.to("g"), ) target_box_final = get_target_box_mass_density( - density=final_density * (u.g / (u.cm**3)), + density=final_density * Units.g_cm3, mass=self.mass.to("g"), ) else: - mass_density = u.Unit("kg") / u.Unit("m**3") - number_density = u.Unit("m**-3") + mass_density = Units.kg_m3 + number_density = Units.n_m3 if shrink_density.units.dimensions == mass_density.units.dimensions: target_box_shrink = get_target_box_mass_density( density=shrink_density, mass=self.mass.to("g") @@ -133,23 +136,25 @@ def run_droplet( ) # Shrink down to higher density self.run_update_volume( - n_steps=shrink_steps, + duration=shrink_duration, period=shrink_period, - kT=shrink_kT, + temperature=shrink_temperature, tau_kt=tau_kt, final_box_lengths=target_box_shrink, write_at_start=True, ) # Expand back up to low density self.run_update_volume( - n_steps=expand_steps, + duration=expand_duration, period=expand_period, - kT=expand_kT, + temperature=expand_temperature, tau_kt=tau_kt, final_box_lengths=target_box_final, ) # Run at low density - self.run_NVT(n_steps=hold_steps, kT=hold_kT, tau_kt=tau_kt) + self.run_NVT( + duration=hold_duration, temperature=hold_temperature, tau_kt=tau_kt + ) class InterfaceBuilder: diff --git a/flowermd/tests/modules/test_surface_wetting.py b/flowermd/tests/modules/test_surface_wetting.py index b2dc908b..a69d0606 100644 --- a/flowermd/tests/modules/test_surface_wetting.py +++ b/flowermd/tests/modules/test_surface_wetting.py @@ -1,9 +1,9 @@ import gsd.hoomd import numpy as np import pytest -import unyt as u from flowermd.base import Pack +from flowermd.internal import Units from flowermd.library.forcefields import OPLS_AA from flowermd.library.surfaces import Graphene from flowermd.modules.surface_wetting import ( @@ -31,20 +31,20 @@ def test_droplet_sim(self, polyethylene): reference_values=drop_system.reference_values, ) drop_sim.run_droplet( - shrink_kT=5.0, - shrink_steps=200, + shrink_temperature=5.0, + shrink_duration=200, shrink_period=10, - shrink_density=0.2 * u.g / u.cm**3, - expand_kT=0.5, - expand_steps=200, + shrink_density=0.2 * Units.g_cm3, + expand_temperature=0.5, + expand_duration=200, expand_period=10, - hold_kT=1.0, - hold_steps=100, - final_density=0.05 * u.g / u.cm**3, + hold_temperature=1.0, + hold_duration=100, + final_density=0.05 * Units.g_cm3, tau_kt=drop_sim.dt * 100, ) assert np.isclose( - drop_sim.density.to(u.g / u.cm**3).value, 0.05, atol=1e-2 + drop_sim.density.to(Units.g_cm3).value, 0.05, atol=1e-2 ) def test_droplet_sim_no_units(self, polyethylene): @@ -64,20 +64,20 @@ def test_droplet_sim_no_units(self, polyethylene): ) with pytest.warns(): drop_sim.run_droplet( - shrink_kT=5.0, - shrink_steps=200, + shrink_temperature=5.0, + shrink_duration=200, shrink_period=10, shrink_density=0.2, - expand_kT=0.5, - expand_steps=200, + expand_temperature=0.5, + expand_duration=200, expand_period=10, - hold_kT=1.0, - hold_steps=100, + hold_temperature=1.0, + hold_duration=100, final_density=0.05, tau_kt=drop_sim.dt * 100, ) assert np.isclose( - drop_sim.density.to(u.g / u.cm**3).value, 0.05, atol=1e-2 + drop_sim.density.to(Units.g_cm3).value, 0.05, atol=1e-2 ) def test_droplet_sim_bad_units(self, polyethylene): @@ -97,20 +97,20 @@ def test_droplet_sim_bad_units(self, polyethylene): ) with pytest.raises(ValueError): drop_sim.run_droplet( - shrink_kT=5.0, - shrink_steps=200, + shrink_temperature=5.0, + shrink_duration=200, shrink_period=10, - shrink_density=0.2 * (u.cm**-3), - expand_kT=0.5, - expand_steps=200, + shrink_density=0.2 * (Units.n_cm3), + expand_temperature=0.5, + expand_duration=200, expand_period=10, - hold_kT=1.0, - hold_steps=100, - final_density=0.05 * (u.cm**-3), + hold_temperature=1.0, + hold_duration=100, + final_density=0.05 * (Units.n_cm3), tau_kt=drop_sim.dt * 100, ) assert np.isclose( - drop_sim.density.to(u.g / u.cm**3).value, 0.05, atol=1e-2 + drop_sim.density.to(Units.g_cm3).value, 0.05, atol=1e-2 ) @@ -123,9 +123,9 @@ def test_interface_builder( # recreate droplet forcefield polyethylene_ff = polyethylene_system.hoomd_forcefield drop_refs = { - "energy": u.unyt_quantity(0.276144, "kJ/mol"), - "length": u.unyt_quantity(0.35, "nm"), - "mass": u.unyt_quantity(12.011, "amu"), + "energy": 0.276144 * Units.kJ_mol, + "length": 0.35 * Units.nm, + "mass": 12.011 * Units.amu, } # load surface snapshot @@ -147,8 +147,8 @@ def test_interface_builder( drop_snapshot=drop_snapshot, drop_ff=polyethylene_ff, drop_ref_values=drop_refs, - box_height=15 * u.nm, - gap=0.4 * u.nm, + box_height=15 * Units.nm, + gap=0.4 * Units.nm, ) assert ( interface.hoomd_snapshot.particles.N @@ -205,7 +205,7 @@ def test_wetting_sim( fix_surface=True, ) wetting_sim.run_NVT( - kT=1.0, + temperature=1.0, tau_kt=1, - n_steps=1e3, + duration=1e3, ) diff --git a/flowermd/tests/modules/test_weld.py b/flowermd/tests/modules/test_weld.py index 09ed0e42..0cd5a6dc 100644 --- a/flowermd/tests/modules/test_weld.py +++ b/flowermd/tests/modules/test_weld.py @@ -19,9 +19,9 @@ def test_interface(self, polyethylene_system): ) sim.add_walls(wall_axis=(1, 0, 0), sigma=1, epsilon=1, r_cut=2) sim.run_update_volume( - n_steps=1000, + duration=1000, period=10, - kT=2.0, + temperature=2.0, tau_kt=0.01, final_box_lengths=sim.box_lengths / 2, ) @@ -54,9 +54,9 @@ def test_interface_2_files(self, polyethylene_system): ) sim.add_walls(wall_axis=(1, 0, 0), sigma=1, epsilon=1, r_cut=2) sim.run_update_volume( - n_steps=1000, + duration=1000, period=10, - kT=2.0, + temperature=2.0, tau_kt=0.01, final_box_lengths=sim.box_lengths / 2, ) @@ -93,7 +93,7 @@ def test_slab_sim_xaxis(self, polyethylene_system): assert any( [isinstance(i, hoomd.md.external.wall.LJ) for i in sim.forces] ) - sim.run_NVT(kT=1.0, tau_kt=0.01, n_steps=500) + sim.run_NVT(temperature=1.0, tau_kt=0.01, duration=500) def test_slab_sim_yaxis(self, polyethylene_system): sim = SlabSimulation( @@ -105,7 +105,7 @@ def test_slab_sim_yaxis(self, polyethylene_system): assert any( [isinstance(i, hoomd.md.external.wall.LJ) for i in sim.forces] ) - sim.run_NVT(kT=1.0, tau_kt=0.01, n_steps=500) + sim.run_NVT(temperature=1.0, tau_kt=0.01, duration=500) def test_slab_sim_zaxis(self, polyethylene_system): sim = SlabSimulation( @@ -117,7 +117,7 @@ def test_slab_sim_zaxis(self, polyethylene_system): assert any( [isinstance(i, hoomd.md.external.wall.LJ) for i in sim.forces] ) - sim.run_NVT(kT=1.0, tau_kt=0.01, n_steps=500) + sim.run_NVT(temperature=1.0, tau_kt=0.01, duration=500) def test_weld_sim(self, polyethylene_system): sim = SlabSimulation( @@ -125,7 +125,7 @@ def test_weld_sim(self, polyethylene_system): forcefield=polyethylene_system.hoomd_forcefield, log_write_freq=2000, ) - sim.run_NVT(kT=1.0, tau_kt=0.01, n_steps=500) + sim.run_NVT(temperature=1.0, tau_kt=0.01, duration=500) sim.save_restart_gsd() # Create interface system from slab restart.gsd file interface = Interface( @@ -176,9 +176,9 @@ def test_interface_with_void_particle(self, polyethylene_system): log_write_freq=2000, ) sim.run_update_volume( - n_steps=1000, + duration=1000, period=10, - kT=2.0, + temperature=2.0, tau_kt=0.01, final_box_lengths=sim.box_lengths / 2, )