QuantumATK Forum
QuantumATK => General Questions and Answers => Topic started by: pippin on March 1, 2010, 03:34
-
It is not documented in the 2010.2 Reference Manual but the OptimizeGeometry() function only takes an object of MolecularConfiguration or BulkConfiguration. If I want to optimize a DeviceConfiguration object, what is the recommended way?
My guess is that I can get a BulkConfiguration using the central_region() method of the DeviceConfiguration class and use that BulkConfiguration in OptimizeGeometry(). But in that case, I'd have to 'constraint' all atoms corresponding to the electrode atoms manually. Otherwise, the optimization will probably move them and create mismatch when I bring the optimized BulkConfiguration back to DeviceConfiguration. Is there a better way to handle this?
Thanks!
-
You are absolutely correct, right now this is how you have to do it, manually. The functionality will be improved, (robably allowing, somehow, to pass the DeviceConfiguration directly to the optimizer, in which case the contraints you mentioned will be imposed automatically, or something like that. This is work in progress right now!
-
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
-
Looks very good (at a quick glance)! Try it! :)