net.algart.model3d.common.movement.model Interface MovementIntegrator

All Known Implementing Classes:
AbstractMovementIntegrator, EulerMovementIntegrator, MovementIntegratorWrapper, RungeKuttaMovementIntegrator

public interface MovementIntegrator

Movement integrator: the basic tool for integrating motion equations of the physical model, described by ItemSet object.

This class operates with some item set (an instance of ItemSet) and with some list of interaction rules (instances of InteractionRule), which are usually passed to a constructor or an instantiation method and cannot be changed in future, and solves the following basic task:

• At the current time moment t, we know the current coordinates and velocities of all items from the given set, having coordinates of centers and velocities — 6 numbers xk, yk, zk, vxk, vyk, vzk per each item #k, returned by methods of HavingCenter and HavingVelocity interfaces for these items.
• We know that some items interact, according to the given set of interaction rules, and, therefore, we can calculate the summary force Fksum = ∑ Fk,j, acting to each item #k (which has a center and a velocity) from the side of all other items #j, interacting with it.
• Then, we need to find the estimated coordinates and velocities of all items, having coordinates of centers and velocities and also having masses, at the moment tt, according Newton's 2nd law, and to store the new found coordinates and velocities in this item set by the corresponding methods of HavingCenter and HavingVelocity interfaces.

Such operation is called "iteration" and performed by performIteration() method — the basic method of this interface.

It is obvious that we've described the classic Cauchy problem:

dw/dt = f(t, w)

the case of the simple motion equations:

dxk/dt = vxk
dyk/dt = vyk
dzk/dt = vzk
dvxk/dt = ∑ Fxk,j / mk
dvyk/dt = ∑ Fyk,j / mk
dvzk/dt = ∑ Fzk,j / mk

where k is an index of some item, implementing HavingVelocity and HavingMass, xk, yk, zk are coordinates ot its center (depending on the current time t), vxk, vyk, vzk are components if its velocity (also depending on the time t), mk is its mass and Fk,j = (Fxk,j, Fyk,j, Fzk,j) is the force of interaction between the item #k and any other item #j — the sum of results of InteractionRule.calculateForce(double[] resultXYZ, Item toItem, Item byItem, double time) method for all interaction rules, supported by this object (and specified while its creating), where toItem argument is the item #k, byItem is the item #j and time=t is the current time.

This package offers two classic solution of this problem: EulerMovementIntegrator, based on Euler algorithm, and RungeKuttaMovementIntegrator, based on the generalized Runge-Kutta algorithm.

The current time t and the time step Δt are stored by this object in some internal fields and can be read or written at any moment by the corresponding methods. The current time t is automatically increased by Δt by performIteration() method, together with correction of coordinates and velocities of items. The Δt step cannot be negative.

Usually, the motion equations are considered according Newton's 2nd law, as described in equations above. But this interface also supports the following non-standard "pseudo-Newton's" form of motion equations:

dxk/dt = vxk = ∑ Fxk,j / mk
dyk/dt = vyk = ∑ Fyk,j / mk
dzk/dt = vzk = ∑ Fzk,j / mk

All implementations of this interface can work in the special mode, corresponding to these motion equations. This mode is called "the mode of viscous forces" and can be activated at any time by setViscousForces(boolean) method.

This interface can perform some additional correction of the left side of motion equations listed above. Namely, the modules of resulting derivative vectors drk/dt = (dxk/dt, dyk/dt, dzk/dt) and dvk/dt = (dvxk/dt, dvyk/dt, dvzk/dt) are compared with the velocity limit Vmax and the acceleration limit Amax, and if the modules are greater than the limits, these vectors are reduced to be equal (by modulus) to these limits. Formally, it means that the real form of motion equations, integrated by this interface, is:

dxk/dt = α vxk
dyk/dt = α vyk
dzk/dt = α vzk
dvxk/dt = β ∑ Fxk,j / mk
dvyk/dt = β ∑ Fyk,j / mk
dvzk/dt = β ∑ Fzk,j / mk
α = min(1, Vmax / |vk|)
β = min(1, Amax / |∑ Fk,j / mk|)

in the standard mode and

dxk/dt = α ∑ Fxk,j / mk
dyk/dt = α ∑ Fyk,j / mk
dzk/dt = α ∑ Fzk,j / mk
α = min(1, Vmax / |∑ Fk,j / mk|)

in the mode of viscous forces. (In the formulas above, the modulus |w| of a vector w = wx, wy, wz) is |w| = (wx²+wy²+wz²)½.) Such correction helps to reduce unwanted results of possible instability — the typical problem of integrating Cauchy problem for motion equations. By default, both limits Vmax and Amax are infinite (Double.POSITIVE_INFINITY), so they do not affect the equations; but you can set them to another values by setVelocityLimit(double) and setAccelerationLimit(double) methods.

Some implementations of this interface (like RKF-45 algorithm) allow to estimate the maximal and mean error of calculating coordinates and velocities. Such implementations return this information via maxLastCoordinateError(), meanLastCoordinateError(), maxLastVelocityError(), meanLastVelocityError() methods. In other implementations, which do not support error estimation, these methods return Double.NaN.

Sometimes, implementations of this interface can use multithreading for accelerating calculations on multiprocessor systems. By default, all calculations are performed in a single thread, but you can set another number of parallel threads by setNumberOfParallelTasks(int) method — if the object will be able to use such optimization, it will do it.

Implementations of this interface are usually not thread-safe, but are thread-compatible and can be synchronized manually if multithread access is necessary. However, there are the following guarantees (without any additional synchronization):

AlgART Laboratory 2010

Since:
JDK 1.5
Version:
1.0
Author:
Daniel Alievsky

