Coverage for src/python/dandeliion/client/__init__.py: 97%

29 statements  

« prev     ^ index     » next       coverage.py v7.6.12, created at 2025-02-22 10:38 +0100

1# built-in modules 

2from pathlib import Path 

3from typing import Union 

4 

5# custom modules 

6from .simulator import Simulator 

7from .solution import Solution 

8 

9# third-party modules 

10from pybamm import Experiment 

11from bpx import parse_bpx_obj, parse_bpx_file, BPX 

12 

13 

14def _convert_experiment(experiment: Experiment): 

15 """ 

16 converts pybamm experiment into dict 

17 """ 

18 operating_conditions, period, temperature, termination = experiment.args 

19 steps = [] 

20 for cond in operating_conditions: 

21 if isinstance(cond, tuple): 

22 steps += list(cond) 

23 else: 

24 steps.append(cond) 

25 

26 return { 

27 "Instructions": steps, 

28 "Period": period, 

29 "Temperature": temperature, 

30 "Termination": termination, 

31 } 

32 

33 

34def solve( 

35 simulator: Simulator, 

36 params: Union[str, Path, dict, BPX], 

37 experiment: Experiment, 

38 extra_params: dict = None, 

39) -> Solution: 

40 

41 """Method for submitting/running a Dandeliion simulation. 

42 

43 Args: 

44 simulator (Simulator): instance of simulator class providing information 

45 to connect to simulation server 

46 params (str|Path|dict|BPX): path to BPX parameter file or already read-in valid BPX as dict or BPX object 

47 experiment (Experiment): instance of pybamm Experiment defining steps 

48 extra_params (dict, optional): extra parameters e.g. simulation mesh, choice of discretisation method 

49 and initial conditions specified in the dictionary 

50 (if none or only subset is provided, either user-defined values 

51 stored in the bpx or, if not present, default values will be used instead) 

52 Returns: 

53 :class:`Solution`: solution for this simulation run 

54 """ 

55 

56 # load & validate BPX 

57 if isinstance(params, dict): 

58 params = parse_bpx_obj(params) 

59 elif isinstance(params, str) or isinstance(params, Path): 

60 params = parse_bpx_file(params) 

61 elif not isinstance(params, BPX): 

62 raise ValueError("`params` has to be either `dict`, `str`, `Path` or `BPX`") 

63 

64 # turn back into dict 

65 params = params.model_dump(by_alias=True, exclude_unset=True) 

66 

67 if ( 

68 "User-defined" not in params['Parameterisation'] or 

69 params['Parameterisation']["User-defined"] is None 

70 ): 

71 params['Parameterisation']["User-defined"] = {} 

72 

73 # add experiment 

74 params['Parameterisation']["User-defined"]["DandeLiion: Experiment"] = _convert_experiment(experiment) 

75 

76 # add/overwrite extra parameters 

77 if extra_params: 

78 for param, value in extra_params.items(): 

79 params['Parameterisation']["User-defined"][f"DandeLiion: {param}"] = value 

80 

81 return simulator.submit(parameters=params, is_blocking=True)