| 1 | /**
|
|---|
| 2 | * @file interface_particles.cpp
|
|---|
| 3 | * @author Julian Iseringhausen <isering@ins.uni-bonn.de>
|
|---|
| 4 | * @date Mon Apr 18 12:56:48 2011
|
|---|
| 5 | *
|
|---|
| 6 | * @brief VMG::InterfaceParticles
|
|---|
| 7 | *
|
|---|
| 8 | */
|
|---|
| 9 |
|
|---|
| 10 |
|
|---|
| 11 | #ifdef HAVE_CONFIG_H
|
|---|
| 12 | #include <config.h>
|
|---|
| 13 | #endif
|
|---|
| 14 |
|
|---|
| 15 | #include <cmath>
|
|---|
| 16 |
|
|---|
| 17 | #include "base/helper.hpp"
|
|---|
| 18 | #include "base/index.hpp"
|
|---|
| 19 | #include "base/vector.hpp"
|
|---|
| 20 | #include "comm/comm.hpp"
|
|---|
| 21 | #include "grid/grid.hpp"
|
|---|
| 22 | #include "grid/multigrid.hpp"
|
|---|
| 23 | #include "grid/tempgrid.hpp"
|
|---|
| 24 | #include "interface/interface_particles.hpp"
|
|---|
| 25 | #include "mg.hpp"
|
|---|
| 26 |
|
|---|
| 27 | using namespace VMG;
|
|---|
| 28 |
|
|---|
| 29 | void InterfaceParticles::ImportRightHandSide(Multigrid& multigrid)
|
|---|
| 30 | {
|
|---|
| 31 | Factory& factory = MG::GetFactory();
|
|---|
| 32 |
|
|---|
| 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];
|
|---|
| 44 |
|
|---|
| 45 | TempGrid* temp_grid = GetTempGrid(0);
|
|---|
| 46 | Grid& grid = multigrid(multigrid.GlobalMaxLevel());
|
|---|
| 47 | LocalIndices local = grid.Local();
|
|---|
| 48 |
|
|---|
| 49 | // We don't need a boundary on this grid
|
|---|
| 50 | local.End() -= local.Begin();
|
|---|
| 51 | local.Begin() = 0;
|
|---|
| 52 | local.BoundaryBegin1() = local.BoundaryEnd1() = 0;
|
|---|
| 53 | local.BoundaryBegin2() = local.BoundaryEnd2() = 0;
|
|---|
| 54 |
|
|---|
| 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;
|
|---|
| 67 | }
|
|---|
| 68 |
|
|---|
| 69 | local.SizeTotal() = local.Size() +
|
|---|
| 70 | local.HaloEnd1() - local.HaloBegin1() +
|
|---|
| 71 | local.HaloEnd2() - local.HaloBegin2();
|
|---|
| 72 |
|
|---|
| 73 | temp_grid->SetProperties(grid.Global(), local, grid.Extent());
|
|---|
| 74 |
|
|---|
| 75 | temp_grid->Clear();
|
|---|
| 76 |
|
|---|
| 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 | }
|
|---|
| 103 | }
|
|---|
| 104 |
|
|---|
| 105 | MG::GetComm()->CommFromGhosts(*temp_grid);
|
|---|
| 106 |
|
|---|
| 107 | for (index.X()=0; index.X()<grid.Local().Size().X(); ++index.X())
|
|---|
| 108 | for (index.Y()=0; index.Y()<grid.Local().Size().Y(); ++index.Y())
|
|---|
| 109 | 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());
|
|---|
| 111 | }
|
|---|
| 112 |
|
|---|
| 113 | void InterfaceParticles::ExportSolution(Grid& grid)
|
|---|
| 114 | {
|
|---|
| 115 | 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 |
|
|---|
| 130 | TempGrid* temp_grid = GetTempGrid(0);
|
|---|
| 131 |
|
|---|
| 132 | for (index.X()=0; index.X()<grid.Local().Size().X(); ++index.X())
|
|---|
| 133 | for (index.Y()=0; index.Y()<grid.Local().Size().Y(); ++index.Y())
|
|---|
| 134 | 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];
|
|---|
| 182 |
|
|---|
| 183 | }
|
|---|
| 184 |
|
|---|
| 185 | }
|
|---|
| 186 |
|
|---|