Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ferrorelectric support in ARTEMIS #116

Draft
wants to merge 15 commits into
base: development
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion GNUmakefile
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@ WarpxBinDir = Bin
USE_PSATD = FALSE
USE_PSATD_PICSAR = FALSE
USE_RZ = FALSE
USE_LLG = TRUE
USE_LLG = FALSE
USE_FERROE = TRUE

USE_EB = FALSE

Expand Down
18 changes: 18 additions & 0 deletions Source/Diagnostics/Diagnostics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,24 @@ Diagnostics::BaseReadParameters ()

#endif

#ifdef WARPX_FERROE
// polarization can be written to file only if WarpX::em_solver_medium == MediumForEM::Macroscopic
if (utils::algorithms::is_in(m_varnames, "px") || utils::algorithms::is_in(m_varnames, "py") || utils::algorithms::is_in(m_varnames, "pz"))
{
AMREX_ALWAYS_ASSERT_WITH_MESSAGE(
WarpX::em_solver_medium == MediumForEM::Macroscopic,
"polarization in plotfiles only works with algo.em_solver_medium=macroscopic");
}

// ferroelectric can be written to file only if WarpX::em_solver_medium == MediumForEM::Macroscopic
if (utils::algorithms::is_in(m_varnames, "ferroelectric"))
{
AMREX_ALWAYS_ASSERT_WITH_MESSAGE(
WarpX::em_solver_medium == MediumForEM::Macroscopic,
"ferroelectric in plotfiles only works with algo.em_solver_medium=macroscopic");
}
#endif

