/*! Print information about private variables {plots,resolution,minmax} */ int Nodes_method::showinfo(ostream & os) { sysprop->showinfo(os); os << endl << endl; os << " Wavefunction " << endl << endl; wfdata->showinfo(os); os<<"#############Nodes_method#################\n"; if (doublemove) os <<"Doing doublemoves with"<<endl; os<<"Plots= "<<plots(0); for(int i=1;i<plots.GetSize();i++) os<<", "<<plots(i); os<<endl; if (doublemove){ os << "Translation vector(s): "<<endl; for(int i=0;i<dxyz.GetDim(0);i++) os<<"( "<<dxyz(i,0)<<" , "<<dxyz(i,1)<<" , "<<dxyz(i,2)<<" )"<<endl; } os<<"resolution "<<resolution<<endl; os<<"xmin="<<minmax(0)<<" xmax="<<minmax(1)<<endl; os<<"ymin="<<minmax(2)<<" ymax="<<minmax(3)<<endl; os<<"zmin="<<minmax(4)<<" zmax="<<minmax(5)<<endl; os<<"done"<<endl; return 1; }
STKUNIT_UNIT_TEST(function, stringFunction_derivative_2) { EXCEPTWATCH; for (unsigned ipts = 0; ipts < NPTS; ipts++) { double x = testpoints_fd[ipts][0]; double y = testpoints_fd[ipts][1]; double z = testpoints_fd[ipts][2]; double t = testpoints_fd[ipts][3]; double eps=1.e-10; double eps_loc = eps*(std::fabs(x) + std::fabs(y) + std::fabs(z) + std::fabs(t))/4.0; // start_demo_stringFunction_derivative_2 StringFunction sf(" sin(x*y*z*z) " ); std::string grad[] = {"y*z*z*cos(x*y*z*z)", "x*z*z*cos(x*y*z*z)", "2*x*y*z*cos(x*y*z*z)"}; std::string gradv = "v[0]="+grad[0]+"; v[1]="+grad[1]+" ; v[2]="+grad[2]+";"; StringFunction dsf_grad(gradv.c_str(), Name("test"), Dimensions(3), Dimensions(3) ); MDArrayString dxyz(3,1); dxyz(0,0)="x"; dxyz(1,0)="y"; dxyz(2,0)="z"; sf.set_gradient_strings(grad, 3); Teuchos::RCP<Function> dsf_grad_fd = sf.derivative_test_fd(dxyz, eps_loc); Teuchos::RCP<Function> dsf_grad_2 = sf.derivative(dxyz); MDArray dv_fd = eval_vec3(x, y, z, t, *dsf_grad_fd); MDArray dv2 = eval_vec3(x, y, z, t, *dsf_grad_2); MDArray dv = eval_vec3(x, y, z, t, dsf_grad); // the two different functions should give the same result for (int ii = 0; ii < 3; ii++) { //std::cout << "\n ii= " << ii << "\n"<< std::endl; STKUNIT_EXPECT_DOUBLE_EQ(dv(ii), dv2(ii)); if (std::fabs(dv(ii)-dv_fd(ii)) > 0.5*(std::fabs(dv_fd(ii))+std::fabs(dv(ii)))*1.e-6) { std::cout << "\nii = " << ii << " x= "<<x<<" y= "<<y<<" z= " << z << " expected= " << dv(ii) << " actual= " << dv_fd(ii) << std::endl; } STKUNIT_EXPECT_DOUBLE_EQ_APPROX_TOL(dv(ii), dv_fd(ii), 1.e-4); } // end_demo } }
STKUNIT_UNIT_TEST(function, stringFunction_derivative_1) { EXCEPTWATCH; for (unsigned ipts = 0; ipts < NPTS; ipts++) { double x = testpoints[ipts][0]; double y = testpoints[ipts][1]; double z = testpoints[ipts][2]; double t = testpoints[ipts][3]; double eps=1.e-6; double eps_loc = eps*(std::fabs(x) + std::fabs(y) + std::fabs(z) + std::fabs(t))/4.0; // start_demo_stringFunction_derivative_1 StringFunction sfxy(" x - y "); StringFunction dsfxy_grad("v[0]=1; v[1]= -1; v[2]=0", Name("test"), Dimensions(3), Dimensions(3) ); MDArrayString dxyz(3,1); dxyz(0,0)="x"; dxyz(1,0)="y"; dxyz(2,0)="z"; std::string grad[] = {"1","-1","0"}; sfxy.set_gradient_strings(grad, 3); Teuchos::RCP<Function> dsfxy_grad_1 = sfxy.derivative_test(dxyz); Teuchos::RCP<Function> dsfxy_grad_fd = sfxy.derivative_test_fd(dxyz, eps_loc); Teuchos::RCP<Function> dsfxy_grad_2 = sfxy.derivative(dxyz); MDArray dvxy1 = eval_vec3(x, y, z, t, *dsfxy_grad_1); MDArray dvxy_fd = eval_vec3(x, y, z, t, *dsfxy_grad_fd); MDArray dvxy2 = eval_vec3(x, y, z, t, *dsfxy_grad_2); MDArray dvxy = eval_vec3(x, y, z, t, dsfxy_grad); // the two different functions should give the same result for (int ii = 0; ii < 3; ii++) { STKUNIT_EXPECT_DOUBLE_EQ(dvxy(ii), dvxy1(ii)); STKUNIT_EXPECT_DOUBLE_EQ(dvxy(ii), dvxy2(ii)); STKUNIT_EXPECT_DOUBLE_EQ_APPROX(dvxy(ii), dvxy_fd(ii)); } // and they should give the same result as C++ STKUNIT_EXPECT_DOUBLE_EQ(dvxy(0), 1.0); STKUNIT_EXPECT_DOUBLE_EQ(dvxy(1), -1.0); // end_demo } }
void akGeometryDeformer::DLBAntipodalitySkinningNoNormals( const btAlignedObjectArray<akMatrix4>* mpalette, const btAlignedObjectArray<akDualQuat>* dqpalette, const UTsize vtxCount, const float* weights, const UTsize weightsStride, const UTuint8* indices, const UTsize indicesStride, const akVector3* vtxSrc, const UTsize vtxSrcStride, akVector3* vtxDst, const UTsize vtxDstStride) { const btAlignedObjectArray<akMatrix4>& matrices = *mpalette; const btAlignedObjectArray<akDualQuat>& dquats = *dqpalette; for(unsigned int i=0; i<vtxCount; i++) { // position 1st pass for non rigid part of the transformation using matrices akVector4 pos(vtxSrc[0].getX(), vtxSrc[0].getY(), vtxSrc[0].getZ(), 1); akVector4 posout(0,0,0,1); if (weights[0]) posout += matrices[indices[0]] * weights[0] * pos; if (weights[1]) posout += matrices[indices[1]] * weights[1] * pos; if (weights[2]) posout += matrices[indices[2]] * weights[2] * pos; if (weights[3]) posout += matrices[indices[3]] * weights[3] * pos; akDualQuat dq0 = dquats[indices[0]]; akDualQuat dq1 = dquats[indices[1]]; akDualQuat dq2 = dquats[indices[2]]; akDualQuat dq3 = dquats[indices[3]]; if( dot(dq0.n, dq1.n) < 0.0) dq1 *= -1.0; if( dot(dq0.n, dq2.n) < 0.0) dq2 *= -1.0; if( dot(dq0.n, dq3.n) < 0.0) dq3 *= -1.0; akDualQuat dq = dq0 * weights[0]; if (weights[1]) dq += dq1 * weights[1]; if (weights[2]) dq += dq2 * weights[2]; if (weights[3]) dq += dq3 * weights[3]; dq /= length(dq.n); akVector3 ndxyz(dq.n.getXYZ()); akVector3 dxyz(dq.d.getXYZ()); //position akVector3 in(posout.getXYZ()); *vtxDst = in + 2.0 * cross( ndxyz, cross(ndxyz, in) + dq.n.getW() * in ) + 2.0 * ( dq.n.getW() * dxyz - dq.d.getW() * ndxyz + cross(ndxyz, dxyz) ); akAdvancePointer(weights, weightsStride); akAdvancePointer(indices, indicesStride); akAdvancePointer(vtxSrc, vtxSrcStride); akAdvancePointer(vtxDst, vtxDstStride); } }
void akGeometryDeformer::DLBSkinning( const btAlignedObjectArray<akMatrix4>* mpalette, const btAlignedObjectArray<akDualQuat>* dqpalette, const UTsize vtxCount, const float* weights, const UTsize weightsStride, const UTuint8* indices, const UTsize indicesStride, const akVector3* vtxSrc, const UTsize vtxSrcStride, akVector3* vtxDst, const UTsize vtxDstStride, const akVector3* normSrc, const UTsize normSrcStride, akVector3* normDst, const UTsize normDstStride) { const btAlignedObjectArray<akMatrix4>& matrices = *mpalette; const btAlignedObjectArray<akDualQuat>& dquats = *dqpalette; for(unsigned int i=0; i<vtxCount; i++) { // position 1st pass for non rigid part of the transformation using matrices akMatrix4 mat(matrices[indices[0]] * weights[0]); if (weights[1]) mat += matrices[indices[1]] * weights[1]; if (weights[2]) mat += matrices[indices[2]] * weights[2]; if (weights[3]) mat += matrices[indices[3]] * weights[3]; akVector3 tmpPos = (mat * akVector4(*vtxSrc, 1.f)).getXYZ(); // position 2nd pass for rigid transformation (rotaion & location) using dual quats akDualQuat dq = dquats[indices[0]] * weights[0]; if (weights[1]) dq += dquats[indices[1]] * weights[1]; if (weights[2]) dq += dquats[indices[2]] * weights[2]; if (weights[3]) dq += dquats[indices[3]] * weights[3]; dq /= length(dq.n); akVector3 ndxyz(dq.n.getXYZ()); akVector3 dxyz(dq.d.getXYZ()); *vtxDst = tmpPos + 2.0 * cross( ndxyz, cross(ndxyz, tmpPos) + dq.n.getW() * tmpPos ) + 2.0 * ( dq.n.getW() * dxyz - dq.d.getW() * ndxyz + cross(ndxyz, dxyz) ); // normal 1st pass inverseTranspose(mat); akVector3 tmpNorm = (mat * akVector4(*normSrc, 0.0f)).getXYZ(); // normal 2nd pass *normDst = tmpNorm + 2.0 * cross( ndxyz, cross(ndxyz, tmpNorm) + dq.n.getW() * tmpNorm ); *normDst = normalize(*normDst); akAdvancePointer(normSrc, normSrcStride); akAdvancePointer(normDst, normDstStride); akAdvancePointer(weights, weightsStride); akAdvancePointer(indices, indicesStride); akAdvancePointer(vtxSrc, vtxSrcStride); akAdvancePointer(vtxDst, vtxDstStride); } }
void akGeometryDeformer::DLBAntipodalitySkinningNoScaling( const btAlignedObjectArray<akMatrix4>* mpalette, const btAlignedObjectArray<akDualQuat>* dqpalette, const UTsize vtxCount, const float* weights, const UTsize weightsStride, const UTuint8* indices, const UTsize indicesStride, const akVector3* vtxSrc, const UTsize vtxSrcStride, akVector3* vtxDst, const UTsize vtxDstStride, const akVector3* normSrc, const UTsize normSrcStride, akVector3* normDst, const UTsize normDstStride) { const btAlignedObjectArray<akMatrix4>& matrices = *mpalette; const btAlignedObjectArray<akDualQuat>& dquats = *dqpalette; for(unsigned int i=0; i<vtxCount; i++) { akDualQuat dq0 = dquats[indices[0]]; akDualQuat dq1 = dquats[indices[1]]; akDualQuat dq2 = dquats[indices[2]]; akDualQuat dq3 = dquats[indices[3]]; if( dot(dq0.n, dq1.n) < 0.0) dq1 *= -1.0; if( dot(dq0.n, dq2.n) < 0.0) dq2 *= -1.0; if( dot(dq0.n, dq3.n) < 0.0) dq3 *= -1.0; akDualQuat dq = dq0 * weights[0]; if (weights[1]) dq += dq1 * weights[1]; if (weights[2]) dq += dq2 * weights[2]; if (weights[3]) dq += dq3 * weights[3]; dq /= length(dq.n); akVector3 ndxyz(dq.n.getXYZ()); akVector3 dxyz(dq.d.getXYZ()); //position akVector3 in(*vtxSrc); *vtxDst = in + 2.0 * cross( ndxyz, cross(ndxyz, in) + dq.n.getW() * in ) + 2.0 * ( dq.n.getW() * dxyz - dq.d.getW() * ndxyz + cross(ndxyz, dxyz) ); // normal akVector3 inn(*normSrc); *normDst = inn + 2.0 * cross( ndxyz, cross(ndxyz, inn) + dq.n.getW() * inn ); akAdvancePointer(normSrc, normSrcStride); akAdvancePointer(normDst, normDstStride); akAdvancePointer(weights, weightsStride); akAdvancePointer(indices, indicesStride); akAdvancePointer(vtxSrc, vtxSrcStride); akAdvancePointer(vtxDst, vtxDstStride); } }
void akGeometryDeformer::DLBSkinningNoNormals( const btAlignedObjectArray<akMatrix4>* mpalette, const btAlignedObjectArray<akDualQuat>* dqpalette, const UTsize vtxCount, const float* weights, const UTsize weightsStride, const UTuint8* indices, const UTsize indicesStride, const akVector3* vtxSrc, const UTsize vtxSrcStride, akVector3* vtxDst, const UTsize vtxDstStride) { const btAlignedObjectArray<akMatrix4>& matrices = *mpalette; const btAlignedObjectArray<akDualQuat>& dquats = *dqpalette; for(unsigned int i=0; i<vtxCount; i++) { // position 1st pass for non rigid part of the transformation using matrices akVector4 pos(vtxSrc[0].getX(), vtxSrc[0].getY(), vtxSrc[0].getZ(), 1); akVector4 posout(0,0,0,1); if (weights[0]) posout += matrices[indices[0]] * weights[0] * pos; if (weights[1]) posout += matrices[indices[1]] * weights[1] * pos; if (weights[2]) posout += matrices[indices[2]] * weights[2] * pos; if (weights[3]) posout += matrices[indices[3]] * weights[3] * pos; // position 2nd pass for rigid transformation (rotaion & location) using dual quats akDualQuat dq = dquats[indices[0]] * weights[0]; if (weights[1]) dq += dquats[indices[1]] * weights[1]; if (weights[2]) dq += dquats[indices[2]] * weights[2]; if (weights[3]) dq += dquats[indices[3]] * weights[3]; dq /= length(dq.n); akVector3 tmpPos2(posout.getXYZ()); akVector3 ndxyz(dq.n.getXYZ()); akVector3 dxyz(dq.d.getXYZ()); *vtxDst = tmpPos2 + 2.0 * cross( ndxyz, cross(ndxyz, tmpPos2) + dq.n.getW() * tmpPos2 ) + 2.0 * ( dq.n.getW() * dxyz - dq.d.getW() * ndxyz + cross(ndxyz, dxyz) ); akAdvancePointer(weights, weightsStride); akAdvancePointer(indices, indicesStride); akAdvancePointer(vtxSrc, vtxSrcStride); akAdvancePointer(vtxDst, vtxDstStride); } }
void PointGroup<scalar_type>::solve(Timers& timers, bool compute_rmm, bool lda, bool compute_forces, bool compute_energy, double& energy, double* fort_forces_ptr) { HostMatrix<scalar_type> rmm_output; uint group_m = total_functions(); if (compute_rmm) { rmm_output.resize(group_m, group_m); rmm_output.zero(); } #if CPU_RECOMPUTE /** Compute functions **/ timers.functions.start(); compute_functions(compute_forces, !lda); timers.functions.pause(); #endif // prepare rmm_input for this group timers.density.start(); HostMatrix<scalar_type> rmm_input(group_m, group_m); get_rmm_input(rmm_input); timers.density.pause(); HostMatrix<vec_type3> forces(total_nucleii(), 1); forces.zero(); HostMatrix<vec_type3> dd; /******** each point *******/ uint point = 0; for (list<Point>::const_iterator point_it = points.begin(); point_it != points.end(); ++point_it, ++point) { timers.density.start(); /** density **/ scalar_type partial_density = 0; vec_type3 dxyz(0,0,0); vec_type3 dd1(0,0,0); vec_type3 dd2(0,0,0); if (lda) { for (uint i = 0; i < group_m; i++) { float w = 0.0; float Fi = function_values(i, point); for (uint j = i; j < group_m; j++) { scalar_type Fj = function_values(j, point); w += rmm_input(j, i) * Fj; } partial_density += Fi * w; } } else { for (uint i = 0; i < group_m; i++) { float w = 0.0; vec_type3 w3(0,0,0); vec_type3 ww1(0,0,0); vec_type3 ww2(0,0,0); scalar_type Fi = function_values(i, point); vec_type3 Fgi(gradient_values(i, point)); vec_type3 Fhi1(hessian_values(2 * (i + 0) + 0, point)); vec_type3 Fhi2(hessian_values(2 * (i + 0) + 1, point)); for (uint j = 0; j <= i; j++) { scalar_type rmm = rmm_input(j,i); scalar_type Fj = function_values(j, point); w += Fj * rmm; vec_type3 Fgj(gradient_values(j, point)); w3 += Fgj * rmm; vec_type3 Fhj1(hessian_values(2 * (j + 0) + 0, point)); vec_type3 Fhj2(hessian_values(2 * (j + 0) + 1, point)); ww1 += Fhj1 * rmm; ww2 += Fhj2 * rmm; } partial_density += Fi * w; dxyz += Fgi * w + w3 * Fi; dd1 += Fgi * w3 * 2 + Fhi1 * w + ww1 * Fi; vec_type3 FgXXY(Fgi.x(), Fgi.x(), Fgi.y()); vec_type3 w3YZZ(w3.y(), w3.z(), w3.z()); vec_type3 FgiYZZ(Fgi.y(), Fgi.z(), Fgi.z()); vec_type3 w3XXY(w3.x(), w3.x(), w3.y()); dd2 += FgXXY * w3YZZ + FgiYZZ * w3XXY + Fhi2 * w + ww2 * Fi; } } timers.density.pause(); timers.forces.start(); /** density derivatives **/ if (compute_forces) { dd.resize(total_nucleii(), 1); dd.zero(); for (uint i = 0, ii = 0; i < total_functions_simple(); i++) { uint nuc = func2local_nuc(ii); uint inc_i = small_function_type(i); vec_type3 this_dd = vec_type3(0,0,0); for (uint k = 0; k < inc_i; k++, ii++) { scalar_type w = 0.0; for (uint j = 0; j < group_m; j++) { scalar_type Fj = function_values(j, point); w += rmm_input(j, ii) * Fj * (ii == j ? 2 : 1); } this_dd -= gradient_values(ii, point) * w; } dd(nuc) += this_dd; } } timers.forces.pause(); timers.pot.start(); timers.density.start(); /** energy / potential **/ scalar_type exc = 0, corr = 0, y2a = 0; if (lda) cpu_pot(partial_density, exc, corr, y2a); else { cpu_potg(partial_density, dxyz, dd1, dd2, exc, corr, y2a); } timers.pot.pause(); if (compute_energy) energy += (partial_density * point_it->weight) * (exc + corr); timers.density.pause(); /** forces **/ timers.forces.start(); if (compute_forces) { scalar_type factor = point_it->weight * y2a; for (uint i = 0; i < total_nucleii(); i++) forces(i) += dd(i) * factor; } timers.forces.pause(); /** RMM **/ timers.rmm.start(); if (compute_rmm) { scalar_type factor = point_it->weight * y2a; HostMatrix<scalar_type>::blas_ssyr(LowerTriangle, factor, function_values, rmm_output, point); } timers.rmm.pause(); } timers.forces.start(); /* accumulate force results for this group */ if (compute_forces) { FortranMatrix<double> fort_forces(fort_forces_ptr, fortran_vars.atoms, 3, fortran_vars.max_atoms); // TODO: mover esto a init.cpp for (uint i = 0; i < total_nucleii(); i++) { uint global_atom = local2global_nuc[i]; vec_type3 this_force = forces(i); fort_forces(global_atom,0) += this_force.x(); fort_forces(global_atom,1) += this_force.y(); fort_forces(global_atom,2) += this_force.z(); } } timers.forces.pause(); timers.rmm.start(); /* accumulate RMM results for this group */ if (compute_rmm) { for (uint i = 0, ii = 0; i < total_functions_simple(); i++) { uint inc_i = small_function_type(i); for (uint k = 0; k < inc_i; k++, ii++) { uint big_i = local2global_func[i] + k; for (uint j = 0, jj = 0; j < total_functions_simple(); j++) { uint inc_j = small_function_type(j); for (uint l = 0; l < inc_j; l++, jj++) { uint big_j = local2global_func[j] + l; if (big_i > big_j) continue; uint big_index = (big_i * fortran_vars.m - (big_i * (big_i - 1)) / 2) + (big_j - big_i); fortran_vars.rmm_output(big_index) += rmm_output(ii, jj); } } } } } timers.rmm.pause(); #if CPU_RECOMPUTE /* clear functions */ function_values.deallocate(); gradient_values.deallocate(); hessian_values.deallocate(); #endif }
/*! Read the "words" from the method section in the input file via doinput() parsing, and store section information in private variables isoses, resolution, and minmax. Set up MO_matrix and Sample_point objects for wavefunction from input */ void Nodes_method::read(vector <string> words, unsigned int & pos, Program_options & options) { pos=0; //always start from first word doublevar Tres; vector <string> Torbs; vector <string> Tminmax; vector <string> orbtext; vector <string> Tdxyz; allocate(options.systemtext[0], sysprop); sysprop->generateSample(mywalker); allocate(options.twftext[0], sysprop, wfdata); wfdata->generateWavefunction(wf); mywalker->attachObserver(wf); pos=0; if(readsection(words,pos=0,Torbs,"CONTOURS")){ // error("Need CONTOURS in METHOD section"); plots.Resize(Torbs.size()); for(unsigned int i=0; i<Torbs.size(); i++){ plots(i)=atoi(Torbs[i].c_str()); } } else { cout <<"WARNING: All electrons are used for scanning!"<<endl; plots.Resize(mywalker->electronSize()); for(int i=0; i<plots.GetSize(); i++){ plots(i)=i+1; } } pos=0; if(! readvalue(words,pos,Tres,"RESOLUTION")) error("Need RESOLUTION in METHOD section"); resolution=Tres; pos=0; minmax.Resize(6); if(readsection(words,pos,Tminmax,"MINMAX")) { if(Tminmax.size() != 6) error("MINMAX needs 6 values"); for(unsigned int i=0; i<Tminmax.size(); i++) { minmax(i)=atof(Tminmax[i].c_str()); } } else { minmax=0.0; int nions=sysprop->nIons(); Array1 <doublevar> ionpos(3); for(int i=0; i< nions; i++) { sysprop->getIonPos(i,ionpos); for(int d=0; d< 3; d++) { if(ionpos(d) < minmax(2*d)) minmax(2*d) = ionpos(d); if(ionpos(d) > minmax(2*d+1)) minmax(2*d+1)=ionpos(d); } } for(int d=0; d< 3; d++) { minmax(2*d)-=4.0; minmax(2*d+1)+=4.0; cout << "minmax " << minmax(2*d) << " " << minmax(2*d+1) << endl; } } // Makes the Nodes methods use the current implementation of Nodes if(readvalue(words, pos=0, readconfig, "READCONFIG")){ Array1 <Config_save_point> config_pos; config_pos.Resize(0); if(readconfig!="") { read_configurations(readconfig, config_pos); } if(config_pos.GetDim(0)<1) error("Could not read a single walker from config file"); //take a first one config_pos(0).restorePos(mywalker); } else { mywalker->randomGuess(); debug_write(cout, 0, " configs read ", 1, " configs randomly generated \n"); } pos=0; doublemove=false; if( readsection(words,pos,Tdxyz,"DOUBLEMOVES")){ doublemove=true; if(plots.GetSize()%2) error("Needs pairs of countours for doublemoves"); unsigned int dummy=3*plots.GetSize()/2; if(Tdxyz.size()!=dummy) error("DOUBLEMOVES needs 3 x # of vectors values"); dxyz.Resize(plots.GetSize()/2,3); for(int i=0; i<plots.GetSize()/2; i++){ for (int j=0; j<3;j++) dxyz(i,j)=atof(Tdxyz[i*3+j].c_str()); } } }
void Nodes_method::run(Program_options & options, ostream & output) { ofstream os; //for writing to *.plt files string pltfile; //name of plotfile being written string confile; //name of configuration of electrons to be being written double max_value,min_value; int count; Array1 <doublevar> xyz(3), xyz2(3), resolution_array(3); //position of electron "in" MO Array1 <int> D_array1(3); //dummy array1 Array2 <doublevar> oldpos(mywalker->electronSize(),3); Array1 <doublevar> tmp(3); D_array1=0; //sets all 3 components to 0. use as counter for gridpoints D_array1(0)=roundoff((minmax(1)-minmax(0))/resolution); D_array1(1)=roundoff((minmax(3)-minmax(2))/resolution); D_array1(2)=roundoff((minmax(5)-minmax(4))/resolution); resolution_array(0)=(minmax(1)-minmax(0))/(D_array1(0)-1); resolution_array(1)=(minmax(3)-minmax(2))/(D_array1(1)-1); resolution_array(2)=(minmax(5)-minmax(4))/(D_array1(2)-1); Array2 <doublevar> grid(plots.GetSize(),D_array1(0)*D_array1(1)*D_array1(2)); Wf_return wfvals(wf->nfunc(), 2); //where wfval fist index labels //wf number ie. ground state // excited state and so on, and second label is for two values, sign and log(wf). //scan electron positions cout << "Using these electron positions:"<<endl; for(int i=0; i<mywalker->electronSize(); i++){ mywalker->getElectronPos(i, tmp); cout.precision(5); cout.width(8); cout <<i+1<<" "<<tmp(0)<<" "<<tmp(1)<<" "<<tmp(2)<<endl; for (int d=0;d<3;d++) oldpos(i,d)=tmp(d); // cout << "pos " << oldpos(i,0) << " " << oldpos(i,1) << " " << oldpos(i,2) // << endl; } //generate .xyz file for gOpenMol to view coordinates pltfile=options.runid + ".xyz"; os.open(pltfile.c_str()); cout<<"writing to "<<pltfile<<endl; vector <string> atomlabels; sysprop->getAtomicLabels(atomlabels); os<<atomlabels.size()+mywalker->electronSize()<<endl; os<<endl; int spin_up=sysprop->nelectrons(0); //cout << "Up electrons "<<spin_up<<endl; for(unsigned int i=0; i<atomlabels.size(); i++){ Array1 <doublevar> pos(3); mywalker->getIonPos(i, pos); os<<atomlabels[i] <<" "<< pos(0) <<" "<<pos(1) <<" "<< pos(2)<<endl; } for(int j=0; j<mywalker->electronSize(); j++){ if (j<spin_up) os<<"Eu"; else os<<"Ed"; // mywalker->getElectronPos(j, pos); os<<" "<< oldpos(j,0)<<" "<<oldpos(j,1) <<" "<< oldpos(j,2)<<endl; } os.close(); if (!doublemove) { //calculate value of each molecular orbital at each grid point and store in an Array1 // grid values with x=fastest running variable, and z=slowest cout<<"calculating "<<D_array1(0)*D_array1(1)*D_array1(2) <<" grid points"<<endl; cout<<"for "<< plots.GetDim(0) <<" 3D projections of wavefunction"<<endl; count=0; xyz(0)=minmax(0); xyz(1)=minmax(2); xyz(2)=minmax(4); //init elec probe to xmin ymin zmin //Array1 <doublevar> oldpos(3) for(int i=0; i<plots.GetSize(); i++){ cout.width(3); cout <<"============================="<<plots(i) <<"==============================" <<endl; count=0; for(int xx=0; xx<D_array1(0);xx++){ xyz(0)=minmax(0)+xx*resolution_array(0); //move forward on x axis one resolution unit max_value=min_value=0.0; cout << "x "; cout.precision(5); cout.width(8); cout<< xyz(0); for(int yy=0; yy<D_array1(1);yy++){ xyz(1)=minmax(2)+yy*resolution_array(1); //move forward on y axis one resolution unit for(int zz=0;zz<D_array1(2);zz++){ xyz(2)=minmax(4)+zz*resolution_array(2); //move forward on z axis one resolution unit // mywalker->getElectronPos(plots(i), oldpos); mywalker->setElectronPos(plots(i)-1,xyz); //move elec#plots(i) to point specified by xyz wf->updateVal(wfdata, mywalker); //update wfdata wf->getVal(wfdata, 0, wfvals); //get wf value const doublevar cutoff=15; if(wfvals.amp(0,0)<cutoff) { grid(i,count)=wfvals.sign(0)*exp(wfvals.amp(0,0)); } else { //cut off the maximum value output so that there aren't overflow errors grid(i,count)=wfvals.sign(0)*exp(cutoff); } //grid(i,count)=exp(2.0*wfvals(0,1));//!square of wavefunction if (grid(i,count)>max_value) max_value=grid(i,count); if (grid(i,count)<min_value) min_value=grid(i,count); // cout << "grid " << grid(i,count)<< " " << xyz(0) << endl; count++; //index for cycling through grid points } } cout.setf(ios::scientific| ios:: showpos); cout <<", max. value "<<max_value<<", min. value "<<min_value<< endl; cout.unsetf(ios::scientific| ios:: showpos); } mywalker->setElectronPos(plots(i)-1, oldpos(plots(i)-1)); } //Loop through and generate plot files for each orbital requested if(plots.GetSize()<=0) error("Number of requested plots is not a positive number"); cout<<"saving data for "<<plots.GetSize()<<" 3D projections of wavefunction"<<endl; for(int i=0; i<plots.GetSize(); i++) { //output to file with orbital number in it char strbuff[40]; sprintf(strbuff, "%d", plots(i)); confile=pltfile = options.runid; confile += ".orb."; pltfile += ".orb."; pltfile += strbuff; confile += strbuff; pltfile += ".cube"; /*FIGURE OUT HOW TO CONVERT INT TO STRING*/ confile += ".xyz"; os.open(pltfile.c_str()); cout<<"writing to "<<pltfile<<endl; os << "QWalk nodes output\n"; os << "Wavefunction single scan with " << plots(i) <<" electron"<<endl; int natoms=sysprop->nIons(); os << " " << natoms+ mywalker->electronSize()-1 << " " << minmax(0) << " " << minmax(2) << " " << minmax(4) << endl; os << D_array1(0) << " " << resolution_array(0) << " 0.0000 0.0000" << endl; os << D_array1(1) << " 0.0000 " << resolution_array(1) << " 0.0000" << endl; os << D_array1(2) << " 0.0000 0.0000 " << resolution_array(2) << endl; Array1 <doublevar> pos(3); for(int at=0; at< natoms; at++) { mywalker->getIonPos(at,pos); os << " " << mywalker->getIonCharge(at) << " 0.0000 " << pos(0) <<" " << pos(1) << " " << pos(2) << endl; } for(int j=0; j<mywalker->electronSize(); j++){ if (j!=plots(i)-1){ if (j<spin_up) os<<" 3 0.0000 "; else os<<" 3 0.0000 "; os<< oldpos(j,0)<<" "<<oldpos(j,1)<<" "<< oldpos(j,2)<<endl; } } os.setf(ios::scientific); for(int j=0; j< D_array1(0)*D_array1(1)*D_array1(2); j++) { os <<setw(16)<<setprecision(8)<<grid(i,j); if(j%6 ==5) os << endl; } os << endl; os.unsetf(ios::scientific); os<<setprecision(6); os.close(); /* old plt file plots // http://www.csc.fi/gopenmol/developers/plt_format.phtml os<<"3 "; //rank=3 always os<<"2\n"; //dummy variable => "Orbital/density surface" //number of grid points for x, y, & z direction os <<D_array1(2)<<" "<<D_array1(1)<<" "<<D_array1(0)<<endl; os <<minmax(4)<<" "<<minmax(5)<<" "<<minmax(2)<<" "<<minmax(3) <<" "<<minmax(0)<<" "<<minmax(1)<<endl; for(int j=0; j<(D_array1(0)*D_array1(1)*D_array1(2)); j++) os<<grid(i,j)<<endl; os.close(); os.open(confile.c_str()); cout<<"writing to "<<confile<<endl; Array1 <doublevar> pos(3); sysprop->getAtomicLabels(atomlabels); os<<atomlabels.size()+ mywalker->electronSize()-1 <<endl; os << endl; for(unsigned int j=0; j<atomlabels.size();j++){ mywalker->getIonPos(j, pos); os<<atomlabels[j] <<" "<< pos(0) <<" "<<pos(1) <<" "<< pos(2)<<endl; } for(int j=0; j<mywalker->electronSize(); j++){ if (j!=plots(i)-1){ if (j<spin_up) os<<"Eu"; else os<<"Ed"; // mywalker->getElectronPos(j, pos); os<<" "<< oldpos(j,0)<<" "<<oldpos(j,1) <<" "<< oldpos(j,2)<<endl; } } os.close(); */ } } else { cout << "Using translation vector(s): "<<endl; for(int i=0;i<dxyz.GetDim(0);i++) cout<<"( "<<dxyz(i,0)<<" , "<<dxyz(i,1)<<" , "<<dxyz(i,2)<<" )"<<endl; for(int i=0; i<plots.GetSize(); i=i+2){ count=0; xyz(0)=minmax(0); xyz(1)=minmax(2); xyz(2)=minmax(4); //init elec probe to xmin ymin zmin //Array1 <doublevar> oldpos(3) cout.width(3); cout <<"============================="<<plots(i)<<" and "<<plots(i+1) <<"==============================" <<endl; for(int xx=0; xx<D_array1(0);xx++){ max_value=min_value=0.0; xyz(0)=minmax(0)+xx*resolution_array(0); xyz2(0)=xyz(0)+dxyz(i/2,0); cout << "x "; cout.precision(5); cout.width(8); cout<< xyz(0); for(int yy=0; yy<D_array1(1);yy++){ xyz(1)=minmax(2)+yy*resolution_array(1); xyz2(1)=xyz(1)+dxyz(i/2,1); for(int zz=0;zz<D_array1(2);zz++){ xyz(2)=minmax(4)+zz*resolution_array(2); xyz2(2)=xyz(2)+dxyz(i/2,2); // mywalker->getElectronPos(plots(i), oldpos); mywalker->setElectronPos(plots(i)-1,xyz);//move elec#plots(i) //to point specified by xyz mywalker->setElectronPos(plots(i+1)-1,xyz2);//move elec#plots(i) //to point specified by xyz wf->updateVal(wfdata, mywalker); //update wfdata wf->getVal(wfdata, 0, wfvals); //get wf value grid(i,count)=wfvals.sign(0)*exp(wfvals.amp(0,0)); //grid(i,count)=exp(2.0*wfvals(0,1));//!square of wavefunction // cout << "grid " << grid(i,count)<< " " << xyz(0) << endl; if (grid(i,count)>max_value) max_value=grid(i,count); if (grid(i,count)<min_value) min_value=grid(i,count); count++; //index for cycling through grid points } } cout.setf(ios::scientific| ios:: showpos); cout <<", max. value "<<max_value<<", min. value "<<min_value<< endl; cout.unsetf(ios::scientific| ios:: showpos); } mywalker->setElectronPos(plots(i)-1, oldpos(plots(i)-1)); mywalker->setElectronPos(plots(i+1)-1, oldpos(plots(i+1)-1)); } //Loop through and generate plot files for each orbital requested if(plots.GetSize()<=0) error("Number of requested plots is not a positive number"); cout<<"saving data for "<<plots.GetSize()<<" 3D projections of wavefunction"<<endl; for(int i=0; i<plots.GetSize(); i=i+2) { char strbuff2[40],strbuff[40]; //output to file with orbital number in it sprintf(strbuff, "%d", plots(i)); sprintf(strbuff2, "%d", plots(i+1)); confile=pltfile = options.runid; confile += ".orb."; pltfile += ".orb."; pltfile += strbuff; confile += strbuff; pltfile += "with"; confile += "with"; pltfile += strbuff2; confile += strbuff2; pltfile += ".cube"; /*FIGURE OUT HOW TO CONVERT INT TO STRING*/ confile += ".xyz"; os.open(pltfile.c_str()); cout<<"writing to "<<pltfile<<endl; os << "GOS nodes output\n"; os << "Wave function double scan with "<< plots(i) <<" & "<<plots(i+1)<<" electrons"<< endl; int natoms=sysprop->nIons(); os << " " << natoms + mywalker->electronSize()-2 << " " << minmax(0) << " " << minmax(2) << " " << minmax(4) << endl; os << D_array1(0) << " " << resolution_array(0) << " 0.0000 0.0000" << endl; os << D_array1(1) << " 0.0000 " << resolution_array(1) << " 0.0000" << endl; os << D_array1(2) << " 0.0000 0.0000 " << resolution_array(2) << endl; Array1 <doublevar> pos(3); for(int at=0; at< natoms; at++) { mywalker->getIonPos(at,pos); os << " " << mywalker->getIonCharge(at) << " 0.0000 " << pos(0) <<" " << pos(1) << " " << pos(2) << endl; } for(int j=0; j<mywalker->electronSize(); j++){ if ((j!=plots(i)-1)&&(j!=plots(i+1)-1)){ if (j<spin_up) os<<" 3 0.0000 "; else os<<" 3 0.0000 "; os<< oldpos(j,0)<<" "<<oldpos(j,1)<<" "<< oldpos(j,2)<<endl; } } os.setf(ios::scientific); for(int j=0; j< D_array1(0)*D_array1(1)*D_array1(2); j++) { os << setw(16) << setprecision(8) << grid(i,j); if(j%6 ==5) os << endl; } os << endl; os.unsetf(ios::scientific); os<<setprecision(6); os.close(); /* old plot to plt file version // http://www.csc.fi/gopenmol/developers/plt_format.phtml os<<"3 "; //rank=3 always os<<"2\n"; //dummy variable => "Orbital/density surface" //number of grid points for x, y, & z direction os <<D_array1(2)<<" "<<D_array1(1)<<" "<<D_array1(0)<<endl; os <<minmax(4)<<" "<<minmax(5)<<" "<<minmax(2)<<" "<<minmax(3) <<" "<<minmax(0)<<" "<<minmax(1)<<endl; for(int j=0; j<(D_array1(0)*D_array1(1)*D_array1(2)); j++) os<<grid(i,j)<<endl; os.close(); os.open(confile.c_str()); cout<<"writing to "<<confile<<endl; Array1 <doublevar> pos(3); sysprop->getAtomicLabels(atomlabels); os<<atomlabels.size()+ mywalker->electronSize()-2 <<endl; os << endl; for(unsigned int j=0; j<atomlabels.size();j++){ mywalker->getIonPos(j, pos); os<<atomlabels[j] <<" "<< pos(0) <<" "<<pos(1) <<" "<< pos(2)<<endl; } for(int j=0; j<mywalker->electronSize(); j++){ if ((j!=plots(i)-1)&&(j!=plots(i+1)-1)){ if (j<spin_up) os<<"Eu"; else os<<"Ed"; // mywalker->getElectronPos(j, pos); os<<" "<< oldpos(j,0)<<" "<<oldpos(j,1) <<" "<< oldpos(j,2)<<endl; } } os.close(); */ } } cout <<"End of Nodes Method"<<endl; }
void akGeometryDeformer::DLBAntipodalitySkinningUniformScale( const btAlignedObjectArray<akMatrix4>* mpalette, const btAlignedObjectArray<akDualQuat>* dqpalette, const UTsize vtxCount, const float* weights, const UTsize weightsStride, const UTuint8* indices, const UTsize indicesStride, const akVector3* vtxSrc, const UTsize vtxSrcStride, akVector3* vtxDst, const UTsize vtxDstStride, const akVector3* normSrc, const UTsize normSrcStride, akVector3* normDst, const UTsize normDstStride) { const btAlignedObjectArray<akMatrix4>& matrices = *mpalette; const btAlignedObjectArray<akDualQuat>& dquats = *dqpalette; for(unsigned int i=0; i<vtxCount; i++) { // positions 1st pass for non rigid part of the transformation using matrices akMatrix4 mat(matrices[indices[0]] * weights[0]); if (weights[1]) mat += matrices[indices[1]] * weights[1]; if (weights[2]) mat += matrices[indices[2]] * weights[2]; if (weights[3]) mat += matrices[indices[3]] * weights[3]; akVector3 tmpPos = (mat * akVector4(*vtxSrc, 1.f)).getXYZ(); akDualQuat dq0 = dquats[indices[0]]; akDualQuat dq1 = dquats[indices[1]]; akDualQuat dq2 = dquats[indices[2]]; akDualQuat dq3 = dquats[indices[3]]; if( dot(dq0.n, dq1.n) < 0.0) dq1 *= -1.0; if( dot(dq0.n, dq2.n) < 0.0) dq2 *= -1.0; if( dot(dq0.n, dq3.n) < 0.0) dq3 *= -1.0; akDualQuat dq = dq0 * weights[0]; if (weights[1]) dq += dq1 * weights[1]; if (weights[2]) dq += dq2 * weights[2]; if (weights[3]) dq += dq3 * weights[3]; dq /= length(dq.n); akVector3 ndxyz(dq.n.getXYZ()); akVector3 dxyz(dq.d.getXYZ()); //position 2nd pass *vtxDst = tmpPos + 2.0 * cross( ndxyz, cross(ndxyz, tmpPos) + dq.n.getW() * tmpPos ) + 2.0 * ( dq.n.getW() * dxyz - dq.d.getW() * ndxyz + cross(ndxyz, dxyz) ); // normal 1rst pass akVector3 tmpNor = (mat * akVector4(*normSrc, 1.f)).getXYZ(); // normal 2nd pass *normDst = tmpNor + 2.0 * cross( ndxyz, cross(ndxyz, tmpNor) + dq.n.getW() * tmpNor ); *normDst = normalize(*normDst); akAdvancePointer(normSrc, normSrcStride); akAdvancePointer(normDst, normDstStride); akAdvancePointer(weights, weightsStride); akAdvancePointer(indices, indicesStride); akAdvancePointer(vtxSrc, vtxSrcStride); akAdvancePointer(vtxDst, vtxDstStride); } }