Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Campaign class to vary multiple inputs #25

Open
wants to merge 30 commits into
base: develop
Choose a base branch
from

Conversation

bendudson
Copy link
Collaborator

@bendudson bendudson commented Sep 8, 2023

Campaign tries to modify multiple parameters to reach a given target. For example if we have a case object:

campaign = uetools.Campaign(case, {'pcoree': 1e6, 'ncore': 6e19}, ".")

will create a campaign to start from the given case, modifying pcoree and ncore parameters to reach the given values. The final input is the path to store simulation states in.

To run the campaign in serial:

campaign.run()

Then details of the converged state are in

state = campaign.closest_state()

Campaign can also run in parallel, using multiple processes to explore paths to the target parameters e.g

campaign.run_async(processes=2)

See docstring for details and examples.

holm10 and others added 9 commits August 18, 2023 10:44
Update main branch with interpolation and input-tracking from develop
Merge dump-routines from develop
Consolidating additional input read/write routines from develop
Fix for standalone import and use of UETOOLS
Merge bugfixes from develop
Intended to automate varying multiple parameters using
multiprocessing.
- If using an old version of UEDGE then isgridhdf5 will not be
  available. In that case make the error message more useful.
- Add example and modify docstrings
  Some inputs can be either YAML or HDF5 files, and the code figures
  it out.
Takes a random walk towards the target input values,
trying to converge at each step.
Uses multiple workers to find a path to the given target
parameters.

Includes a Parallel.QuietPool to suppress output from multiple
UEDGE simulations running at the same time.

Instructions in the docstrings.
@bendudson bendudson changed the title WIP: Campaign class to vary multiple inputs Campaign class to vary multiple inputs Sep 8, 2023
bendudson and others added 2 commits September 8, 2023 10:02
Document how to run jobs asyncronously step-by-step.

Need to keep calculating distance from start to target, so
calculate it once and re-use.
Copy link
Collaborator

@holm10 holm10 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is great! I amended the description for the default variables that are saved to the HDF5 file.

@holm10
Copy link
Collaborator

holm10 commented Sep 8, 2023

One thing that struck me just now: how does your algorithm handle indices, e.g. setting elements of arrays? In your example you set pcoree and ncore: pcoree is a float an unambiguous, but ncore is an array that controls the ion species separately. Commonly we are interested in varying the first index only, but for some instances and variables we are interested in varying all, a subset, or one element somewhere in the array.

@bendudson
Copy link
Collaborator Author

@holm10 For an array, this algorithm will change all of the elements together, for example if recycp is [0.8, 0, 0, 0, 0] and you want to change it to [0.9, 0, 0.1, 0, 0] then the algorithm should cope with that. The array is treated as one variable, so all elements of an array are interpolated between initial and final state together.

Discrete switches are more difficult, and currently all target settings are assumed to be floats or arrays of floats. In principle it should be possible to make the code decide whether or not to enable the switch. Similarly there are decisions like changing grid resolution that the algorithm might be extended to make.

The "brains" of the algorithm is the next_action() function here:
https://github.com/LLNL/UETOOLS/pull/25/files#diff-a1aa56063bcc52322aaf63f5f2640d1eb29dee8daeee2504d72e497126b075ddR339
It takes the currently known list of states, and tries to decide which parameters to vary. Currently what it does is:

  • Choose a starting state randomly, weighted to prefer states closer to the target
  • Choose randomly whether to go directly to the target, with a probability that increases closer to the target
  • If not going to the target value: For each parameter (an array is treated as a single parameter), choose a random point in between its current value and the target value.

This can definitely be improved. I tried to design something that has sensible preferences, but has a large element of chance so that it will (hopefully) eventually stumble on a path that works. The priority is to be robust without human intervention, not efficient in CPU time.

If an exception is thrown, then distance should be stored
in the result. To ensure that it isn't used again, distance
is set to a large number.
@holm10
Copy link
Collaborator

holm10 commented Sep 8, 2023

Thanks for the clarification, @bendudson . I can think of three instances one might want to do in UEDGE for variables that are arrays:

  1. Change the whole array
  • For afracs (impurity concentration), etc
  1. Change individual indices
  • E.g. ncore, recyrb_use, albrb, etc.
  1. Modify a subarray of a UEDGE variable array
  • E.g. modify the divertor diffusivities only using kye_use, dif_use, etc.

1 Is already taken care of by the default behavior. 2 I think could be quite easily implemented by passing a nested dict, where indices could be set individually: e.g. {'pcoree': 1e6, 'ncore': {0:6e19, 3:1e20}}. This would be more user-friendly than copying the original array and changing the individual indices before passing them. 3 is definitely the most challenging, and I am looking into some sort of solution for the continuation solve. I a settling for
try: var[indices] = target except: var = target
or something similar, where indices is a tuple of slices, e.g. (slice(0, com.ixpt1[0]+1), slice(None), 0) for setting the inner leg diffusivity for hydrogenic ions. I think the most important thing is to make it unambiguous how the setting of the variable works.

As for the next_action()-function, I understand that a CPU-intensive and human-independent approach may be better off biasing the new states towards the target value, but in my experience it is often more effective (also wall-clock) to bias towards the starting state, e.g. progressing in many small steps rather than one big step. I guess the dynamics change as the Campaign really unleashes a large number of cases, and it is enough that only one of them converges in somewhat reasonable time for it to be worthwhile. However, it's probably worth looking into how editing the bias will change the performance.

bendudson and others added 13 commits September 8, 2023 13:30
If an attempt fails more than once, set their distance to
a large number so that they are not chosen again.
When new results are obtained, pickle the campaign so
it can be restored later if needed.
Check whether a state is converged before including it
Adds three parameters that control how cautious the solver is.
Currently fixed, but could be made adaptive in future.
If a case is not converged, when it is retried mark the original as
large distance so it won't be chosen again.
Not included in the uetools package, so causes error on install.
Mypy still not happy, but improving
A uedgerc configuration is not always needed, so continue
to create a Case object even if configuration is not available.
Updates UETOOLS to v1.1.0
- Update to v1.1.1
- Updates documentation
- Adds catch for when running UETOOLS without UEDGE.
holm10 and others added 5 commits February 20, 2024 16:59
- Fixes backwards-compatibility issues with older UEDGE versions
- Adds grip morphing routines
- Updates Jupyter notebooks
- Interactive plots use separate class
- Interactive plots can consider different grids in same database
Conflicts:
	setup.py
	src/uetools/__init__.py
	uetools/UeCase/Case.py
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants