<HTML>
<CENTER><A HREF = "Section_tools.html">Previous Section</A> - <A HREF = "https://sparta.github.io">SPARTA WWW Site</A> -
<A HREF = "Manual.html">SPARTA Documentation</A> - <A HREF = "Section_commands.html#comm">SPARTA Commands</A> - <A HREF = "Section_python.html">Next
Section</A> 
</CENTER>






<HR>

<H3>10. Modifying & extending SPARTA 
</H3>
<P>This section describes how to extend SPARTA by modifying its source code.
</P>
10.1 <A HREF = "#mod_1">Compute styles</A><BR>
10.2 <A HREF = "#mod_2">Fix styles</A><BR>
10.3 <A HREF = "#mod_3">Region styles</A><BR>
10.4 <A HREF = "#mod_4">Collision styles</A><BR>
10.5 <A HREF = "#mod_5">Surface collision styles</A><BR>
10.6 <A HREF = "#mod_6">Chemistry styles</A><BR>
10.7 <A HREF = "#mod_7">Dump styles</A><BR>
10.8 <A HREF = "#mod_8">Input script commands</A> <BR>

<P>SPARTA is designed in a modular fashion so as to be easy to modify and
extend with new functionality.
</P>
<P>In this section, changes and additions users can make are listed along
with minimal instructions.  If you add a new feature to SPARTA and
think it will be of general interest to users, please submit it to the
<A HREF = "https://sparta.github.io/authors.html">developers</A> for inclusion in
the released version of SPARTA.
</P>
<P>The best way to add a new feature is to find a similar feature in
SPARTA and look at the corresponding source and header files to figure
out what it does. You will need some knowledge of C++ to be able to
understand the hi-level structure of SPARTA and its class
organization, but functions (class methods) that do actual
computations are written in vanilla C-style code and operate on simple
C-style data structures (vectors, arrays, structs).
</P>
<P>The new features described in this section require you to write a new
C++ derived class. Creating a new class requires 2 files, a source
code file (*.cpp) and a header file (*.h).  The derived class must
provide certain methods to work as a new option.  Depending on how
different your new feature is compared to existing features, you can
either derive from the base class itself, or from a derived class that
already exists.  Enabling SPARTA to invoke the new class is as simple
as putting the two source files in the src dir and re-building SPARTA.
</P>
<P>The advantage of C++ and its object-orientation is that all the code
and variables needed to define the new feature are in the 2 files you
write, and thus shouldn't make the rest of SPARTA more complex or
cause side-effect bugs.
</P>
<P>Here is a concrete example. Suppose you write 2 files collide_foo.cpp
and collide_foo.h that define a new class CollideFoo that computes
inter-particle collisions described in the classic 1997 paper by Foo,
et al. If you wish to invoke those potentials in a SPARTA input script
with a command like
</P>
<P>collide foo mix-ID params.foo 3.0
</P>
<P>then your collide_foo.h file should be structured as follows:
</P>
<P>#ifdef COLLIDE_CLASS
CollideStyle(foo,CollideFoo)
#else
...
(class definition for CollideFoo)
...
#endif 
</P>
<P>where "foo" is the style keyword in the collid command, and CollideFoo
is the class name defined in your collide_foo.cpp and collide_foo.h
files.
</P>
<P>When you re-build SPARTA, your new collision model becomes part of the
executable and can be invoked with a <A HREF = "collide.html">collide</A> command
like the example above.  Arguments like a mixture ID, params.foo (a
file with collision parameters), and 3.0 can be defined and processed
by your new class.
</P>
<P>As illustrated by this example, many kinds of options are referred to
in the SPARTA documentation as the "style" of a particular command.
</P>
<P>The instructions below give the header file for the base class that
these styles are derived from.  Public variables in that file are ones
used and set by the derived classes which are also used by the base
class.  Sometimes they are also used by the rest of SPARTA.  Virtual
functions in the base class header file which are set = 0 are ones
that must be defined in the new derived class to give it the
functionality SPARTA expects.  Virtual functions that are not set to 0
are functions that can be optionally defined.
</P>
<P>Here are additional guidelines for modifying SPARTA and adding new
functionality:
</P>
<UL><LI>Think about whether what you want to do would be better as a pre- or
post-processing step. Many computations are more easily and more
quickly done that way. 

<LI>Don't do anything within the timestepping of a run that isn't
parallel.  E.g. don't accumulate a large volume of data on a single
processor and analyze it.  This runs the risk of seriously degrading
the parallel efficiency. 

<P>If you have a question about how to compute something or about
internal SPARTA data structures or algorithms, feel free to send an
email to the <A HREF = "https://sparta.github.io/authors.html">developers</A>.
</P>
<LI>If you add something you think is generally useful, also send an email
to the <A HREF = "https://sparta.github.io/authors.html">developers</A> so we can
consider adding it to the SPARTA distribution. 
</UL>
<HR>

