Skip to content

Commit a5ae92b

Browse files
refactor field solvers
- add all solver to the namespace `picongpu::fields::maxwellSolver` - add the current interpolation as template parameter - make the solver cell type aware - provide forwared definitions in `*.def` files
1 parent 12f6fd6 commit a5ae92b

File tree

21 files changed

+1121
-872
lines changed

21 files changed

+1121
-872
lines changed

include/picongpu/fields/MaxwellSolver/DirSplitting/DirSplitting.def

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -20,31 +20,51 @@
2020
#pragma once
2121

2222
#include "picongpu/simulation_defines.hpp"
23+
#include "picongpu/fields/currentInterpolation/CurrentInterpolation.def"
2324

2425
namespace picongpu
2526
{
26-
namespace dirSplitting
27+
namespace fields
2728
{
28-
class DirSplitting;
29-
} // dirSplitting
29+
namespace maxwellSolver
30+
{
31+
32+
template< typename T_CurrentInterpolation = currentInterpolation::NoneDS >
33+
class DirSplitting;
34+
35+
} // namespace maxwellSolver
36+
} // namespace fields
3037

3138
namespace traits
3239
{
3340

34-
template<>
35-
struct GetMargin<picongpu::dirSplitting::DirSplitting, picongpu::FIELD_B>
36-
{
37-
typedef pmacc::math::CT::Int < 1, 1, 1 > LowerMargin;
38-
typedef pmacc::math::CT::Int < 1, 1, 1 > UpperMargin;
39-
};
41+
template< typename T_CurrentInterpolation >
42+
struct GetMargin<
43+
picongpu::fields::maxwellSolver::DirSplitting< T_CurrentInterpolation >,
44+
picongpu::FIELD_B
45+
>
46+
{
47+
using LowerMargin = pmacc::math::CT::Int <
48+
1,
49+
1,
50+
1
51+
>;
52+
using UpperMargin = LowerMargin;
53+
};
4054

41-
template<>
42-
struct GetMargin<picongpu::dirSplitting::DirSplitting, picongpu::FIELD_E>
43-
{
44-
typedef pmacc::math::CT::Int < 1, 1, 1 > LowerMargin;
45-
typedef pmacc::math::CT::Int < 1, 1, 1 > UpperMargin;
46-
};
55+
template< typename T_CurrentInterpolation >
56+
struct GetMargin<
57+
picongpu::fields::maxwellSolver::DirSplitting< T_CurrentInterpolation >,
58+
picongpu::FIELD_E
59+
>
60+
{
61+
using LowerMargin = pmacc::math::CT::Int <
62+
1,
63+
1,
64+
1
65+
>;
66+
using UpperMargin = LowerMargin;
67+
};
4768

4869
} //namespace traits
49-
5070
} // picongpu

include/picongpu/fields/MaxwellSolver/DirSplitting/DirSplitting.hpp

Lines changed: 150 additions & 142 deletions
Original file line numberDiff line numberDiff line change
@@ -19,170 +19,178 @@
1919

2020
#pragma once
2121

22-
#include "DirSplitting.def"
23-
22+
#include "picongpu/fields/MaxwellSolver/DirSplitting/DirSplitting.def"
2423
#include "picongpu/simulation_defines.hpp"
25-
2624
#include "picongpu/fields/MaxwellSolver/DirSplitting/DirSplitting.kernel"
27-
#include <pmacc/dataManagement/DataConnector.hpp>
2825
#include "picongpu/fields/FieldB.hpp"
2926
#include "picongpu/fields/FieldE.hpp"
27+
#include "picongpu/fields/numericalCellTypes/NumericalCellTypes.hpp"
28+
3029
#include <pmacc/cuSTL/algorithm/kernel/ForeachBlock.hpp>
3130
#include <pmacc/cuSTL/cursor/NestedCursor.hpp>
3231
#include <pmacc/math/Vector.hpp>
3332
#include <pmacc/math/vector/Int.hpp>
3433
#include <pmacc/math/vector/TwistComponents.hpp>
3534
#include <pmacc/math/vector/compile-time/TwistComponents.hpp>
35+
#include <pmacc/dataManagement/DataConnector.hpp>
3636

3737

