1 /* $RCSfile$
2  * $Author: hansonr $
3  * $Date: 2006-10-22 14:12:46 -0500 (Sun, 22 Oct 2006) $
4  * $Revision: 5999 $
5  *
6  * Copyright (C) 2003-2005  Miguel, Jmol Development, www.jmol.org
7  *
8  * Contact: jmol-developers@lists.sf.net
9  *
10  *  This library is free software; you can redistribute it and/or
11  *  modify it under the terms of the GNU Lesser General Public
12  *  License as published by the Free Software Foundation; either
13  *  version 2.1 of the License, or (at your option) any later version.
14  *
15  *  This library is distributed in the hope that it will be useful,
16  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
17  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
18  *  Lesser General Public License for more details.
19  *
20  *  You should have received a copy of the GNU Lesser General Public
21  *  License along with this library; if not, write to the Free Software
22  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
23  */
24 
25 package org.jmol.adapter.readers.xml;
26 
27 
28 
29 import org.jmol.adapter.smarter.Atom;
30 import org.jmol.util.Logger;
31 import javajs.util.PT;
32 
33 import javajs.util.SB;
34 import javajs.util.V3;
35 
36 /**
37  *
38  * Vasp vasprun.xml reader
39  *
40  * @author hansonr
41  *
42  */
43 
44 public class XmlVaspReader extends XmlReader {
45 
46   private SB data;
47   private String name;
48   private int ac;
49   private int iAtom;
50   private boolean isE_wo_entrp = false;
51   private boolean isE_fr_energy = false;
52   private String enthalpy = null;
53   private String gibbsEnergy = null;
54 //  private String[] myAttributes = { "name" };
55 
XmlVaspReader()56   public XmlVaspReader() {
57   }
58 
59 //  @Override
60 //  protected String[] getDOMAttributes() {
61 //    return myAttributes;
62 //  }
63 
64   @Override
processXml(XmlReader parent, Object saxReader)65   protected void processXml(XmlReader parent,
66                             Object saxReader) throws Exception {
67     parent.doProcessLines = true;
68     processXml2(parent, saxReader);
69   }
70 
71   @Override
processStartElement(String localName, String nodeName)72   public void processStartElement(String localName, String nodeName) {
73     if (debugging)
74       Logger.debug("xmlvasp: start " + localName);
75 
76     if (!parent.continuing)
77       return;
78 
79     if ("calculation".equals(localName)) {
80       enthalpy = null;
81       gibbsEnergy = null;
82       return;
83     }
84 
85     if ("i".equals(localName)) {
86       String s = atts.get("name");
87       if (s.charAt(0) != 'e')
88         return;
89       isE_wo_entrp = s.equals("e_wo_entrp");
90       isE_fr_energy = s.equals("e_fr_energy");
91       setKeepChars(isE_wo_entrp || isE_fr_energy);
92       return;
93     }
94 
95     if ("structure".equals(localName)) {
96       if (!parent.doGetModel(++parent.modelNumber, null)) {
97         parent.checkLastModel();
98         return;
99       }
100       parent.setFractionalCoordinates(true);
101       asc.doFixPeriodic = true;
102       asc.newAtomSet();
103       if (enthalpy != null) {
104         asc.setCurrentModelInfo("enthalpy", Double.valueOf(enthalpy));
105       }
106       if (gibbsEnergy != null) {
107         asc.setAtomSetEnergy("" + gibbsEnergy, parseFloatStr(gibbsEnergy));
108         asc.setCurrentModelInfo("gibbsEnergy", Double.valueOf(gibbsEnergy));
109       }
110       if (enthalpy != null && gibbsEnergy != null)
111         asc.setAtomSetName("Enthalpy = " + enthalpy + " eV Gibbs Energy = " + gibbsEnergy + " eV");
112       return;
113     }
114     if (!parent.doProcessLines)
115       return;
116 
117     if ("v".equals(localName)) {
118       setKeepChars(data != null);
119       return;
120     }
121 
122     if ("c".equals(localName)) {
123       setKeepChars(iAtom < ac);
124       return;
125     }
126 
127     if ("varray".equals(localName)) {
128       name = atts.get("name");
129       if (name != null && PT.isOneOf(name, ";basis;positions;forces;"))
130         data = new SB();
131       return;
132     }
133 
134     if ("atoms".equals(localName)) {
135       setKeepChars(true);
136       return;
137     }
138 
139   }
140 
141   boolean haveUnitCell = false;
142   String[] atomNames;
143   String[] atomSyms;
144   String atomName;
145   String atomSym;
146   float a;
147   float b;
148   float c;
149   float alpha;
150   float beta;
151   float gamma;
152 
153   @Override
154   void processEndElement(String localName) {
155 
156     if (debugging)
157       Logger.debug("xmlvasp: end " + localName);
158 
159     while (true) {
160 
161       if (!parent.doProcessLines)
162         break;
163 
164       if (isE_wo_entrp) {
165         isE_wo_entrp = false;
166         enthalpy = chars.toString().trim();
167         break;
168       }
169 
170       if (isE_fr_energy) {
171         isE_fr_energy = false;
172         gibbsEnergy = chars.toString().trim();
173         break;
174       }
175 
176       if ("v".equals(localName) && data != null) {
177         data.append(chars.toString());
178         break;
179       }
180 
181       if ("c".equals(localName)) {
182         if (iAtom < ac) {
183           if (atomName == null) {
184             atomName = atomSym = chars.toString().trim();
185           } else {
186             atomNames[iAtom++] = atomName + chars.toString().trim();
187             atomName = null;
188           }
189         }
190         break;
191       }
192 
193       if ("atoms".equals(localName)) {
194         ac = parseIntStr(chars.toString());
195         atomNames = new String[ac];
196         atomSyms = new String[ac];
197         iAtom = 0;
198         break;
199       }
200 
201       if ("varray".equals(localName) && data != null) {
202         if (name == null) {
203         } else if ("basis".equals(name) && !haveUnitCell) {
204           haveUnitCell = true;
205           float[] ijk = getTokensFloat(data.toString(), null, 9);
206           V3 va = V3.new3(ijk[0], ijk[1], ijk[2]);
207           V3 vb = V3.new3(ijk[3], ijk[4], ijk[5]);
208           V3 vc = V3.new3(ijk[6], ijk[7], ijk[8]);
209           a = va.length();
210           b = vb.length();
211           c = vc.length();
212           va.normalize();
213           vb.normalize();
214           vc.normalize();
215           alpha = (float) (Math.acos(vb.dot(vc)) * 180 / Math.PI);
216           beta = (float) (Math.acos(va.dot(vc)) * 180 / Math.PI);
217           gamma = (float) (Math.acos(va.dot(vb)) * 180 / Math.PI);
218         } else if ("positions".equals(name)) {
219           parent.setUnitCell(a, b, c, alpha, beta, gamma);
220           float[] fdata = new float[ac * 3];
221           getTokensFloat(data.toString(), fdata, ac * 3);
222           int fpt = 0;
223           for (int i = 0; i < ac; i++) {
224             Atom atom = asc.addNewAtom();
225             parent.setAtomCoordXYZ(atom, fdata[fpt++], fdata[fpt++], fdata[fpt++]);
226             atom.elementSymbol = atomSyms[i];
227             atom.atomName = atomNames[i];
228           }
229         } else if ("forces".equals(name)) {
230           float[] fdata = new float[ac * 3];
231           getTokensFloat(data.toString(), fdata, ac * 3);
232           int fpt = 0;
233           int i0 = asc.getLastAtomSetAtomIndex();
234 
235           //TODO question here as to whether these need transformation
236 
237           for (int i = 0; i < ac; i++)
238             asc.addVibrationVector(i0 + i, fdata[fpt++],
239                 fdata[fpt++], fdata[fpt++]);
240         }
241         data = null;
242         break;
243       }
244       if ("structure".equals(localName)) {
245         try {
246           parent.applySymmetryAndSetTrajectory();
247         } catch (Exception e) {
248           // TODO
249         }
250         break;
251       }
252 
253       return;
254     }
255     setKeepChars(false);
256   }
257 
258 }
259