<HR>

<A NAME = "mod_1"></A><H4>10.1 Compute styles 
</H4>
<P><A HREF = "compute.html">Compute style commands</A> calculate instantaneous
properties of the simulated system.  They can be global properties, or
per particle or per grid cell or per surface element properties.  The
result can be single value or multiple values (global or per particle
or per grid or per surf).
</P>
<P>Here is a brief description of methods to define in a new derived
class.  See compute.h for details.  All of these methods are optional.
</P>
<DIV ALIGN=center><TABLE  BORDER=1 >
<TR><TD >init</TD><TD > initialization before a run</TD></TR>
<TR><TD >compute_scalar</TD><TD > compute a global scalar quantity</TD></TR>
<TR><TD >compute_vector</TD><TD > compute a global vector of quantities</TD></TR>
<TR><TD >compute_per_particle</TD><TD > compute one or more quantities per particle</TD></TR>
<TR><TD >compute_per_grid</TD><TD > compute one or more quantities per grid cell</TD></TR>
<TR><TD >compute_per_surf</TD><TD > compute one or more quantities per surface element</TD></TR>
<TR><TD >surf_tally</TD><TD > call when a particle hits a surface element</TD></TR>
<TR><TD >boundary_tally</TD><TD > call when a particle hits a simulation box boundary</TD></TR>
<TR><TD >memory_usage</TD><TD > tally memory usage 
</TD></TR></TABLE></DIV>

<P>Note that computes with "/particle" in their style name calculate per
particle quantities, with "/grid" in their name calculate per grid
cell quantities, and with "/surf" in their name calculate per surface
element properties.  All others calcuulate global quantities.
</P>
<P>Flags may also need to be set by a compute to enable specific
properties.  See the compute.h header file for one-line descriptions.
</P>
<HR>

<A NAME = "mod_2"></A><H4>10.2 Fix styles 
</H4>
<P><A HREF = "fix.html">Fix style commands</A> perform operations during the
timestepping loop of a simulation.  They can define methods which are
invoked at different points within the timestep.  They can be used to
insert particles, perform load-balancing, or perform time-averaging of
various quantities.  They can also define and maintain new
per-particle vectors and arrays that define quantities that move with
particles when they migrate from processor to processor or when the
grid is rebalanced or adapated.  They can also produce output of
various kinds, similar to <A HREF = "compute.html">compute</A> commands.
</P>
<P>Here is a brief description of methods to define in a new derived
class.  See fix.h for details.  All of these methods are optional,
except setmask().
</P>
<DIV ALIGN=center><TABLE  BORDER=1 >
<TR><TD >setmask</TD><TD > set flags that determine when the fix is called within a timestep</TD></TR>
<TR><TD >init</TD><TD > initialization before a run</TD></TR>
<TR><TD >start_of_step</TD><TD > called at beginning of timestep</TD></TR>
<TR><TD >end_of_step</TD><TD > called at end of timestep</TD></TR>
<TR><TD >add_particle</TD><TD > called when a particle is created</TD></TR>
<TR><TD >surf_react</TD><TD > called when a surface reaction occurs</TD></TR>
<TR><TD >memory_usage</TD><TD > tally memory usage 
</TD></TR></TABLE></DIV>

<P>Flags may also need to be set by a fix to enable specific properties.
See the fix.h header file for one-line descriptions.
</P>
<P>Fixes can interact with the Particle class to create new
per-particle vectors and arrays and access and update their
values.  These are the relevant Particle class methods:
</P>
<DIV ALIGN=center><TABLE  BORDER=1 >
<TR><TD >add_custom</TD><TD > add a new custom vector or array</TD></TR>
<TR><TD >find_custom</TD><TD > find a previously defined custom vector or array</TD></TR>
<TR><TD >remove_custom</TD><TD > remove a custom vector or array 
</TD></TR></TABLE></DIV>

<P>See the <A HREF = "fix_ambipolar.html">fix ambipolar</A> for an example of how these
are used.  It define an integer vector called "ionambi" to flag
particles as ambipolar ions, and a floatin-point array called
"velambi" to store the velocity vector for the associated electron.
</P>
<HR>

<A NAME = "mod_3"></A><H4>10.3 Region styles 
</H4>
<P><A HREF = "region.html">Region style commands</A> define geometric regions
within the simulation box.  Other commands use regions
to limit their computational scope.
</P>
<P>Here is a brief description of methods to define in a new derived
class.  See region.h for details.  The inside() method is required.
</P>
<P>inside: determine whether a point is inside/outside the region 
</P>
<HR>