3838
namespace picongpu
3939
{
40-
namespace dirSplitting
40+
namespace fields
4141
{
42-
using namespace pmacc;
43-
44-
/** Check Directional Splitting grid and time conditions
45-
*
46-
* This is a workaround that the condition check is only
47-
* triggered if the current used solver is `DirSplitting`
48-
*/
49-
template<typename T_UsedSolver, typename T_Dummy=void>
50-
struct ConditionCheck
42+
namespace maxwellSolver
5143
{
52-
};
53-
54-
template<typename T_Dummy>
55-
struct ConditionCheck<DirSplitting, T_Dummy>
44+
namespace dirSplitting
5645
{
57-
/* Directional Splitting conditions:
58-
*
59-
* using SI units to avoid round off errors
60-
*
61-
* The compiler is allowed to evaluate an expression those not depends on a template parameter
62-
* even if the class is never instantiated. In that case static assert is always
63-
* evaluated (e.g. with clang), this results in an error if the condition is false.
64-
* http://www.boost.org/doc/libs/1_60_0/doc/html/boost_staticassert.html
46+
/** Check Directional Splitting grid and time conditions
6547
*
66-
* A workaround is to add a template dependency to the expression.
67-
* `sizeof(ANY_TYPE) != 0` is always true and defers the evaluation.
48+
* This is a workaround that the condition check is only
49+
* triggered if the current used solver is `DirSplitting`
6850
*/
69-
PMACC_CASSERT_MSG(DirectionSplitting_Set_dX_equal_dt_times_c____check_your_gridConfig_param_file,
70-
(SI::SPEED_OF_LIGHT_SI * SI::DELTA_T_SI) == SI::CELL_WIDTH_SI &&
71-
(sizeof(T_Dummy) != 0));
72-
PMACC_CASSERT_MSG(DirectionSplitting_use_cubic_cells____check_your_gridConfig_param_file,
73-
SI::CELL_HEIGHT_SI == SI::CELL_WIDTH_SI &&
74-
(sizeof(T_Dummy) != 0));
75-
#if (SIMDIM == DIM3)
76-
PMACC_CASSERT_MSG(DirectionSplitting_use_cubic_cells____check_your_gridConfig_param_file,
77-
SI::CELL_DEPTH_SI == SI::CELL_WIDTH_SI &&
78-
(sizeof(T_Dummy) != 0));
79-
#endif
80-
};
81-
82-
class DirSplitting : private ConditionCheck<fieldSolver::FieldSolver>
83-
{
84-
private:
85-
template<typename OrientationTwist,typename CursorE, typename CursorB, typename GridSize>
86-
void propagate(CursorE cursorE, CursorB cursorB, GridSize gridSize) const
51+
template<typename T_UsedSolver, typename T_Dummy = void>
52+
struct ConditionCheck
8753
{
88-
using namespace cursor::tools;
89-
using namespace pmacc::math;
90-
91-
auto gridSizeTwisted = twistComponents<OrientationTwist>(gridSize);
54+
};
9255

93-
/* twist components of the supercell */
94-
typedef typename CT::TwistComponents<SuperCellSize, OrientationTwist>::type BlockDim;
95-
96-
algorithm::kernel::ForeachBlock<BlockDim> foreach;
97-
foreach(zone::SphericZone<3>(pmacc::math::Size_t<3>(BlockDim::x::value, gridSizeTwisted.y(), gridSizeTwisted.z())),
98-
cursor::make_NestedCursor(twistVectorFieldAxes<OrientationTwist>(cursorE)),
99-
cursor::make_NestedCursor(twistVectorFieldAxes<OrientationTwist>(cursorB)),
100-
DirSplittingKernel<BlockDim>((int)gridSizeTwisted.x()));
101-
}
102-
public:
103-
DirSplitting(MappingDesc) {}
104-
105-
void update_beforeCurrent(uint32_t currentStep) const
56+
template<typename T_CurrentInterpolation, typename T_Dummy>
57+
struct ConditionCheck<DirSplitting< T_CurrentInterpolation >, T_Dummy>
10658
{
107-
typedef SuperCellSize GuardDim;
108-
109-
DataConnector &dc = Environment<>::get().DataConnector();
110-
111-
auto fieldE = dc.get< FieldE >( FieldE::getName(), true );
112-
auto fieldB = dc.get< FieldB >( FieldB::getName(), true );
113-
114-
auto fieldE_coreBorder =
115-
fieldE->getGridBuffer().getDeviceBuffer().
116-
cartBuffer().view(GuardDim().toRT(),
117-
-GuardDim().toRT());
118-
auto fieldB_coreBorder =
119-
fieldB->getGridBuffer().getDeviceBuffer().
120-
cartBuffer().view(GuardDim().toRT(),
121-
-GuardDim().toRT());
122-
123-
using namespace cursor::tools;
124-
using namespace pmacc::math;
125-
126-
pmacc::math::Size_t<3> gridSize = fieldE_coreBorder.size();
127-
128-
129-
typedef pmacc::math::CT::Int<0,1,2> Orientation_X;
130-
propagate<Orientation_X>(
131-
fieldE_coreBorder.origin(),
132-
fieldB_coreBorder.origin(),
133-
gridSize);
134-
135-
__setTransactionEvent(fieldE->asyncCommunication(__getTransactionEvent()));
136-
__setTransactionEvent(fieldB->asyncCommunication(__getTransactionEvent()));
137-
138-
typedef pmacc::math::CT::Int<1,2,0> Orientation_Y;
139-
propagate<Orientation_Y>(
140-
fieldE_coreBorder.origin(),
141-
fieldB_coreBorder.origin(),
142-
gridSize);
143-
144-
__setTransactionEvent(fieldE->asyncCommunication(__getTransactionEvent()));
145-
__setTransactionEvent(fieldB->asyncCommunication(__getTransactionEvent()));
146-
147-
typedef pmacc::math::CT::Int<2,0,1> Orientation_Z;
148-
propagate<Orientation_Z>(
149-
fieldE_coreBorder.origin(),
150-
fieldB_coreBorder.origin(),
151-
gridSize);
152-
153-
if (laserProfile::INIT_TIME > float_X(0.0))
154-
fieldE->laserManipulation(currentStep);
155-
156-
__setTransactionEvent(fieldE->asyncCommunication(__getTransactionEvent()));
157-
__setTransactionEvent(fieldB->asyncCommunication(__getTransactionEvent()));
158-
159-
dc.releaseData( FieldE::getName() );
160-
dc.releaseData( FieldB::getName() );
161-
}
162-
163-
void update_afterCurrent(uint32_t) const
164-
{
165-
DataConnector &dc = Environment<>::get().DataConnector();
166-
167-
auto fieldE = dc.get< FieldE >( FieldE::getName(), true );
168-
auto fieldB = dc.get< FieldB >( FieldB::getName(), true );
169-
170-
EventTask eRfieldE = fieldE->asyncCommunication(__getTransactionEvent());
171-
EventTask eRfieldB = fieldB->asyncCommunication(__getTransactionEvent());
172-
__setTransactionEvent(eRfieldE);
173-
__setTransactionEvent(eRfieldB);
174-
175-
dc.releaseData( FieldE::getName() );
176-
dc.releaseData( FieldB::getName() );
177-
}
178-
179-
static pmacc::traits::StringProperty getStringProperties()
59+
/* Directional Splitting conditions:
60+
*
61+
* using SI units to avoid round off errors
62+
*
63+
* The compiler is allowed to evaluate an expression those not depends on a template parameter
64+
* even if the class is never instantiated. In that case static assert is always
65+
* evaluated (e.g. with clang), this results in an error if the condition is false.
66+
* http://www.boost.org/doc/libs/1_60_0/doc/html/boost_staticassert.html
67+
*
68+
* A workaround is to add a template dependency to the expression.
69+
* `sizeof(ANY_TYPE) != 0` is always true and defers the evaluation.
70+
*/
71+
PMACC_CASSERT_MSG(DirectionSplitting_Set_dX_equal_dt_times_c____check_your_gridConfig_param_file,
72+
(SI::SPEED_OF_LIGHT_SI * SI::DELTA_T_SI) == SI::CELL_WIDTH_SI &&
73+
(sizeof(T_Dummy) != 0));
74+
PMACC_CASSERT_MSG(DirectionSplitting_use_cubic_cells____check_your_gridConfig_param_file,
75+
SI::CELL_HEIGHT_SI == SI::CELL_WIDTH_SI &&
76+
(sizeof(T_Dummy) != 0));
77+
#if (SIMDIM == DIM3)
78+
PMACC_CASSERT_MSG(DirectionSplitting_use_cubic_cells____check_your_gridConfig_param_file,
79+
SI::CELL_DEPTH_SI == SI::CELL_WIDTH_SI &&
80+
(sizeof(T_Dummy) != 0));
81+
#endif
82+
};
83+
} // namespace dirSplitting
84+
85+
template< typename T_CurrentInterpolation >
86+
class DirSplitting: private dirSplitting::ConditionCheck< DirSplitting< T_CurrentInterpolation > >
18087
{
181-
pmacc::traits::StringProperty propList( "name", "DS" );
182-
return propList;
183-
}
184-
};
88+
private:
89+
template<typename OrientationTwist,typename CursorE, typename CursorB, typename GridSize>
90+
void propagate(CursorE cursorE, CursorB cursorB, GridSize gridSize) const
91+
{
92+
using namespace cursor::tools;
93+
using namespace pmacc::math;
18594

186-
} // dirSplitting
95+
auto gridSizeTwisted = twistComponents<OrientationTwist>(gridSize);
96+
97+
/* twist components of the supercell */
98+
typedef typename CT::TwistComponents<SuperCellSize, OrientationTwist>::type BlockDim;
99+
100+
algorithm::kernel::ForeachBlock<BlockDim> foreach;
101+
foreach(zone::SphericZone<3>(pmacc::math::Size_t<3>(BlockDim::x::value, gridSizeTwisted.y(), gridSizeTwisted.z())),
102+
cursor::make_NestedCursor(twistVectorFieldAxes<OrientationTwist>(cursorE)),
103+
cursor::make_NestedCursor(twistVectorFieldAxes<OrientationTwist>(cursorB)),
104+
DirSplittingKernel<BlockDim>((int)gridSizeTwisted.x()));
105+
}
106+
public:
107+
108+
using NummericalCellType = picongpu::numericalCellTypes::EMFCenteredCell;
109+
using CurrentInterpolation = T_CurrentInterpolation;
110+
111+
DirSplitting(MappingDesc) {}
112+
113+
void update_beforeCurrent(uint32_t currentStep) const
114+
{
115+
typedef SuperCellSize GuardDim;
116+
117+
DataConnector &dc = Environment<>::get().DataConnector();
118+
119+
auto fieldE = dc.get< FieldE >( FieldE::getName(), true );
120+
auto fieldB = dc.get< FieldB >( FieldB::getName(), true );
121+
122+
auto fieldE_coreBorder =
123+
fieldE->getGridBuffer().getDeviceBuffer().
124+
cartBuffer().view(GuardDim().toRT(),
125+
-GuardDim().toRT());
126+
auto fieldB_coreBorder =
127+
fieldB->getGridBuffer().getDeviceBuffer().
128+
cartBuffer().view(GuardDim().toRT(),
129+
-GuardDim().toRT());
130+
131+
using namespace cursor::tools;
132+
using namespace pmacc::math;
133+
134+
pmacc::math::Size_t<3> gridSize = fieldE_coreBorder.size();
135+
136+
137+
typedef pmacc::math::CT::Int<0,1,2> Orientation_X;
138+
propagate<Orientation_X>(
139+
fieldE_coreBorder.origin(),
140+
fieldB_coreBorder.origin(),
141+
gridSize);
142+
143+
__setTransactionEvent(fieldE->asyncCommunication(__getTransactionEvent()));
144+
__setTransactionEvent(fieldB->asyncCommunication(__getTransactionEvent()));
145+
146+
typedef pmacc::math::CT::Int<1,2,0> Orientation_Y;
147+
propagate<Orientation_Y>(
148+
fieldE_coreBorder.origin(),
149+
fieldB_coreBorder.origin(),
150+
gridSize);
151+
152+
__setTransactionEvent(fieldE->asyncCommunication(__getTransactionEvent()));
153+
__setTransactionEvent(fieldB->asyncCommunication(__getTransactionEvent()));
154+
155+
typedef pmacc::math::CT::Int<2,0,1> Orientation_Z;
156+
propagate<Orientation_Z>(
157+
fieldE_coreBorder.origin(),
158+
fieldB_coreBorder.origin(),
159+
gridSize);
160+
161+
if (laserProfile::INIT_TIME > float_X(0.0))
162+
fieldE->laserManipulation(currentStep);
163+
164+
__setTransactionEvent(fieldE->asyncCommunication(__getTransactionEvent()));
165+
__setTransactionEvent(fieldB->asyncCommunication(__getTransactionEvent()));
166+
167+
dc.releaseData( FieldE::getName() );
168+
dc.releaseData( FieldB::getName() );
169+
}
170+
171+
void update_afterCurrent(uint32_t) const
172+
{
173+
DataConnector &dc = Environment<>::get().DataConnector();
174+
175+
auto fieldE = dc.get< FieldE >( FieldE::getName(), true );
176+
auto fieldB = dc.get< FieldB >( FieldB::getName(), true );
177+
178+
EventTask eRfieldE = fieldE->asyncCommunication(__getTransactionEvent());
179+
EventTask eRfieldB = fieldB->asyncCommunication(__getTransactionEvent());
180+
__setTransactionEvent(eRfieldE);
181+
__setTransactionEvent(eRfieldB);
182+
183+
dc.releaseData( FieldE::getName() );
184+
dc.releaseData( FieldB::getName() );
185+
}
186+
187+
static pmacc::traits::StringProperty getStringProperties()
188+
{
189+
pmacc::traits::StringProperty propList( "name", "DS" );
190+
return propList;
191+
}
192+
};
187193

188-
} // picongpu
194+
} // namespace maxwellSolver
195+
} // namespace fields
196+
} // namespace picongpu

0 commit comments

Comments
 (0)