Skip to content

Version 2 of Case Generate#3

Open
orlandoisepic wants to merge 125 commits intomainfrom
develop
Open

Version 2 of Case Generate#3
orlandoisepic wants to merge 125 commits intomainfrom
develop

Conversation

@orlandoisepic
Copy link
Copy Markdown
Contributor

Changes

This changes everything 🤯 🤩

The biggest overarching change is the inclusion of preCICE Config Graph as a dependency and a change to the topology schema.

Process flow

  1. Read arguments and check that the given file is a .yaml file and adheres to the topology schema
  2. Preprocess the topology (for details see "Preprocessing")
  3. Create config-graph nodes (for details, see "Changes to the generating process")
  4. Based on these nodes, create the precice-config.xml file
  5. Also create the adapter-config.json based on the nodes
  6. Copy (or fill out) utility template files to the output folder

Changes to the topology

The topology only takes the two arguments (or "main" elements) participants and exchanges. A detailed overview over the topology can be found in precicecasegenerate/schemas/README.md.
The elements coupling-scheme and acceleration were removed to reduce complexity.

Preprocessing

Preprocessing includes checking if the topology is valid. The following checks are executed:

  • Participant names are unique
  • Participants mentioned in exchanges actually exist
  • Exchanges are not loops (i.e., from A to A)
  • Remove any participants that are declared but not used (do not appear in any exchange)
  • Check data names to see if they contain special words (see "Changes to the generating process", 3.)

These checks are necessary to guarantee a valid topology and adapter-configs.

Changes to the generating process

Well, it was redesigned from the ground up.
I tried to make everything as modular as possible, so that single functions can be modified without influencing others.
The main logic now relies on the preCICE Config Graph and its nodes. These nodes are created in the following sequence:

  1. Participants. They are not influenced by any other node.
  2. Patches (they are not actually config-graph nodes, but they are vital for the data nodes, meshes etc.). They are tricky to initialize because they depend on the data that is exchanged from / to them.

    The patches names might be altered and this step MUST be executed before data nodes are initialized.

  3. Data nodes. This step assigns the exchanges to data nodes, so that they can be retrieved later. This step is very complex, as all kinds of edge-case scenarios are probed.

    These include: A --Color (scalar)-> B and A --Color (vector) -> B, which needs to be resolved into two data nodes, "Color-Vector" and "Color-Scalar".
    Another possibility is A --Color-> B and B --Color-> A, which means that one of the "Color"'s needs to be changed to something unique, like "Pretty-Color". This is why, during preprocessing, it is checked whether any data name contains such a special "uniquifier".

    A full list of these uniquifiers, intensive and extensive data, as well as data->data-type map can be found in precicecasegenerate/cli_helper.py

  4. Meshes. Meshes are created based on the patches and data exchanged between participants.

    If participants with different dimensionalities try to exchange data, the dimension of the mesh with lower dimensionality is increased.

  5. Mappings. Mappings are created based on the meshes and data exchanged between participants.

    Extensive data leads to a write-conservative mapping, intensive data leads to a read-consistent mapping.

  6. Exchanges. They are created based on the exchanges tag of the topology and are not so complex.

    However, since no coupling-scheme configuration is given, any coupling-scheme must be inferred from them. Since "strong" exchanges do no necessarily lead to implicit coupling schemes, only a list of "potential couplings" is created.

  7. Coupling-schemes. These are created in two steps:
    First, the list of "potential couplings" is scanned to find bidirectional strong couplings. If any exist, an implicit-, or multi-coupling-scheme, is created.
    Next, explicit coupling-scheme are created based on the remaining "potential couplings"
  8. M2N. They are created for all participants exchanging something between them and the control participant of the multi-coupling-scheme.

As mentioned above, each of these steps can be modified without influencing the other steps, as long as necessary return values remain in their original format.

The code for this can be found in precicecasegenereate/node_creator.py.

New features

At least I was not aware of them before:

  • There can now be multiple coupling-schemes and a multi-coupling-scheme is only created if more than two strong exchanges exist
  • Data names do not have to be unique to result in a correct config file. If the topology is "unambiguous", then data-names will be made unique by prepending adjectives like "Scary-". This is used to avoid situations where A --Color-> B and B --Color-> A, which would result in the same data being read and written by a participant, which is not allowed.
  • Mappings will be chosen based on the "type" (this is a bad word since the topology uses "type" in another context. I used "kind"-of-data in the code) of data, which can either be "extensive" -> write-conservative or "intensive" -> read-consistent.
  • Data-type (vector or scalar) will be inferred from data name if not given (force -> vector, temperature -> scalar)
  • Patches will be split up if necessary. It can be necessary to split them up, if both extensive and intensive data is supposed to be mapped from them. Then we create "Intensive-" and "Extensive-" versions of this patch

Changes to utility files

The README.md template has been reworked slightly, as well as the clean.sh file.

Changes to tests

Tests now include validating topologies against predefined ones with the config-graph's new check_config_equivalence() function as well as running the config-checker.

Reflect new project structure
Exclude logs from git
Updated the schema to reflect new topology, which is more accessible
A custom logger
A class to read and validate the topology
A class to create the precice configuration file based on config-graph nodes
A class to create nodes based on a topology file
Helper functions and values for the node creator
Updated the main to reflect the project structure and functionality
Moved displacement to "extensive-data"
They contain the precice beginner tutorials and a more complex multi coupling
Removed old TODOs
Rearranged entries and added some explanations
Make logs folder hidden on unix
Make `create_config_str()` "private"
Create a new class for patches
Create patch nodes and naming improvements
Create a class for creating adapter configurations
update the main method to include adapter config generation
Updated description to reflect double usage of the method
A schema for the adapter-config.json files.
Validate created adapter configs against the schema
Updated name to "_validate..." to reflect changes in adapter config creator
Changed imports
Add a new helper function for solver i.e. participant directories
Use new helper function
They were adopted from the previous version
Created a new class for creating the utility files.
The readme is somewhat inspired by the old version, but contains less words and more information :)
Includes the checking if the exchanges are unique up to patches, as suggested by @uekerman
it now uses textwrap and is cleaner.
Copy link
Copy Markdown
Member

@fsimonis fsimonis left a comment

Choose a reason for hiding this comment

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

The examples currently include the output in the _generated folder, so they will be overwritten when calling the script.

I suggest to either remove them or rename them to _reference or _expected if you plan to use them in tests.

Comment thread precicecasegenerate/logging_setup.py Outdated
Comment thread precicecasegenerate/schemas/adapter-config-schema.json Outdated
Comment thread precicecasegenerate/input_handler/topology_reader.py Outdated
Comment thread precicecasegenerate/cli.py
Comment thread precicecasegenerate/cli_helper.py Outdated
Comment thread precicecasegenerate/cli.py Outdated
return parser.parse_args()


def validate_args(args: argparse.Namespace) -> int:
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.

You can set the type argument of argparse.add_argument to a callable. In this callable, you can run your custom error checking.
https://docs.python.org/3/library/argparse.html#type

This keeps the error including formatting inside the argparser framework.

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.

Not sure why you marked this as resolved.

Comment thread precicecasegenerate/helper.py Outdated
Comment thread precicecasegenerate/node_creator.py Outdated
@orlandoisepic orlandoisepic requested a review from fsimonis May 1, 2026 17:02

def main() -> int:
# Parse the command line arguments
parser = cli_helper.makeGenerateParser()
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.

The makeGenerateParser needs to be visible in this file.
I think you could simply reexport it using from cli_helper import makeGenerateParser.

This line needs to work when you release the new version:

https://github.com/precice/cli/blob/8361729197b0e2d7abc86755e02e04045e2bda4a/precicecli/cli.py#L21

type=Path,
nargs="?",
help="Path to the input YAML topology file.",
default=Path.cwd() / "topology.yaml"
Copy link
Copy Markdown
Member

@fsimonis fsimonis May 6, 2026

Choose a reason for hiding this comment

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

Equivalent to the shorter:

Suggested change
default=Path.cwd() / "topology.yaml"
default=Path("topology.yaml")

Same applies to the output path

Copy link
Copy Markdown
Member

@fsimonis fsimonis left a comment

Choose a reason for hiding this comment

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

IMHO the only thing blocking this PR from my perspective is the compatibility with the preicice-cli.

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