11from os import PathLike
22from pathlib import Path
3- from typing import ClassVar
3+ from warnings import warn
44
55from flopy .discretization .modeltime import ModelTime
66from modflow_devtools .misc import cd , run_cmd
7- from xattree import field , xattree
7+ from xattree import xattree
88
99from flopy4 .mf6 .component import Component
1010from flopy4 .mf6 .exchange import Exchange
1111from flopy4 .mf6 .model import Model
1212from flopy4 .mf6 .solution import Solution
13+ from flopy4 .mf6 .spec import field
1314from flopy4 .mf6 .tdis import Tdis
1415
1516
@@ -27,31 +28,49 @@ class Simulation(Component):
2728 exchanges : dict [str , Exchange ] = field ()
2829 solutions : dict [str , Solution ] = field ()
2930 tdis : Tdis = field (converter = convert_time )
30- # TODO: decorator for components bound
31- # to some directory or file path?
32- path : Path = field (default = None )
33- filename : ClassVar [str ] = "mfsim.nam"
31+ workspace : Path = field (default = None )
32+ filename : str = field (default = "mfsim.nam" )
33+
34+ def __attrs_post_init__ (self ):
35+ """Post-initialization hook to set up the simulation."""
36+ super ().__attrs_post_init__ ()
37+ if self .filename != "mfsim.nam" :
38+ warn (
39+ "Simulation filename must be 'mfsim.nam'." ,
40+ UserWarning ,
41+ )
42+ self .filename = "mfsim.nam"
43+
44+ @property
45+ def path (self ) -> Path :
46+ """Return the path to the simulation namefile."""
47+ if self .workspace is None :
48+ raise ValueError ("Simulation has no workspace path." )
49+ return Path (self .workspace ).expanduser ().resolve () / self .filename
3450
3551 @property
3652 def time (self ) -> ModelTime :
53+ """Return the simulation time discretization."""
3754 return self .tdis .to_time ()
3855
3956 def run (self , exe : str | PathLike = "mf6" , verbose : bool = False ) -> None :
4057 """Run the simulation using the given executable."""
41- if self .path is None :
58+ if self .workspace is None :
4259 raise ValueError (f"Simulation { self .name } has no workspace path." )
43- with cd (self .path ):
60+ with cd (self .workspace ):
4461 stdout , stderr , retcode = run_cmd (exe , verbose = verbose )
4562 if retcode != 0 :
4663 raise RuntimeError (
4764 f"Simulation { self .name } : { exe } failed to run with returncode " # type: ignore
4865 f"{ retcode } , and error message:\n \n { stdout + stderr } "
4966 )
5067
51- def load (self , format ):
52- with cd (self .path ):
68+ def load (self , format = "ascii" ):
69+ """Load the simulation in the specified format."""
70+ with cd (self .workspace ):
5371 super ().load (format )
5472
55- def write (self , format ):
56- with cd (self .path ):
73+ def write (self , format = "ascii" ):
74+ """Write the simulation in the specified format."""
75+ with cd (self .workspace ):
5776 super ().write (format )
0 commit comments