generate_cdse.m 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. #!/usr/bin/env octave
  2. % Copyright (C) 2019 Kei Kebreau
  3. %
  4. % This program is free software: you can redistribute it and/or modify
  5. % it under the terms of the GNU General Public License as published by
  6. % the Free Software Foundation, either version 3 of the License, or
  7. % (at your option) any later version.
  8. %
  9. % This program is distributed in the hope that it will be useful,
  10. % but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. % GNU General Public License for more details.
  13. %
  14. % You should have received a copy of the GNU General Public License
  15. % along with this program. If not, see <http://www.gnu.org/licenses/>.
  16. % Return a matrix representation of a tetrahedral CdSe cluster with a given
  17. % number of layers of cadmium, and optionally save the cluster as an XYZ file
  18. % specified by the given file name.
  19. function cdse_cluster = generate_cdse (layer_count, file_name)
  20. try
  21. pkg load geometry;
  22. catch
  23. error('Could not load Octave Forge package "geometry"');
  24. end
  25. % The number of Cd atoms in a cluster of 'n' layers is the cumulative sum of
  26. % the first 'n' triangular number for all 'n' > 0 while the number of Se atoms
  27. % in a cluster of 'n' layers is the cumulative sum of the first 'n-1'
  28. % triangular numbers for all 'n' > 1.
  29. if layer_count < 2
  30. error('A tetrahedral CdSe cluster requires at least 2 layers.');
  31. end
  32. se_count = sum(arrayfun(@triangular_number, 1:layer_count-1));
  33. cd_count = se_count + triangular_number(layer_count);
  34. % Create a tetrahedral grid.
  35. [vertices, edges, faces] = createTetrahedron;
  36. cd_scaling_factor = 3.0385 * (layer_count - 1);
  37. se_scaling_factor = 3.0385 * (layer_count - 2);
  38. cd_cluster = tetrahedron_grid(layer_count - 1, vertices', cd_count)';
  39. se_cluster = tetrahedron_grid(layer_count - 2, vertices', se_count)';
  40. cd_cluster = cd_cluster * cd_scaling_factor;
  41. se_cluster = se_cluster * se_scaling_factor + [1.5193 1.5193 1.5193];
  42. cdse_cluster = [cd_cluster; se_cluster];
  43. % Optional file output.
  44. if nargin < 2
  45. return;
  46. end
  47. xyz_id = fopen(file_name, 'w');
  48. fdisp(xyz_id, sprintf('%d\n', cd_count + se_count));
  49. for ii = 1:size(cd_cluster)(1)
  50. fdisp(xyz_id, sprintf('Cd %f %f %f', cd_cluster(ii,:)));
  51. end
  52. for ii = 1:size(se_cluster)(1)
  53. fdisp(xyz_id, sprintf('Se %f %f %f', se_cluster(ii,:)));
  54. end
  55. fclose(xyz_id);
  56. end
  57. % Return the nth triangular number.
  58. function result = triangular_number (n)
  59. result = n * (n + 1) / 2;
  60. end