Octopus uses the so-called factory pattern to create instances of the systems and interaction classes.
The abstract factory classes are introduced to avoid the problem of circular dependencies.
The function of the factories is to create an object of a (dynamically) given type and return a pointer to it. This is done by calling the respective
constructors of the classes, of which an instance is to be created.
recursivefunctionsystem_factory_create(this,namespace,type)result(system)class(system_factory_t),intent(in)::this!< the system factory
type(namespace_t),intent(in)::namespace!< namespace of the system
integer,intent(in)::type!< type of the system to create
class(system_t),pointer::system!< pointer to newly created system
integer::n_systems,is,ic,iothertype(block_t)::blkcharacter(len=128),allocatable::names(:)integer,allocatable::types(:)PUSH_SUB(system_factory_create)!%Variable Systems
!%Type block
!%Section System
!%Description
!% List of systems that will be treated in the calculation.
!% The first column should be a string containing the system name.
!% The second column should be the system type. See below for a list of
!% available system types.
!%Option electronic 1
!% An electronic system. (not fully implemented yet)
!%Option maxwell 2
!% A maxwell system.
!%Option classical_particle 3
!% A classical particle. Used for testing purposes only.
!%Option charged_particle 4
!% A charged classical particle.
!%Option dftbplus 5
!% A DFTB+ system
!%Option linear_medium 6
!% A linear medium for classical electrodynamics.
!%Option matter 7
!% A matter system containing electrons and classical ions.
!%Option dispersive_medium 8
!% (Experimental) A dispersive medium for classical electrodynamics.
!%Option multisystem 9
!% A system containing other systems.
!%Option ions 10
!% An ensemble of classical charged particles.
!%End
selectcase(type)case(SYSTEM_MULTISYSTEM)! Parse the input file to get the list of subsystems
if(parse_block(namespace,'Systems',blk)==0)thenn_systems=parse_block_n(blk)SAFE_ALLOCATE(names(1:n_systems))SAFE_ALLOCATE(types(1:n_systems))dois=1,n_systems! Parse system name and type
callparse_block_string(blk,is-1,0,names(is))if(len_trim(names(is))==0)thencallmessages_input_error(namespace,'Systems','All systems must have a name')endifdoic=1,len(parser_varname_excluded_characters)if(index(trim(names(is)),parser_varname_excluded_characters(ic:ic))/=0)thencallmessages_input_error(namespace,'Systems',&'Illegal character "'//parser_varname_excluded_characters(ic:ic)//'" in system name',row=is-1,column=0)endifenddocallparse_block_integer(blk,is-1,1,types(is))! Check that the system name is unique
doiother=1,is-1if(names(is)==names(iother))thencallmessages_input_error(namespace,'Systems','Duplicated system in multi-system',&row=is-1,column=0)endifenddoenddocallparse_block_end(blk)elsecallmessages_input_error(namespace,'Systems','Missing Systems block')endifsystem=>multisystem_basic_t(namespace,names,types,this)SAFE_DEALLOCATE_A(names)SAFE_DEALLOCATE_A(types)case(SYSTEM_ELECTRONIC)system=>electrons_t(namespace)case(SYSTEM_MAXWELL)system=>maxwell_t(namespace)case(SYSTEM_CLASSICAL_PARTICLE)system=>classical_particle_t(namespace)case(SYSTEM_CHARGED_PARTICLE)system=>charged_particle_t(namespace)case(SYSTEM_DFTBPLUS)system=>dftb_t(namespace)case(SYSTEM_LINEAR_MEDIUM)system=>linear_medium_t(namespace)case(SYSTEM_MATTER)system=>matter_t(namespace)case(SYSTEM_DISPERSIVE_MEDIUM)system=>dispersive_medium_t(namespace)callmessages_experimental('dispersive_medium',namespace=namespace)case(SYSTEM_IONS)system=>ions_t(namespace)casedefaultcallmessages_input_error(namespace,'Systems','Unknown system type.')endselectPOP_SUB(system_factory_create)endfunctionsystem_factory_create
Definition of interactions_factory_abst_create_interactions()
Definition of interactions_factory_create()
functioninteractions_factory_create(this,type,partner)result(interaction)class(interactions_factory_t),intent(in)::thisinteger,intent(in)::typeclass(interaction_partner_t),target,intent(inout)::partnerclass(interaction_t),pointer::interactionPUSH_SUB(interactions_factory_create)selectcase(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_TO_EM_FIELD)interaction=>linear_medium_to_em_field_t(partner)case(CURRENT_TO_MXLL_FIELD)interaction=>current_to_mxll_field_t(partner)case(MXLL_E_FIELD_TO_MATTER)interaction=>mxll_e_field_to_matter_t(partner)case(MXLL_B_FIELD_TO_MATTER)interaction=>mxll_b_field_to_matter_t(partner)case(MXLL_VEC_POT_TO_MATTER)interaction=>mxll_vec_pot_to_matter_t(partner)case(LENNARD_JONES)interaction=>lennard_jones_t(partner)casedefaultmessage(1)="Unknown interaction in interactions_factory_create"callmessages_fatal(1)endselectPOP_SUB(interactions_factory_create)endfunctioninteractions_factory_create