// If user requests to plot proc_number for a serial run,
// delete proc_number from fields_to_plot
if (amrex::ParallelDescriptor::NProcs() == 1){
Expand Down
38 changes: 38 additions & 0 deletions Source/Diagnostics/FlushFormats/FlushFormatCheckpoint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,15 @@ FlushFormatCheckpoint::WriteToFile (
amrex::MultiFabFileFullPrefix(lev, checkpointname, default_level_prefix, "Hzbias_fp"));
#endif

#ifdef WARPX_FERROE
VisMF::Write(warpx.getpolarization_fp(lev, 0),
amrex::MultiFabFileFullPrefix(lev, checkpointname, default_level_prefix, "px_fp"));
VisMF::Write(warpx.getpolarization_fp(lev, 1),
amrex::MultiFabFileFullPrefix(lev, checkpointname, default_level_prefix, "py_fp"));
VisMF::Write(warpx.getpolarization_fp(lev, 2),
amrex::MultiFabFileFullPrefix(lev, checkpointname, default_level_prefix, "pz_fp"));
#endif

if (WarpX::fft_do_time_averaging)
{
VisMF::Write(warpx.getEfield_avg_fp(lev, 0),
Expand Down Expand Up @@ -123,6 +132,16 @@ FlushFormatCheckpoint::WriteToFile (
amrex::MultiFabFileFullPrefix(lev, checkpointname, default_level_prefix, "jz_fp"));
}

if (warpx.getis_synchronized() || WarpX::yee_coupled_solver_algo == CoupledYeeSolver::MaxwellFerroE) {
// Need to save j if synchronized because after restart we need j to evolve E by dt/2.
VisMF::Write(warpx.getcurrent_fp(lev, 0),
amrex::MultiFabFileFullPrefix(lev, checkpointname, default_level_prefix, "jx_fp"));
VisMF::Write(warpx.getcurrent_fp(lev, 1),
amrex::MultiFabFileFullPrefix(lev, checkpointname, default_level_prefix, "jy_fp"));
VisMF::Write(warpx.getcurrent_fp(lev, 2),
amrex::MultiFabFileFullPrefix(lev, checkpointname, default_level_prefix, "jz_fp"));
}

if (lev > 0)
{
VisMF::Write(warpx.getEfield_cp(lev, 0),
Expand Down Expand Up @@ -159,6 +178,15 @@ FlushFormatCheckpoint::WriteToFile (
amrex::MultiFabFileFullPrefix(lev, checkpointname, default_level_prefix, "Hzbias_fp"));
#endif

#ifdef WARPX_FERROE
VisMF::Write(warpx.getpolarization_cp(lev, 0),
amrex::MultiFabFileFullPrefix(lev, checkpointname, default_level_prefix, "px_cp"));
VisMF::Write(warpx.getpolarization_cp(lev, 1),
amrex::MultiFabFileFullPrefix(lev, checkpointname, default_level_prefix, "py_cp"));
VisMF::Write(warpx.getpolarization_cp(lev, 2),
amrex::MultiFabFileFullPrefix(lev, checkpointname, default_level_prefix, "pz_cp"));
#endif

if (WarpX::fft_do_time_averaging)
{
VisMF::Write(warpx.getEfield_avg_cp(lev, 0),
Expand All @@ -185,6 +213,16 @@ FlushFormatCheckpoint::WriteToFile (
VisMF::Write(warpx.getcurrent_cp(lev, 2),
amrex::MultiFabFileFullPrefix(lev, checkpointname, default_level_prefix, "jz_cp"));
}

if (warpx.getis_synchronized() || WarpX::yee_coupled_solver_algo == CoupledYeeSolver::MaxwellFerroE) {
// Need to save j if synchronized because after restart we need j to evolve E by dt/2.
VisMF::Write(warpx.getcurrent_cp(lev, 0),
amrex::MultiFabFileFullPrefix(lev, checkpointname, default_level_prefix, "jx_cp"));
VisMF::Write(warpx.getcurrent_cp(lev, 1),
amrex::MultiFabFileFullPrefix(lev, checkpointname, default_level_prefix, "jy_cp"));
VisMF::Write(warpx.getcurrent_cp(lev, 2),
amrex::MultiFabFileFullPrefix(lev, checkpointname, default_level_prefix, "jz_cp"));
}
}

if (warpx.DoPML()) {
Expand Down
5 changes: 5 additions & 0 deletions Source/Diagnostics/FlushFormats/FlushFormatPlotfile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -573,6 +573,11 @@ FlushFormatPlotfile::WriteAllRawFields(
WriteRawMF( warpx.getMfield_fp(lev, 0), dm, raw_pltname, default_level_prefix, "M_xface_fp", lev, plot_raw_fields_guards);
WriteRawMF( warpx.getMfield_fp(lev, 1), dm, raw_pltname, default_level_prefix, "M_yface_fp", lev, plot_raw_fields_guards);
WriteRawMF( warpx.getMfield_fp(lev, 2), dm, raw_pltname, default_level_prefix, "M_zface_fp", lev, plot_raw_fields_guards);
#endif
#ifdef WARPX_FERROE
WriteRawMF( warpx.getpolarization_fp(lev, 0), dm, raw_pltname, default_level_prefix, "px_fp", lev, plot_raw_fields_guards);
WriteRawMF( warpx.getpolarization_fp(lev, 1), dm, raw_pltname, default_level_prefix, "py_fp", lev, plot_raw_fields_guards);
WriteRawMF( warpx.getpolarization_fp(lev, 2), dm, raw_pltname, default_level_prefix, "pz_fp", lev, plot_raw_fields_guards);
#endif
if (warpx.get_pointer_F_fp(lev))
{
Expand Down
17 changes: 17 additions & 0 deletions Source/Diagnostics/FullDiagnostics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "Utils/WarpXAlgorithmSelection.H"
#include "FieldSolver/FiniteDifferenceSolver/MacroscopicProperties/MacroscopicProperties.H"
#include "FieldSolver/London/London.H"
#include "FieldSolver/FerroE/FerroE.H"
#include "WarpX.H"


Expand Down Expand Up @@ -701,6 +702,22 @@ FullDiagnostics::InitializeFieldFunctors (int lev)
} else if (m_varnames[comp] == "mag_anisotropy_zface" ){
MacroscopicProperties& macroscopic = warpx.GetMacroscopicProperties();
m_all_field_functors[lev][comp] = std::make_unique<CellCenterFunctor>(macroscopic.getmag_pointer_anisotropy(2), lev, m_crse_ratio);
#endif
#ifdef WARPX_FERROE
} else if ( m_varnames[comp] == "ferroelectric") {
m_all_field_functors[lev][comp] = std::make_unique<CellCenterFunctor>(warpx.getFerroE().m_ferroelectric_mf.get(), lev, m_crse_ratio);
} else if ( m_varnames[comp] == "px" ){
m_all_field_functors[lev][comp] = std::make_unique<CellCenterFunctor>(warpx.get_pointer_polarization_fp(lev, 0), lev, m_crse_ratio, true, 1, 0);
} else if ( m_varnames[comp] == "py" ){
m_all_field_functors[lev][comp] = std::make_unique<CellCenterFunctor>(warpx.get_pointer_polarization_fp(lev, 1), lev, m_crse_ratio, true, 1, 0);
} else if ( m_varnames[comp] == "pz" ){
m_all_field_functors[lev][comp] = std::make_unique<CellCenterFunctor>(warpx.get_pointer_polarization_fp(lev, 2), lev, m_crse_ratio, true, 1, 0);
} else if ( m_varnames[comp] == "dpxdt" ){
m_all_field_functors[lev][comp] = std::make_unique<CellCenterFunctor>(warpx.get_pointer_polarization_fp(lev, 0), lev, m_crse_ratio, true, 1, 1);
} else if ( m_varnames[comp] == "dpydt" ){
m_all_field_functors[lev][comp] = std::make_unique<CellCenterFunctor>(warpx.get_pointer_polarization_fp(lev, 1), lev, m_crse_ratio, true, 1, 1);
} else if ( m_varnames[comp] == "dpzdt" ){
m_all_field_functors[lev][comp] = std::make_unique<CellCenterFunctor>(warpx.get_pointer_polarization_fp(lev, 2), lev, m_crse_ratio, true, 1, 1);
#endif
} else if ( m_varnames[comp] == "superconductor") {
m_all_field_functors[lev][comp] = std::make_unique<CellCenterFunctor>(warpx.getLondon().m_superconductor_mf.get(), lev, m_crse_ratio);
Expand Down
43 changes: 43 additions & 0 deletions Source/Diagnostics/WarpXIO.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,9 @@ WarpX::InitFromCheckpoint ()
Bfield_fp[lev][i]->setVal(0.0);
#ifdef WARPX_MAG_LLG
Mfield_fp[lev][i]->setVal(0.0);
#endif
#ifdef WARPX_FERROE
polarization_fp[lev][i]->setVal(0.0);
#endif
}

Expand All @@ -302,6 +305,9 @@ WarpX::InitFromCheckpoint ()
Bfield_cp[lev][i]->setVal(0.0);
#ifdef WARPX_MAG_LLG
Mfield_cp[lev][i]->setVal(0.0);
#endif
#ifdef WARPX_FERROE
polarization_cp[lev][i]->setVal(0.0);
#endif
}
}
Expand Down Expand Up @@ -340,6 +346,16 @@ WarpX::InitFromCheckpoint ()
VisMF::Read(*H_biasfield_fp[lev][2],
amrex::MultiFabFileFullPrefix(lev, restart_chkfile, level_prefix, "Hzbias_fp"));
#endif

#ifdef WARPX_FERROE
VisMF::Read(*polarization_fp[lev][0],
amrex::MultiFabFileFullPrefix(lev, restart_chkfile, level_prefix, "px_fp"));
VisMF::Read(*polarization_fp[lev][1],
amrex::MultiFabFileFullPrefix(lev, restart_chkfile, level_prefix, "py_fp"));
VisMF::Read(*polarization_fp[lev][2],
amrex::MultiFabFileFullPrefix(lev, restart_chkfile, level_prefix, "pz_fp"));
#endif

if (WarpX::fft_do_time_averaging)
{
VisMF::Read(*Efield_avg_fp[lev][0],
Expand All @@ -366,6 +382,15 @@ WarpX::InitFromCheckpoint ()
amrex::MultiFabFileFullPrefix(lev, restart_chkfile, level_prefix, "jz_fp"));
}

if (is_synchronized || WarpX::yee_coupled_solver_algo == CoupledYeeSolver::MaxwellFerroE) {
VisMF::Read(*current_fp[lev][0],
amrex::MultiFabFileFullPrefix(lev, restart_chkfile, level_prefix, "jx_fp"));
VisMF::Read(*current_fp[lev][1],
amrex::MultiFabFileFullPrefix(lev, restart_chkfile, level_prefix, "jy_fp"));
VisMF::Read(*current_fp[lev][2],
amrex::MultiFabFileFullPrefix(lev, restart_chkfile, level_prefix, "jz_fp"));
}

if (lev > 0)
{
VisMF::Read(*Efield_cp[lev][0],
Expand Down Expand Up @@ -404,6 +429,15 @@ WarpX::InitFromCheckpoint ()
VisMF::Read(*H_biasfield_cp[lev][2],
amrex::MultiFabFileFullPrefix(lev, restart_chkfile, level_prefix, "Hzbias_cp"));
#endif

#ifdef WARPX_FERROE
VisMF::Read(*polarization_cp[lev][0],
amrex::MultiFabFileFullPrefix(lev, restart_chkfile, level_prefix, "px_cp"));
VisMF::Read(*polarization_cp[lev][1],
amrex::MultiFabFileFullPrefix(lev, restart_chkfile, level_prefix, "py_cp"));
VisMF::Read(*polarization_cp[lev][2],
amrex::MultiFabFileFullPrefix(lev, restart_chkfile, level_prefix, "pz_cp"));
#endif
if (WarpX::fft_do_time_averaging)
{
VisMF::Read(*Efield_avg_cp[lev][0],
Expand All @@ -429,6 +463,15 @@ WarpX::InitFromCheckpoint ()
VisMF::Read(*current_cp[lev][2],
amrex::MultiFabFileFullPrefix(lev, restart_chkfile, level_prefix, "jz_cp"));
}

if (is_synchronized || WarpX::yee_coupled_solver_algo == CoupledYeeSolver::MaxwellFerroE) {
VisMF::Read(*current_cp[lev][0],
amrex::MultiFabFileFullPrefix(lev, restart_chkfile, level_prefix, "jx_cp"));
VisMF::Read(*current_cp[lev][1],
amrex::MultiFabFileFullPrefix(lev, restart_chkfile, level_prefix, "jy_cp"));
VisMF::Read(*current_cp[lev][2],
amrex::MultiFabFileFullPrefix(lev, restart_chkfile, level_prefix, "jz_cp"));
}
}
}

Expand Down
25 changes: 25 additions & 0 deletions Source/Evolve/WarpXEvolve.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include "Utils/WarpXProfilerWrapper.H"
#include "Utils/WarpXUtil.H"
#include "FieldSolver/London/London.H"
#include "FieldSolver/FerroE/FerroE.H"

#include <ablastr/utils/SignalHandling.H>
#include <ablastr/warn_manager/WarnManager.H>
Expand Down Expand Up @@ -150,6 +151,14 @@ WarpX::Evolve (int numsteps)
m_london->EvolveLondonJ(-0.5_rt*dt[0]); // J^(n) to J^(n-1/2) using E^(n)
FillBoundaryJ(guard_cells.ng_alloc_EB);
}
#ifdef WARPX_FERROE
if (WarpX::yee_coupled_solver_algo == CoupledYeeSolver::MaxwellFerroE) {
m_ferroe->EvolveP(-0.5_rt*dt[0]); // P^(n) to P^(n-1/2) using E^(n)
FillBoundaryP(guard_cells.ng_alloc_EB);
m_ferroe->EvolveFerroEJ(-0.5_rt*dt[0]); // J^(n) to J^(n-1/2) using E^(n)
FillBoundaryJ(guard_cells.ng_alloc_EB);
}
#endif
is_synchronized = false;
} else {
if (electrostatic_solver_id == ElectrostaticSolverAlgo::None) {
Expand Down Expand Up @@ -203,6 +212,9 @@ WarpX::Evolve (int numsteps)
if (WarpX::yee_coupled_solver_algo != CoupledYeeSolver::MaxwellLondon) {
PushParticlesandDepose(cur_time, skip_deposition);
}
if (WarpX::yee_coupled_solver_algo != CoupledYeeSolver::MaxwellFerroE) {
PushParticlesandDepose(cur_time, skip_deposition);
}
}
// Electromagnetic case: multi-J algorithm
else if (do_multi_J)
Expand Down Expand Up @@ -429,6 +441,9 @@ WarpX::OneStep_nosub (Real cur_time)
if (WarpX::yee_coupled_solver_algo != CoupledYeeSolver::MaxwellLondon) {
PushParticlesandDepose(cur_time);
}
if (WarpX::yee_coupled_solver_algo != CoupledYeeSolver::MaxwellFerroE) {
PushParticlesandDepose(cur_time);
}
#ifndef WARPX_MAG_LLG
if (WarpX::yee_coupled_solver_algo == CoupledYeeSolver::MaxwellLondon) {
amrex::Print() << " in evolve london j\n";
Expand All @@ -438,6 +453,16 @@ WarpX::OneStep_nosub (Real cur_time)
// fill boundary here
}
#endif
#ifdef WARPX_FERROE
if (WarpX::yee_coupled_solver_algo == CoupledYeeSolver::MaxwellFerroE) {
amrex::Print() << " in evolve ferroelectric j\n";
m_ferroe->EvolveP(dt[0]); // P^(n-1/2) to P^(n+1/2) using E^(n)
FillBoundaryP(guard_cells.ng_alloc_EB);
m_ferroe->EvolveFerroEJ(dt[0]); // J^(n-1/2) to J^(n+1/2) using E^(n)
FillBoundaryJ(guard_cells.ng_alloc_EB);
// fill boundary here
}
#endif

ExecutePythonCallback("afterdeposition");

Expand Down
4 changes: 4 additions & 0 deletions Source/FieldSolver/FerroE/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
target_sources(WarpX
PRIVATE
FerroE.cpp
)
Loading