In physics, interactions are in general symmetric. However, the magnitude with which it affects the interaction partners can be very different.
Also, the way the interactions have to be implemented can differ depending on the ‘‘direction’’ of the interaction.
Therefore, in Octopus interactions are broken down into their forward and their backward parts, which are treated seperately.
As we will see, in some approximations, only one of them (usually the forward interaction) are used.
The ‘‘partners’’ are instances of interaction_partner_t derived types. The interactions (from now on uni-directional) are implemented as derived types of the abstract interaction_t class.
An interaction ‘‘belongs’’ to partner A and acts on partner B.
Abstract classes
interaction_t
Definition of interaction_t
type,abstract::interaction_tprivate!> The interaction requires access to some quantities from a system to be evaluated.
integer,public::n_system_quantities!< Number of quantities needed from the system
integer,allocatable,public::system_quantities(:)!< Identifiers of the quantities needed from the system
type(clock_t),public::clock!< Clock storing the time at which the interaction was last updated.
character(len=:),public,allocatable::labelcontains
procedure(interaction_update),deferred::updateprocedure(interaction_calculate),deferred::calculateend type interaction_t
This is the minimal data structure for interactions, which only contains information relating to partner A, who owns the interacion.
In particular, the interaction has a list of quantities, which partner A needs to expose, so that the interaction can be calculated.
The IDs for the exposed quantities are defined in the section Exposed Quantities.
Furthermore, this abstract type already contains the clock for the interaction, and defines the interfaces for the deferred update()
and calculate() routines.
interaction_with_partner_t
Curretly, all interactions are derived from interaction_with_partner_t, which extends interaction_t and adds the information about partner B, from here on only called ‘‘partner’’.
Definition of interaction_with_partner_t
type,extends(interaction_t),abstract::interaction_with_partner_tprivate
class(interaction_partner_t),public,pointer::partnerinteger,public::n_partner_quantities!< Number of quantities needed from the partner
integer,allocatable,public::partner_quantities(:)!< Identifiers of the quantities needed from the partner
contains
procedure::update=>interaction_with_partner_updateend type interaction_with_partner_t
This type adds a pointer to the interaction partner and a list of IDs of the quantities, the partner exposes to the interaction.
Furthermore, at this level, we can implement the update() procedure.
force_interaction_t
The next level of specialization of interaction, are all interactions which create a force on the partner. Here we only add the actual force vector, acting on the partner system.
Definition of force_interaction_t
type,extends(interaction_with_partner_t),abstract::force_interaction_tinteger::dim=0!< spatial dimensions
integer::system_np=0!< number of particles in the system that the forces are acting on
FLOAT,allocatable,public::force(:,:)end type force_interaction_t
Specific classes:
Specific interaction classes extend the abstract ones. The most important element they add to the abstract classes is the information about the quantities, required to calculate the interaction. In case of the system. owning the interaction (system A), it is sufficient to keep pointers to the data, stored in the system itself. Thr reason is that the interaction is always updated by the propagator of the system A. For the partner system (system B), however, the interaction keeps a copy of the exposed quantities. This allows the partner system to continue the propagation beyond the time for which the quantities are requested, which might happen if the two systems are using different time steps.
Ghost interaction
Definition of ghost_interaction_t
type,extends(interaction_with_partner_t)::ghost_interaction_tcontains
procedure::calculate=>ghost_interaction_calculatefinal::ghost_interaction_finalizeend type ghost_interaction_t
Gravity
Definition of gravity_t
type,extends(force_interaction_t)::gravity_tprivate
FLOAT,pointer::system_mass(:)!< pointer to array storing the masses of the particles
FLOAT,pointer::system_pos(:,:)!< pointer to array storing the positions of the particles
integer,public::partner_np=0!< number of particles in the partner system
FLOAT,allocatable,public::partner_mass(:)!< array storing a copy of the masses of the partner particles
FLOAT,allocatable,public::partner_pos(:,:)!< array storing a copy of the positions of the partner particles
contains
procedure::init=>gravity_initprocedure::calculate=>gravity_calculatefinal::gravity_finalizeend type gravity_t
Coulomb force
Definition of coulomb_force_t
type,extends(force_interaction_t)::coulomb_force_tprivate
FLOAT,pointer::system_charge(:)!< pointer to array storing the charges of the particles
FLOAT,pointer::system_pos(:,:)!< pointer to array storing the positions of the particles
integer,public::partner_np=0!< number of particles in the partner system
FLOAT,allocatable,public::partner_charge(:)!< array storing a copy of the masses of the partner particles
FLOAT,allocatable,public::partner_pos(:,:)!< array storing a copy of the positions of the partner particles
contains
procedure::init=>coulomb_force_initprocedure::calculate=>coulomb_force_calculatefinal::coulomb_force_finalizeend type coulomb_force_t
Lorentz force
Definition of lorentz_force_t
type,extends(force_interaction_t)::lorentz_force_tprivate
FLOAT,pointer::system_charge(:)!< pointer to array storing the charges of the particles
FLOAT,pointer,public::system_pos(:,:)!< pointer to array storing the positions of the particles
FLOAT,pointer::system_vel(:,:)!< pointer to array storing the velocities of the particles
FLOAT,allocatable,public::partner_E_field(:,:)!< E field generated by partner at the positions of the system particles
FLOAT,allocatable,public::partner_B_field(:,:)!< B field generated by partner at the positions of the system particles
contains
procedure::init=>lorentz_force_initprocedure::calculate=>lorentz_force_calculatefinal::lorentz_force_finalizeend type lorentz_force_t
Interaction factory
Instances of interaction_t or derived types are, like systems, generated using a factory.
Definition of interactions_factory_abst_t
type,abstract::interactions_factory_abst_tcontains
procedure::create_interactions=>interactions_factory_abst_create_interactionsprocedure(interactions_factory_abst_create),deferred::createprocedure(interactions_factory_abst_default_mode),deferred::default_modeprocedure(interactions_factory_abst_block_name),deferred::block_nameend type interactions_factory_abst_t
Definition of interactions_factory_t
type,extends(interactions_factory_abst_t)::interactions_factory_tcontains
procedure::create=>interactions_factory_createprocedure::default_mode=>interactions_factory_default_modeprocedure::block_name=>interactions_factory_block_nameend type interactions_factory_t
The interactions_factory_create() function calls the constructor of the requested type and returns a pointer to the created instance.
Definition of interactions_factory_create()
function interactions_factory_create(this,type,partner)result(interaction)class(interactions_factory_t),intent(in)::thisinteger,intent(in)::type
class(interaction_partner_t),target,intent(inout)::partnerclass(interaction_t),pointer::interactionPUSH_SUB(interactions_factory_create)!%Variable Interactions
!%Type block
!%Section System
!%Description
!% This input option controls the interactions between systems. It basically
!% allows to select which systems will interact with another system through
!% a given interaction type. The format of the block is the following:
!%
!% <br>%<tt>Namespace.Interactions
!% <br> interaction_type | interaction_mode | ...
!% <br>%</tt>
!%
!% Here is an example to better understand how this works:
!%
!% <br>%<tt>SystemA.Interactions
!% <br> gravity | all_except | "SystemB"
!% <br>%</tt>
!%
!% This means that SystemA and all the systems that belong to the same
!% namespace (i.e., all its subsystems) will interact through gravity with
!% all interaction partners that are also able to interact through gravity,
!% except with SystemB. Note that the opposite is not true so, although
!% clearly unphysical, this will not prevent SystemB from feeling the
!% gravity from SystemA (in <tt>Octopus</tt> the interactions are always
!% one-sided).
!%
!% NB: Each interaction type should only appear once in the block. Any
!% further instances beyond the first will be ignored.
!%
!% Available modes and interaction types:
!%Option no_partners -1
!% (interaction mode)
!% Do not interact with any partner.
!%Option all_partners -2
!% (interaction mode)
!% Interact with all available partners.
!%Option only_partners -3
!% (interaction mode)
!% Interact only with some specified partners. A list of partner names must
!% be given.
!%Option all_except -4
!% (interaction mode)
!% Interact with all available partners except with some specified
!% partners. A list of partner names to exclude must be given.
!%Option gravity 1
!% (interaction type)
!% Gravity interaction between two masses.
!%Option lorenz_force 2
!% (interaction type)
!% Lorenz force resulting from an EM field acting on a moving charge.
!%Option coulomb_force 3
!% (interaction type)
!% Coulomb force between two charged particles.
!%Option linear_medium_em_field 3
!% (interaction type)
!% Linear medium for propagation of EM fields.
!%End
select case(type)case(GRAVITY)interaction=>gravity_t(partner)case(COULOMB_FORCE)interaction=>coulomb_force_t(partner)case(LORENTZ_FORCE)interaction=>lorentz_force_t(partner)case(LINEAR_MEDIUM_EM_FIELD)interaction=>linear_medium_em_field_t(partner)case default! This should never happen, as this is handled in
! interactions_factory_abst_create_interactions
end select
POP_SUB(interactions_factory_create)end function interactions_factory_create
Currently, the following interaction types are defined: