Hello,
I’m tring to use the bond/create command in order to “glue” some ionic species on a solide surface (cf input script and data file).
I’ve got the following problem: even if there is only two ionic species in the system (which means that I can’t logically have more than two bonds), an infinity of bonds is created (and the simulation shuts down). (According to the documentation of the fix bond/create “if a bond does not already exist between I and J (…), then I,J is labeled as a “possible” bond pair” so it shouldn’t happen).
Where do the problem comes from?
Best regards,
Simon Gravelle
in.lammps (1018 Bytes)
data.lammps (46.3 KB)
From the fix bond/create doc page:
IMPORTANT NOTE: To create a new bond, the internal LAMMPS data structures that store this information must have space for it. When LAMMPS is initialized from a data file, the list of bonds is scanned and the maximum number of bonds per atom is tallied. If some atom will acquire more bonds than this limit as this fix operates, then the “extra bonds per atom” parameter in the data file header must be set to allow for it. See the read_data command for more details. Note that if this parameter needs to be set, it means a data file must be used to initialize the system, even if it initially has no bonds. A data file with no atoms can be used if you wish to add unbonded atoms via the create atoms command, e.g. for a percolation simulation.
Steve
steve,
this looks like a real bug, though.
in fact, i see two issues with the current code:
in read_data the extra bond per atom information is only processed,
when you have a Bonds section, so something like this one-liner is
needed.
diff --git a/src/read_data.cpp b/src/read_data.cpp
index 14b933e..cf35f81 100644
--- a/src/read_data.cpp
+++ b/src/read_data.cpp
@@ -225,6 +225,9 @@ void ReadData::command(int narg, char **arg)
atom->allocate_type_arrays();
atom->avec->grow(n);
1 Like
simon,
please find attached a patch that upgrades today's git/svn version of
LAMMPS to correct for the bugs related to adding bonds with fix
bond/create.
axel.
lammps-bond-create-fixup.diff.gz (964 Bytes)
Axel’s change is to make a check that a 2nd duplicate bond is
not formed between atoms I,J. However, I don’t
see why that is necessary. Fix bond/create requires
that the special_bond setting for 1-2 interactions
be 0.0, which should mean that as soon as the first
bond between I,J is created, the I-J interaction now
gets excluded from the neighbor list. Thus forever
after there should be no chance of another bond forming,
since I no longer knows J is its neighbor.
If this was a problem, I don’t know why we (or others)
wouldn’t have seen it before. What am I missing?
You mentioned ions. Are you running with a long-range
solver? If so, the neighbor list is adjusted to include
1-2 interactions which I see should then be checked
to see if the weight is actually 0.0. (The long-range
pair style treat those pairs differently.) If that’s
the issue you’re probably the first person to use
this fix with long-range Coulombics.
Steve
Axel's change is to make a check that a 2nd duplicate bond is
not formed between atoms I,J. However, I don't
see why that is necessary. Fix bond/create requires
that the special_bond setting for 1-2 interactions
be 0.0, which should mean that as soon as the first
bond between I,J is created, the I-J interaction now
gets excluded from the neighbor list. Thus forever
after there should be no chance of another bond forming,
since I no longer knows J is its neighbor.
If this was a problem, I don't know why we (or others)
wouldn't have seen it before. What am I missing?
they *do* show up.
You mentioned ions. Are you running with a long-range
solver? If so, the neighbor list is adjusted to include
that is indeed the case.
1-2 interactions which I see should then be checked
to see if the weight is actually 0.0. (The long-range
pair style treat those pairs differently.) If that's
the issue you're probably the first person to use
this fix with long-range Coulombics.
why not keep the test i am proposing and then be compatible with 1-2
scaling != 0.0, too?
axel.
why not keep the test i am proposing and then be compatible with 1-2
scaling != 0.0, too?
yes, that’s a good idea. Will be in next patch
thanks,
Steve
Dear Axel and Steve,
First, I would like to thank you for your reactivity.
Also, despite last modifications, there is still a problem: The simulation stop when the first bond is created. I've got the message:
ERROR on proc 0: New bond exceeded bonds per atom in fix bond/create (../fix_bond_create.cpp:427)
Could you fix that?
Simon Gravelle
Ph.D. student
Institut Lumière Matière, Lyon
webpage: http://simongravelle.fr/
Dear Axel and Steve,
First, I would like to thank you for your reactivity.
Also, despite last modifications, there is still a problem: The simulation stop when the first bond is created. I've got the message:
ERROR on proc 0: New bond exceeded bonds per atom in fix bond/create (../fix_bond_create.cpp:427)
Could you fix that?
i had it fixed (at least partially) in my patch to read_data and then
steve improved on it. unfortunately, the improvement is never
reached, since your data file has no topology information at all and
thus the line "if (!topoflag) break;" short circuits the processing.
the attached patch takes steve's generalization and puts it back into
a segment that is (always) called and before it may be potentially
overridden with additional per topology element info.
axel.
lammps-extra-data-init.diff.gz (534 Bytes)
Hello,
I confirm that bond/create and bond/break are working perfectly with long-range solver.
Thank you very much!
Simon
Dear Axel and Steve,
I would like to inform you that I still get weird behavior when I run a simulation with both long range interaction and fix bond create. I'm not quite sure, but I think it depends on the geometry I'm using (no problem with flat wall, error with cylindrical tube). In some cases, it also seems to depend on the number of processors I'm using (works with one processor but fail with more than one processor).
You may want to try the attached input. In principle, it will fail quickly (the number of bond it's gonna increase) if you run it on more than one processor.
Could you please have a look on that problem?
Thank you very much,
Simon Gravelle
Ph.D. Student
Institut Lumiere Matiere, Lyon, France
webpage: http://simongravelle.fr/
data.lammps (603 KB)
in.bond_create (1.46 KB)
Dear Axel and Steve,
I would like to inform you that I still get weird behavior when I run a simulation with both long range interaction and fix bond create. I'm not quite sure, but I think it depends on the geometry I'm using (no problem with flat wall, error with cylindrical tube). In some cases, it also seems to depend on the number of processors I'm using (works with one processor but fail with more than one processor).
You may want to try the attached input. In principle, it will fail quickly (the number of bond it's gonna increase) if you run it on more than one processor.
what is "quickly"?
Could you please have a look on that problem?
it stops after >49900 steps with the message:
Sorry Axel, my message was not clear enough.
which indicates, that you'd need to adjust your settings in the data file. if you think this is in error, you need to provide more specifics why
you think so.
In my system there are free ions and there are 60 traps located on surfaces. Each trap can "bond" with one ion at a time. It means that the total number of bond can not be higher than 60. After a number of steps which approximately is between 10 000 and 1 000 000, I've got the message:
[raptor02:63916] *** Process received signal ***
[raptor02:63916] Signal: Segmentation fault (11)
[raptor02:63916] Signal code: Address not mapped (1)
[raptor02:63916] Failing at address: 0x18
[raptor02:63916] [ 0] /lib/x86_64-linux-gnu/libpthread.so.0(+0xf030) [0x7f2cd4667030]
[raptor02:63916] [ 1] /lib/x86_64-linux-gnu/libc.so.6(+0x78550) [0x7f2cd4340550]
[raptor02:63916] [ 2] /lib/x86_64-linux-gnu/libc.so.6(cfree+0x6c) [0x7f2cd4343aac]
[raptor02:63916] [ 3] ./lmp_mpi(_ZN9LAMMPS_NS4Comm9grow_recvEi+0x2d) [0x57978d]
[raptor02:63916] [ 4] ./lmp_mpi(_ZN9LAMMPS_NS4Comm8exchangeEv+0x47a) [0x57929a]
[raptor02:63916] [ 5] ./lmp_mpi(_ZN9LAMMPS_NS6Verlet3runEi+0xed) [0xc303dd]
[raptor02:63916] [ 6] ./lmp_mpi(_ZN9LAMMPS_NS3Run7commandEiPPc+0x295) [0xbff3b5]
[raptor02:63916] [ 7] ./lmp_mpi(_ZN9LAMMPS_NS5Input15command_creatorINS_3RunEEEvPNS_6LAMMPSEiPPc+0x2e) [0x7ea04e]
[raptor02:63916] [ 8] ./lmp_mpi(_ZN9LAMMPS_NS5Input15execute_commandEv+0x714) [0x7e7f44]
[raptor02:63916] [ 9] ./lmp_mpi(_ZN9LAMMPS_NS5Input4fileEv+0x50c) [0x7e9cec]
[raptor02:63916] [10] ./lmp_mpi(main+0x46) [0x4d5806]
[raptor02:63916] [11] /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xfd) [0x7f2cd42e6ead]
[raptor02:63916] [12] ./lmp_mpi() [0x4d7bb1]
[raptor02:63916] *** End of error message ***
Sorry Axel, my message was not clear enough.
which indicates, that you'd need to adjust your settings in the data file. if you think this is in error, you need to provide more specifics why
you think so.
In my system there are free ions and there are 60 traps located on surfaces. Each trap can "bond" with one ion at a time. It means that the total number of bond can not be higher than 60. After a number of steps which approximately is between 10 000 and 1 000 000, I've got the message:
this is strange. there should not be a segfault, but a clean exit.
which version of LAMMPS do you use?
[raptor02:63916] *** Process received signal ***
[raptor02:63916] Signal: Segmentation fault (11)
[raptor02:63916] Signal code: Address not mapped (1)
[raptor02:63916] Failing at address: 0x18
[...]
this "failing at address 0x18" hints at some pointer variable being
overwritten with data.
and the number of bond just increased irrationally (until it reached the fixed limit). I could be wrong but I think the data file is OK, the number of extra bond per atom is already really high. The same simulation works fine if you run it on one processor, so may be there is a problem with the communication between processors?
so i added an option to write the number of bonds per atom to the dump
file for each atom and found that there is only one specific atom that
gets all the additional bonds assigned. this hints that there is some
typo somewhere in the fix bond/create code. will have a closer look.
axel.
hi again,
i think i have spotted the problem. can you please make some tests in
parallel using
newton on off
instead of the default "newton on on" setting? that should work around
the issue until the code is properly corrected. this would also
explain why it works with one processor.
axel.
Hello again,
i think i have spotted the problem. can you please make some tests in
parallel using
newton on off
instead of the default "newton on on" setting? that should work around
the issue until the code is properly corrected. this would also
explain why it works with one processor.
You're right, it does work! (I tried it with several numbers of processors, with or without the patch you gave me in the very same conversation, it works in any case.)
Thank you very much Axel!
Simon
Hello again,
i think i have spotted the problem. can you please make some tests in
parallel using
newton on off
instead of the default "newton on on" setting? that should work around
the issue until the code is properly corrected. this would also
explain why it works with one processor.
You're right, it does work! (I tried it with several numbers of processors, with or without the patch you gave me in the very same conversation, it works in any case.)
excellent!
and here is the proper fix for the issue. basically, you have to
replace tag[i] and tag[j] with i and j. so it is consistent with how
LAMMPS distributes bonds across processors. that was a tricky one.
diff --git a/src/MC/fix_bond_create.cpp b/src/MC/fix_bond_create.cpp
index 1fa49e2..7f9a4e7 100644
--- a/src/MC/fix_bond_create.cpp
+++ b/src/MC/fix_bond_create.cpp
@@ -421,8 +421,9 @@ void FixBondCreate::post_integrate()
// if newton_bond is set, only store with I or J
// if not newton_bond, store bond with both I and J
+ // NOTE: I and J are local indices *not* tags. same as in neigh_bond.cpp
- if (!newton_bond || tag[i] < tag[j]) {
+ if (!newton_bond || (i < j)) {
if (num_bond[i] == atom->bond_per_atom)
error->one(FLERR,"New bond exceeded bonds per atom in fix bond/create")
bond_type[i][num_bond[i]] = btype;
sorry, I’m not seeing why that change is correct.
The purpose of that chunk of code is to insure the bond gets
created only once when newton_bond is set. It needs to work
whether J is an owned atom or a ghost atom.
With the change you made, it will be formed twice if J is
a ghost atom, since I < J will be the case on both processors.
But tag[i] < tag[j] will only be the case on one of the processors,
as desired.
What am I missing?
Steve
sorry, I'm not seeing why that change is correct.
The purpose of that chunk of code is to insure the bond gets
created only once when newton_bond is set. It needs to work
whether J is an owned atom or a ghost atom.
With the change you made, it will be formed twice if J is
a ghost atom, since I < J will be the case on both processors.
hmmm... but that would depend on newton_pair being set to off, would it not?
with newton_pair set to on, there would be only one pair straddling two domains.
But tag[i] < tag[j] will only be the case on one of the processors,
as desired.
What am I missing?
the fact, that in neigh_bond.cpp the bond will be migrated to a
different processor, so that in the next time step it will be created
again (and again, and again), since the processor holding the I-J pair
that would potentially form the bond, doesn't hold the bond itself.
due to the requirement that with newton_bond on bonds are stored only
where the first atom of a bond is local.
axel.