00001
00006 #ifndef _psi3_bin_optking_bend_h_
00007 #define _psi3_bin_optking_bend_h_
00008
00009 namespace psi { namespace optking {
00010
00011 class bend_class {
00012 int id;
00013 int A;
00014 int B;
00015 int C;
00016 double value;
00017 double *s_A;
00018 double *s_B;
00019 double *s_C;
00020 public:
00021 bend_class() {
00022 s_A = new double[3];
00023 s_B = new double[3];
00024 s_C = new double[3];
00025 }
00026 ~bend_class() {
00027
00028 delete [] s_A;
00029 delete [] s_B;
00030 delete [] s_C;
00031 }
00032 void print(FILE *fp_out, int print_flag) {
00033 if (print_flag == 0)
00034 fprintf(fp_out," (%d %d %d %d)\n", id,A+1,B+1,C+1);
00035 else
00036 fprintf(fp_out," (%d %d %d %d) (%.8lf)\n", id,A+1,B+1,C+1,value);
00037 }
00038 void set_id(int i){ id = i;}
00039 int get_id(void) { return id;}
00040 void set_A(int i) { A = i;}
00041 int get_A(void) { return A;}
00042 void set_B(int i) { B = i;}
00043 int get_B(void) { return B;}
00044 void set_C(int i) { C = i;}
00045 int get_C(void) { return C;}
00046 void set_value(double new_val) { value = new_val;}
00047 double get_value(void) { return value;}
00048 void set_s_A(double s_A0, double s_A1, double s_A2) {
00049 s_A[0] = s_A0; s_A[1] = s_A1; s_A[2] = s_A2; }
00050 double get_s_A(int i) { return s_A[i]; }
00051 void set_s_B(double s_B0, double s_B1, double s_B2) {
00052 s_B[0] = s_B0; s_B[1] = s_B1; s_B[2] = s_B2; }
00053 double get_s_B(int i) { return s_B[i]; }
00054 void set_s_C(double s_C0, double s_C1, double s_C2) {
00055 s_C[0] = s_C0; s_C[1] = s_C1; s_C[2] = s_C2; }
00056 double get_s_C(int i) { return s_C[i]; }
00057 };
00058
00059
00060 class bend_set {
00061
00062 int num;
00063 bend_class *bend_array;
00064
00065 public:
00066
00067 bend_set(int size) {
00068 if(0 <= size < 10000) {
00069 bend_array = new bend_class[size];
00070 }
00071 else { fprintf(outfile,"\nWARNING: bad number of bends\n");}
00072 }
00073
00074 bend_set(void) { }
00075 void allocate(int size) {
00076 if (0 <= size <10000)
00077 bend_array = new bend_class[size];
00078 else
00079 fprintf(outfile,"\nWARNING: bad number of bends\n");
00080 }
00081
00082
00083 ~bend_set() {
00084
00085 delete [] bend_array;
00086 }
00087
00088 void print(FILE *fp_out, int print_flag) {
00089 int i;
00090 if (num > 0) {
00091 if (print_flag == 0) fprintf(fp_out," bend = (\n");
00092 else fprintf(fp_out, "Bends\n");
00093 for (i=0; i < num; ++i)
00094 bend_array[i].print(fp_out, print_flag);
00095 if (print_flag == 0) fprintf(fp_out," )\n");
00096 }
00097 return;
00098 }
00099
00100 void print_s() {
00101 int i;
00102 for (i=0;i<num;++i) {
00103 fprintf(outfile,"S vector for bend %d %d %d: atom A\n",get_A(i),get_B(i),get_C(i) );
00104 fprintf(outfile,"(%16.10f,%16.10f,%16.10f)\n", get_s_A(i,0), get_s_A(i,1), get_s_A(i,2) );
00105 fprintf(outfile,"S vector for bend %d %d %d: atom B\n",get_A(i),get_B(i),get_C(i) );
00106 fprintf(outfile,"(%16.10f,%16.10f,%16.10f)\n", get_s_B(i,0), get_s_B(i,1), get_s_B(i,2) );
00107 fprintf(outfile,"S vector for bend %d %d %d: atom C\n",get_A(i),get_B(i),get_C(i) );
00108 fprintf(outfile,"(%16.10f,%16.10f,%16.10f)\n", get_s_C(i,0), get_s_C(i,1), get_s_C(i,2) );
00109 }
00110 return;
00111 }
00112
00113 void set_num(int i) { num = i;}
00114 int get_num(void) { return num;}
00115 void set_id(int index, int new_id) { bend_array[index].set_id(new_id);}
00116 int get_id(int index) { return bend_array[index].get_id();}
00117 void set_A(int index, int new_A) { bend_array[index].set_A(new_A);}
00118 int get_A(int index) {return bend_array[index].get_A();}
00119 void set_B(int index, int new_B) { bend_array[index].set_B(new_B);}
00120 int get_B(int index) { return bend_array[index].get_B();}
00121 void set_C(int index, int new_C) { bend_array[index].set_C(new_C);}
00122 int get_C(int index) { return bend_array[index].get_C();}
00123 void set_val(int index, double new_val) { bend_array[index].set_value(new_val);}
00124 double get_val(int index) { return bend_array[index].get_value();}
00125
00126 void set_s_A(int index, double s_A0, double s_A1, double s_A2) {
00127 bend_array[index].set_s_A(s_A0,s_A1,s_A2); }
00128 double get_s_A(int index, int i) { return bend_array[index].get_s_A(i); }
00129
00130 void set_s_B(int index, double s_B0, double s_B1, double s_B2) {
00131 bend_array[index].set_s_B(s_B0,s_B1,s_B2); }
00132 double get_s_B(int index, int i) { return bend_array[index].get_s_B(i); }
00133
00134 void set_s_C(int index, double s_C0, double s_C1, double s_C2) {
00135 bend_array[index].set_s_C(s_C0,s_C1,s_C2); }
00136 double get_s_C(int index, int i) { return bend_array[index].get_s_C(i); }
00137 void compute(int natom, double *geom) {
00138 int i,j,A,B,C;
00139 double rBA,rBC,eBA[3],eBC[3],tmp[3],dotprod,angle;
00140
00141 for (i=0;i<num;++i) {
00142 A = get_A(i);
00143 B = get_B(i);
00144 C = get_C(i);
00145
00146 for (j=0;j<3;++j) {
00147 eBA[j] = geom[3*A+j] - geom[3*B+j];
00148 eBC[j] = geom[3*C+j] - geom[3*B+j];
00149 }
00150
00151 rBA = sqrt( SQR(eBA[0])+SQR(eBA[1])+SQR(eBA[2]) );
00152 rBC = sqrt( SQR(eBC[0])+SQR(eBC[1])+SQR(eBC[2]) );
00153
00154 scalar_div(rBA,eBA);
00155 scalar_div(rBC,eBC);
00156
00157 dot_arr(eBA,eBC,3,&dotprod);
00158
00159 if (dotprod > 1.0) angle = 0.0;
00160 else if (dotprod < -1.0) angle = _pi;
00161 else angle = acos(dotprod)*180.0/_pi;
00162
00163 set_val(i,angle);
00164 }
00165 return;
00166 }
00167 void compute_s(int natom, double *geom) {
00168 int i,j,A,B,C;
00169 double val,rBA,rBC;
00170 double eBA[3], eBC[3], tmp[3];
00171 double *geom_ang;
00172
00173 geom_ang = new double[3*natom];
00174 for (i=0;i<natom*3;++i)
00175 geom_ang[i] = geom[i] * _bohr2angstroms;
00176
00177 for (i=0;i<num;++i) {
00178 A = get_A(i);
00179 B = get_B(i);
00180 C = get_C(i);
00181 val = get_val(i)*_pi/180.0;
00182
00183 for (j=0;j<3;++j) {
00184 eBA[j] = geom_ang[3*A+j] - geom_ang[3*B+j];
00185 eBC[j] = geom_ang[3*C+j] - geom_ang[3*B+j];
00186 }
00187
00188 rBA = sqrt( SQR(eBA[0]) + SQR(eBA[1]) + SQR(eBA[2]) );
00189 rBC = sqrt( SQR(eBC[0]) + SQR(eBC[1]) + SQR(eBC[2]) );
00190
00191 for (j=0;j<3;++j) {
00192 eBA[j] = eBA[j] / rBA;
00193 eBC[j] = eBC[j] / rBC;
00194 }
00195
00196 for (j=0;j<3;++j) {
00197 tmp[j] = (eBA[j]*cos(val) - eBC[j]) / (rBA*sin(val));
00198 }
00199 set_s_A(i,tmp[0],tmp[1],tmp[2]);
00200
00201 for (j=0;j<3;++j) {
00202 tmp[j] = ((rBA - rBC*cos(val))*eBA[j] + (rBC-rBA*cos(val))*eBC[j])
00203 / (rBA * rBC * sin(val));
00204 }
00205 set_s_B(i,tmp[0],tmp[1],tmp[2]);
00206
00207 for (j=0;j<3;++j) {
00208 tmp[j] = (eBC[j]*cos(val) - eBA[j]) / (rBC*sin(val));
00209 }
00210 set_s_C(i,tmp[0],tmp[1],tmp[2]);
00211 }
00212 delete [] geom_ang;
00213 return;
00214 }
00215 int get_id_from_atoms(int a, int b, int c) {
00216 int i;
00217
00218 for (i=0;i<num;++i) {
00219 if ( (a == get_A(i)) && (b == get_B(i)) && (c == get_C(i)) ) break;
00220 }
00221 if (i == num) {
00222 fprintf(outfile,"Could not find simple bend for atoms \
00223 %d %d %d in list.\n", a+1, b+1, c+1);
00224 exit(2);
00225 }
00226
00227 return get_id(i);
00228 }
00229 };
00230
00231 }}
00232
00233 #endif