As explained in the previous chapter (1.4.4 Processors) the P2Ps we initially created may lead to problems later on. Therefore, we now define P2Ps that directly react to the change in manipulator flowrates by using events. More in depth information on events in V-HAB can be found in chapter 4. Events API (timer, source) but the information provided here should be sufficient to get you started and solve most commonly encountered problems.

The concept of events is that certain points in the code can trigger an event with a specific name and other components can bind calculations to these triggers. In our example the P2Ps for oxygen and hydrogen are supposed to transport the mass flowrates produced by the manipulator into the respective gas phases. For this purpose it would be great if we can simply tell the P2Ps to change their flowrate whenever the manipulator changes its flowrates right? Well this can be done with a very simple approach, calling the setMatterProperty() functions of the two P2Ps from the manipulator update after it finished calculating. However, if we do it like that the manipulator has to know the path and name of both of the P2Ps and if we have other components that also want to update at this location we require quite a lot of code lines. If we define an event instead the different components do not actually have to know about each other, which makes moving and renaming them much easier!

First we have to add a trigger to the manipulator update function. For this you first have to inherit the event source from the event core class to get access to the events. This can be done by simply changing the class definition to:

classdef O2_Generation_Manip < matter.manips.substance.stationary & event.source

You have to add the same inheritance to the General_P2P class definition!

Now add the following line of code behind everything else in the manipulator update() function:

this.trigger('OGA_ManipulatorUpdate')

As with everything else try to give the event triggers easily recognizable names!

Now we can bind a function calculating the P2P flowrate to this trigger by adding

oStore.toPhases.Water.toManips.substance.bind('OGA_ManipulatorUpdate', @this.calculateFlowRate);

to the constructor of the P2P. Since this calls references the manipulator, you now also have to make sure that the manipulator is defined before the P2Ps! The .bind operator must always be referenced to the object which contains the respectíve trigger to which you want to bind the function. That way only the P2P requires information about the manipulator, not the other way round! For this we use a different function than the update function of the P2P (simply leave the update function empty) because we really only want to change the flowrate when the manipulator changes its flowrate. So add the calculateFlowRate() function to the P2P now and empty the update function!

function calculateFlowRate(this,~)
    this.fSubstanceFlowRate = this.oStore.toPhases.Water.toManips.substance.afPartialFlows(this.oMT.tiN2I.(this.sSubstance));

    % Connected phases have to do a massupdate before we set the
    % new flow rate - so the mass for the LAST time step, with the
    % old flow rate, is actually moved from tank to tank. In the
    % massupdate the update for the P2P will be triggered, which is
    % then executed in the post tick after the phase massupdates
    this.oIn.oPhase.registerMassupdate();
    this.oOut.oPhase.registerMassupdate();
end

Note that it is not allowed to directly use setMatterProperties here, because that would directly change the flowrate, but we first have to perform the massupdate of the phases before the flowrate is changed. The update of P2P is then called in the phase massupdate functions. Therefore, we only store the flowrate in the new property fSubstanceFlowRate, which you should initialize to 0. The Update function of the P2P must use access right protected, as defined by the parent class and can now simply set the flowrate as defined in the calculateFlowRate function using the following code:

function update(this)
	this.setMatterProperties(this.fSubstanceFlowRate , this.arExtractPartials);
end

This is already sufficient to bind the flowrate calculation of the P2P to the manipulator. Thus we circumvent the need to calculate a time step and prevent the issues mentioned earlier from ever occuring. At the same time we keep the calculations at the location where they should occur, if we place the calculations for the P2P flows into the manipulator update function for example, we cannot use that manipulator without the P2Ps. Of course, this P2P example could also be improved, for example by making the manipultor whose flowrates we use an Input to be more general. But that is not necessary for now

  • Keine Stichwörter