How to write UI-supported classes?

 

This page describes how to write new classes that can be loaded like a plug-in, just by giving their name in the User Interface, not changing any piece of the pre-existing SPIS code. Your new class can be a new type of transport model, environment, particle source, etc.

 

If you want to write a new piece of code for SPIS/NUM, you may have several approaches.

 

You may be thinking in terms of routines, as e.g. in Fortran 90. You will be forced by Java to write your code as a method of a class, but you'll be free to write it as you want. You may even declare it static, declaring this way that it is the same method/routine for any instance of the class. It would then real be like on old-fashioned routine. This is most of the time to be avoided.

 

In SPIS object oriented (OO) code you will more likely derive a new class from an existing class. Examples:

-         if you want to write a new source of particle defined by a surface velocity distribution (e.g. an electric thruster exhaust), you will follow the right "model" of surface distribution, so that your model can be used generically as any other source of particles: you will derive your class from SurfDistrib. Your new class will then automatically offer the requested capabilities to be a surface distribution: providing distribution moments or particle samples (the abstract methods of SurfDistrib you'll have to implement)

-         if you want to write a new model of material interaction, you'll write a new class derived from MaterialModel, different of BasicMaterialModel currently under use. It will need to offer all what offers a material model, basically Interactors for all types of interactions.

-         Or you may just write an new interactor (e.g. for a more refined mode of photo-emission) deriving from Interactor class. You'll have to write a constructor for your new class that will pass in and out fluxes to Interactor constructor,

 

The next question is how to "plug" your new class into the code, i.e. how to have it executed properly in place of another version of source/model/interactor, etc.

The regular way is to modify the existing code which calls the piece of code you want to replace to have your new piece of code called instead. So you would have to modify SPIS.

The alternative, explained here, is to have your new piece of code (new class) called without change a single piece of pre-existing SPIS code. You simply switch to your new class by typing your class name as a global parameter in SPIS GUI. Internally this is made possible by Java introspection capabilities.

In practice, such "plug-in" classes must:

a)      follow the regular OO rules explained above for derived classes: implement the abstract methods to follow the class model

b)      also provide a predefined constructor, so that not only the usage of your new class can be generic (automatic), but also its instantiation can be generic

As of SPIS v3.6 this mechanism has been implemented for four types of classes:

-         Environment

-         VolDistribWithIO

-         NonPicSurfDistrib

-         VolInteractor

and could be extended to other regular object types, as e.g. generic surface Interactor, that cannot for now be added as a plug-in (the original reason is that the list of surface interactions was predefined).

The interface of the predefined constructor imposed by the plug-in principle (b) is defined in the documentation of the four classes above.

More comments are also supplied on each of these four plug-in models (list of implemented versions…) in the following sections of Controlling NUM from UI.html:

-         Plasma section: Environment and VolDistribWithIO models

-         Particle sources section: NonPicSurfDistrib model

-         Volume interactions section: VolInteractor model

 

Note that the existence of this specific constructor is not enforced at compilation time, and its incorrect definition will generate an Exception at execution time only.

 

NB: A different way of defining plug-in classes for a better enforcement at compilation time could be to simply request a zero-argument constructor (still not enforceable at compilation time, but simpler to specify) and add an abstract initialisation method to be implemented (enforceable at compilation time). Instantiation of objects of such a class would involve a call of the zero-argument constructor, then a call of the initialisation method, which is not really the OO logics, in which the constructor call normally performs the initialisations (this is the drawback of this way of defining plug-in classes, reducing the advantage of an improved control at compilation time).