Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nanoribbon geometry #201

Merged
merged 13 commits into from
Apr 4, 2020
Merged

Nanoribbon geometry #201

merged 13 commits into from
Apr 4, 2020

Conversation

tfrederiksen
Copy link
Contributor

Easy construction of nanoribbon geometries

  • armchair and zigzag type
  • w/wo edge saturation

@codecov
Copy link

codecov bot commented Apr 2, 2020

Codecov Report

Merging #201 into master will increase coverage by 0.01%.
The diff coverage is 90.24%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #201      +/-   ##
==========================================
+ Coverage   85.22%   85.23%   +0.01%     
==========================================
  Files         120      121       +1     
  Lines       19305    19346      +41     
==========================================
+ Hits        16453    16490      +37     
- Misses       2852     2856       +4     
Impacted Files Coverage Δ
sisl/geom/nanoribbon.py 90.00% <90.00%> (ø)
sisl/geom/__init__.py 100.00% <100.00%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update fd7c041...958e0d9. Read the comment docs.

Copy link
Owner

@zerothi zerothi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, great addition! A few suggestions, and a very general one?

What do you think?

@pfebrer
Copy link
Contributor

pfebrer commented Apr 2, 2020

Hey! Nice work :)

I need lots of different ribbons for a project that I am doing and I built something similar. There are two things that I "discovered" and I think they could be useful for this pull request, if you don't mind me suggesting them:

  • The saturation part would be very nice as a standalone function. If there is only one missing bond, the calculation of the direction of the missing bond works exactly the same for all the coordinations that I can think of (linear, trigonal, tetrahedral, quadroplanar, octahedral...), it's always the sum of all bonds and then change the sign. Adding Nick suggestions about possibility to saturate with any atom it would be pretty general. I guess you would only need an extra argument min_neighbours, and below that number, you would saturate. The only thing that I don't know how to build easily is when more than one bond is missing, but I believe it's worth giving it a thought to provide the saturating functionality for any geometry that it's fairly normal, because doing it manually is a pain :)

  • This second one is less important, but I'm studying specifically ribbons that don't have a constant width and it is impossible to find a way of programming them (there are endless possibilities on how to join them). Therefore I wrote an interactive ribbon builder that displays your current ribbon (with Geometry.plot()) and asks for input to add a section with a different width, tile the current section, move it up and down or offset its unit cell by one half (you can build any ribbon basically). Do you think it's meaningful to make it available here also making use of Thomas nanoribbon builder or is it a specific thing that I use but nobody will need?

Cheers!

@pfebrer
Copy link
Contributor

pfebrer commented Apr 2, 2020

Forget the second part, sorry, but having saturation as a function would be great!

@zerothi
Copy link
Owner

zerothi commented Apr 2, 2020

  • The saturation part would be very nice as a standalone function. If there is only one missing bond, the calculation of the direction of the missing bond works exactly the same for all the coordinations that I can think of (linear, trigonal, tetrahedral, quadroplanar, octahedral...), it's always the sum of all bonds and then change the sign. Adding Nick suggestions about possibility to saturate with any atom it would be pretty general. I guess you would only need an extra argument min_neighbours, and below that number, you would saturate. The only thing that I don't know how to build easily is when more than one bond is missing, but I believe it's worth giving it a thought to provide the saturating functionality for any geometry that it's fairly normal, because doing it manually is a pain :)

I don't get this? ;)
Do you mean if you saturate with more than 1 atom at the edges, or?

  • This second one is less important, but I'm studying specifically ribbons that don't have a constant width and it is impossible to find a way of programming them (there are endless possibilities on how to join them). Therefore I wrote an interactive ribbon builder that displays your current ribbon (with Geometry.plot()) and asks for input to add a section with a different width, tile the current section, move it up and down or offset its unit cell by one half (you can build any ribbon basically). Do you think it's meaningful to make it available here also making use of Thomas nanoribbon builder or is it a specific thing that I use but nobody will need?

Hmm, actually with my suggestion wouldn't attaching different ribbons be unique with 3 different integers: width, length and offset

E.g. something like this:

def shift(r, offset=0):
    # shift to center
    xyz = np.average(r.xyz, axis=0)
    xyz[0] = 0.
    return r.move(-xyz)

ribbon = shift(nanoribbon(6))
for w, l, o in [(10, 2, 0), (6, 2, 0), (10, 2, 1), (6, 1, 1)]:
    ribbon = ribbon.append(shift(nanoribbon(w), o).tile(l, 0), 0)

Yes, there are some problems with the above for offsets and widths that don't play well. But one must be able to figure out how the commensurate stuff would work ;)

Cheers!

Thanks for chipping in Pol!

Copy link
Contributor Author

@tfrederiksen tfrederiksen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the encouraging comments. I would like to focus next on the best placement of the saturation code.

@pfebrer
Copy link
Contributor

pfebrer commented Apr 2, 2020

I don't get this? ;)
Do you mean if you saturate with more than 1 atom at the edges, or?

Not at the edges of a ribbon, of course, because that be weird :) The easiest example I can think of (maybe with little relevance in the objective of sisl) is a terminal carbon of an organic molecule, it can need either 1, 2 or 3 saturating Hs. Is it possible that some surfaces might also have more than one dangling bond per atom? Idk. But if not, this means less problems then!

The saturate function could accept a function to decide if an atom needs to be saturated, apart from min_neighbors. Maybe it is useful for someone. I'm thinking of, for example :

saturate(geom, min_neighbours = 3, sat_atom=O, should_saturate=lambda at: random())

to randomly oxidize a surface.

Hmm, actually with my suggestion wouldn't attaching different ribbons be unique with 3 different integers: width, length and offset

Thomas answered for me :)

There are really many ways to put individual GNRs together. The basic units created here could be aligned according to their center axis, along their edges, and many other ways. I tend to think these more complicated structures belong to some separate method, or? Maybe some higher-level growth method?

Of course one can determine the exact parameters that it needs to build a ribbon. But at some point, it stops making sense and doing it interactively can be faster. In fact, what I did is tracking the commands issued by the user to build some kind of "fingerprint". You can also provide the fingerprint instead of triggering the interactive mode, so after your first build, you may be able to automatically generate ribbons from that fingerprint (tiling a region a bit more, shifting up or down, etc...)

This is an example of a ribbon that, sure, you can program its structure, but it's just painful (note that there are single chains of a given width at some point):
Screenshot from 2020-04-02 23-28-22

Copy link
Owner

@zerothi zerothi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great! Thanks for the PR

@zerothi zerothi merged commit 958e0d9 into zerothi:master Apr 4, 2020
@tfrederiksen
Copy link
Contributor Author

Maybe we could think of another function composite_nanoribbon to create more advanced structures (joining basic blocks), as you proposed?

@tfrederiksen tfrederiksen deleted the nanoribbon branch April 6, 2020 15:06
@pfebrer
Copy link
Contributor

pfebrer commented Apr 29, 2020

Hey, sorry for commenting now. I'm using now the nanoribbon function and it seemed wierd to me that bond and atom were positional arguments. Is it a wild guess to use 1.42 and "C" as defaults?

I had to do

sisl.geom.nanoribbon(1.42, "C", 9)

when I expected that this would work:

sisl.geom.nanoribbon(9)

Actually, I wasn't sure if I needed to pass the kind of ribbon I wanted, but I assumed that the bond and atom would have defaults.

Is it just me? :)

@pfebrer
Copy link
Contributor

pfebrer commented Apr 29, 2020

Nevermind, I just noticed that I should have used sisl.geom.graphene_nanorribon, sorry haha

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants