Skip to content

Commit eaaaef5

Browse files
RemiLeheroelof-groenewaldpre-commit-ci[bot]
authored
Use new stair-case approximation in hybrid solver (#5558)
Merge #5534 first. This extends the changes of #5534 and #5574 to the hybrid solver. Note that this effectively changes the definition of the stair-cased embedded boundary for the hybrid solver. --------- Co-authored-by: Roelof Groenewald <40245517+roelof-groenewald@users.noreply.github.com> Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent 88412f3 commit eaaaef5

File tree

8 files changed

+128
-113
lines changed

8 files changed

+128
-113
lines changed

Source/FieldSolver/FiniteDifferenceSolver/FiniteDifferenceSolver.H

+9-9
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ class FiniteDifferenceSolver
103103
* \param[out] Efield vector of electric field MultiFabs updated at a given level
104104
* \param[in] Bfield vector of magnetic field MultiFabs at a given level
105105
* \param[in] Jfield vector of current density MultiFabs at a given level
106-
* \param[in] edge_lengths length of edges along embedded boundaries
106+
* \param[in] eb_update_E indicate in which cell E should be updated (related to embedded boundaries)
107107
* \param[in] dt timestep of the simulation
108108
* \param[in] macroscopic_properties contains user-defined properties of the medium.
109109
*/
@@ -147,7 +147,7 @@ class FiniteDifferenceSolver
147147
* \param[in] Bfield vector of magnetic field MultiFabs at a given level
148148
* \param[in] rhofield scalar ion charge density Multifab at a given level
149149
* \param[in] Pefield scalar electron pressure MultiFab at a given level
150-
* \param[in] edge_lengths length of edges along embedded boundaries
150+
* \param[in] eb_update_E indicate in which cell E should be updated (related to embedded boundaries)
151151
* \param[in] lev level number for the calculation
152152
* \param[in] hybrid_model instance of the hybrid-PIC model
153153
* \param[in] solve_for_Faraday boolean flag for whether the E-field is solved to be used in Faraday's equation
@@ -158,7 +158,7 @@ class FiniteDifferenceSolver
158158
ablastr::fields::VectorField const& Bfield,
159159
amrex::MultiFab const& rhofield,
160160
amrex::MultiFab const& Pefield,
161-
ablastr::fields::VectorField const& edge_lengths,
161+
std::array< std::unique_ptr<amrex::iMultiFab>,3> const& eb_update_E,
162162
int lev, HybridPICModel const* hybrid_model,
163163
bool solve_for_Faraday );
164164

@@ -168,13 +168,13 @@ class FiniteDifferenceSolver
168168
*
169169
* \param[out] Jfield vector of current MultiFabs at a given level
170170
* \param[in] Bfield vector of magnetic field MultiFabs at a given level
171-
* \param[in] edge_lengths length of edges along embedded boundaries
171+
* \param[in] eb_update_E indicate in which cell E should be updated (related to embedded boundaries)
172172
* \param[in] lev level number for the calculation
173173
*/
174174
void CalculateCurrentAmpere (
175175
ablastr::fields::VectorField& Jfield,
176176
ablastr::fields::VectorField const& Bfield,
177-
ablastr::fields::VectorField const& edge_lengths,
177+
std::array< std::unique_ptr<amrex::iMultiFab>,3> const& eb_update_E,
178178
int lev );
179179

180180
private:
@@ -243,15 +243,15 @@ class FiniteDifferenceSolver
243243
ablastr::fields::VectorField const& Bfield,
244244
amrex::MultiFab const& rhofield,
245245
amrex::MultiFab const& Pefield,
246-
ablastr::fields::VectorField const& edge_lengths,
246+
std::array< std::unique_ptr<amrex::iMultiFab>,3> const& eb_update_E,
247247
int lev, HybridPICModel const* hybrid_model,
248248
bool solve_for_Faraday );
249249

250250
template<typename T_Algo>
251251
void CalculateCurrentAmpereCylindrical (
252252
ablastr::fields::VectorField& Jfield,
253253
ablastr::fields::VectorField const& Bfield,
254-
ablastr::fields::VectorField const& edge_lengths,
254+
std::array< std::unique_ptr<amrex::iMultiFab>,3> const& eb_update_E,
255255
int lev
256256
);
257257

@@ -347,15 +347,15 @@ class FiniteDifferenceSolver
347347
ablastr::fields::VectorField const& Bfield,
348348
amrex::MultiFab const& rhofield,
349349
amrex::MultiFab const& Pefield,
350-
ablastr::fields::VectorField const& edge_lengths,
350+
std::array< std::unique_ptr<amrex::iMultiFab>,3> const& eb_update_E,
351351
int lev, HybridPICModel const* hybrid_model,
352352
bool solve_for_Faraday );
353353

354354
template<typename T_Algo>
355355
void CalculateCurrentAmpereCartesian (
356356
ablastr::fields::VectorField& Jfield,
357357
ablastr::fields::VectorField const& Bfield,
358-
ablastr::fields::VectorField const& edge_lengths,
358+
std::array< std::unique_ptr<amrex::iMultiFab>,3> const& eb_update_E,
359359
int lev
360360
);
361361
#endif

Source/FieldSolver/FiniteDifferenceSolver/HybridPICModel/HybridPICModel.H

+9-9
Original file line numberDiff line numberDiff line change
@@ -62,15 +62,15 @@ public:
6262
* subtracted as well. Used in the Ohm's law solver (kinetic-fluid hybrid model).
6363
*
6464
* \param[in] Bfield Magnetic field from which the current is calculated.
65-
* \param[in] edge_lengths Length of cell edges taking embedded boundaries into account
65+
* \param[in] eb_update_E Indicate in which cell J should be calculated (related to embedded boundaries).
6666
*/
6767
void CalculatePlasmaCurrent (
6868
ablastr::fields::MultiLevelVectorField const& Bfield,
69-
ablastr::fields::MultiLevelVectorField const& edge_lengths
69+
amrex::Vector<std::array< std::unique_ptr<amrex::iMultiFab>,3 > >& eb_update_E
7070
);
7171
void CalculatePlasmaCurrent (
7272
ablastr::fields::VectorField const& Bfield,
73-
ablastr::fields::VectorField const& edge_lengths,
73+
std::array< std::unique_ptr<amrex::iMultiFab>,3 >& eb_update_E,
7474
int lev
7575
);
7676

@@ -83,31 +83,31 @@ public:
8383
ablastr::fields::MultiLevelVectorField const& Jfield,
8484
ablastr::fields::MultiLevelVectorField const& Bfield,
8585
ablastr::fields::MultiLevelScalarField const& rhofield,
86-
ablastr::fields::MultiLevelVectorField const& edge_lengths,
86+
amrex::Vector<std::array< std::unique_ptr<amrex::iMultiFab>,3 > >& eb_update_E,
8787
bool solve_for_Faraday) const;
8888

8989
void HybridPICSolveE (
9090
ablastr::fields::VectorField const& Efield,
9191
ablastr::fields::VectorField const& Jfield,
9292
ablastr::fields::VectorField const& Bfield,
9393
amrex::MultiFab const& rhofield,
94-
ablastr::fields::VectorField const& edge_lengths,
94+
std::array< std::unique_ptr<amrex::iMultiFab>,3 >& eb_update_E,
9595
int lev, bool solve_for_Faraday) const;
9696

9797
void HybridPICSolveE (
9898
ablastr::fields::VectorField const& Efield,
9999
ablastr::fields::VectorField const& Jfield,
100100
ablastr::fields::VectorField const& Bfield,
101101
amrex::MultiFab const& rhofield,
102-
ablastr::fields::VectorField const& edge_lengths,
102+
std::array< std::unique_ptr<amrex::iMultiFab>,3 >& eb_update_E,
103103
int lev, PatchType patch_type, bool solve_for_Faraday) const;
104104

