Thank you for your quick response. Since I construct my structure in such a way that the left electrode atoms are always at the beginning of the central region and the right electrode atoms are always at the end of the central region (I think most people would do it this way), I wrote a wrapper function for OptimizeGeometry(), which takes a DeviceConfiguration as an argument. The function is shown below. This should work, shouldn't it?
def OptimizeDeviceGeometry(device, maximum_forces = 0.01*eV/Ang,
constraints = [], trajectory_filename = None):
# Obtain components of device
central_region = device.centralRegion()
electrodes = device.electrodes()
nleft = len(electrodes[0].elements())
nright = len(electrodes[1].elements())
ncenter = len(central_region.elements())
electrode_constraints = range(nleft) + range(ncenter)[-nright:]
constraints += electrode_constraints
# Construct an LCAO calculator based on a DeivceLCAO calculator
device_calculator = device.calculator()
central_region_caculator = LCAOCalculator(
basis_set = device_calculator.basisSet(),
numerical_accuracy_parameters = device_calculator.numericalAccuracyParameters(),
iteration_control_parameters = device_calculator.iterationControlParameters(),
poisson_solver = device_calculator.poissonSolver()
)
central_region.setCalculator(central_region_caculator)
# Perform optimization
print "Performing optimization..."
opt = OptimizeGeometry(
configuration = central_region,
maximum_forces = maximum_forces,
constraints = constraints,
trajectory_filename = trajectory_filename
)
print "Optimization completed"
# Re-construct a device
device_opt = DeviceConfiguration(
opt, [electrodes[0], electrodes[1]]
)
device_opt.setCalculator(device_calculator)
return device_opt