WOSPotential::ValueType WOSPotential::method4(ParticleSet& P) { double V0 = 0.0; WP->setP(P); Domain domain; double pe = 0.0; double dpe = 0.0; int hfruns = m_runs/2; for(int irun = 0; irun < hfruns; irun++) { domain.runner = WP->R0; /// initialise runner domain.in_device = true; /// runner is inside device device->MaximumSphere(domain); /// calc d_{0} domain.WalkOnSphere(); posvec_t r1(-domain.runner[0],-domain.runner[1],-domain.runner[2]); double vD0 = device->OC_contrib0(domain.radius,domain.runner,WP); double vbare = device->OC_passage(V0,domain,WP); WP->calcwt(); double vol = 0.0; while(domain.in_device) { device->MaximumSphere(domain); vol += device->contribk(domain,WP); domain.WalkOnSphere(); vbare += device->OC_passage(V0,domain,WP); } vol *= WP->qwt; /// the half has been included double vrun = vol + vbare + vD0; pe += vrun; dpe += vrun * vrun; domain.runner = WP->R0; /// initialise runner domain.in_device = true; /// runner is inside device device->MaximumSphere(domain); /// calc d_{0} domain.runner = r1; //domain.WalkOnSphere(); vD0 = device->OC_contrib0(domain.radius,domain.runner,WP); vbare = device->OC_passage(V0,domain,WP); WP->calcwt(); vol = 0.0; while(domain.in_device) { device->MaximumSphere(domain); vol += device->contribk(domain,WP); domain.WalkOnSphere(); vbare += device->OC_passage(V0,domain,WP); } vol *= WP->qwt; /// the half has been included vrun = vol + vbare + vD0; pe += vrun; dpe += vrun * vrun; } pe *= m_norm; dpe *= m_norm; dpe = sqrt(m_norm * fabs ( dpe - pe * pe )); cout << pe << '\t' << dpe << endl; exit(-1); return pe; }
void HeteroStructure::sample_point(Domain& domain){ calc_dfrac(domain); sample_prob(domain); int nlayers = layers.size(); double phi = 2.0 * M_PI * Random(); double rnd = Random(); double hop = Random(); for( int ilayer = 0; ilayer < nlayers; ilayer++){ if ( hop <= layers[ilayer]->prob_d){ double theta = acos( ( 1.0 - rnd ) * interfaces[ ilayer + 1 ]->d_frac + rnd * interfaces[ ilayer ]->d_frac ); domain.WalkOnSphere( theta, phi ); return; } } for(int ilayer = 0; ilayer < nlayers; ilayer++){ if(hop <= interfaces[ilayer]->prob_d){ double d = fabs( interfaces[ilayer]->d_frac ); double denom = 1.0 - ( 1.0 - d ) * rnd; denom = denom * denom; double rho = domain.radius * d * sqrt( 1.0 / denom - 1.0 ); weight_bc *= interfaces[ ilayer ]->xsign; domain.WalkOnDisk( rho, phi, interfaces[ ilayer ]->z_val ); return; } } }
WOSPotential::ValueType WOSPotential::method0(ParticleSet& P) { WP->setP(P); Domain domain; double pe = 0.0; double dpe = 0.0; double tau = 0.01; double v0 = -8.709; double branch = 0.0; for(int irun = 0; irun < m_runs; irun++) { double vrun = 0.0; for(int i = 0; i < WP->m_qpts; i++) /// start run { domain.runner = WP->R[i]; domain.in_device = true; device->MaximumSphere(domain); double vi = device->contrib0(i,domain,WP); domain.WalkOnSphere(); double vbare = device->passage(domain); while(domain.in_device) { device->MaximumSphere(domain); vi += device->contribk(domain,WP); domain.WalkOnSphere(); vbare += device->passage(domain); } /// end walk: runner on boundary vi = WP->Q[i] * ( 0.5 * vi + vbare ); vrun += vi; } /// end run/particle loop pe += vrun; dpe += vrun * vrun; /// collect statistics branch += exp(-(vrun-v0)*tau); } /// end runners-loop /// compute estimates pe *= m_norm; branch *= m_norm; dpe *= m_norm; double var = dpe - pe*pe; dpe = sqrt(m_norm * fabs ( dpe - pe * pe )); cout << "basic: " << pe << '\t' << dpe << '\t' << branch << '\t' << branch*exp(-0.5*var*tau*tau) << endl; exit(-1); return pe; }
/// correlated sampling WOSPotential::ValueType WOSPotential::method2(ParticleSet& P) { double V0 = 0; /// intialise the particles in WP; WP->setP(P); Domain domain; /// create domain; double pe = 0.0; double dpe = 0.0; for(int irun = 0; irun < m_runs; irun++) { domain.runner = WP->R0; /// initialise runner domain.in_device = true; /// runner is inside device device->MaximumSphere(domain); /// calc d_{0} domain.WalkOnSphere(); double vD0 = device->OC_contrib0(domain.radius,domain.runner,WP); double vbare = device->OC_passage(V0,domain,WP); WP->calcwt(); double vol = 0.0; while(domain.in_device) { device->MaximumSphere(domain); vol += device->contribk(domain,WP); domain.WalkOnSphere(); vbare += device->OC_passage(V0,domain,WP); } vol *= WP->qwt; /// the half has been included double vrun = vol + vbare + vD0; pe += vrun; dpe += vrun * vrun; } pe *= m_norm; dpe *= m_norm; dpe = ( dpe - pe * pe )/static_cast<double>(m_runs-1); /// CHANGE FOR DMC, WARNING Tau is zero for VMC WOS pe += dpe * Tau; // sigma^2 * Tau // cout << "VWOS: "<< pe << '\t' << Tau << endl; P.Properties(WOSVAR) = -dpe; //P.Properties(WOSVAR) = dpe; return pe; }
WOSPotential::ValueType WOSPotential::method5(ParticleSet& P) { static const double V0 = 0; /// intialise the particles in WP; WP->setP(P); Domain domain; /// create domain; double branch = 0.0; double tau = 0.01; double v0 = -8.709; double pe = 0.0; double dpe = 0.0; for(int irun = 0; irun < m_runs; irun++) { domain.runner = WP->R0; /// initialise runner domain.in_device = true; /// runner is inside device device->MaximumSphere(domain); /// calc d_{0} // domain.WalkOnSphere(); double Gwt = domain.ImportanceWalk(); double vD0 = device->OC_contrib0(domain.radius,domain.runner,WP); double vbare = device->OC_passage(V0,domain,WP); WP->calcwt(); double vol = 0.0; while(domain.in_device) { device->MaximumSphere(domain); vol += device->contribk(domain,WP); domain.WalkOnSphere(); vbare += device->OC_passage(V0,domain,WP); } vol *= WP->qwt; /// the half has been included // double vrun = vol + vbare + vD0; double vrun = 0.25*(vol + vbare)/Gwt + vD0; pe += vrun; dpe += vrun * vrun; // cout << vrun << '\t' << v0 << '\t' << branch << endl; } pe *= m_norm; branch *= m_norm; dpe *= m_norm; dpe = sqrt(m_norm * fabs ( dpe - pe * pe )); double var = dpe - pe * pe; cout << "correlated: " << pe << '\t' << dpe << '\t' << var << '\t' << branch << '\t' << branch*exp(-0.5*var*tau*tau) << endl; exit(-1); return pe; }
/// importance sampling WOSPotential::ValueType WOSPotential::method3(ParticleSet& P) { WP->setP(P); Domain domain; double pe = 0.0; double dpe = 0.0; for(int irun = 0; irun < m_runs; irun++) { double vrun = 0.0; for(int i = 0; i < WP->m_qpts; i++) /// start run { domain.runner = WP->R[i]; domain.in_device = true; device->MaximumSphere(domain); double vi = device->contrib0(i,domain,WP); double Gwt = domain.ImportanceWalk(); double vbare = device->passage(domain); double vol = 0.0; while(domain.in_device) { device->MaximumSphere(domain); vol += device->contribk(domain,WP); domain.WalkOnSphere(); vbare += device->passage(domain); } /// end walk: runner on boundary // vi = 0.0; vol = 0.0; vi = WP->Q[i] * (0.25*( 0.5 * vol + vbare )/Gwt + 0.5*vi); vrun += vi; } /// end run/particle loop pe += vrun; dpe += vrun * vrun; /// collect statistics } /// end runners-loop /// compute estimates pe *= m_norm; dpe *= m_norm; dpe = sqrt(m_norm * fabs ( dpe - pe * pe )); double var = dpe - pe * pe; cout << "importance: " << pe << '\t' << dpe << '\t' << var << endl; exit(-1); return pe; }
/// Antithetic variates WOSPotential::ValueType WOSPotential::method1(ParticleSet& P) { WP->setP(P); Domain domain; double pe = 0.0; double dpe = 0.0; int hfruns = m_runs/2; double h_norm = 1.0/double(hfruns); for(int irun = 0; irun < hfruns; irun++) { double vrun = 0.0; for(int i = 0; i < WP->m_qpts; i++) { domain.runner = WP->R[i]; domain.in_device = true; device->MaximumSphere(domain); double vi = device->contrib0(i,domain,WP); domain.WalkOnSphere(); /// store the antithetic pair (refelcted about particle position) posvec_t r1(2*WP->R[i][0]-domain.runner[0], 2*WP->R[i][1]-domain.runner[1], 2*WP->R[i][2]-domain.runner[2]); double vbare = device->passage(domain); while(domain.in_device) { device->MaximumSphere(domain); vi += device->contribk(domain,WP); domain.WalkOnSphere(); vbare += device->passage(domain); } vi = WP->Q[i] * ( 0.5 * vi + vbare ); vrun += vi; /// since there will be a pair of runners domain.runner = WP->R[i]; domain.in_device = true; device->MaximumSphere(domain); vi = device->contrib0(i,domain,WP); //domain.WalkOnSphere(); domain.runner = r1; vbare = device->passage(domain); while(domain.in_device) { device->MaximumSphere(domain); vi += device->contribk(domain,WP); domain.WalkOnSphere(); vbare += device->passage(domain); } vi = WP->Q[i] * ( 0.5 * vi + vbare ); vrun += vi; } /// end run/particle loop vrun *= 0.5; /// since we used the antithetic pair. pe += vrun; dpe += vrun * vrun; } pe *= h_norm; dpe *= h_norm; dpe = sqrt(h_norm * fabs( dpe - pe * pe )); // cout << "antithetic: " << pe << '\t' << dpe << endl; // exit(-1); return pe; }
/// correlated sampling WOSPotential::ValueType WOSPotential::method6(ParticleSet& P) { double V0 = 0; /// intialise the particles in WP; WP->setP(P); Domain domain; /// create domain; double pe = 0.0; double dpe = 0.0; for(int irun = 0; irun < m_runs; irun++) { domain.runner = WP->R0; /// initialise runner domain.in_device = true; /// runner is inside device device->MaximumSphere(domain); /// calc d_{0} domain.WalkOnSphere(); double vD0 = device->OC_contrib0(domain.radius,domain.runner,WP); double vbare = device->OC_passage(V0,domain,WP); WP->calcwt(); double vol = 0.0; while(domain.in_device) { device->MaximumSphere(domain); vol += device->contribk(domain,WP); domain.WalkOnSphere(); vbare += device->OC_passage(V0,domain,WP); } vol *= WP->qwt; /// the half has been included double vrun = vol + vbare + vD0; pe += vrun; dpe += vrun * vrun; } pe *= m_norm; dpe *= m_norm; dpe = ( dpe - pe * pe )/static_cast<double>(m_runs-1); double stsq = dpe * Tau * Tau; double correction = 1.0 + stsq * (0.25 + stsq / static_cast<double>(3*(m_runs+3)) ) / static_cast<double>(2*(m_runs+1)); /// CHANGE FOR DMC, WARNING Tau is zero for VMC WOS // pe += dpe * Tau; // sigma^2 * Tau double pe1 = 0.0; double dpe1 = 0.0; for(int irun = 0; irun < 1; irun++) { domain.runner = WP->R0; /// initialise runner domain.in_device = true; /// runner is inside device device->MaximumSphere(domain); /// calc d_{0} domain.WalkOnSphere(); double vD0 = device->OC_contrib0(domain.radius,domain.runner,WP); double vbare = device->OC_passage(V0,domain,WP); WP->calcwt(); double vol = 0.0; while(domain.in_device) { device->MaximumSphere(domain); vol += device->contribk(domain,WP); domain.WalkOnSphere(); vbare += device->OC_passage(V0,domain,WP); } vol *= WP->qwt; /// the half has been included double vrun = vol + vbare + vD0; pe1 += vrun; dpe1 += vrun * vrun; } //pe1 *= m_norm; P.Properties(WOSVAR) = 2*(pe - pe1)/Tau + dpe;// * correction; return pe1; }