I am performing fitting with a model which contains from the start many atoms. My superstructure is composed of 1080 atoms, but it has also high cubic symmetry (Pa-3), so it can be reduced. If I add xyz coordinates as fitting parameters using standar "for par in sgpar.xyzpars:" my fitting works flawlessly.
However, now I am developing a set of constrains defining polyhedra in the unit cell comprising bond length and bond angle conditions. For this, I would like to skip symmetry and add all the atoms in the unit cell. I am following a method written under this message. Let's assume that right now I treat coordinates as free variable without any other additional constrains.
This code adds variables to the recipe correctly, regardless if I use addVar (default) or newVar (just playing). I can see them with fit.getNames(). But when I run fitting, the xyz variables seem to be stuck on single values. When eventually the leastsq optimiser gives up, the values are unchanged, and the errors are crazy high at 1e12. All other variable like scale, or d2 are changing. I am using unified values of Uiso for each element, so these are reduced in my case to only 3, and they also are adjusted.
Is it a problem with having too many parameters? If I follow the sgpar.xyzpars route but for P1 symmetry, this seems to do something, although I have those extra coordinates. Or am I missing something in the code?
added_params = set()
for atom in getattr(cpdf, phase).phase.getScatterers():
try:
atom_label =
atom.name atom_symbol= atom.element
tags = ['xyz', 'xyz_' + atom_label, 'xyz_' + atom_symbol, 'xyz_' + atom_symbol + '_' + str(phase),'xyz_'+str(phase), str(phase)]
# Add X coordinate
x_var_name = f'x_{atom_label}_{phase}'
if x_var_name not in added_params:
#fit.newVar(name = x_var_name, value = atom.x.value, fixed = False, tags = tags)
# fit.constrain(atom.x, x_var_name)
fit.addVar(atom.x, value = atom.x.value, name=x_var_name,fixed = False, tags=tags)
fit.restrain(x_var_name, lb = atom.x.value *(1-pos_restrain), ub =atom.x.value*(1+pos_restrain), sig = 0.0005)
added_params.add(x_var_name)
print(f"{x_var_name} : atom position added to variables.")
# Add Y coordinate
y_var_name = f'y_{atom_label}_{phase}'
if y_var_name not in added_params:
# fit.newVar(name = y_var_name, value = atom.y.value, fixed = False, tags = tags)
# fit.constrain(atom.y, y_var_name)
fit.addVar(atom.y, value = atom.y.value, name=y_var_name, fixed = False, tags=tags)
added_params.add(y_var_name)
#fit.restrain(y_var_name, lb = atom.y.value *(1-pos_restrain), ub =atom.y.value*(1+pos_restrain), sig = 0.0005)
print(f"{y_var_name} : atom position added to variables.")
# Add Z coordinate
z_var_name = f'z_{atom_label}_{phase}'
if z_var_name not in added_params:
# fit.newVar(name = z_var_name, value = atom.z.value, fixed = False, tags = tags)
# fit.constrain(atom.z, z_var_name)
fit.addVar(atom.z, value = atom.z.value, name=z_var_name, fixed = False, tags=tags)
added_params.add(z_var_name)
#fit.restrain(z_var_name, lb = atom.z.value *(1-pos_restrain), ub =atom.z.value*(1+pos_restrain), sig = 0.0005)
print(f"{z_var_name} : atom position added to variables.")
except:
pass
# =============================================================================