Method Summary
Modifier and Type Method and Description
void copyBasicSettings(MovementIntegrator source)
Copies all basic settings, that can be accessed via getXxx/setXxx methods of this interface, from the specified object.
double getAccelerationLimit()
Returns the acceleration limit Amax.
long getCounterOfCheckedNeighbours()
Returns the internal thread-safe counter of "neighbour" item pairs, which were checked by performIteration() method while calculation of the right side of the motion equations.
long getCounterOfProcessedInteractions()
Returns the internal thread-safe counter of really interacted item pairs, which were really processed by performIteration() method while calculation of the right side of the motion equations, that is for which calculateForce method was really called and returned true.
long getCounterOfProcessedItems()
Returns the internal thread-safe counter of items, which were processed by performIteration() method while calculation of the right side of the motion equations.
long getCounterOfProcessedSymmetricInteractions()
An analog of the counter getCounterOfProcessedInteractions(), counting only pairs, which were processed in more efficient way thanks to symmetric interaction rules.
double getDeltaT()
Returns the time step Δt for one iteration of integration.
java.util.List<InteractionRule> getInteractionRules()
Returns the list of interaction rules, used by this object.
ItemSet getItemSet()
Returns the item set, processed by this object.
Returns the current number of parallel threads, which is recommended this object to use for optimizing calculations on multiprocessor systems.
double getT()
Returns the current time t in the physical model.
double getVelocityLimit()
Returns the velocity limit Vmax.
boolean getViscousForces()
Returns true if this object works in the mode of viscous forces.
boolean isErrorInformationAvailable()
Returns true if this implementation allows to estimate the maximal and mean error of calculating coordinates and velocities.
double maxLastCoordinateError()
Returns the estimation of the maximal error of calculating coordinates while the previous performIteration() call, if this implementation supports this feature, or Double.NaN in other case.
double maxLastVelocityError()
Returns the estimation of the maximal error of calculating velocities while the previous performIteration() call, if this implementation supports this feature, or Double.NaN in other case.
double meanLastCoordinateError()
Returns the estimation of the average error of calculating coordinates while the previous performIteration() call, if this implementation supports this feature, or Double.NaN in other case.
double meanLastVelocityError()
Returns the estimation of the average error of calculating velocities while the previous performIteration() call, if this implementation supports this feature, or Double.NaN in other case.
void performIteration()
Performs one iteration of integration.
void resetCounters()
Resets to 0 all internal counters, returned by getCounterOfProcessedItems(), getCounterOfCheckedNeighbours(), getCounterOfProcessedInteractions() and getCounterOfProcessedSymmetricInteractions() methods.
void setAccelerationLimit(double accelerationLimit)
Sets the acceleration limit Amax to the given value.
void setDeltaT(double deltaT)
Sets the current time Δt for one iteration of integration.
Sets the number of parallel threads, which should be used, if possible, for optimizing calculations on multiprocessor systems.
void setT(double t)
Sets the current time t in the physical model.
void setVelocityLimit(double velocityLimit)
Sets the velocity limit Vmax to the given value.
void setViscousForces(boolean viscousForces)
Sets the mode of viscous forces ("pseudo-Newton's" motion equations), if the argument is true, or the usual mode (standard Newton's laws), if the argument is false See comments to this interface for more details.

Method Detail

getItemSet

ItemSet getItemSet()
Returns the item set, processed by this object. Usually it is set while instantiation and cannot be changed in future. But you can change this item set by methods of ItemSet interface.

Returns:
the reference to ItemSet object, processed by this object.

getInteractionRules

java.util.List<InteractionRule> getInteractionRules()
Returns the list of interaction rules, used by this object. Usually it is set while instantiation and cannot be changed in future.

The result is an immutable view (Collections.unmodifiableList) or a clone of the internal collection, stored by this object: you cannot modify the set of used interaction rules via the result of this method.

The elements of the returned list are never null.

Returns:
the list of interaction rules, used by this object.

Returns the current number of parallel threads, which is recommended this object to use for optimizing calculations on multiprocessor systems.

The returned value is always positive (>0).

Returns:
the current number of parallel threads for multiprocessor optimization.

Sets the number of parallel threads, which should be used, if possible, for optimizing calculations on multiprocessor systems. This value should not be greater than the number of available processors or processor kernels.

If this argument is 0, it is automatically replaced with Runtime.getRuntime().availableProcessors(): the number of available processors. Note that in this case getNumberOfParallelTasks() method will return not 0, but the actual number of available processors.

Parameters:
Throws:
java.lang.IllegalArgumentException - if the argument is negative.

getViscousForces

boolean getViscousForces()
Returns true if this object works in the mode of viscous forces. See comments to this interface for more details.

Returns:
whether this object works in the mode of viscous forces.

setViscousForces

void setViscousForces(boolean viscousForces)
Sets the mode of viscous forces ("pseudo-Newton's" motion equations), if the argument is true, or the usual mode (standard Newton's laws), if the argument is false See comments to this interface for more details.

Parameters:
viscousForces - whether you this object should be switched in the mode of viscous forces.

getAccelerationLimit

double getAccelerationLimit()
Returns the acceleration limit Amax. It can be Double.POSITIVE_INFINITY: it means that the accelerations are not limited. See comments to this interface for more details.

Returns:
the acceleration limit Amax.

setAccelerationLimit

void setAccelerationLimit(double accelerationLimit)
Sets the acceleration limit Amax to the given value. You can pass Double.POSITIVE_INFINITY: it means that the accelerations will be not limited. See comments to this interface for more details.

Parameters:
accelerationLimit - new acceleration limit Amax.
Throws:
java.lang.IllegalArgumentException - if the argument is negative (< 0.0).

getVelocityLimit

double getVelocityLimit()
Returns the velocity limit Vmax. It can be Double.POSITIVE_INFINITY: it means that the velocities are not limited. See comments to this interface for more details.

Returns:
the velocity limit Amax.

setVelocityLimit

void setVelocityLimit(double velocityLimit)
Sets the velocity limit Vmax to the given value. You can pass Double.POSITIVE_INFINITY: it means that the velocities will be not limited. See comments to this interface for more details.

Parameters:
velocityLimit - new velocity limit Vmax.
Throws:
java.lang.IllegalArgumentException - if the argument is negative (< 0.0).

getT

double getT()
Returns the current time t in the physical model. It is usually 0.0 after creating new object and automatically updated (increased by Δt) by performIteration() method.

Returns:
the current time t.
getDeltaT()

setT

void setT(double t)
Sets the current time t in the physical model.

Parameters:
t - new value of the current time t.

getDeltaT

double getDeltaT()
Returns the time step Δt for one iteration of integration. It is usually specified while instantiating new object. It cannot be negative.

Returns:
the time step Δt.

setDeltaT

void setDeltaT(double deltaT)
Sets the current time Δt for one iteration of integration.

Parameters:
deltaT - new value of the time step Δt.
Throws:
java.lang.IllegalArgumentException - if the argument is negative (< 0.0).

copyBasicSettings

void copyBasicSettings(MovementIntegrator source)
Copies all basic settings, that can be accessed via getXxx/setXxx methods of this interface, from the specified object. In other words, this method is equivalent to the following calls:
setViscousForces(source.getViscousForces());
setAccelerationLimit(source.getAccelerationLimit());
setVelocityLimit(source.getVelocityLimit());
setT(source.getT());
setDeltaT(source.getDeltaT());

Parameters:
source - another movement integrator, the basic settings of which should be copied into this one.
Throws:
java.lang.NullPointerException - if the argument is null.

getCounterOfProcessedItems

long getCounterOfProcessedItems()
Returns the internal thread-safe counter of items, which were processed by performIteration() method while calculation of the right side of the motion equations.

Note that performIteration() can calculate the right side of the equations several times (as in Runge-Kutta algorithms), and then every item will be also counted several times. Usually the items, which do not have coordinates of centers and velocities or do not have masses, are not counted.

This counter is 0 after creating new instance of this class and can be set to 0 by resetCounters() method.

This method is provided for profiling and debugging needs only. It works as described above in the implementations, offered by this package, but there is no guarantee that it will return correct values in all implementations. If the implementation does not provide this counter, this method should return 0 always.

Returns:
the counter of processed items.

getCounterOfCheckedNeighbours

long getCounterOfCheckedNeighbours()
Returns the internal thread-safe counter of "neighbour" item pairs, which were checked by performIteration() method while calculation of the right side of the motion equations. This number depends on the implementation of ItemSet interface: good implementations, like GridItemSet, allow to check only restricted number of items while finding all "neighbours" of the given item, which can interact with it.

Note that the "neighbour" pair is counted independently for both its elements. In other words, it two items act to each other, their pair is counter twice.

Note that performIteration() can calculate the right side of the equations several times (as in Runge-Kutta algorithms), and then every neighbour item pair will be also counted several times.

This counter is 0 after creating new instance of this class and can be set to 0 by resetCounters() method.

This method is provided for profiling and debugging needs only. It works as described above in the implementations, offered by this package, but there is no guarantee that it will return correct values in all implementations. If the implementation does not provide this counter, this method should return 0 always.

Returns:
the counter of processed "neighbour" item pairs.

getCounterOfProcessedInteractions

long getCounterOfProcessedInteractions()
Returns the internal thread-safe counter of really interacted item pairs, which were really processed by performIteration() method while calculation of the right side of the motion equations, that is for which calculateForce method was really called and returned true.

Note that an interacted pair is counted independently for both items. In other words, it two items act to each other, their pair is counter twice.

Note that an interacted pair is counted again for every interaction rule, applicable for this pair. So, if there are K>1 rules, in which calculateForce method returned true for the given pair, then this pair will be counted K times.

Note that performIteration() can calculate the right side of the equations several times (as in Runge-Kutta algorithms), and then every neighbour item pair will be also counted several times.

This counter is 0 after creating new instance of this class and can be set to 0 by resetCounters() method.

This method is provided for profiling and debugging needs only. It works as described above in the implementations, offered by this package, but there is no guarantee that it will return correct values in all implementations. If the implementation does not provide this counter, this method should return 0 always.

Returns:
the counter of processed really interacted item pairs.

getCounterOfProcessedSymmetricInteractions

long getCounterOfProcessedSymmetricInteractions()
An analog of the counter getCounterOfProcessedInteractions(), counting only pairs, which were processed in more efficient way thanks to symmetric interaction rules. Namely, some implementations of this interface can use the fact, that some interaction is symmetric (implements SymmetricInteractionRule), and calculate the interaction force only once. The force F' of acting of the 2nd item to the 1st one is produced from the force F of acting of the 1st item to the 2nd one by changing the sign: F'=−F. In this case, the counter, returned by this method, is increased by 2 for each such interaction rule, as well as the counter, returned by getCounterOfProcessedInteractions() method. But some "neighbour" item pairs cannot be processed in such a manner, for example, when the first item is processed (moved) by one processor in multiprocessor system and the second one is processed by another processor. In such situation, this counter is not increased, though the counter, returned by getCounterOfProcessedInteractions() method, is increased by 2 (by 1 for each from two items). So, this method can help to measure optimization, achieved thanks to usage of symmetric interaction rules.

This counter is 0 after creating new instance of this class and can be set to 0 by resetCounters() method.

This method is provided for profiling and debugging needs only. It works as described above in the implementations, offered by this package, but there is no guarantee that it will return correct values in all implementations. If the implementation does not provide this counter, this method should return 0 always.

Returns:
the counter of processed really interacted item pairs, for which the interaction force was not calculated twice, because of using symmetric interaction rules.

resetCounters

void resetCounters()
Resets to 0 all internal counters, returned by getCounterOfProcessedItems(), getCounterOfCheckedNeighbours(), getCounterOfProcessedInteractions() and getCounterOfProcessedSymmetricInteractions() methods.

performIteration

void performIteration()
Performs one iteration of integration. This method sets the current time t to tt and correspondingly corrects the coordinates and velocities of all items in the processed item set, having centers and velocities and having masses, according to the motion equations. See comments to this interface for more details.

isErrorInformationAvailable

boolean isErrorInformationAvailable()
Returns true if this implementation allows to estimate the maximal and mean error of calculating coordinates and velocities. In this case, you can use maxLastCoordinateError(), meanLastCoordinateError(), maxLastVelocityError(), meanLastVelocityError() methods after every performIteration() call to get this information. In other case, those methods return Double.NaN.

Returns:
whether this implementation supports estimating the maximal and mean error of calculating coordinates and velocities.

maxLastCoordinateError

double maxLastCoordinateError()
Returns the estimation of the maximal error of calculating coordinates while the previous performIteration() call, if this implementation supports this feature, or Double.NaN in other case.

Returns:
the estimation of the maximal error of calculating coordinates while the last integrating iteration.

maxLastVelocityError

double maxLastVelocityError()
Returns the estimation of the maximal error of calculating velocities while the previous performIteration() call, if this implementation supports this feature, or Double.NaN in other case.

Returns:
the estimation of the maximal error of calculating velocities while the last integrating iteration.

meanLastCoordinateError

double meanLastCoordinateError()
Returns the estimation of the average error of calculating coordinates while the previous performIteration() call, if this implementation supports this feature, or Double.NaN in other case.

Returns:
the estimation of the average error of calculating coordinates while the last integrating iteration.

meanLastVelocityError

double meanLastVelocityError()
Returns the estimation of the average error of calculating velocities while the previous performIteration() call, if this implementation supports this feature, or Double.NaN in other case.

Returns:
the estimation of the average error of calculating velocities while the last integrating iteration.