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

C-API v2.0 #123

Open
schmoelder opened this issue Feb 17, 2023 · 0 comments
Open

C-API v2.0 #123

schmoelder opened this issue Feb 17, 2023 · 0 comments

Comments

@schmoelder
Copy link
Contributor

schmoelder commented Feb 17, 2023

Once #115 is merged, we can consider additional functionality that we would like to expose via the C-API. This issue serves as a super issue to collect ideas.

Simulating individual sections

Instead of running the complete simulations, it might be advantageous to only run a specific number of sections before deciding whether to continue or not. This is particularly useful for control algorithms but also important when evaluating cyclic stationarity etc.

For this purpose, we should reconsider the way we define section dependent parameters. Instead of globally defining the values for each section as an array in /input/model/unit_xxx/parameter_xxx, it would be convenient if we could overwrite each parameter independently for each section. For an example, refer to the SystemSolver class in the CADET-Python-Simulator which expects a Section with the following structure:

class Section:
    """
    Represents a section with start, end, connections, and section states.

    Attributes
    ----------
    start : int
        The start point of the section.
    end : int
        The end point of the section.
    connections : list[List[float]]
        Connections represented as a list of lists, where each connection is
        a list [from, to, value].
    section_states : dict[str, dict[str, npt.ArrayLike]]
        A dictionary containing the section states. The keys represent the
        state names (e.g., 'inlet'), and each state contains a dictionary
        of variable names mapped to ArrayLike values.
    """

    def __init__(
            self,
            start: int,
            end: int,
            connections: list[list[float]],
            section_states: dict[str, dict[str, npt.ArrayLike]]
            ) -> None:
        """
        Initialize a Section instance.

        Parameters
        ----------
        start : int
            The start point of the section.
        end : int
            The end point of the section.
        connections : list[list[float]]
            A list of connections, each represented as [from, to, value].
        section_states : dict[str, dict[str, npt.ArrayLike]]
            A dictionary containing the section states.
        """
        self.start = start
        self.end = end
        self.connections = connections
        self.section_states = section_states

If a parameter is not updated in a section, its previous values is used (open question: How to treat piecewise polynomial parameters?)

Conditional Events (Related: #27)

Once running individual sections is implemented, we can start adding some logic for conditional events (e.g. start next section once concentration exceeds some value). As a first step, it would also be great if we could "go back" to the beginning of the section in case we "overshot" and restart with different parameters / section time. This logic could even be implemented outside of CADET-Core which keeps the core simulator nice and clean.

Restructure the interface function arguments

Currently, we explicitly have to pass in pointers to each of the solution dimensions s.t. CADET-Core can return the number of for that dimensions and we can reshape the solution array correspondingly using numpy.

However, since for every model the dimensions of bulk, particle can change (e.g. because singleton dimensions might need to be squeezed or not), the signature for these becomes very long and tedious:

cdtResult get##NAME##Particle(cdtDriver* drv, int unitOpId SENS_IDX_SIG, int parType, double const** time, double const** data, int* nTime, int* nAxialCells, int* nRadialCells, int* nParShells, int* nComp, bool* keepAxialSingletonDimension, bool* keepParticleSingletonDimension) \

To simplify this, we could introduce a struct dimensions argument, where each key is a dimension of that solution and each value the number of entries.

cdtResult get##NAME##Particle(cdtDriver* drv, int unitOpId SENS_IDX_SIG, const** data, struct dimensions \

I haven't checked if it is possible to expose structs via ctypes in Python but there would be other options, e.g. we could simply return an array of strings and integers or just the shape as an array / tuple (we don't actually really need the dimension names, I believe).


If any of you have ideas, feel free to edit / comment.

@ronald-jaepel ronald-jaepel added this to the v5.0.0 "CADET-Core" milestone Jun 12, 2024
@jbreue16 jbreue16 modified the milestones: v5.0.0 "CADET-Core", v6.0.0 Jul 25, 2024
@schmoelder schmoelder changed the title Allow CAPI to execute only single section (or time step) C-API v2.0 Aug 19, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
Status: Todo
Development

No branches or pull requests

3 participants