105105
void BfieldEvolveRK (
106106
ablastr::fields::MultiLevelVectorField const& Bfield,
107107
ablastr::fields::MultiLevelVectorField const& Efield,
108108
ablastr::fields::MultiLevelVectorField const& Jfield,
109109
ablastr::fields::MultiLevelScalarField const& rhofield,
110-
ablastr::fields::MultiLevelVectorField const& edge_lengths,
110+
amrex::Vector<std::array< std::unique_ptr<amrex::iMultiFab>,3 > >& eb_update_E,
111111
amrex::Real dt, DtType a_dt_type,
112112
amrex::IntVect ng, std::optional<bool> nodal_sync);
113113

@@ -116,7 +116,7 @@ public:
116116
ablastr::fields::MultiLevelVectorField const& Efield,
117117
ablastr::fields::MultiLevelVectorField const& Jfield,
118118
ablastr::fields::MultiLevelScalarField const& rhofield,
119-
ablastr::fields::MultiLevelVectorField const& edge_lengths,
119+
amrex::Vector<std::array< std::unique_ptr<amrex::iMultiFab>,3 > >& eb_update_E,
120120
amrex::Real dt, int lev, DtType dt_type,
121121
amrex::IntVect ng, std::optional<bool> nodal_sync);
122122

@@ -125,7 +125,7 @@ public:
125125
ablastr::fields::MultiLevelVectorField const& Efield,
126126
ablastr::fields::MultiLevelVectorField const& Jfield,
127127
ablastr::fields::MultiLevelScalarField const& rhofield,
128-
ablastr::fields::MultiLevelVectorField const& edge_lengths,
128+
amrex::Vector<std::array< std::unique_ptr<amrex::iMultiFab>,3 > >& eb_update_E,
129129
amrex::Real dt, DtType dt_type,
130130
amrex::IntVect ng, std::optional<bool> nodal_sync);
131131

Source/FieldSolver/FiniteDifferenceSolver/HybridPICModel/HybridPICModel.cpp

+20-20
Original file line numberDiff line numberDiff line change
@@ -250,26 +250,26 @@ void HybridPICModel::GetCurrentExternal ()
250250

251251
void HybridPICModel::CalculatePlasmaCurrent (
252252
ablastr::fields::MultiLevelVectorField const& Bfield,
253-
ablastr::fields::MultiLevelVectorField const& edge_lengths)
253+
amrex::Vector<std::array< std::unique_ptr<amrex::iMultiFab>,3 > >& eb_update_E)
254254
{
255255
auto& warpx = WarpX::GetInstance();
256256
for (int lev = 0; lev <= warpx.finestLevel(); ++lev)
257257
{
258-
CalculatePlasmaCurrent(Bfield[lev], edge_lengths[lev], lev);
258+
CalculatePlasmaCurrent(Bfield[lev], eb_update_E[lev], lev);
259259
}
260260
}
261261

