-
-
Notifications
You must be signed in to change notification settings - Fork 61
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
Function to build heteroribbons #421
Conversation
Also if you prefer other names for the functions I don't mind, Thomas used |
11a5374
to
de20144
Compare
Codecov Report
@@ Coverage Diff @@
## main #421 +/- ##
==========================================
- Coverage 87.34% 87.34% -0.01%
==========================================
Files 373 374 +1
Lines 47705 47959 +254
==========================================
+ Hits 41669 41889 +220
- Misses 6036 6070 +34
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great job! Minor changes here and there. @tfrederiksen the name of the function, what do you think?
Great work @pfebrer ! Overall it looks great to me. However, I am not fully convinced about the use of imaginary numbers to specify "open" structures. I think it follows naturally that each consequtive "column" in the structure needs to be of alternating type. Hence, for a given input of widths and repetitions are only two possible structures that can be created. This could be one flag to the function, say |
I think it is good (and relatively short) as it is. In the literature I see mostly the formulation "graphene nanoribbon heterojunctions" for these structures. Other possibilities could therefore be the pair Could the method eventually be extended to 2D nanomeshes? |
I like Hmm.. On the other hand explicitness is good... hmmm. Since |
But then the graphene version of it would be |
But that is the same as the other arguments in the Section tuple, no?
Agreed... Hmm.... |
Yes, it's just that the more parameters you add, the worse it gets :) Specially if parameters are not easily ordered by importance. E.g. we can all agree that length will be very used so it makes sense that it is the first optional argument. |
Also, for the name: It is not really a |
True... Perhaps you should add the possibility of accepting sections = [Heteroribbon_section(*section) for section in sections]
# to
def conv(s):
if isinstance(s):
return Heteroribbon_section(**s)
return Heteroribbon_section(*s)
sections = [conv(section) for section in sections] |
Well in that case you might as well build the section object yourself instead of passing a dict :) |
In any case I think it might be useful for some. |
However would you then introduce the |
The imaginary number seems natural to me. |
I don't know about this, @tfrederiksen what do you say? |
Another option could be using negative numbers ( |
I think I didn't express my idea correctly. It is not to apply an invert operation after creating the structure, but to let the user select the "phase" of the first column (open/closed). I fully agree that this choice will create different structures. But the consecutive columns must respect phase alternation, no?. Indeed the meaning of shift would have to be redefined (no longer just multiples of the lattice vector in My point is just that from the user perspective it may be simpler if one does not have to keep track of the phase, but just specify opening type and then widths/reps/shifts. Edit: Additionally, in my opinion it is not very clear from the user perspective if a given "column" should be denoted "closed" (real) or "open" (imaginary). It seems ambiguous to me. |
Oooh ok I understand now, so graphene_nanoribbon([(7, 2), (11, 2)], open_start=True) # or invert=True would be the old graphene_nanoribbon([(7, 2j), (11, 2)]) ? I like it :) But then the second case still remains. |
Exactly!
What do you mean by second case? The meaning of shift would then have to refer to half the lattice vector in |
For odd columns I think it's very well defined. Why not? You have to consider if you are looking at it from the left or the right, but that seems fine to me. I mean I do not call the column "open" or close, the same column can be an open or closed border. For even columns it is arbitrary I agree, but once you establish which is which it isn't ambiguous either. |
My point is just that understanding all of this would not be required by the user. One could just choose one of two possible "openings" and then build anything from there. |
Hmm ok, then you'd have to, for example always align at the bottom and then shift. I get your point. But I don't think that makes it more intuitive necessarily. That might make it harder to build valid ribbons because you have to know the allowed shift values. The main point of building this function for me was that I didn't have to think about which shifts are valid and which are not. I like the idea of just going by:
If the user needs to specify exactly where to place the ribbon (your proposal) I believe they have to think even more about phases, since otherwise they won't generate valid ribbons. |
All integer shifts should be valid (in units of half the lattice vector). But clearly the function needs to pick the only meaningful phase for that column not to mess up the bonding pattern. |
No, they are not, because some shifts leave dangling bonds at the edges of the ribbon |
@pfebrer we had a meeting and you were doing some explorations, but now I can't recall those explorations? What is the status here? |
We thought about having some way to merge geometries in a smart way by adding two classes: full_geom = Section() + Junction() + Section() + ... Then we thought that we shouldn't limit it to full_geom = MetalSurface("Au", "111") + DefectAction() + Junction(adapt_to_lattice=0) + MetalSurface("Cu", "111") for example would create an Au surface, then create a defect on it, and then join it with a Cu surface that would use the same lattice as gold. This was a nice idea but I couldn't find a way to make it general and at the same time not much more difficult to use than the current approach for graphene nanoribbons which is just based on passing a list of tuples. Now this is stalled, and for now I did not have plans to work on it 😅 |
The advantage of this approach was that there would be a general API for creating composite structures, instead of each method implementing one. |
Great, thanks for the reminder. Ok, so what about I run it through again, and then we just merge this? Then we can always think about the next thing. After having read your recap of our conversation, perhaps the most ideal thing would be to fix |
What do you mean by "run it through"?
Yes but that would require the |
I'll check this PR again.
True, hmm... |
I am thinking this could be helpful. So I think we should merge it. :) |
Any comments @tfrederiksen @pfebrer |
|
||
|
||
def test_graphene_heteroribbon(): | ||
a = graphene_heteroribbon([(7, 2), (9, 2)]) |
Check notice
Code scanning / CodeQL
Unused local variable
aligned_match = last_bot_edge_open == this_bot_edge_open | ||
|
||
# Shift the incoming section if the vertical shift makes them not match. | ||
if aligned_match == (shift % 2 == 1): |
Check failure
Code scanning / CodeQL
Potentially uninitialized local variable
The only pitfall I see is that this introduces some kind of "framework" for composite structures, which might be a pain in the future if you want to go in another direction. But if you think it's fine, then OK 👍 |
Agreed, but if you think this functionality is valuable, I think we should merge it. Then we can always move things to a deprecated folder and introduce the new method over time.... I think it has a long time perspective to get a better overall working scheme. |
Ok, is it properly documented (can't explore it now I'm on the metro)? If it is then for me it is ok to merge it. Otherwise I can try to document it this afternoon or tomorrow. |
I'll have a go and ask for another go by you. I think the section classes could be hosted in the function as a property def heteroribbon(...):
heteroribbon.section = _heteroribbon_section or similar. |
@@ -1,10 +1,14 @@ | |||
# This Source Code Form is subject to the terms of the Mozilla Public | |||
# License, v. 2.0. If a copy of the MPL was not distributed with this | |||
# file, You can obtain one at https://mozilla.org/MPL/2.0/. | |||
import itertools | |||
import math as m |
Check notice
Code scanning / CodeQL
Unused import
|
||
@abstractmethod | ||
def build_section(self, geometry): | ||
... |
Check notice
Code scanning / CodeQL
Statement has no effect
|
||
@abstractmethod | ||
def add_section(self, geometry, geometry_addition): | ||
... |
Check notice
Code scanning / CodeQL
Statement has no effect
Signed-off-by: Nick Papior <[email protected]>
Signed-off-by: Nick Papior <[email protected]>
Signed-off-by: Nick Papior <[email protected]>
Now they are exposed Signed-off-by: Nick Papior <[email protected]>
Signed-off-by: Nick Papior <[email protected]>
@pfebrer feel free to have a look now :) |
Yeah I think it's fine! Thank you for the polishing :) |
Closes #420
I still need confirmation from @tfrederiksen that there's nothing super wrong with the way it can be used :)
Is the code structure/arguments fine?