source: src/units/particle/interface_fcs.cpp@ 952298

Last change on this file since 952298 was 952298, checked in by Julian Iseringhausen <isering@…>, 14 years ago

Improve serial performance by 10 - 20 percent by explicit loop unrolling in GSRB smoother.

git-svn-id: https://svn.version.fz-juelich.de/scafacos/trunk@1814 5161e1c8-67bf-11de-9fd5-51895aff932f

  • Property mode set to 100644
File size: 9.3 KB
Line 
1/*
2 * vmg - a versatile multigrid solver
3 * Copyright (C) 2012 Institute for Numerical Simulation, University of Bonn
4 *
5 * vmg is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * vmg is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19/**
20 * @file interface_fcs.cpp
21 * @author Julian Iseringhausen <isering@ins.uni-bonn.de>
22 * @date Mon Apr 18 12:56:20 2011
23 *
24 * @brief VMG::InterfaceFCS
25 *
26 */
27
28#ifdef HAVE_CONFIG_H
29#include <config.h>
30#endif
31
32#ifndef HAVE_MPI
33#error MPI is needed to use the Scafacos interface.
34#endif
35
36#include <mpi.h>
37#ifdef HAVE_MARMOT
38#include <enhancempicalls.h>
39#include <sourceinfompicalls.h>
40#endif
41
42#include "base/object.hpp"
43#include "base/timer.hpp"
44#include "comm/domain_decomposition_mpi.hpp"
45#ifdef DEBUG
46#include "comm/mpi/error_handler.hpp"
47#endif
48#include "level/level_operator_cs.hpp"
49#include "level/level_operator_fas.hpp"
50#include "level/stencils.hpp"
51#include "samples/discretization_poisson_fd.hpp"
52#include "samples/discretization_poisson_fv.hpp"
53#include "samples/techniques.hpp"
54#include "smoother/gsrb_poisson_2.hpp"
55#include "smoother/gsrb_poisson_4.hpp"
56#ifdef HAVE_LAPACK
57#include "solver/dgesv.hpp"
58#include "solver/dsysv.hpp"
59#else
60#include "solver/givens.hpp"
61#endif
62#include "solver/solver_regular.hpp"
63#include "solver/solver_singular.hpp"
64#include "units/particle/comm_mpi_particle.hpp"
65#include "units/particle/interface_fcs.h"
66#include "units/particle/interface_particles.hpp"
67
68
69using namespace VMG;
70
71namespace VMGBackupSettings
72{
73 static vmg_int level = -1;
74 static vmg_int periodic[3] = {-1, -1, -1};
75 static vmg_int max_iter = -1;
76 static vmg_int smoothing_steps = -1;
77 static vmg_int cycle_type = -1;
78 static vmg_float precision = -1;
79 static vmg_float box_offset[3];
80 static vmg_float box_size = -1.0;
81 static vmg_int near_field_cells = -1;
82 static vmg_int interpolation_degree = -1;
83 static vmg_int discretization_order = -1;
84 static MPI_Comm mpi_comm;
85}
86
87static void VMG_fcs_init(vmg_int level, vmg_int* periodic,vmg_int max_iter,
88 vmg_int smoothing_steps, vmg_int cycle_type, vmg_float precision,
89 vmg_float* box_offset, vmg_float box_size,
90 vmg_int near_field_cells, vmg_int interpolation_degree,
91 vmg_int discretization_order, MPI_Comm mpi_comm)
92{
93 VMGBackupSettings::level = level;
94 std::memcpy(VMGBackupSettings::periodic, periodic, 3*sizeof(vmg_int));
95 VMGBackupSettings::max_iter = max_iter;
96 VMGBackupSettings::smoothing_steps = smoothing_steps;
97 VMGBackupSettings::cycle_type = cycle_type;
98 VMGBackupSettings::precision = precision;
99 std::memcpy(VMGBackupSettings::box_offset, box_offset, 3*sizeof(vmg_float));
100 VMGBackupSettings::box_size = box_size;
101 VMGBackupSettings::near_field_cells = near_field_cells;
102 VMGBackupSettings::interpolation_degree = interpolation_degree;
103 VMGBackupSettings::discretization_order = discretization_order;
104 VMGBackupSettings::mpi_comm = mpi_comm;
105
106#ifdef DEBUG
107 MPI_Errhandler mpiErrorHandler;
108 MPI_Comm_create_errhandler(VMG::MPI::ConvertToException, &mpiErrorHandler);
109 MPI_Comm_set_errhandler(MPI_COMM_WORLD, mpiErrorHandler);
110#endif
111
112 const Boundary boundary(periodic[0] ? Periodic : Open,
113 periodic[1] ? Periodic : Open,
114 periodic[2] ? Periodic : Open);
115
116 const bool singular = periodic[0] * periodic[1] * periodic[2];
117
118 /*
119 * Register communication class.
120 */
121 Comm* comm = new Particle::CommMPI(boundary, new DomainDecompositionMPI());
122 comm->Register("COMM");
123
124 /*
125 * Register particle interface.
126 */
127 Interface* interface;
128 if (singular)
129 interface = new InterfaceParticles(boundary, 2, level, Vector(box_offset), box_size, near_field_cells, 0, 1.0);
130 else
131 interface = new InterfaceParticles(boundary, 2, level, Vector(box_offset), box_size, near_field_cells, 2, 1.6);
132 MG::SetInterface(interface, comm);
133
134 /*
135 * Define discretization of the Poisson equation.
136 * Finite volumes for locally refined grids and
137 * finite differences otherwise.
138 */
139 Discretization* discretization;
140 if (singular)
141 discretization = new DiscretizationPoissonFD(discretization_order);
142 else
143 discretization = new DiscretizationPoissonFV(discretization_order);
144 discretization->Register("DISCRETIZATION");
145
146 /*
147 * Use a correction scheme multigrid algorithm with full weight stencils.
148 * Since we use the Gauss-Seidel RB smoother here, this may be replaced
149 * with a half-weight version once debugging is finished.
150 */
151 LevelOperator* lop;
152 if (singular)
153 lop = new LevelOperatorCS(Stencils::RestrictionFullWeight, Stencils::InterpolationTrilinear);
154 else
155 lop = new LevelOperatorFAS(Stencils::RestrictionFullWeight, Stencils::Injection, Stencils::InterpolationTrilinear);
156 lop->Register("LEVEL_OPERATOR");
157
158 /*
159 * Use Gauss-Seidel Red-Black ordering
160 */
161 if (discretization_order == 2) {
162 Smoother* smoother = new GaussSeidelRBPoisson2();
163 smoother->Register("SMOOTHER");
164 }else {
165 Smoother* smoother = new GaussSeidelRBPoisson4();
166 smoother->Register("SMOOTHER");
167 }
168
169 /*
170 * Use LAPACK solver when available, otherwise use Givens rotations.
171 */
172#ifdef HAVE_LAPACK
173 Solver* solver = (singular ?
174 static_cast<Solver*>(new DSYSV<SolverSingular>()) :
175 static_cast<Solver*>(new DGESV<SolverRegular>()));
176#else
177 Solver* solver = (singular ?
178 static_cast<Solver*>(new Givens<SolverSingular>()) :
179 static_cast<Solver*>(new Givens<SolverRegular>()));
180#endif
181 solver->Register("SOLVER");
182
183 /*
184 * Set commands for the actual multigrid cycle
185 */
186 if (singular)
187 Techniques::SetCorrectionSchemePeriodic(interface->MinLevel(), interface->MaxLevel(), cycle_type);
188 else
189 Techniques::SetFullApproximationSchemeDirichlet(interface->MinLevel(), interface->MaxLevel(), cycle_type);
190
191 /*
192 * Register required parameters
193 */
194 new ObjectStorage<int>("PRESMOOTHSTEPS", smoothing_steps);
195 new ObjectStorage<int>("POSTSMOOTHSTEPS", smoothing_steps);
196 new ObjectStorage<vmg_float>("PRECISION", precision);
197 new ObjectStorage<int>("MAX_ITERATION", max_iter);
198 new ObjectStorage<int>("PARTICLE_NEAR_FIELD_CELLS", near_field_cells);
199 new ObjectStorage<int>("PARTICLE_INTERPOLATION_DEGREE", interpolation_degree);
200
201 /*
202 * Check whether the library is correctly initialized now.
203 */
204 MG::IsInitialized();
205
206 /*
207 * Post init communication class
208 */
209 MG::PostInit();
210}
211
212void VMG_fcs_setup(vmg_int level, vmg_int* periodic, vmg_int max_iter,
213 vmg_int smoothing_steps, vmg_int cycle_type, vmg_float precision,
214 vmg_float* box_offset, vmg_float box_size,
215 vmg_int near_field_cells, vmg_int interpolation_degree,
216 vmg_int discretization_order, MPI_Comm mpi_comm)
217{
218 if (VMGBackupSettings::level != level ||
219 VMGBackupSettings::periodic[0] != periodic[0] ||
220 VMGBackupSettings::periodic[1] != periodic[1] ||
221 VMGBackupSettings::periodic[2] != periodic[2] ||
222 VMGBackupSettings::max_iter != max_iter ||
223 VMGBackupSettings::smoothing_steps != smoothing_steps ||
224 VMGBackupSettings::cycle_type != cycle_type ||
225 VMGBackupSettings::precision != precision ||
226 VMGBackupSettings::box_offset[0] != box_offset[0] ||
227 VMGBackupSettings::box_offset[1] != box_offset[1] ||
228 VMGBackupSettings::box_offset[2] != box_offset[2] ||
229 VMGBackupSettings::box_size != box_size ||
230 VMGBackupSettings::near_field_cells != near_field_cells ||
231 VMGBackupSettings::interpolation_degree != interpolation_degree ||
232 VMGBackupSettings::discretization_order != discretization_order ||
233 VMGBackupSettings::mpi_comm != mpi_comm) {
234
235 VMG_fcs_destroy();
236 VMG_fcs_init(level, periodic, max_iter,
237 smoothing_steps, cycle_type, precision,
238 box_offset, box_size, near_field_cells,
239 interpolation_degree, discretization_order,
240 mpi_comm);
241
242 }
243}
244
245int VMG_fcs_check()
246{
247 const int& near_field_cells = MG::GetFactory().GetObjectStorageVal<int>("PARTICLE_NEAR_FIELD_CELLS");
248 const Multigrid& multigrid = *MG::GetRhs();
249 const Grid& grid = multigrid(multigrid.MaxLevel());
250
251 int error_code;
252
253 if (!grid.Global().LocalSize().IsComponentwiseGreater(near_field_cells))
254 error_code = 1;
255 else
256 error_code = 0;
257
258 error_code = MG::GetComm()->GlobalMax(error_code);
259
260 return error_code;
261}
262
263void VMG_fcs_run(vmg_float* x, vmg_float* q, vmg_float* p, vmg_float* f, vmg_int num_particles_local)
264{
265 /*
266 * Register parameters for later use.
267 */
268 new ObjectStorage<vmg_float*>("PARTICLE_POS_ARRAY", x);
269 new ObjectStorage<vmg_float*>("PARTICLE_CHARGE_ARRAY", q);
270 new ObjectStorage<vmg_float*>("PARTICLE_POTENTIAL_ARRAY", p);
271 new ObjectStorage<vmg_float*>("PARTICLE_FIELD_ARRAY", f);
272 new ObjectStorage<vmg_int>("PARTICLE_NUM_LOCAL", num_particles_local);
273
274 /*
275 * Start the multigrid solver
276 */
277 MG::Solve();
278
279#ifdef DEBUG_MEASURE_TIME
280 Timer::Print();
281#endif
282}
283
284void VMG_fcs_print_timer()
285{
286 Timer::Print();
287}
288
289void VMG_fcs_destroy(void)
290{
291 /*
292 * Delete all data.
293 */
294 MG::Destroy();
295}
Note: See TracBrowser for help on using the repository browser.