The spatial domain is represented by units from different classes defined by the users. Each unit carries its own information that can be exploited through accessor methods (see classes docs), and also input data and simulation variables that can be exploited through special methods (see Access to function parameters and Access to input data).
The spatial domain can be parsed using the macros intended for handling spatial entities.
To parse units of a specific class, you can use:
To parse all units of the spatial domain, you can use:
To parse a specific list of units, you can use:
Example:
bool MyFunc::runStep(const openfluid::base::SimulationStatus* SimStatus) { openfluid::core::Unit* SU; openfluid::core::Unit* UU; openfluid::core::Unit* UpSU; openfluid::core::UnitsPtrList_t* UpSUsList; double TmpValue; DECLARE_UNITS_ORDERED_LOOP(1); DECLARE_UNITS_LIST_LOOP(25); DECLARE_GLOBAL_UNITS_ORDERED_LOOP(10) BEGIN_UNITS_ORDERED_LOOP(1,"SU",SU) UpSUsList = SU->getFromUnits("SU"); BEGIN_UNITS_LIST_LOOP(25,UpSUsList,UpSU) OPENFLUID_GetVariable(UpSU,"water.surf.Q.downstream-su",CurrentStep-1,TmpValue); END_LOOP END_LOOP; BEGIN_GLOBAL_UNITS_ORDERED_LOOP(10,UU) // do something here with UU pointer END_LOOP }
To parse units of a specific class, you can use:
To parse all units of the spatial domain, you can use:
Example:
void MyFunc::computeA(openfluid::core::Unit* aUnit) { // compute something // use/produce variables } void MyFunc::computeB(openfluid::core::Unit* U, const openfluid::base::SimulationStatus* SimStatus, const double Coeff) { // compute something else, with extra args // use/produce variables } bool MyFunc::runStep(const openfluid::base::SimulationStatus* SimStatus) { DECLARE_UNITS_ORDERED_LOOP(1); DECLARE_UNITS_ORDERED_LOOP(7); DECLARE_GLOBAL_UNITS_ORDERED_LOOP(10) APPLY_UNITS_ORDERED_LOOP_THREADED(1,"SU",MyFunc::computeA); APPLY_UNITS_ORDERED_LOOP_THREADED(7,"TU",MyFunc::computeB, SimStatus, 2.5); APPLY_GLOBAL_UNITS_ORDERED_LOOP_THREADED(10,MyFunc::computeA); }
Please note:
Concurrent parsing using multi-threading should improve computing performance, reducing simulations durations. But in case of very short computing durations, the cost of multi-threading management may nullify the speed improvements of concurrent computing.
The spatial domain graph can be defined statically through the input dataset. It can also be defined and modified dynamically, during simulations, through primitives allowing to create and delete spatial units, and also to add and remove connections between these spatial units.
For better use of simulation functions which modify the spatial domain graph, please fill the signature with the correct directives. See Spatial units graph signature.
Spatial units can be created and deleted dynamically, whenever during simulations. However, it is really tricky to perform it once the simulation has started (for modelling consistency reasons).
In order to create and delete units, you can use the following methods:
Connections between spatial units can be of two types:
In order to add and remove connections, you can use the following methods, whenever during simulations:
Example:
bool prepareData() { /* TU.1 TU.2 | | --> TU.22 <-- | --> TU.18 | TU.52 --> OU.5 <-- OU.13 | --> OU.25 VU1 <-> VU2 with: TU1, TU2, TU22, TU18 are children of VU1 TU52, OU5, OU13, OU25 are children of VU2 */ OPENFLUID_AddUnit("VU",1,1); OPENFLUID_AddUnit("VU",2,2); OPENFLUID_AddUnit("TU",1,1); OPENFLUID_AddUnit("TU",2,1); OPENFLUID_AddUnit("TU",22,2); OPENFLUID_AddUnit("TU",18,3); OPENFLUID_AddUnit("TU",52,1); OPENFLUID_AddUnit("OU",5,4); OPENFLUID_AddUnit("OU",13,1); OPENFLUID_AddUnit("OU",25,5); OPENFLUID_AddFromToConnection("VU",1,"VU",2); OPENFLUID_AddFromToConnection("VU",2,"VU",1); OPENFLUID_AddFromToConnection("TU",1,"TU",22); OPENFLUID_AddFromToConnection("TU",2,"TU",22); OPENFLUID_AddFromToConnection("TU",22,"TU",18); OPENFLUID_AddFromToConnection("TU",18,"OU",5); OPENFLUID_AddFromToConnection("TU",52,"OU",5); OPENFLUID_AddFromToConnection("OU",13,"OU",5); OPENFLUID_AddFromToConnection("OU",5,"OU",25); OPENFLUID_AddChildParentConnection("TU",1,"VU",1); OPENFLUID_AddChildParentConnection("TU",2,"VU",1); OPENFLUID_AddChildParentConnection("TU",22,"VU",1); OPENFLUID_AddChildParentConnection("TU",18,"VU",1); OPENFLUID_AddChildParentConnection("TU",52,"VU",2); OPENFLUID_AddChildParentConnection("OU",5,"VU",2); OPENFLUID_AddChildParentConnection("OU",13,"VU",2); OPENFLUID_AddChildParentConnection("OU",25,"VU",2); return true; }
The spatial domain graph can be queried, whenever during simulations, in order to get informations about spatial units and connections.
You can use the following methods:
Generators can help to automatically build a spatial domain graph, or to extend an existing one.
The following spatial domain generators are available: