Carbons

In the next section, a brief description of the available methods to generate carbon models is provided. Following the previous work developed on CarbGen (you can check the Python version on the project's GitHub page), ProtoSyn implements methods to generate functionalized microcrystallites of multi-layered carbon sheets.

ProtoSyn Carbons

Figure 1 | Example showcase of ProtoSyn's carbon microcrystallite generation methods. 1 | Single carbon sheet. 2 | Multi-layered carbon microcrystallite. 3 | Micro-porosity generation. 4 | Functionalization. ProtoSyn includes several common functional groups, by default, on the ProtoSyn.modification_grammar. The shown example includes ether groups, carboxyls, carbonyls, hydroxyls, amine-N groups, graphitic-N, oxidized-N groups and pyridines.

ProtoSyn.Materials.generate_carbon_layerFunction
generate_carbon_layer(x::Int, y::Int; [r::T = 1.4]) where {T <: AbstractFloat}

The carbon layer is generated using internal coordinates: all atoms are always placed at a distance r and angle of 120° from the parent atom, either with a clockwise or counter-clockwise rotation in the dihedral angle. For each ring added, 4 parameters need to be defined:

  • The number of atoms to add (N);
  • The selected atom to continue X expansion (X);
  • The selected atom to continue Y expansion (Y);
  • The bonds to add (B).

Such parameters are first compiled in 4 matrixes (1 for each) which are then consumed to generate the actual atom positions and bonds. This algorithm is, therefore, sensitive to the order of addition of layers (whether to add Y axis or X axis first, changes the N, X, Y and B matrixes, as well as rotation of dihedral angles). For this particular implementation, the X axis is added first, and all expansion is then added from this layer in the Y axis. As atoms are added, the next anchor atoms (as selected by the X and Y matrixes) are added to the A matrix. Each new ring checks this matrix for the next anchor/parent atom. All dihedral angles on the first atom of each new ring added are rotated by 180° (default is 0°), except on the first layer where the second atom added is also rotated by 180°. 6 possible bonding patterns are available:

  1. Bond 4th atom to start atom
  2. Bond 4th atom to 3rd atom of previous ring
  3. Bond 1st atom to 3rd atom of previous ring
  4. Bond 4th atom to parent of start atom
  5. Perform both 3 and 4 patterns simultaneously
  6. Bond 2nd atom to 1st atom of previous ring

Besides this "extra" bonds, all added atoms are bonded to the respective parent atom. Note that it's guaranteed that the main plane of the generated layer lies in the x-y plane (z cartesian coordinate = 0.0).

See also

generate_carbon

Examples

julia> pose = ProtoSyn.Materials.generate_carbon_layer(5, 5)
Pose{Topology}(Topology{/CRV:65069}, State{Float64}:
 Size: 70
 i2c: false | c2i: false
 Energy: Dict(:Total => Inf)
)
source
ProtoSyn.Materials.generate_carbonFunction
generate_carbon(x::Int, y::Int, [z::Int = 0]; [r::T = 1.4], [d::T = 3.4]) where {T <: AbstractFloat}

Generate a carbon microcrystallite with multiple carbon sheet layers (built using generate_carbon_layer with x and y dimensions for the number of carbon rings in the x- and y-axis, respectivelly, and r distance between atoms, in Å). The generated layers are copied z times (in the x-axis) with a distance of d Å. Every odd layer is displaced to match π-π stacking chemistry in carbon sheets.

See also

generate_porosity generate_carbon_from_file

Examples

julia> pose = ProtoSyn.Materials.generate_carbon(5, 5, 5)
Pose{Topology}(Topology{/CRV:23442}, State{Float64}:
 Size: 350
 i2c: false | c2i: false
 Energy: Dict(:Total => Inf)
)
source
ProtoSyn.Materials.generate_porosityFunction
generate_porosity(pose::Pose, pore_fraction::T; [clean_sweeps::Int = 15], [random::Bool = false], [neat_indexation::Bool = false]) where {T <: AbstractFloat}

Generate porosity on the given Pose pose by removing Atom instances according to a generated Perlin noise (see the perlin method). The pore_fraction field ajusts the amount of Atom instances removed, as a value between 0.0 and 1.0.

Note:

The pose_fraction field cannot be roughly translated as a direct percentage value of Atom instances to remove. Instead, this value refers to the perlin noise level to consider for atom removal, and as such scales exponentially. As a baseline, a pore_fraction of 0.4 removes approximately 50% of the Atom instances in the given Pose.

For high pore_fraction values, the Atom removal may leave unconnected chains of Atom instances in each Segment. Such cases should be manually verified. Since this function is intended to be applied to carbon microcrystallites, these hanging atoms may constitute carbon atoms with wrong valency numbers. This method automatically performs clean_sweeps and removes any atom with 1 or 0 bonds. If random is set to true (false, by default), the generated noise is randomized. If neat_indexation is set to true (false, by default), the sort_atoms_by_graph! method is applied to reindex Atom instances and sort them according to the new graph (after removing Atom instances).

See also

generate_carbon

Examples

julia> ProtoSyn.Materials.generate_porosity(pose, 0.405)
Pose{Topology}(Topology{/CRV:36031}, State{Float64}:
 Size: 190
 i2c: false | c2i: false
 Energy: Dict(:Total => Inf)
)
source
ProtoSyn.Materials.perlinoctavesFunction
perlinoctaves(x::T, y::T, z::T, octaves::Int = 1, persistence::T = 1.0)

Compute the perlin noise value at coordinates x, y and z with the given octaves. In sum, generates a perlin noise with some randomization. Taken from https://github.com/ararslan/ProceduralNoise.jl. All credit goes to ararslan. Based on https://gist.github.com/Flafla2/f0260a861be0ebdeef76. Hash lookup table as defined by Ken Perlin.

Examples

julia> ProtoSyn.Materials.perlinoctaves(0.5, 0.5, 0.5, 8)
0.484375
source
ProtoSyn.Materials.functionalize!Function
functionalize!(pose::Pose, functional_groups::Dict{Fragment, T}; normalize_frequencies::Bool = false) where {T <: AbstractFloat}

Add N functional groups to the given Pose pose. The number of added functional groups is given by the functional groups dictionary, mapping Fragment instances (for example, from the default ProtoSyn.modification_grammar) to a percentage of achoring points available. By default, anchoring points are non-charged carbon Atom instances. If the normalize_frequencies flag is set to true (false, by default), ProtoSyn normalizes the input functional_groups dictionary so that all possible non-charged carbon Atom instances are functionalized (in proportional percentages to the input dictionary). Note that this method expects correctly ordered Segment instances (1 is bottom, :end is top).

Note:

The reason only non-charged carbon Atom instances are considered for functionalization is because ProtoSyn automatically assigns a charge when adding a functional group. Therefore, only non-charged Atom instances are left "open" for functionalization.


functionalize!(pose::Pose, functional_groups::Dict{Fragment, Int})

In an alternative syntax, the functional_groups fictionary directly maps Fragment instances to the actual number of desired functional groups to add.

See also

add_functionalization!

Examples

julia> ProtoSyn.Materials.functionalize!(pose, Dict(ProtoSyn.modification_grammar.variables["XYL"] => 10))

julia> pose
Pose{Topology}(Topology{/CRV:42474}, State{Float64}:
 Size: 380
 i2c: false | c2i: false
 Energy: Dict(:Total => Inf)
)
source
ProtoSyn.Materials.add_functionalization!Function
add_functionalization!(pose::Pose, fcn::Fragment, atom::Atom)

Add a single functional group fcn (a Fragment instance) to the given Atom instance atom in the Pose pose. The Atom instance atom is replaced (using the replace_by_fragment! method).

See also

functionalize!

Examples

julia> ProtoSyn.Materials.add_functionalization!(pose, ProtoSyn.modification_grammar.variables["XYL"], pose.graph[1, 1, 16])

julia> pose
Pose{Topology}(Topology{/CRV:14425}, State{Float64}:
 Size: 353
 i2c: false | c2i: false
 Energy: Dict(:Total => Inf)
)
source
ProtoSyn.Materials.generate_carbon_from_fileFunction
generate_carbon_from_file(filename::String, output::Opt{String} = nothing)

Generate a functionalized carbon model from a .yml input file (named filename). If output is set to a String (nothing, by default), outputs the generated carbon model to a file. For an input file example, check the resources/Materials/carbon.yml file.

See also

functionalize!

Examples

julia> pose = ProtoSyn.Materials.generate_carbon_from_file("carbon.yml")
Pose{Topology}(Topology{/CRV:40141}, State{Float64}:
 Size: 960
 i2c: false | c2i: false
 Energy: Dict(:Total => Inf)
)
source