/** * @brief This function recalculates the routing in and around the box bounded by min and max. * @sa CMod_LoadRouting * @sa Grid_RecalcRouting * @param[in] mapTiles List of tiles the current (RMA-)map is composed of * @param[in] routing The routing map (either server or client map) * @param[in] box The box to recalc routing for * @param[in] list The local models list (a local model has a name starting with * followed by the model number) */ void Grid_RecalcBoxRouting (mapTiles_t *mapTiles, Routing &routing, const GridBox &box, const char **list) { int x, y, z, actorSize, dir; /* check unit heights */ for (actorSize = 1; actorSize <= ACTOR_MAX_SIZE; actorSize++) { GridBox rBox(box); /* the box we will actually reroute */ /* Offset the initial X and Y to compensate for larger actors when needed. */ rBox.expandXY(actorSize - 1); /* also start one level above the box to measure high floors correctly */ rBox.addOneZ(); for (y = rBox.mins[1]; y <= rBox.maxs[1]; y++) { for (x = rBox.mins[0]; x <= rBox.maxs[0]; x++) { /** @note RT_CheckCell goes from top (7) to bottom (0) */ for (z = rBox.maxs[2]; z >= 0; z--) { const int newZ = RT_CheckCell(mapTiles, routing, actorSize, x, y, z, list); assert(newZ <= z); z = newZ; } } } } /* check connections */ for (actorSize = 1; actorSize <= ACTOR_MAX_SIZE; actorSize++) { GridBox rBox(box); /* the box we will actually reroute */ rBox.expandXY(actorSize); /* for connections, expand by the full size of the actor */ for (y = rBox.mins[1]; y <= rBox.maxs[1]; y++) { for (x = rBox.mins[0]; x <= rBox.maxs[0]; x++) { for (dir = 0; dir < CORE_DIRECTIONS; dir++) { /** @note The new version of RT_UpdateConnectionColumn can work bidirectional, so we can * trace every other dir, unless we are on the edge. */ #if RT_IS_BIDIRECTIONAL == 1 if ((dir & 1) && x != minX && x != maxX && y != minY && y != maxY) continue; #endif /* for places outside the model box, skip dirs that can not be affected by the model */ if (x > box.maxs[0] && dir != 1 && dir != 5 && dir != 6) continue; if (y > box.maxs[1] && dir != 3 && dir != 5 && dir != 7) continue; if (actorSize == ACTOR_SIZE_NORMAL) { if (x < box.mins[0] && dir != 0 && dir != 4 && dir != 7) continue; if (y < box.mins[1] && dir != 2 && dir != 4 && dir != 6) continue; } else { /* the position of 2x2 actors is their lower left cell */ if (x < box.mins[0] - 1 && dir != 0 && dir != 4 && dir != 7) continue; if (y < box.mins[1] - 1 && dir != 2 && dir != 4 && dir != 6) continue; } RT_UpdateConnectionColumn(mapTiles, routing, actorSize, x, y, dir, list); } } } } }
/** * @brief This function recalculates the routing in and around the box bounded by min and max. * @sa CMod_LoadRouting * @sa Grid_RecalcRouting * @param[in] mapTiles List of tiles the current (RMA-)map is composed of * @param[in] routing The routing map (either server or client map) * @param[in] box The box to recalc routing for * @param[in] list The local models list (a local model has a name starting with * followed by the model number) */ void Grid_RecalcBoxRouting (mapTiles_t* mapTiles, Routing& routing, const GridBox& box, const char** list) { int x, y, z, actorSize, dir; /* check unit heights */ for (actorSize = 1; actorSize <= ACTOR_MAX_SIZE; actorSize++) { GridBox rBox(box); /* the box we will actually reroute */ /* Offset the initial X and Y to compensate for larger actors when needed. */ rBox.expandXY(actorSize - 1); /* also start one level above the box to measure high floors correctly */ rBox.addOneZ(); for (y = rBox.getMinY(); y <= rBox.getMaxY(); y++) { for (x = rBox.getMinX(); x <= rBox.getMaxX(); x++) { /** @note RT_CheckCell goes from top (7) to bottom (0) */ for (z = rBox.getMaxZ(); z >= 0; z--) { const int newZ = RT_CheckCell(mapTiles, routing, actorSize, x, y, z, list); assert(newZ <= z); z = newZ; } } } } /* check connections */ for (actorSize = 1; actorSize <= ACTOR_MAX_SIZE; actorSize++) { GridBox rBox(box); /* the box we will actually reroute */ rBox.expandXY(actorSize); /* for connections, expand by the full size of the actor */ rBox.addOneZ(); for (y = rBox.getMinY(); y <= rBox.getMaxY(); y++) { for (x = rBox.getMinX(); x <= rBox.getMaxX(); x++) { for (dir = 0; dir < CORE_DIRECTIONS; dir++) { /* for places outside the model box, skip dirs that can not be affected by the model */ if (x > box.getMaxX() && dir != 1 && dir != 5 && dir != 6) continue; if (y > box.getMaxY() && dir != 3 && dir != 5 && dir != 7) continue; if (actorSize == ACTOR_SIZE_NORMAL) { if (x < box.getMinX() && dir != 0 && dir != 4 && dir != 7) continue; if (y < box.getMinY() && dir != 2 && dir != 4 && dir != 6) continue; } else { /* the position of 2x2 actors is their lower left cell */ if (x < box.getMinX() - 1 && dir != 0 && dir != 4 && dir != 7) continue; if (y < box.getMinY() - 1 && dir != 2 && dir != 4 && dir != 6) continue; } // RT_UpdateConnectionColumn(mapTiles, routing, actorSize, x, y, dir, list); RT_UpdateConnectionColumn(mapTiles, routing, actorSize, x, y, dir, list, rBox.getMinZ(), rBox.getMaxZ()); } } } } }
void MPC::compute_g_G(double &g_0, vector<double> &g_G, int N) { double L = PtclRef->Lattice.WignerSeitzRadius; double Linv = 1.0/L; double Linv3 = Linv*Linv*Linv; // create an FFTW plan Array<complex<double>,3> rBox(N,N,N); Array<complex<double>,3> GBox(N,N,N); // app_log() << "Doing " << N << " x " << N << " x " << N << " FFT.\n"; //create BC handler DTD_BConds<double,3,SUPERCELL_BULK> mybc(PtclRef->Lattice); // Fill the real-space array with f(r) double Ninv = 1.0/(double)N; TinyVector<double,3> u, r; for (int ix=0; ix<N; ix++) { u[0] = Ninv*ix; for (int iy=0; iy<N; iy++) { u[1] = Ninv*iy; for (int iz=0; iz<N; iz++) { u[2] = Ninv*iz; r = PtclRef->Lattice.toCart (u); //DTD_BConds<double,3,SUPERCELL_BULK>::apply (PtclRef->Lattice, r); //double rmag = std::sqrt(dot(r,r)); double rmag = std::sqrt(mybc.apply_bc(r)); if (rmag < L) rBox(ix,iy,iz) = -0.5*rmag*rmag*Linv3 + 1.5*Linv; else rBox(ix,iy,iz) = 1.0/rmag; } } } fftw_plan fft = fftw_plan_dft_3d (N, N, N, (fftw_complex*)rBox.data(), (fftw_complex*) GBox.data(), 1, FFTW_ESTIMATE); fftw_execute (fft); fftw_destroy_plan (fft); // Now, copy data into output, and add on analytic part double norm = Ninv*Ninv*Ninv; int numG = Gints.size(); for (int iG=0; iG < numG; iG++) { TinyVector<int,OHMMS_DIM> gint = Gints[iG]; for (int j=0; j<OHMMS_DIM; j++) gint[j] = (gint[j] + N)%N; g_G[iG] = norm * real(GBox(gint[0], gint[1], gint[2])); } g_0 = norm * real(GBox(0,0,0)); }
void MPC::init_spline() { Array<complex<double>,3> rBox(SplineDim[0], SplineDim[1], SplineDim[2]), GBox(SplineDim[0], SplineDim[1], SplineDim[2]); Array<double,3> splineData(SplineDim[0], SplineDim[1], SplineDim[2]); GBox = complex<double>(); Vconst = 0.0; // Now fill in elements of GBox double vol = PtclRef->Lattice.Volume; double volInv = 1.0/vol; for (int iG=0; iG < Gvecs.size(); iG++) { TinyVector<int,OHMMS_DIM> gint = Gints[iG]; PosType G = Gvecs[iG]; double G2 = dot(G,G); TinyVector<int,OHMMS_DIM> index; for (int j=0; j<OHMMS_DIM; j++) index[j] = (gint[j] + SplineDim[j]) % SplineDim[j]; if (!(index[0]==0 && index[1]==0 && index[2]==0)) { GBox(index[0], index[1], index[2]) = vol * Rho_G[iG] * (4.0*M_PI*volInv/G2 - f_G[iG]); Vconst -= 0.5 * vol * vol * norm(Rho_G[iG]) * (4.0*M_PI*volInv/G2 - f_G[iG]); } } // G=0 component calculated seperately GBox(0,0,0) = -vol * f_0 * Rho_G[0]; Vconst += 0.5 * vol * vol * f_0 * norm(Rho_G[0]); app_log() << " Constant potential = " << Vconst << endl; fftw_plan fft = fftw_plan_dft_3d (SplineDim[0], SplineDim[1], SplineDim[2], (fftw_complex*)GBox.data(), (fftw_complex*) rBox.data(), -1, FFTW_ESTIMATE); fftw_execute (fft); fftw_destroy_plan (fft); for (int i0=0; i0<SplineDim[0]; i0++) for (int i1=0; i1<SplineDim[1]; i1++) for (int i2=0; i2<SplineDim[2]; i2++) splineData(i0, i1, i2) = real(rBox(i0,i1,i2)); BCtype_d bc0, bc1, bc2; Ugrid grid0, grid1, grid2; grid0.start=0.0; grid0.end=1.0; grid0.num = SplineDim[0]; grid1.start=0.0; grid1.end=1.0; grid1.num = SplineDim[1]; grid2.start=0.0; grid2.end=1.0; grid2.num = SplineDim[2]; bc0.lCode = bc0.rCode = PERIODIC; bc1.lCode = bc1.rCode = PERIODIC; bc2.lCode = bc2.rCode = PERIODIC; VlongSpline = create_UBspline_3d_d (grid0, grid1, grid2, bc0, bc1, bc2, splineData.data()); // grid0.num = PtclRef->Density_r.size(0); // grid1.num = PtclRef->Density_r.size(1); // grid2.num = PtclRef->Density_r.size(2); // DensitySpline = create_UBspline_3d_d (grid0, grid1, grid2, bc0, bc1, bc2, // PtclRef->Density_r.data()); }