262262
void HybridPICModel::CalculatePlasmaCurrent (
263263
ablastr::fields::VectorField const& Bfield,
264-
ablastr::fields::VectorField const& edge_lengths,
264+
std::array< std::unique_ptr<amrex::iMultiFab>,3 >& eb_update_E,
265265
const int lev)
266266
{
267267
WARPX_PROFILE("HybridPICModel::CalculatePlasmaCurrent()");
268268

269269
auto& warpx = WarpX::GetInstance();
270270
ablastr::fields::VectorField current_fp_plasma = warpx.m_fields.get_alldirs(FieldType::hybrid_current_fp_plasma, lev);
271271
warpx.get_pointer_fdtd_solver_fp(lev)->CalculateCurrentAmpere(
272-
current_fp_plasma, Bfield, edge_lengths, lev
272+
current_fp_plasma, Bfield, eb_update_E, lev
273273
);
274274

275275
// we shouldn't apply the boundary condition to J since J = J_i - J_e but
@@ -293,15 +293,15 @@ void HybridPICModel::HybridPICSolveE (
293293
ablastr::fields::MultiLevelVectorField const& Jfield,
294294
ablastr::fields::MultiLevelVectorField const& Bfield,
295295
ablastr::fields::MultiLevelScalarField const& rhofield,
296-
ablastr::fields::MultiLevelVectorField const& edge_lengths,
296+
amrex::Vector<std::array< std::unique_ptr<amrex::iMultiFab>,3 > >& eb_update_E,
297297
const bool solve_for_Faraday) const
298298
{
299299
auto& warpx = WarpX::GetInstance();
300300
for (int lev = 0; lev <= warpx.finestLevel(); ++lev)
301301
{
302302
HybridPICSolveE(
303303
Efield[lev], Jfield[lev], Bfield[lev], *rhofield[lev],
304-
edge_lengths[lev], lev, solve_for_Faraday
304+
eb_update_E[lev], lev, solve_for_Faraday
305305
);
306306
}
307307
}
@@ -311,13 +311,13 @@ void HybridPICModel::HybridPICSolveE (
311311
ablastr::fields::VectorField const& Jfield,
312312
ablastr::fields::VectorField const& Bfield,
313313
amrex::MultiFab const& rhofield,
314-
ablastr::fields::VectorField const& edge_lengths,
314+
std::array< std::unique_ptr<amrex::iMultiFab>,3 >& eb_update_E,
315315
const int lev, const bool solve_for_Faraday) const
316316
{
317317
WARPX_PROFILE("WarpX::HybridPICSolveE()");
318318

319319
HybridPICSolveE(
320-
Efield, Jfield, Bfield, rhofield, edge_lengths, lev,
320+
Efield, Jfield, Bfield, rhofield, eb_update_E, lev,
321321
PatchType::fine, solve_for_Faraday
322322
);
323323
if (lev > 0)
@@ -332,7 +332,7 @@ void HybridPICModel::HybridPICSolveE (
332332
ablastr::fields::VectorField const& Jfield,
333333
ablastr::fields::VectorField const& Bfield,
334334
amrex::MultiFab const& rhofield,
335-
ablastr::fields::VectorField const& edge_lengths,
335+
std::array< std::unique_ptr<amrex::iMultiFab>,3 >& eb_update_E,
336336
const int lev, PatchType patch_type,
337337
const bool solve_for_Faraday) const
338338
{
@@ -344,7 +344,7 @@ void HybridPICModel::HybridPICSolveE (
344344
// Solve E field in regular cells
345345
warpx.get_pointer_fdtd_solver_fp(lev)->HybridPICSolveE(
346346
Efield, current_fp_plasma, Jfield, Bfield, rhofield,
347-
*electron_pressure_fp, edge_lengths, lev, this, solve_for_Faraday
347+
*electron_pressure_fp, eb_update_E, lev, this, solve_for_Faraday
348348
);
349349
amrex::Real const time = warpx.gett_old(0) + warpx.getdt(0);
350350
warpx.ApplyEfieldBoundary(lev, patch_type, time);
@@ -411,15 +411,15 @@ void HybridPICModel::BfieldEvolveRK (
411411
ablastr::fields::MultiLevelVectorField const& Efield,
412412
ablastr::fields::MultiLevelVectorField const& Jfield,
413413
ablastr::fields::MultiLevelScalarField const& rhofield,
414-
ablastr::fields::MultiLevelVectorField const& edge_lengths,
414+
amrex::Vector<std::array< std::unique_ptr<amrex::iMultiFab>,3 > >& eb_update_E,
415415
amrex::Real dt, DtType dt_type,
416416
IntVect ng, std::optional<bool> nodal_sync )
417417
{
418418
auto& warpx = WarpX::GetInstance();
419419
for (int lev = 0; lev <= warpx.finestLevel(); ++lev)
420420
{
421421
BfieldEvolveRK(
422-
Bfield, Efield, Jfield, rhofield, edge_lengths, dt, lev, dt_type,
422+
Bfield, Efield, Jfield, rhofield, eb_update_E, dt, lev, dt_type,
423423
ng, nodal_sync
424424
);
425425
}
@@ -430,7 +430,7 @@ void HybridPICModel::BfieldEvolveRK (
430430
ablastr::fields::MultiLevelVectorField const& Efield,
431431
ablastr::fields::MultiLevelVectorField const& Jfield,
432432
ablastr::fields::MultiLevelScalarField const& rhofield,
433-
ablastr::fields::MultiLevelVectorField const& edge_lengths,
433+
amrex::Vector<std::array< std::unique_ptr<amrex::iMultiFab>,3 > >& eb_update_E,
434434
amrex::Real dt, int lev, DtType dt_type,
435435
IntVect ng, std::optional<bool> nodal_sync )
436436
{
@@ -457,7 +457,7 @@ void HybridPICModel::BfieldEvolveRK (
457457
// The Runge-Kutta scheme begins here.
458458
// Step 1:
459459
FieldPush(
460-
Bfield, Efield, Jfield, rhofield, edge_lengths,
460+
Bfield, Efield, Jfield, rhofield, eb_update_E,
461461
0.5_rt*dt, dt_type, ng, nodal_sync
462462
);
463463

@@ -473,7 +473,7 @@ void HybridPICModel::BfieldEvolveRK (
473473

474474
// Step 2:
475475
FieldPush(
476-
Bfield, Efield, Jfield, rhofield, edge_lengths,
476+
Bfield, Efield, Jfield, rhofield, eb_update_E,
477477
0.5_rt*dt, dt_type, ng, nodal_sync
478478
);
479479

@@ -493,7 +493,7 @@ void HybridPICModel::BfieldEvolveRK (
493493

494494
// Step 3:
495495
FieldPush(
496-
Bfield, Efield, Jfield, rhofield, edge_lengths,
496+
Bfield, Efield, Jfield, rhofield, eb_update_E,
497497
dt, dt_type, ng, nodal_sync
498498
);
499499

@@ -509,7 +509,7 @@ void HybridPICModel::BfieldEvolveRK (
509509

510510
// Step 4:
511511
FieldPush(
512-
Bfield, Efield, Jfield, rhofield, edge_lengths,
512+
Bfield, Efield, Jfield, rhofield, eb_update_E,
513513
0.5_rt*dt, dt_type, ng, nodal_sync
514514
);
515515

@@ -543,16 +543,16 @@ void HybridPICModel::FieldPush (
543543
ablastr::fields::MultiLevelVectorField const& Efield,
544544
ablastr::fields::MultiLevelVectorField const& Jfield,
545545
ablastr::fields::MultiLevelScalarField const& rhofield,
546-
ablastr::fields::MultiLevelVectorField const& edge_lengths,
546+
amrex::Vector<std::array< std::unique_ptr<amrex::iMultiFab>,3 > >& eb_update_E,
547547
amrex::Real dt, DtType dt_type,
548548
IntVect ng, std::optional<bool> nodal_sync )
549549
{
550550
auto& warpx = WarpX::GetInstance();
551551

552552
// Calculate J = curl x B / mu0 - J_ext
553-
CalculatePlasmaCurrent(Bfield, edge_lengths);
553+
CalculatePlasmaCurrent(Bfield, eb_update_E);
554554
// Calculate the E-field from Ohm's law
555-
HybridPICSolveE(Efield, Jfield, Bfield, rhofield, edge_lengths, true);
555+
HybridPICSolveE(Efield, Jfield, Bfield, rhofield, eb_update_E, true);
556556
warpx.FillBoundaryE(ng, nodal_sync);
557557
// Push forward the B-field using Faraday's law
558558
amrex::Real const t_old = warpx.gett_old(0);

0 commit comments

Comments
 (0)