Actual source code: petscfwk.h
1: #ifndef __PETSCFWK_H
4: #include petscsys.h
8: /*
9: There is only one type implementing PetscFwk,
10: so all the code is in the interface and implements only one class PETSCFWK (below)
11: rather than using something like PETSCFWK_BASIC, etc.
12: */
13: #define PETSCFWK "petscfwk"
16: struct _p_PetscFwk;
17: typedef struct _p_PetscFwk *PetscFwk;
20: #define PETSC_FWK_DEFAULT_SELF PETSC_FWK_DEFAULT_(PETSC_COMM_SELF)
21: #define PETSC_FWK_DEFAULT_WORLD PETSC_FWK_DEFAULT_(PETSC_COMM_WORLD)
28: /**/
32: /**/
45: /*
46: This library deals with components and frameworks.
48: PetscFwk can (i) act as a "framework" (more or less as before), or
49: (ii) as a "component" (more about it below).
51: (i) As a "framework", PetscFwk is a bag of "components" (other
52: PetscFwk objects).
53: One can register components (PetscFwkRegisterComponent) and
54: dependencies between them (PetscRegisterDependence) through keys.
55: For each new key the framework creates a new PetscFwk component with
56: its PetscObject name equal to the key, and inserts a vertex into the
57: dependency graph.
58: For each dependency between two keys, it inserts a corresponding edge
59: into the dependency graph.
60: A framework can "visit" its components in the topological sort order
61: of the dependency graph, and "call" each component
62: with a string "<message>": PetscFwkVisit
64: (ii) As a "component", PetscFwk supports essentially one interface:
65: "call" with two arguments,
66: the component itself and a string "<message>". This call is forwarded
67: to an implementing function in two different ways:
68: (a) the component's vtable (to be defined below) is searched for a
69: message handler for <message>
70: if the subroutine is found, its called with the component as the
71: sole argument.
72: (b) if (a) fails to locate an appropriate message handler, and only
73: then, the component's vtable is searched for a
74: message handler for message "call"; if the subroutine is found,
75: it is called with the component and "<message>" as the
76: two arguments;
77: Otherwise an error occurs, since the component is unable to handle
78: the message.
79: The message handler acts on the component state, which is accessible
80: through the public PETSc API.
81: In particular, the message handler can extract PetscObjects attached
82: to the component via PetscObjectCompose.
83: This is a slow and somewhat cumbersome way of passing arguments to a
84: message handler, but it's one that can span
85: language boundaries (e.g., from C to Python).
87: vtable:
88: A component can implement message handling routines two different ways:
89: (1) Message handlers can be composed with the component object via
90: PetscObjectComposeFunction
91: A component with PetscObject name <name> handles message
92: <message> using function with the name
93: "<name><Message>" (i.e., appending <message> to <name> and
94: capitalizing the first letter of the <message> string).
95: (2) Message handlers can be found using a URL associated with a
96: component. The URL is of the one of the two forms:
97: (2.1) "[<path>/<lib>.a:]<name>" or "[<path>/<lib>.so:]<name>",
98: in which case all message handler searches are done not
99: among the composed functions, but among the dynamic
100: symbols in the lib.
101: If the lib is absent, then the symbols are searched for
102: in the main executable, and have to be exported as dynamic,
103: in order to be found.
104: (2.2) "<path>/<module>.py:<name>", in which case message handlers
105: are supposed to be static methods in a Python class <name>,
106: located in <module>, found at <path>. In this case
107: message handlers must have names matching <message>,
108: if a <message>-specific handler is absent. These
109: handlers are passed a petsc4py.Fwk object wrapping the component,
110: and a Python string, encapsulating <message>, if necessary.
112: A URL can be associated with an PetscFwk using PetscFwkSetURL.
113: A URL can be reset using repeated calls to PetscFwkSetURL.
114: The URL can be retrieved using PetscFwkGetURL.
116: A component attached to a framework using a key can be extracted with
117: PetscFwkGetComponent,
118: and then its vtable can be manipulated either by composing functions
119: with it using PetscObjectComposeFunction,
120: or by setting the component's URL.
121: There is a shorthand way of associating a URL to a component being
122: attached to a framework: PetscFwkRegisterComponentURL.
123:
124: */
125: #endif