Changeset dfed1c for src/interface
- Timestamp:
- Nov 22, 2011, 9:22:10 PM (14 years ago)
- Children:
- facba0
- Parents:
- 66f24d
- Location:
- src/interface
- Files:
-
- 2 added
- 2 deleted
- 6 edited
-
interface.cpp (modified) (2 diffs)
-
interface.hpp (modified) (4 diffs)
-
interface_fcs.cpp (modified) (8 diffs)
-
interface_fcs.h (modified) (1 diff)
-
interface_particles.cpp (modified) (5 diffs)
-
interface_particles.hpp (modified) (2 diffs)
-
interface_particles_cf.cpp (added)
-
interface_particles_cf.hpp (added)
-
interface_vtk.cpp (deleted)
-
interface_vtk.hpp (deleted)
Legend:
- Unmodified
- Added
- Removed
-
src/interface/interface.cpp
r66f24d rdfed1c 12 12 #endif 13 13 14 #include <algorithm> 14 15 #include <cmath> 15 16 … … 19 20 using namespace VMG; 20 21 21 Interface::Interface(BC boundary, int levelMin_, int levelMax_, vmg_float box_begin_, vmg_float box_end_,22 int coarseningSteps, vmg_floatalpha)22 void Interface::InitInterface(const Vector& box_offset, const vmg_float& box_size, 23 const int& coarseningSteps, const vmg_float& alpha) 23 24 { 24 bc = boundary; 25 levelMin = levelMin_; 26 levelMax = levelMax_; 25 Index size_factor_max = 1; 26 int num_cells; 27 27 28 bool restricted = false;28 const Vector box_center = box_offset + 0.5 * box_size; 29 29 30 const vmg_float box_center = 0.5 * (box_begin_ + box_end_); 31 const vmg_float box_size = box_end_ - box_begin_; 32 33 for (int i=0; i<coarseningSteps; ++i) { 30 for (int i=levelMax; i>=levelMin; --i) { 34 31 35 32 global.push_back(GlobalIndices()); 36 33 extent.push_back(SpatialExtent()); 37 34 38 extent.back().SizeFactor() = Helper::intpow(2, static_cast<int>(log(pow(alpha, i+1)) / log(2.0) + 1.0));35 num_cells = Helper::intpow(2, i); 39 36 40 extent.back().Size() = box_size * static_cast<Vector>(extent.back().SizeFactor()); 41 extent.back().Begin() = box_center - 0.5 * extent.back().Size(); 42 extent.back().End() = extent.back().Begin() + extent.back().Size(); 43 extent.back().MeshWidth() = pow(2.0, i-levelMax); 37 extent.back().SizeFactor() = 1; 38 extent.back().Size() = box_size; 39 extent.back().Begin() = box_offset; 40 extent.back().End() = box_offset + box_size; 41 extent.back().MeshWidth() = box_size / num_cells; 44 42 45 global.back().Size() = static_cast<Index>(static_cast<Vector>(extent.back().Size()) / extent.back().MeshWidth() + 0.5) + 1; 46 global.back().Begin() = 0; 47 global.back().End() = global.back().Size(); 43 global.back().SizeGlobal() = num_cells + 1; 44 global.back().SizeLocal() = num_cells + 1; 45 global.back().BeginFinest() = 0; 46 global.back().BeginLocal() = 0; 47 global.back().EndLocal() = num_cells + 1; 48 49 if (i == levelMax) { 50 global.back().SizeFinest() = num_cells + 1; 51 global.back().EndFinest() = num_cells + 1; 52 global.back().BoundaryType() = GlobalMax; 53 }else { 54 global.back().SizeFinest() = (++global.rbegin())->SizeFinest(); 55 global.back().EndFinest() = (++global.rbegin())->SizeFinest(); 56 global.back().BoundaryType() = GlobalCoarsened; 57 } 48 58 49 59 } 50 60 51 for (int i=0; i<coarseningSteps; ++i) { 52 53 if (restricted) { 54 global[i].BoundaryType() = GlobalCoarsened; 55 }else if (extent[i].SizeFactor() == extent.back().SizeFactor()) { 56 global[i].BoundaryType() = GlobalMax; 57 restricted = true; 58 }else { 59 global[i].BoundaryType() = LocallyRefined; 60 } 61 62 if (i==0) { 63 global[0].AlignmentBegin() = (global[0].Size() - static_cast<int>( pow(2.0, levelMax) + 0.5) - 1) / 2; 64 }else if (global[i].BoundaryType() == LocallyRefined) 65 global[i].AlignmentBegin() = (extent[i].Size() - extent[i-1].Size()) * pow(2.0, levelMax-i-1) + 0.5; 66 else if (global[i].BoundaryType() == GlobalMax) 67 global[i].AlignmentBegin() = (extent[i].Size() - extent[i-1].Size()) * pow(2.0, levelMax-i-1) - 0.5; 68 else 69 global[i].AlignmentBegin() = 0; 70 71 global[i].AlignmentEnd() = global[i].Size() - global[i].AlignmentBegin(); 72 } 73 74 while (global.size() == 0 || global.back().Size().Max() > Helper::intpow(2,levelMin)+1) { 75 76 global.push_back(GlobalIndices()); 77 extent.push_back(SpatialExtent()); 78 79 extent.back().SizeFactor() = (global.size() > 1 ? (++extent.rbegin())->Size() : 1); 80 extent.back().Size() = (global.size() > 1 ? (++extent.rbegin())->Size() : box_size); 81 extent.back().Begin() = box_center - 0.5 * static_cast<Vector>(extent.back().Size()); 82 extent.back().End() = extent.back().Begin() + extent.back().Size(); 83 extent.back().MeshWidth() = pow(2.0, static_cast<int>(global.size())-levelMax-1); 84 85 global.back().Size() = static_cast<Index>(static_cast<Vector>(extent.back().Size()) / extent.back().MeshWidth() + 0.5) + 1; 86 global.back().Begin() = 0; 87 global.back().End() = global.back().Size(); 88 89 if (global.size() > 1) 90 global.back().BoundaryType() = GlobalCoarsened; 91 else 92 global.back().BoundaryType() = GlobalMax; 93 94 global.back().AlignmentBegin() = 0; 95 global.back().AlignmentEnd() = global.back().Size(); 96 97 } 98 99 if (boundary == Periodic) 100 for (std::vector<GlobalIndices>::iterator iter=global.begin(); iter!=global.end(); ++iter) 101 iter->Size() -= 1; 61 for (int i=0; i<3; ++i) 62 if (bc[i] == Periodic) 63 for (unsigned int j=0; j<global.size(); ++j) { 64 global[j].SizeGlobal()[i] -= 1; 65 global[j].SizeFinest()[i] -= Helper::intpow(2, j); 66 global[j].SizeLocal()[i] -= 1; 67 global[j].EndLocal()[i] -= 1; 68 global[j].EndFinest()[i] -= Helper::intpow(2, j); 69 } 102 70 103 71 levelMin = levelMax - global.size() + 1; -
src/interface/interface.hpp
r66f24d rdfed1c 14 14 15 15 #include "base/object.hpp" 16 #include "grid/grid_ indexing.hpp"16 #include "grid/grid_properties.hpp" 17 17 18 18 namespace VMG … … 25 25 { 26 26 public: 27 Interface(BC boundary, int levelMin, int levelMax, vmg_float box_begin, vmg_float box_end, 28 int coarseningSteps=0, vmg_float alpha=1.6); 27 Interface(const Boundary& boundary, const int& levelMin, const int& levelMax, 28 const Vector& box_offset, const vmg_float box_size, 29 int coarseningSteps=0, vmg_float alpha=1.6) : 30 bc(boundary), 31 levelMin(levelMin), 32 levelMax(levelMax) 33 { 34 InitInterface(box_offset, box_size, coarseningSteps, alpha); 35 } 29 36 30 37 virtual ~Interface() {} … … 35 42 const std::vector<GlobalIndices>& Global() const {return global;} 36 43 const std::vector<SpatialExtent>& Extent() const {return extent;} 37 const BC& BoundaryConditions() const {return bc;} 44 45 const GlobalIndices& Global(const int& level) const 46 { 47 return global[levelMax - level]; 48 } 49 50 const SpatialExtent& Extent(const int& level) const 51 { 52 return extent[levelMax - level]; 53 } 54 55 const Boundary& BoundaryConditions() const {return bc;} 38 56 39 57 const int& MinLevel() const {return levelMin;} … … 41 59 42 60 private: 61 void InitInterface(const Vector& box_offset, const vmg_float& box_end, 62 const int& coarseningSteps, const vmg_float& alpha); 63 43 64 std::vector<GlobalIndices> global; 44 65 std::vector<SpatialExtent> extent; 45 66 46 B Cbc;67 Boundary bc; 47 68 48 69 int levelMin, levelMax; -
src/interface/interface_fcs.cpp
r66f24d rdfed1c 19 19 20 20 #include "base/object.hpp" 21 #include "comm/comm_serial.hpp" 21 #include "base/timer.hpp" 22 #include "comm/comm_mpi.hpp" 23 #include "comm/domain_decomposition_mpi.hpp" 22 24 #include "interface/interface_fcs.h" 23 25 #include "interface/interface_particles.hpp" … … 33 35 #include "solver/givens.hpp" 34 36 #endif 35 #include "solver/solver_ dirichlet.hpp"36 #include "solver/solver_ periodic.hpp"37 #include "solver/solver_regular.hpp" 38 #include "solver/solver_singular.hpp" 37 39 38 40 using namespace VMG; 39 41 40 void VMGInterfaceFCSInit(vmg_int level, vmg_int periodic, vmg_int spline_degree, 41 vmg_int max_iter, vmg_int smoothing_steps, vmg_int gamma, 42 vmg_float precision, vmg_float box_begin, vmg_float box_end, 43 MPI_Comm mpi_comm) 44 { 45 const BC bc = (periodic ? Periodic : Dirichlet); 46 47 /* 48 * Register all the parameters for later use. 49 */ 50 new ObjectStorage<int>("LEVEL_FCS", level); 51 new ObjectStorage<int>("PERIODIC_FCS", periodic); 52 new ObjectStorage<int>("SPLINE_DEGREE_FCS", spline_degree); 53 new ObjectStorage<int>("MAX_ITER_FCS", max_iter); 54 new ObjectStorage<int>("SMOOTHING_STEPS_FCS", smoothing_steps); 55 new ObjectStorage<int>("GAMMA_FCS", gamma); 56 new ObjectStorage<vmg_float>("PRECISION_FCS", precision); 57 new ObjectStorage<vmg_float>("BOX_BEGIN_FCS", box_begin); 58 new ObjectStorage<vmg_float>("BOX_END_FCS", box_end); 59 new ObjectStorage<MPI_Comm>("MPI_COMM_FCS", mpi_comm); 42 namespace VMGBackupSettings 43 { 44 static vmg_int level = -1; 45 static vmg_int periodic[3] = {-1, -1, -1}; 46 static vmg_int max_iter = -1; 47 static vmg_int smoothing_steps = -1; 48 static vmg_int gamma = -1; 49 static vmg_float precision = -1; 50 static vmg_float box_offset[3]; 51 static vmg_float box_size = -1.0; 52 static vmg_int near_field_cells = -1; 53 static MPI_Comm mpi_comm; 54 } 55 56 static void VMG_fcs_init(vmg_int level, vmg_int* periodic,vmg_int max_iter, 57 vmg_int smoothing_steps, vmg_int gamma, vmg_float precision, 58 vmg_float* box_offset, vmg_float box_size, 59 vmg_int near_field_cells, MPI_Comm mpi_comm) 60 { 61 VMGBackupSettings::level = level; 62 std::memcpy(VMGBackupSettings::periodic, periodic, 3*sizeof(vmg_int)); 63 VMGBackupSettings::max_iter = max_iter; 64 VMGBackupSettings::smoothing_steps = smoothing_steps; 65 VMGBackupSettings::gamma = gamma; 66 VMGBackupSettings::precision = precision; 67 std::memcpy(VMGBackupSettings::box_offset, box_offset, 3*sizeof(vmg_float)); 68 VMGBackupSettings::box_size = box_size; 69 VMGBackupSettings::near_field_cells = near_field_cells; 70 VMGBackupSettings::mpi_comm = mpi_comm; 71 72 const Boundary boundary(periodic[0] ? Periodic : Open, 73 periodic[1] ? Periodic : Open, 74 periodic[2] ? Periodic : Open); 75 76 const bool singular = periodic[0] * periodic[1] * periodic[2]; 60 77 61 78 /* 62 79 * Register communication class. 63 * For now, parallel version is not yet released. 64 */ 65 Comm* comm = new CommSerial(bc); 80 */ 81 Comm* comm = new CommMPI(boundary, new DomainDecompositionMPI()); 66 82 comm->Register("COMM"); 67 83 … … 69 85 * Register particle interface. 70 86 */ 71 Interface* interface = new VMG::InterfaceParticles(b c, 2, level, box_begin, box_end);87 Interface* interface = new VMG::InterfaceParticles(boundary, 2, level, Vector(box_offset), box_size, near_field_cells); 72 88 MG::SetInterface(interface, comm); 73 89 … … 96 112 */ 97 113 #ifdef HAVE_LAPACK 98 Solver* solver = ( periodic?99 static_cast<Solver*>(new DSYSV<Solver Periodic>()) :100 static_cast<Solver*>(new DGESV<Solver Dirichlet>()));114 Solver* solver = (singular ? 115 static_cast<Solver*>(new DSYSV<SolverSingular>()) : 116 static_cast<Solver*>(new DGESV<SolverRegular>())); 101 117 #else 102 Solver* solver = ( periodic?103 static_cast<Solver*>(new Givens<Solver Periodic>()) :104 static_cast<Solver*>(new Givens<Solver Dirichlet>()));118 Solver* solver = (singular ? 119 static_cast<Solver*>(new Givens<SolverSingular>()) : 120 static_cast<Solver*>(new Givens<SolverRegular>())); 105 121 #endif 106 122 solver->Register("SOLVER"); … … 109 125 * Set commands for the actual multigrid cycle 110 126 */ 111 if ( periodic)127 if (singular) 112 128 Techniques::SetCorrectionSchemePeriodic(2, level, gamma); 113 129 else … … 122 138 new ObjectStorage<int>("MAX_ITERATION", max_iter); 123 139 140 new ObjectStorage<int>("PARTICLE_NEAR_FIELD_CELLS", near_field_cells); 141 124 142 /* 125 143 * Check whether the library is correctly initialized now. … … 128 146 } 129 147 130 void VMGInterfaceFCSRun(vmg_float* x, vmg_float* q, vmg_float* p, vmg_float* f, vmg_int num_particles_local) 148 void VMG_fcs_setup(vmg_int level, vmg_int* periodic, vmg_int max_iter, 149 vmg_int smoothing_steps, vmg_int gamma, vmg_float precision, 150 vmg_float* box_offset, vmg_float box_size, 151 vmg_int near_field_cells, MPI_Comm mpi_comm) 152 { 153 if (VMGBackupSettings::level != level || 154 VMGBackupSettings::periodic[0] != periodic[0] || 155 VMGBackupSettings::periodic[1] != periodic[1] || 156 VMGBackupSettings::periodic[2] != periodic[2] || 157 VMGBackupSettings::max_iter != max_iter || 158 VMGBackupSettings::smoothing_steps != smoothing_steps || 159 VMGBackupSettings::gamma != gamma || 160 VMGBackupSettings::precision != precision || 161 VMGBackupSettings::box_offset[0] != box_offset[0] || 162 VMGBackupSettings::box_offset[1] != box_offset[1] || 163 VMGBackupSettings::box_offset[2] != box_offset[2] || 164 VMGBackupSettings::box_size != box_size || 165 VMGBackupSettings::near_field_cells != near_field_cells || 166 VMGBackupSettings::mpi_comm != mpi_comm) { 167 168 VMG_fcs_destroy(); 169 VMG_fcs_init(level, periodic, max_iter, 170 smoothing_steps, gamma, precision, 171 box_offset, box_size, near_field_cells, 172 mpi_comm); 173 174 } 175 } 176 177 void VMG_fcs_run(vmg_float* x, vmg_float* q, vmg_float* p, vmg_float* f, vmg_int num_particles_local) 131 178 { 132 179 /* 133 180 * Register parameters for later use. 134 181 */ 135 new ObjectStorage<vmg_float*>(" X_FCS", x);136 new ObjectStorage<vmg_float*>(" Q_FCS", q);137 new ObjectStorage<vmg_float*>("P _FCS", p);138 new ObjectStorage<vmg_float*>(" F_FCS", f);139 new ObjectStorage<vmg_int>(" NUM_PARTICLES_LOCAL_FCS", num_particles_local);182 new ObjectStorage<vmg_float*>("PARTICLE_POS_ARRAY", x); 183 new ObjectStorage<vmg_float*>("PARTICLE_CHARGE_ARRAY", q); 184 new ObjectStorage<vmg_float*>("PARTICLE_POTENTIAL_ARRAY", p); 185 new ObjectStorage<vmg_float*>("PARTICLE_FORCE_ARRAY", f); 186 new ObjectStorage<vmg_int>("PARTICLE_NUM_LOCAL", num_particles_local); 140 187 141 188 /* … … 145 192 } 146 193 147 void VMGInterfaceFCSDestroy(void) 194 void VMG_fcs_print_timer() 195 { 196 Timer::Print(); 197 } 198 199 void VMG_fcs_destroy(void) 148 200 { 149 201 /* -
src/interface/interface_fcs.h
r66f24d rdfed1c 13 13 #endif 14 14 15 void VMG InterfaceFCSInit(vmg_int level, vmg_int periodic, vmg_int spline_degree,16 vmg_int max_iter, vmg_int smoothing_steps, vmg_int gamma,17 vmg_float precision, vmg_float box_begin, vmg_float box_end,18 MPI_Comm mpi_comm);15 void VMG_fcs_setup(vmg_int level, vmg_int* periodic, vmg_int max_iter, 16 vmg_int smoothing_steps, vmg_int gamma, vmg_float precision, 17 vmg_float* box_offset, vmg_float box_size, 18 vmg_int near_field_cells, MPI_Comm mpi_comm); 19 19 20 void VMG InterfaceFCSRun(vmg_float* x, vmg_float* q, vmg_float* p, vmg_float* f, vmg_int num_particles_local);20 void VMG_fcs_run(vmg_float* pos, vmg_float* charge, vmg_float* potential, vmg_float* f, vmg_int num_particles_local); 21 21 22 void VMGInterfaceFCSDestroy(void); 22 void VMG_fcs_print_timer(void); 23 24 void VMG_fcs_destroy(void); 23 25 24 26 #ifdef __cplusplus -
src/interface/interface_particles.cpp
r66f24d rdfed1c 8 8 */ 9 9 10 11 10 #ifdef HAVE_CONFIG_H 12 11 #include <config.h> 13 12 #endif 14 13 14 #ifdef HAVE_MPI 15 #include <mpi.h> 16 #endif 17 15 18 #include <cmath> 19 #include <cstring> 16 20 17 21 #include "base/helper.hpp" 18 22 #include "base/index.hpp" 23 #include "base/linked_cell_list.hpp" 24 #include "base/timer.hpp" 19 25 #include "base/vector.hpp" 20 26 #include "comm/comm.hpp" … … 29 35 void InterfaceParticles::ImportRightHandSide(Multigrid& multigrid) 30 36 { 37 Timer::Start("Particle/Grid Interpolation"); 38 39 Index index_global, index_local, index; 40 Vector pos_rel, pos_abs, grid_val; 41 vmg_float length; 42 31 43 Factory& factory = MG::GetFactory(); 32 44 33 const int& deg = factory.GetObjectStorageVal<int>("SPLINE_DEGREE_FCS"); 34 const vmg_int& num_particles_local = factory.GetObjectStorageVal<vmg_int>("NUM_PARTICLES_LOCAL_FCS"); 35 const int deg_2 = deg / 2; 36 37 vmg_float* x = factory.GetObjectStorageVal<vmg_float*>("X_FCS"); 38 vmg_float* q = factory.GetObjectStorageVal<vmg_float*>("Q_FCS"); 39 40 Index index_global, index_local, index; 41 Vector pos_rel, pos_abs, index_float, grid_val; 42 vmg_float foo; 43 vmg_float MMtbl[3][deg]; 45 const int& near_field_cells = factory.GetObjectStorageVal<int>("PARTICLE_NEAR_FIELD_CELLS"); 44 46 45 47 TempGrid* temp_grid = GetTempGrid(0); 46 48 Grid& grid = multigrid(multigrid.GlobalMaxLevel()); 47 49 LocalIndices local = grid.Local(); 50 51 //TODO This has to be replaced for a VMG::Vector for different mesh widths on the axis 52 const vmg_float r_cut = (near_field_cells+0.5) * grid.Extent().MeshWidth().Max(); 48 53 49 54 // We don't need a boundary on this grid … … 53 58 local.BoundaryBegin2() = local.BoundaryEnd2() = 0; 54 59 55 // 56 // Check if we need to communicate and resize halo sizes 57 // 58 if ((local.HaloEnd1() - local.HaloBegin1()).Product() > 0) { 59 local.HaloBegin1() = 0; 60 local.HaloEnd1() = local.Begin() = deg_2; 61 local.End() = local.Begin() + local.Size(); 62 } 63 64 if ((local.HaloEnd2() - local.HaloBegin2()).Product() > 0) { 65 local.HaloBegin2() = local.End(); 66 local.HaloEnd2() = local.HaloBegin2() + deg_2; 60 // Set grid size of intermediate temporary grid 61 for (int i=0; i<3; ++i) { 62 63 if (local.HasHalo1()[i]) { 64 local.HaloBegin1()[i] = 0; 65 local.HaloEnd1()[i] = local.Begin()[i] = near_field_cells+1; 66 local.End()[i] = local.Begin()[i] + local.Size()[i]; 67 } 68 69 if (local.HasHalo2()[i]) { 70 local.HaloBegin2()[i] = local.End()[i]; 71 local.HaloEnd2()[i] = local.HaloBegin2()[i] + near_field_cells+1; 72 } 73 67 74 } 68 75 … … 72 79 73 80 temp_grid->SetProperties(grid.Global(), local, grid.Extent()); 74 75 81 temp_grid->Clear(); 76 82 77 for (vmg_int i=0; i<num_particles_local; ++i) { 78 79 //TODO: Check for correct conversions here 80 index_float = (static_cast<Vector>(&x[3*i]) - grid.Extent().Begin()) / grid.Extent().MeshWidth(); 81 index_global = static_cast<Index>(index_float); 82 index_local = temp_grid->GlobalToLocalIndex(index_global); 83 84 Helper::MM(deg, std::modf(index_float[0], &foo), MMtbl[0]); 85 Helper::MM(deg, std::modf(index_float[1], &foo), MMtbl[1]); 86 Helper::MM(deg, std::modf(index_float[2], &foo), MMtbl[2]); 87 88 for (index.X() = 0; index.X() < deg; ++index.X()) { 89 90 grid_val.X() = q[i] * MMtbl[0][index.X()]; 91 92 for (index.Y() = 0; index.Y() < deg; ++index.Y()) { 93 94 grid_val.Y() = grid_val.X() * MMtbl[1][index.Y()]; 95 96 for (index.Z() = 0; index.Z() < deg; ++index.Z()) { 97 98 (*temp_grid)(index_local + index - deg_2) -= grid_val.Y() * MMtbl[2][index.Z()]; 99 100 } 101 } 102 } 83 /* 84 * Distribute particles to their processes 85 */ 86 particles.clear(); 87 MG::GetComm()->CommParticles(grid, particles); 88 89 /* 90 * Charge assignment on the grid 91 */ 92 std::list<Particle::Particle>::iterator iter; 93 94 #ifdef DEBUG_OUTPUT 95 vmg_float particle_charges = 0.0; 96 for (iter=particles.begin(); iter!=particles.end(); ++iter) 97 particle_charges += iter->Charge(); 98 particle_charges = MG::GetComm()->GlobalSumRoot(particle_charges); 99 MG::GetComm()->PrintStringOnce("Particle list charge sum: %e", particle_charges); 100 #endif 101 102 for (iter=particles.begin(); iter!=particles.end(); ++iter) { 103 104 // Compute global and local grid index of the lower left corner of the grid cell containing the particle 105 index_global = static_cast<Index>((iter->Pos() - temp_grid->Extent().Begin()) / temp_grid->Extent().MeshWidth()); 106 index_local = index_global - temp_grid->Global().BeginLocal() + temp_grid->Local().Begin(); 107 108 // Iterate over all grid points which lie in the support of the interpolating B-Spline 109 for (index.X()=-1*near_field_cells-1; index.X()<=near_field_cells+1; ++index.X()) 110 for (index.Y()=-1*near_field_cells-1; index.Y()<=near_field_cells+1; ++index.Y()) 111 for (index.Z()=-1*near_field_cells-1; index.Z()<=near_field_cells+1; ++index.Z()) { 112 113 // Compute distance from grid point to particle 114 length = ( iter->Pos() - grid.Extent().Begin() - grid.Extent().MeshWidth() * (index_global+index) ).Length(); 115 116 // If grid point lies in the support of the B-Spline, do charge interpolation 117 if (length < r_cut) 118 (*temp_grid)(index_local+index) += spl.EvaluateSpline(length) * iter->Charge(); 119 120 } 121 103 122 } 104 123 124 // Communicate charges over halo 105 125 MG::GetComm()->CommFromGhosts(*temp_grid); 106 126 127 // Assign charge values to the right hand side 107 128 for (index.X()=0; index.X()<grid.Local().Size().X(); ++index.X()) 108 129 for (index.Y()=0; index.Y()<grid.Local().Size().Y(); ++index.Y()) 109 130 for (index.Z()=0; index.Z()<grid.Local().Size().Z(); ++index.Z()) 110 grid(index + grid.Local().Begin()) = (*temp_grid)(index + temp_grid->Local().Begin()); 131 grid(index + grid.Local().Begin()) = temp_grid->GetVal(index + temp_grid->Local().Begin()); 132 133 Timer::Stop("Particle/Grid Interpolation"); 134 135 #ifdef DEBUG_OUTPUT 136 Grid::iterator grid_iter; 137 vmg_float charge_sum = 0.0; 138 for (grid_iter=grid.Iterators().Local().Begin(); grid_iter!=grid.Iterators().Local().End(); ++grid_iter) 139 charge_sum += grid.GetVal(*grid_iter); 140 charge_sum = MG::GetComm()->GlobalSum(charge_sum); 141 MG::GetComm()->PrintStringOnce("Grid charge sum: %e", charge_sum); 142 #endif 111 143 } 112 144 113 145 void InterfaceParticles::ExportSolution(Grid& grid) 114 146 { 147 Timer::Start("Grid/Particle Interpolation"); 148 149 Index index; 150 vmg_float length; 151 Vector dist_vec; 152 153 #ifdef DEBUG_OUTPUT 154 vmg_float e = 0.0; 155 vmg_float e_long = 0.0; 156 vmg_float e_self = 0.0; 157 #endif 158 115 159 Factory& factory = MG::GetFactory(); 116 117 const int& deg = factory.GetObjectStorageVal<int>("SPLINE_DEGREE_FCS"); 118 const vmg_int& num_particles_local = factory.GetObjectStorageVal<vmg_int>("NUM_PARTICLES_LOCAL_FCS"); 119 const Vector h_inv = 1.0 / grid.Extent().MeshWidth(); 120 121 vmg_float* x = factory.GetObjectStorageVal<vmg_float*>("X_FCS"); 122 vmg_float* q = factory.GetObjectStorageVal<vmg_float*>("Q_FCS"); 123 vmg_float* f = factory.GetObjectStorageVal<vmg_float*>("F_FCS"); 124 125 Index index, index_global, index_local; 126 Vector index_float, spl, der; 127 vmg_float foo; 128 vmg_float MMtbl[3][deg], MdMtbl[3][deg]; 129 160 Comm* comm = MG::GetComm(); 161 162 /* 163 * Get parameters and arrays 164 */ 165 const vmg_int& num_particles_local = factory.GetObjectStorageVal<vmg_int>("PARTICLE_NUM_LOCAL"); 166 const int& near_field_cells = factory.GetObjectStorageVal<int>("PARTICLE_NEAR_FIELD_CELLS"); 167 vmg_float* p = factory.GetObjectStorageArray<vmg_float>("PARTICLE_POTENTIAL_ARRAY"); 168 169 const vmg_float r_cut = (near_field_cells+0.5) * grid.Extent().MeshWidth().Max(); 170 171 /* 172 * Initialze potential 173 */ 174 for (vmg_int i=0; i<num_particles_local; ++i) 175 p[i] = 0.0; 176 177 /* 178 * Copy potential values to a grid with sufficiently large halo size. 179 * This may be optimized in future. 180 * The parameters of this grid have been set in the import step. 181 */ 130 182 TempGrid* temp_grid = GetTempGrid(0); 131 183 … … 133 185 for (index.Y()=0; index.Y()<grid.Local().Size().Y(); ++index.Y()) 134 186 for (index.Z()=0; index.Z()<grid.Local().Size().Z(); ++index.Z()) 135 (*temp_grid)(index + temp_grid->Local().Begin()) = grid(index + grid.Local().Begin()); 136 137 MG::GetComm()->CommToGhosts(*temp_grid); 138 139 for (vmg_int i=0; i<num_particles_local; ++i) { 140 141 index_float = (static_cast<Vector>(&x[3*i]) - grid.Extent().Begin()) / grid.Extent().MeshWidth(); 142 index_global = static_cast<Index>(index_float); 143 index_local = temp_grid->GlobalToLocalIndex(index_global); 144 145 Helper::MdM(deg, std::modf(index_float[0], &foo), MMtbl[0], MdMtbl[0]); 146 Helper::MdM(deg, std::modf(index_float[1], &foo), MMtbl[1], MdMtbl[1]); 147 Helper::MdM(deg, std::modf(index_float[2], &foo), MMtbl[2], MdMtbl[2]); 148 149 for (int j=0; j<3; ++j) 150 f[3*i+j] = 0.0; 151 152 for (index.X() = 0; index.X() < deg; ++index.X()) { 153 154 spl.X() = MMtbl[0][index.X()]; 155 der.X() = MdMtbl[0][index.X()]; 156 157 for (index.Y() = 0; index.Y() < deg; ++index.Y()) { 158 159 spl.Y() = MMtbl[1][index.Y()]; 160 der.Y() = MdMtbl[1][index.Y()]; 161 162 for (index.Z() = 0; index.Z() < deg; ++index.Z()) { 163 164 spl.Z() = MMtbl[2][index.Z()]; 165 der.Z() = MdMtbl[2][index.Z()]; 166 167 f[3*i ] += temp_grid->GetVal(index + temp_grid->Local().Begin()) * 168 der[0]*spl[1]*spl[2] * h_inv[0]; 169 170 f[3*i+1] += temp_grid->GetVal(index + temp_grid->Local().Begin()) * 171 spl[0]*der[1]*spl[2] * h_inv[1]; 172 173 f[3*i+2] += temp_grid->GetVal(index + temp_grid->Local().Begin()) * 174 spl[0]*spl[1]*der[2] * h_inv[2]; 175 176 } 177 } 178 } 179 180 for (int j=0; j<3; ++j) 181 f[3*i+j] *= q[i]; 187 (*temp_grid)(index + temp_grid->Local().Begin()) = grid.GetVal(index + grid.Local().Begin()); 188 189 comm->CommToGhosts(*temp_grid); 190 191 /* 192 * Do potential back-interpolation 193 */ 194 std::list<Particle::Particle>::iterator p_iter; 195 for (p_iter=particles.begin(); p_iter!=particles.end(); ++p_iter) { 196 197 // Interpolate long range part of potential 198 p_iter->Pot() = 0.5 * (Helper::InterpolateTrilinear(p_iter->Pos(), *temp_grid) - p_iter->Charge() * spl.GetAntiDerivativeZero()); 199 200 #ifdef DEBUG_OUTPUT 201 e_long += 0.5 * p_iter->Charge() * Helper::InterpolateTrilinear(p_iter->Pos(), *temp_grid); 202 e_self += 0.5 * p_iter->Charge() * p_iter->Charge() * spl.GetAntiDerivativeZero(); 203 #endif 182 204 183 205 } 184 206 207 comm->CommAddPotential(particles); 208 209 /* 210 * Compute near field correction 211 */ 212 Particle::LinkedCellList lc(particles, near_field_cells, grid); 213 Particle::LinkedCellList::iterator p1, p2; 214 Grid::iterator iter; 215 216 comm->CommLCListGhosts(grid, lc); 217 218 for (iter=lc.Iterators().Local().Begin(); iter!=lc.Iterators().Local().End(); ++iter) 219 for (p1=lc(*iter).begin(); p1!=lc(*iter).end(); ++p1) 220 for (index.X()=-1*near_field_cells-1; index.X()<=near_field_cells+1; ++index.X()) 221 for (index.Y()=-1*near_field_cells-1; index.Y()<=near_field_cells+1; ++index.Y()) 222 for (index.Z()=-1*near_field_cells-1; index.Z()<=near_field_cells+1; ++index.Z()) 223 for (p2=lc(*iter+index).begin(); p2!=lc(*iter+index).end(); ++p2) 224 if (*p1 != *p2) { 225 226 length = (p2->Pos() - p1->Pos()).Length(); 227 228 //TODO Rewrite this equation more efficiently 229 if (length < r_cut) 230 p1->Pot() += 0.5 * p2->Charge() / length * (0.25*M_1_PI + spl.EvaluatePotential(length)); 231 232 } 233 234 comm->CommAddPotential(lc); 235 236 Timer::Stop("Grid/Particle Interpolation"); 237 238 #ifdef DEBUG_OUTPUT 239 vmg_float* q = factory.GetObjectStorageArray<vmg_float>("PARTICLE_CHARGE_ARRAY"); 240 241 for (int i=0; i<num_particles_local; ++i) 242 e += p[i] * q[i]; 243 244 e = comm->GlobalSumRoot(e); 245 e_long = comm->GlobalSumRoot(e_long); 246 e_self = comm->GlobalSumRoot(e_self); 247 248 comm->PrintStringOnce("E_long: %e", e_long); 249 comm->PrintStringOnce("E_short: %e", e - e_long + e_self); 250 comm->PrintStringOnce("E_self: %e", e_self); 251 comm->PrintStringOnce("E_total: %e", e); 252 253 #endif /* DEBUG_OUTPUT */ 254 185 255 } 186 -
src/interface/interface_particles.hpp
r66f24d rdfed1c 12 12 #define INTERFACE_PARTIVLES_HPP 13 13 14 #include <list> 15 14 16 #include "base/has_tempgrids.hpp" 17 #include "base/linked_cell_list.hpp" 18 #include "base/particle.hpp" 19 #include "comm/mpi/has_request_vec.hpp" 15 20 #include "interface/interface.hpp" 21 #include "samples/bspline.hpp" 16 22 17 23 namespace VMG … … 21 27 class Multigrid; 22 28 23 class InterfaceParticles : public Interface, public HasTempGrids 29 class InterfaceParticles : public Interface, public HasTempGrids, public HasRequestVec 24 30 { 25 31 public: 26 InterfaceParticles(BC boundary, int levelMin, int levelMax, vmg_float box_begin, vmg_float box_end) : 27 Interface(boundary, levelMin, levelMax, box_begin, box_end, 0, 1.0), 28 HasTempGrids() 32 InterfaceParticles(const Boundary& boundary, const int& levelMin, const int& levelMax, 33 const Vector& box_offset, const vmg_float& box_size, 34 const int& near_field_cells) : 35 Interface(boundary, levelMin, levelMax, box_offset, box_size, 0, 1.0), 36 HasTempGrids(), 37 HasRequestVec(), 38 spl((near_field_cells+0.5)*Extent(MaxLevel()).MeshWidth().Max()) 29 39 {} 30 40 31 41 void ImportRightHandSide(Multigrid& multigrid); 32 42 void ExportSolution(Grid& grid); 43 44 protected: 45 BSpline spl; 46 47 private: 48 std::list<Particle::Particle> particles; 33 49 }; 34 50
Note:
See TracChangeset
for help on using the changeset viewer.
