void MPC::init_f_G() { int numG = Gints.size(); f_G.resize(numG); int N = max(64, 2*MaxDim+1); vector<double> g_G_N(numG), g_G_2N(numG), g_G_4N(numG); double g_0_N, g_0_2N, g_0_4N; compute_g_G(g_0_N , g_G_N, 1*N); compute_g_G(g_0_2N, g_G_2N, 2*N); compute_g_G(g_0_4N, g_G_4N, 4*N); // fprintf (stderr, "g_G_1N[0] = %18.14e\n", g_G_N[0]); // fprintf (stderr, "g_G_2N[0] = %18.14e\n", g_G_2N[0]); // fprintf (stderr, "g_G_4N[0] = %18.14e\n", g_G_4N[0]); double volInv = 1.0/PtclRef->Lattice.Volume; double L = PtclRef->Lattice.WignerSeitzRadius; TinyVector<double,2> g0_12 (g_0_2N, g_0_4N); TinyVector<double,3> g0_124 (g_0_N, g_0_2N, g_0_4N); f_0 = extrap (N, g0_124); app_log().precision(12); app_log() << " Linear extrap = " << std::scientific << extrap (2*N, g0_12) << endl; app_log() << " Quadratic extrap = " << std::scientific << f_0 << endl; f_0 += 0.4*M_PI*L*L*volInv; // cerr << "f_0 = " << f_0/volInv << endl; double worst = 0.0, worstLin, worstQuad; int iworst = 0; for (int iG=0; iG<numG; iG++) { TinyVector<double,2> g_12 (g_G_2N[iG], g_G_4N[iG]); TinyVector<double,3> g_124 (g_G_N [iG], g_G_2N[iG], g_G_4N[iG]); double linearExtrap = extrap (2*N, g_12); double quadExtrap = extrap (N, g_124); double diff = std::fabs(linearExtrap - quadExtrap); if (diff > worst) { worst = diff; iworst = iG; worstLin = linearExtrap; worstQuad = quadExtrap; } f_G[iG] = quadExtrap; double G2 = dot(Gvecs[iG], Gvecs[iG]); double G = std::sqrt(G2); f_G[iG] += volInv*M_PI*(4.0/G2 + 12.0/(L*L*G2*G2)* (std::cos(G*L) - std::sin(G*L)/(G*L))); // cerr << "f_G = " << f_G[iG]/volInv << endl; // cerr << "f_G - 4*pi/G2= " << f_G[iG]/volInv - 4.0*M_PI/G2 << endl; } char buff[1000]; snprintf (buff, 1000 , " Worst MPC discrepancy:\n" " Linear Extrap : %18.14e\n" " Quadratic Extrap: %18.14e\n", worstLin, worstQuad); app_log() << buff; }
inline float key_extrap(float input, const vector<XObjKey>& table, int n) { if (table.empty()) return 0.0f; if (table.size() == 1) return table.front().v[n]; if (table.size() == 2) return extrap(table[0].key,table[0].v[n],table[1].key,table[1].v[n],input); vector<XObjKey>::const_iterator i = std::lower_bound(table.begin(), table.end(), input, compare_key()); vector<XObjKey>::const_iterator p1, p2; if (i == table.end()) { p1 = i-2; p2 = i-1; } else if (i->key == input) { return i->v[n]; } else if (i == table.begin()) { p1 = i; p2 = i+1; } else { p1 = i-1; p2 = i; } return extrap(p1->key,p1->v[n],p2->key,p2->v[n], input); }