3
\brief Enter brief description of file here
7
#include "prototypes.h"
11
int* fock_to_pitzer(int, int*);
14
namespace psi { namespace oeprop {
21
double xmin, ymin, zmin, xmax, ymax, zmax; /* molecular dimensions */
23
errcod = ip_data("GRID","%d",&grid,0);
25
punt("GRID type must be positive");
27
if (grid == 5 || grid == 6)
30
/* which MOs to plot? */
35
if (ip_exist("MO_TO_PLOT",0)) {
36
errcod = ip_count("MO_TO_PLOT",&num_mos_to_plot,0);
37
if (errcod == IPE_NOT_AN_ARRAY)
38
punt("MO_TO_PLOT must be an array. See the manual.");
40
errcod = ip_string("MO_TO_PLOT",&tmpstring,1,0);
41
/* If signed integers are used - Fock ordering is used, convert indices back to Pitzer ... */
42
if (tmpstring[0] == '+' || tmpstring[0] == '-') {
43
fock_mos = init_int_array(num_mos_to_plot);
44
for(mo=0;mo<num_mos_to_plot;mo++) {
45
errcod = ip_data("MO_TO_PLOT","%d",&fock_mos[mo],1,mo);
47
punt("Problem reading elements of MO_TO_PLOT. See the manual.");
49
mos_to_plot = fock_to_pitzer(num_mos_to_plot,fock_mos);
52
/* ... else indices are already Pitzer indices */
54
mos_to_plot = init_int_array(num_mos_to_plot);
55
for(mo=0;mo<num_mos_to_plot;mo++) {
56
errcod = ip_data("MO_TO_PLOT","%d",&mos_to_plot[mo],1,mo);
57
if (mos_to_plot[mo] <= 0 || mos_to_plot[mo] > nmo)
58
punt("One of the elements of MO_TO_PLOT out of range");
61
punt("Problem reading elements of MO_TO_PLOT. See the manual.");
66
/* If MO_TO_PLOT is not specified just use HOMO and LUMO */
69
fock_mos = init_int_array(num_mos_to_plot);
72
mos_to_plot = fock_to_pitzer(num_mos_to_plot,fock_mos);
77
/*--------------------------------------------------------------------
78
If GRID_ORIGIN is present read in user's specification for the grid
79
else create a default grid using molecular dimensions
80
--------------------------------------------------------------------*/
81
if (ip_exist("GRID_ORIGIN",0)) {
83
ip_count("GRID_ORIGIN",&i,0);
85
punt("GRID_ORIGIN must have 3 components");
87
errcod = ip_data("GRID_ORIGIN","%lf",&grid_origin[i],1,i);
89
punt("Error in the definition of GRID_ORIGIN");
92
if (ip_exist("GRID_UNIT_X",0)) {
93
ip_count("GRID_UNIT_X",&i,0);
95
punt("GRID_UNIT_X must have 3 components");
97
errcod = ip_data("GRID_UNIT_X","%lf",&grid_unit_x[i],1,i);
99
punt("Problem in parsing GRID_UNIT_X");
103
punt("GRID_UNIT_X must be defined when GRID_ORIGIN is given");
105
if (ip_exist("GRID_UNIT_Y",0)) {
106
ip_count("GRID_UNIT_Y",&i,0);
108
punt("GRID_UNIT_Y must have 3 components");
110
errcod = ip_data("GRID_UNIT_Y","%lf",&grid_unit_y[i],1,i);
111
if (errcod != IPE_OK)
112
punt("Problem in parsing GRID_UNIT_Y");
116
punt("GRID_UNIT_Y must be defined when GRID_ORIGIN is given");
119
if (ip_exist("GRID_XY0",0)) {
120
ip_count("GRID_XY0",&i,0);
122
punt("GRID_XY0 must have 2 components");
124
errcod = ip_data("GRID_XY0","%lf",&grid_xy0[i],1,i);
125
if (errcod != IPE_OK)
126
punt("Error in the definition of GRID_XY0");
130
punt("GRID_XY0 is not defined");
132
if (ip_exist("GRID_XY1",0)) {
133
ip_count("GRID_XY1",&i,0);
135
punt("GRID_XY1 must have 2 components");
137
errcod = ip_data("GRID_XY1","%lf",&grid_xy1[i],1,i);
138
if (errcod != IPE_OK)
139
punt("Error in the definition of GRID_XY1");
140
else if (grid_xy1[i] <= grid_xy0[i])
141
punt("GRID_XY1 must point to the upper right corner of the grid");
145
punt("GRID_XY1 is not defined");
148
if (ip_exist("GRID_XYZ0",0)) {
149
ip_count("GRID_XYZ0",&i,0);
151
punt("GRID_XYZ0 must have 3 components");
153
errcod = ip_data("GRID_XYZ0","%lf",&grid_xyz0[i],1,i);
154
if (errcod != IPE_OK)
155
punt("Error in the definition of GRID_XYZ0");
159
punt("GRID_XYZ0 is not defined");
161
if (ip_exist("GRID_XYZ1",0)) {
162
ip_count("GRID_XYZ1",&i,0);
164
punt("GRID_XYZ1 must have 3 components");
166
errcod = ip_data("GRID_XYZ1","%lf",&grid_xyz1[i],1,i);
167
if (errcod != IPE_OK)
168
punt("Error in the definition of GRID_XYZ1");
169
else if (grid_xyz1[i] <= grid_xyz0[i])
170
punt("GRID_XYZ1 must point to the upper right corner of the grid parallelepiped");
174
punt("GRID_XYZ1 is not defined");
178
/* GRID_ORIGIN not specified -- use molecular dimensions in 3D case */
181
xmax = ymax = zmax = 0.0;
182
xmin = ymin = zmin = 0.0;
184
for(atom=0; atom<natom; atom++) {
185
if (geom[atom][0] > xmax)
186
xmax = geom[atom][0];
187
if (geom[atom][0] < xmin)
188
xmin = geom[atom][0];
189
if (geom[atom][1] > ymax)
190
ymax = geom[atom][1];
191
if (geom[atom][1] < ymin)
192
ymin = geom[atom][1];
193
if (geom[atom][2] > zmax)
194
zmax = geom[atom][2];
195
if (geom[atom][2] < zmin)
196
zmin = geom[atom][2];
199
grid_origin[0] = 0.0;
200
grid_origin[1] = 0.0;
201
grid_origin[2] = 0.0;
203
grid_unit_x[0] = 1.0;
204
grid_unit_x[1] = 0.0;
205
grid_unit_x[2] = 0.0;
206
grid_unit_y[0] = 0.0;
207
grid_unit_y[1] = 1.0;
208
grid_unit_y[2] = 0.0;
210
grid_xyz0[0] = xmin - 2.0;
211
grid_xyz0[1] = ymin - 2.0;
212
grid_xyz0[2] = zmin - 2.0;
213
grid_xyz1[0] = xmax + 2.0;
214
grid_xyz1[1] = ymax + 2.0;
215
grid_xyz1[2] = zmax + 2.0;
217
/* It's a 2D grid and no GRID_ORIGIN is given -- fail */
219
punt("GRID_ORIGIN must be specified for two-dimentional grids");
221
i = 0; errcod = ip_data("NIX","%d",&i,0);
224
punt("NIX must be greater than 1");
225
i = 0; errcod = ip_data("NIY","%d",&i,0);
228
punt("NIY must be greater than 1");
230
i = 0; errcod = ip_data("NIZ","%d",&i,0);
233
punt("NIZ must be greater than 1");
236
/* orthonormalize grid unit vectors */
239
/* Which format to use for the 3D grid */
241
errcod = ip_string("GRID_FORMAT", &grid_format, 0);
242
if (grid_format == NULL) {
244
grid_format = strdup("GAUSSCUBE");
246
grid_format = strdup("PLOTMTV");
248
else if (strcmp(grid_format,"GAUSSCUBE") &&
249
strcmp(grid_format,"PLOTMTV") &&
250
strcmp(grid_format,"MEGAPOVPLUS"))
251
punt("Invalid value for GRID_FORMAT");
253
/* Check if the grid output format is compatibe with the type of grid */
254
if (!strcmp(grid_format,"PLOTMTV") && grid3d)
255
punt("GRID_FORMAT=PLOTMTV can only be used for 2-d grids");
256
if (strcmp(grid_format,"PLOTMTV") && !grid3d)
257
punt("Only GRID_FORMAT=PLOTMTV can be used for 2-d grids");
260
errcod = ip_data("GRID_ZMIN","%lf",&grid_zmin,0);
261
errcod = ip_data("GRID_ZMAX","%lf",&grid_zmax,0);
262
if (grid_zmin >= grid_zmax)
263
punt("GRID_ZMIN must be less than GRID_ZMAX");
264
errcod = ip_data("EDGRAD_LOGSCALE","%d",&edgrad_logscale,0);
268
}} //namespace psi::oeprop
270
using namespace psi::oeprop;
272
int* fock_to_pitzer(int num_mo, int* fock_mos)
275
int nvirt, nocc, ndocc, nsocc;
277
int current_highest, current_lowest;
278
int *f2p_virt, *f2p_occ;
279
int *mo_offset, *occ_offset, *virt_offset;
283
ndocc = nvirt = nsocc = 0;
284
for(irrep=0;irrep<nirreps;irrep++) {
285
ndocc += clsdpi[irrep];
286
nsocc += openpi[irrep];
287
nvirt += orbspi[irrep] - clsdpi[irrep] - openpi[irrep];
289
nocc = ndocc + nsocc;
290
f2p_occ = init_int_array(nocc);
291
f2p_virt = init_int_array(nvirt);
292
pitzer_mos = init_int_array(num_mo);
293
virt_offset = init_int_array(nirreps);
294
occ_offset = init_int_array(nirreps);
295
mo_offset = init_int_array(nirreps);
297
virt_offset[0] = clsdpi[0] + openpi[0];
298
occ_offset[0] = clsdpi[0] + openpi[0] - 1;
300
for(irrep=1;irrep<nirreps;irrep++) {
302
mo_offset[irrep] = mo_offset[irrep-1] + orbspi[irrep-1];
303
no = clsdpi[irrep] + openpi[irrep];
306
occ_offset[irrep] = mo_offset[irrep] + no - 1;
308
occ_offset[irrep] = -1;
310
virt_offset[irrep] = mo_offset[irrep] + no;
312
virt_offset[irrep] = -1;
316
/*---------------------------------------------------------------
317
construct Fock->Pitzer mapping for virtual orbitals (f2p_virt)
318
---------------------------------------------------------------*/
319
for(v=0;v<nvirt;v++) {
320
eval = 1E300; /* to be greater than any eigenvalue to be encountered */
321
for(irrep=0;irrep<nirreps;irrep++) {
322
if (virt_offset[irrep] >= 0)
323
if (eval > scf_evals[virt_offset[irrep]]) {
324
current_lowest = irrep;
325
eval = scf_evals[virt_offset[irrep]];
328
f2p_virt[v] = virt_offset[current_lowest];
329
virt_offset[current_lowest]++;
330
/* If all virtual MOs in this irrep have been exhausted - set virt_offset for
331
that irrep to -1 so that it's skipped on subsequent passes */
332
if (current_lowest == nirreps-1) {
333
if (virt_offset[current_lowest] == nmo)
334
virt_offset[current_lowest] = -1;
337
if (virt_offset[current_lowest] == mo_offset[current_lowest+1])
338
virt_offset[current_lowest] = -1;
342
/*----------------------------------------------------------------
343
construct Fock->Pitzer mapping for occupied orbitals (f2o_occ)
344
----------------------------------------------------------------*/
345
for(o=0;o<nocc;o++) {
346
eval = -1E300; /* to be smaller than any eigenvalue to be encountered */
347
for(irrep=0;irrep<nirreps;irrep++) {
348
if (occ_offset[irrep] >= 0)
349
if (eval < scf_evals[occ_offset[irrep]]) {
350
current_highest = irrep;
351
eval = scf_evals[occ_offset[irrep]];
354
f2p_occ[o] = occ_offset[current_highest];
355
occ_offset[current_highest]--;
356
/* If all occupied MOs in this irrep have been exhausted - set occ_offset for
357
that irrep to -1 so that it's skipped on subsequent passes */
358
if (occ_offset[current_highest] == mo_offset[current_highest]-1)
359
occ_offset[current_highest] = -1;
362
for(mo=0;mo<num_mo;mo++)
363
if (fock_mos[mo] < 0) {
364
o = -fock_mos[mo] - 1;
366
punt("MOS_TO_PLOT contains occupied indices outside of allowed range");
368
pitzer_mos[mo] = f2p_occ[o];
371
v = fock_mos[mo] - 1;
373
punt("MOS_TO_PLOT contains unoccupied indices outside of allowed range");
375
pitzer_mos[mo] = f2p_virt[v];
389
namespace psi { namespace oeprop {
394
double sum1, sum2, dot;
395
double step_x, step_y, step_z;
397
/*-------------------------------------------------
398
First orthonormalize grid_unit_x and grid_unit_y
399
and compute grid_unit_z
400
-------------------------------------------------*/
402
/* Normalizing the grid_unit's */
403
dot_arr(grid_unit_x,grid_unit_x,3,&sum1);
404
dot_arr(grid_unit_y,grid_unit_y,3,&sum2);
405
sum1 = sqrt(sum1); sum2 = sqrt(sum2);
407
grid_unit_x[i] /= sum1;
408
grid_unit_y[i] /= sum2;
411
/* Checking if vectors are parallel */
412
dot_arr(grid_unit_x,grid_unit_y,3,&dot);
413
if (1.0 - fabs(dot) < ADOTB_ORTHOGONAL) /* Vectors are parallel - abort */
414
punt("Vectors GRID_UNIT_X and GRID_UNIT_Y are parallel");
415
else if (fabs(dot) > ADOTB_ORTHOGONAL) { /* Vectors are not orthogonal - orthonormalizing */
417
grid_unit_y[i] -= dot*grid_unit_x[i];
418
dot_arr(grid_unit_y,grid_unit_y,3,&sum1);
421
grid_unit_y[i] /= sum1;
424
/* Get grid_unit_z as a vector product */
426
grid_unit_z[0] = grid_unit_x[1]*grid_unit_y[2] - grid_unit_x[2]*grid_unit_y[1];
427
grid_unit_z[1] = grid_unit_x[2]*grid_unit_y[0] - grid_unit_x[0]*grid_unit_y[2];
428
grid_unit_z[2] = grid_unit_x[0]*grid_unit_y[1] - grid_unit_x[1]*grid_unit_y[0];
431
/* grid_origin will now contain the origin of the grid rectangle/box rather
432
than the grid coordinate systems */
435
grid_origin[i] += grid_xyz0[0]*grid_unit_x[i] + grid_xyz0[1]*grid_unit_y[i] + grid_xyz0[2]*grid_unit_z[i];
438
grid_origin[i] += grid_xy0[0]*grid_unit_x[i] + grid_xy0[1]*grid_unit_y[i];
441
/* Compute grid size and unit cell vectors */
443
step_x = (grid_xyz1[0] - grid_xyz0[0])/nix;
444
step_y = (grid_xyz1[1] - grid_xyz0[1])/niy;
445
step_z = (grid_xyz1[2] - grid_xyz0[2])/niz;
447
grid_step_x[i] = grid_unit_x[i]*step_x;
448
grid_step_y[i] = grid_unit_y[i]*step_y;
449
grid_step_z[i] = grid_unit_z[i]*step_z;
453
step_x = (grid_xy1[0] - grid_xy0[0])/nix;
454
step_y = (grid_xy1[1] - grid_xy0[1])/niy;
456
grid_step_x[i] = grid_unit_x[i]*step_x;
457
grid_step_y[i] = grid_unit_y[i]*step_y;
464
}} // namespace psi::oeprop