Skip to content
Open
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion petsctools/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -502,11 +502,17 @@ def __init__(self, parameters: dict[str, Any],
# The parameters to drop from the global options when we leave the
# inserted_options context. This is everything except for options
# passed on the command line.
to_delete = set(parameters.keys())
to_delete = set(parameters.keys()) | set(default_options.keys())
Comment thread
pbrubeck marked this conversation as resolved.
Resolved

# Start building parameters from the defaults so
# that they will overwritten by any other source.
Comment thread
pbrubeck marked this conversation as resolved.
Resolved
# Start building parameters from the defaults so
# that they will overwritten by any other source.
Comment thread
pbrubeck marked this conversation as resolved.
Resolved
# Start building parameters from the defaults so
# that they will overwritten by any other source.
parameters = default_options | parameters
Comment thread
pbrubeck marked this conversation as resolved.
Resolved
to_delete = set(parameters.keys())
to_delete = set(parameters.keys())
Comment thread
pbrubeck marked this conversation as resolved.
Resolved
unsafe_options = []
for full_key, v in self.options_object.getAll().items():
if full_key.startswith(options_prefix):
Expand Down
69 changes: 69 additions & 0 deletions tests/test_options.py
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,75 @@ def test_default_options():
assert options2.parameters["opt4"] == "6"


@pytest.mark.skipnopetsc4py
def test_inserted_options_deletes_default_options():
"""Check that inserted_options removes the options that the
OptionsManager receives through its default options set, and keeps
the options that the database already held."""
from petsc4py import PETSc

options = PETSc.Options()
options["parent_ksp_type"] = "cg"
options["parent_0_pc_type"] = "jacobi"
opts_before = dict(options.getAll())
Comment on lines +189 to +192

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Please can you test:

  1. having multiple prefixes in the set (i.e. at least parent_0 and parent_1), and calling inserted_options on both in turn (not nested).
  2. The case where a default option gets overridden? e.g. -parent_ksp_type cg -parent_1_ksp_type gmres


child = petsctools.OptionsManager(
parameters={},
options_prefix="parent_0",
default_options_set=petsctools.DefaultOptionSet("parent", [0]))
assert child.parameters == {"ksp_type": "cg", "pc_type": "jacobi"}

with child.inserted_options():
pass

assert options.getAll() == opts_before


@pytest.mark.skipnopetsc4py
def test_inserted_options_deletes_defaults_for_multiple_prefixes():
"""Check shared defaults are removed for sequential child managers."""
from petsc4py import PETSc

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

What is the reasoning for having these as three separate tests? It'd be simpler just to have one test that covers all these cases.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

The advantage to keeping separate tests is that one can easily tell when individual features break. But we also want to be covering the interaction between these features, so it makes sense to merge them into a single test, so I did this.


options = PETSc.Options()
options["parent_ksp_type"] = "cg"
default_options_set = petsctools.DefaultOptionSet("parent", [0, 1])
children = [
petsctools.OptionsManager(
parameters={},
options_prefix=f"parent_{i}",
default_options_set=default_options_set,
)
for i in (0, 1)
]

for child in children:
key = child.options_prefix + "ksp_type"
with child.inserted_options():
assert options[key] == "cg"
assert key not in options.getAll()


@pytest.mark.skipnopetsc4py
def test_inserted_options_child_option_overrides_default():
"""Check a child option overrides a shared default while inserted."""
from petsc4py import PETSc

options = PETSc.Options()
options["parent_ksp_type"] = "cg"
options["parent_1_ksp_type"] = "gmres"
opts_before = dict(options.getAll())
child = petsctools.OptionsManager(
parameters={},
options_prefix="parent_1",
default_options_set=petsctools.DefaultOptionSet("parent", [0, 1]),
)

assert child.parameters["ksp_type"] == "gmres"
with child.inserted_options():
assert options["parent_1_ksp_type"] == "gmres"
assert options.getAll() == opts_before


@pytest.mark.skipnopetsc4py
def test_python_options_with_manager():
petsctools.init()
Expand Down
Loading