<A NAME = "mod_4"></A><H4>10.4 Collision styles 
</H4>
<P><A HREF = "collide.html">Collision style commands</A> define collision models that
calculate interactions between particles in the same grid cell.
</P>
<P>Here is a brief description of methods to define in a new derived
class.  See collide.h for details.  All of these methods are required
except init() and modify_params().
</P>
<DIV ALIGN=center><TABLE  BORDER=1 >
<TR><TD >init</TD><TD > initialization before a run</TD></TR>
<TR><TD >modify_params</TD><TD > process style-specific options of the <A HREF = "collide_modify.html">collide_modify</A> command</TD></TR>
<TR><TD >vremax_init</TD><TD > estimate VREmax settings</TD></TR>
<TR><TD >attempt_collision</TD><TD > compute # of collisions to attempt for entire cell</TD></TR>
<TR><TD >attempt_collision</TD><TD > compute # of collisions to attempt between 2 species groups</TD></TR>
<TR><TD >test_collision</TD><TD > determine if a collision bewteen 2 particles occurs</TD></TR>
<TR><TD >setup_collision</TD><TD > pre-computation before a 2-particle collision</TD></TR>
<TR><TD >perform_collision</TD><TD > calculate the outcome of a 2-particle collision 
</TD></TR></TABLE></DIV>

<HR>

<A NAME = "mod_5"></A><H4>10.5 Surface collision styles 
</H4>
<P><A HREF = "collide.html">Surface collision style commands</A> define collision
models that calculate interactions between a particle and surface
element.
</P>
<P>Here is a brief description of methods to define in a new derived
class.  See surf_collide.h for details.  All of these methods are
required except dynamic().
</P>
<DIV ALIGN=center><TABLE  BORDER=1 >
<TR><TD >init</TD><TD > initialization before a run</TD></TR>
<TR><TD >collide</TD><TD > perform a particle/surface-element collision</TD></TR>
<TR><TD >dynamic</TD><TD > allow surface property to change during a simulation 
</TD></TR></TABLE></DIV>

<HR>

<A NAME = "mod_6"></A><H4>10.6 Chemistry styles 
</H4>
<P>Particle/particle chemistry models in SPARTA are specified by
<A HREF = "react.html">reaction style commands</A> which define lists of possible
reactions and their parameters.
</P>
<P>Here is a brief description of methods to define in a new derived
class.  See react.h for details.  The init() method is optional;
the attempt() method is required.
</P>
<DIV ALIGN=center><TABLE  BORDER=1 >
<TR><TD >init</TD><TD > initialization before a run</TD></TR>
<TR><TD >attempt</TD><TD > attempt a chemical reaction between two particles 
</TD></TR></TABLE></DIV>

<HR>

<A NAME = "mod_7"></A><H4>10.7 Dump styles 
</H4>
<P><A HREF = "dump.html">Dump commands</A> output snapshots of simulation data to a
file periodically during a simulation, in a particular file format.
Per particle, per grid cell, or per surface element data can be
output.
</P>
<P>Here is a brief description of methods to define in a new derived
class.  See dump.h for details.  The init_style(), modify_param(), and
memory_usage() methods are optional; all the others are required.
</P>
<DIV ALIGN=center><TABLE  BORDER=1 >
<TR><TD >init_style</TD><TD > style-specific initialization before a run</TD></TR>
<TR><TD >modify_param</TD><TD > process style-specific options of the <A HREF = "dump_modify.html">dump_modify</A> command</TD></TR>
<TR><TD >write_header</TD><TD > write the header of a snapshot to a file</TD></TR>
<TR><TD >count</TD><TD > # of entities this processor will output</TD></TR>
<TR><TD >pack</TD><TD > pack a processor's data into a buffer</TD></TR>
<TR><TD >write_data</TD><TD > write a buffer of data to a file</TD></TR>
<TR><TD >memory_usage</TD><TD > tally memory usage 
</TD></TR></TABLE></DIV>

<HR>

<A NAME = "mod_8"></A><H4>10.8 Input script commands 
</H4>
<P>New commands can be added to SPARTA that will be recognized in input
scripts.  For example, the <A HREF = "create_particles.html">create_particles</A>,
<A HREF = "read_surf.html">read_surf</A>, and <A HREF = "run.html">run</A> commands are all
implemented in this fashion.  When such a command is encountered in an
input script, SPARTA simply creates a class with the corresponding
name, invokes the "command" method of the class, and passes it the
arguments from the input script.  The command() method can perform
whatever operations it wishes on SPARTA data structures.
</P>
<P>The single method the new class must define is as follows:
</P>
<DIV ALIGN=center><TABLE  BORDER=1 >
<TR><TD >command</TD><TD > operations performed by the input script command 
</TD></TR></TABLE></DIV>

<P>Of course, the new class can define other methods and variables as
needed.
</P>
</HTML>
