00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <math.h>
00023 #include <stdlib.h>
00024 #include <stdio.h>
00025
00026 #include "DrawMolItem.h"
00027 #include "DrawMolecule.h"
00028 #include "BaseMolecule.h"
00029 #include "Inform.h"
00030 #include "Isosurface.h"
00031 #include "MoleculeList.h"
00032 #include "Scene.h"
00033 #include "Orbital.h"
00034 #include "QMData.h"
00035 #include "VolumetricData.h"
00036 #include "VMDApp.h"
00037 #include "utilities.h"
00038 #include "WKFUtils.h"
00039
00040 #define MYSGN(a) (((a) > 0) ? 1 : -1)
00041
00042 void DrawMolItem::draw_orbital(int density, int wavefnctype, int wavefncspin,
00043 int wavefncexcitation, int orbid,
00044 float isovalue,
00045 int drawbox, int style,
00046 float gridspacing, int stepsize, int thickness) {
00047 if (!mol->numframes() || gridspacing <= 0.0f)
00048 return;
00049
00050
00051 int regenorbital=1;
00052 int useorbgridfromrep = -1;
00053
00054 if (density != orbgridisdensity ||
00055 wavefnctype != waveftype ||
00056 wavefncspin != wavefspin ||
00057 wavefncexcitation != wavefexcitation ||
00058 orbid != gridorbid ||
00059 gridspacing != orbgridspacing ||
00060 orbvol == NULL ||
00061 needRegenerate & MOL_REGEN ||
00062 needRegenerate & SEL_REGEN) {
00063
00064 #if defined(VMDENABLEORBITALGRIDBACKDOOR)
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076 int repcnt = mol->repList.num();
00077 int r;
00078 for (r=0; r<repcnt && useorbgridfromrep < 0; r++) {
00079 DrawMolItem *dmi = mol->repList[r];
00080 if (dmi->repNumber != repNumber) {
00081 AtomRep *ar = dmi->atomRep;
00082 if (ar->method() == AtomRep::ORBITAL) {
00083 if (orbid == dmi->gridorbid &&
00084 wavefnctype == dmi->waveftype &&
00085 wavefncspin == dmi->wavefspin &&
00086 wavefncexcitation == dmi->wavefexcitation &&
00087 gridspacing == dmi->orbgridspacing &&
00088 density == dmi->orbgridisdensity &&
00089 dmi->orbvol != NULL) {
00090
00091 useorbgridfromrep=r;
00092 delete orbvol;
00093 orbvol = dmi->orbvol;
00094 }
00095 }
00096 }
00097 }
00098
00099 if (useorbgridfromrep >= 0)
00100 regenorbital=0;
00101 else
00102 #endif
00103 regenorbital=1;
00104 }
00105
00106 double motime=0, voltime=0, gradtime=0;
00107 wkf_timerhandle timer = wkf_timer_create();
00108 wkf_timer_start(timer);
00109
00110 if (regenorbital) {
00111
00112
00113 int frame = mol->frame();
00114 const Timestep *ts = mol->get_frame(frame);
00115
00116 if (!ts->qm_timestep || !mol->qm_data ||
00117 !mol->qm_data->num_basis || orbid < 1) {
00118 wkf_timer_destroy(timer);
00119 return;
00120 }
00121
00122
00123
00124
00125 int waveid = mol->qm_data->find_wavef_id_from_gui_specs(
00126 wavefnctype, wavefncspin, wavefncexcitation);
00127
00128
00129
00130 int iwave = ts->qm_timestep->get_wavef_index(waveid);
00131
00132 if (iwave<0 ||
00133 !ts->qm_timestep->get_wavecoeffs(iwave) ||
00134 !ts->qm_timestep->get_num_orbitals(iwave) ||
00135 orbid > ts->qm_timestep->get_num_orbitals(iwave)) {
00136 wkf_timer_destroy(timer);
00137 return;
00138 }
00139
00140
00141 int orbindex = ts->qm_timestep->get_orbital_index_from_id(iwave, orbid);
00142
00143
00144 Orbital *orbital = mol->qm_data->create_orbital(iwave, orbindex,
00145 ts->pos, ts->qm_timestep);
00146
00147
00148 orbital->set_grid_to_bbox(ts->pos, 3.0, gridspacing);
00149
00150
00151 #if 0
00152
00153
00154
00155
00156
00157 orbital->find_optimal_grid(0.01, 2, 8);
00158 #endif
00159
00160
00161 orbital->calculate_mo(mol, density);
00162
00163 motime = wkf_timer_timenow(timer);
00164
00165
00166 const int *numvoxels = orbital->get_numvoxels();
00167 const float *origin = orbital->get_origin();
00168
00169 float xaxis[3], yaxis[3], zaxis[3];
00170 orbital->get_grid_axes(xaxis, yaxis, zaxis);
00171
00172
00173 char dataname[64];
00174 sprintf(dataname, "molecular orbital %i", orbid);
00175
00176
00177 orbgridisdensity = density;
00178 waveftype = wavefnctype;
00179 wavefspin = wavefncspin;
00180 wavefexcitation = wavefncexcitation;
00181 gridorbid = orbid;
00182 orbgridspacing = gridspacing;
00183 delete orbvol;
00184 orbvol = new VolumetricData(dataname, origin,
00185 xaxis, yaxis, zaxis,
00186 numvoxels[0], numvoxels[1], numvoxels[2],
00187 orbital->get_grid_data());
00188 delete orbital;
00189
00190 voltime = wkf_timer_timenow(timer);
00191
00192 orbvol->compute_volume_gradient();
00193
00194 gradtime = wkf_timer_timenow(timer);
00195 }
00196
00197
00198
00199 sprintf(commentBuffer, "Mol[%d] Rep[%d] Orbital", mol->id(), repNumber);
00200 cmdCommentX.putdata(commentBuffer, cmdList);
00201
00202 if (drawbox > 0) {
00203
00204 if (atomColor->method() == AtomColor::VOLUME) {
00205 append(DVOLTEXOFF);
00206 }
00207
00208 if (style > 0 || drawbox == 2) {
00209 draw_volume_box_lines(orbvol);
00210 } else {
00211 draw_volume_box_solid(orbvol);
00212 }
00213 if (atomColor->method() == AtomColor::VOLUME) {
00214 append(DVOLTEXON);
00215 }
00216 }
00217
00218 if ((drawbox == 2) || (drawbox == 0)) {
00219 switch (style) {
00220 case 3:
00221
00222 draw_volume_isosurface_lit_points(orbvol, isovalue, stepsize, thickness);
00223 break;
00224
00225 case 2:
00226
00227 draw_volume_isosurface_points(orbvol, isovalue, stepsize, thickness);
00228 break;
00229
00230 case 1:
00231
00232 draw_volume_isosurface_lines(orbvol, isovalue, stepsize, thickness);
00233 break;
00234
00235 case 0:
00236 default:
00237
00238 draw_volume_isosurface_trimesh(orbvol, isovalue, stepsize);
00239 break;
00240 }
00241 }
00242
00243
00244
00245 if (useorbgridfromrep >= 0) {
00246 orbvol = NULL;
00247 }
00248
00249 if (regenorbital) {
00250 double surftime = wkf_timer_timenow(timer);
00251 if (surftime > 5) {
00252 char strmsg[1024];
00253 sprintf(strmsg, "Total MO rep time: %.3f [MO: %.3f vol: %.3f grad: %.3f surf: %.2f]",
00254 surftime, motime, voltime - motime, gradtime - motime, surftime - gradtime);
00255
00256 msgInfo << strmsg << sendmsg;
00257 }
00258 }
00259
00260 wkf_timer_destroy(timer);
00261 }
00262