ERF
Energy Research and Forecasting: An Atmospheric Modeling Code
erf_sbm::SBMStateManager Class Reference

#include <ERF_SBMStateManager.H>

Collaboration diagram for erf_sbm::SBMStateManager:

Classes

struct  LevelState
 

Public Member Functions

 SBMStateManager (SBMLayout layout, int nlevels)
 
const SBMLayout & layout () const noexcept
 
int nlevels () const noexcept
 
bool is_defined (int lev) const
 
void define (int lev, const amrex::BoxArray &grids, const amrex::DistributionMapping &mapping, double current_time, int ngrow=0)
 
void destroy (int lev)
 
const amrex::MultiFab & old_state (int lev) const
 
double old_time (int lev) const
 
bool old_valid (int lev) const
 
const amrex::MultiFab & new_state (int lev) const
 
double new_time (int lev) const
 
bool new_valid (int lev) const
 
amrex::MultiFab & new_state_for_initialization (int lev)
 
amrex::MultiFab & new_target_storage (int lev)
 
bool begin_step (int lev, double step_old_time, std::string &diagnostic)
 
bool accept_stage_target (int lev, double target_time, bool physical_step_complete, std::string &diagnostic)
 
bool step_active (int lev) const
 
void project_to_core (int lev, amrex::MultiFab &core, int qc_component, int qr_component) const
 

Private Member Functions

LevelState & level (int lev)
 
const LevelState & level (int lev) const
 

Private Attributes

SBMLayout m_layout
 
SBMBulkProjection m_projection
 
std::vector< LevelState > m_levels
 

Detailed Description

Owns the authoritative old/new spectral state and its semantic times.

Constructor & Destructor Documentation

◆ SBMStateManager()

erf_sbm::SBMStateManager::SBMStateManager ( SBMLayout  layout,
int  nlevels 
)
12  : m_layout(std::move(layout)), m_projection(m_layout)
13 {
14  if (nlevels <= 0) throw std::invalid_argument("SBM state manager needs at least one level");
15  m_levels.resize(static_cast<std::size_t>(nlevels));
16 }
std::vector< LevelState > m_levels
Definition: ERF_SBMStateManager.H:74
SBMBulkProjection m_projection
Definition: ERF_SBMStateManager.H:73
SBMLayout m_layout
Definition: ERF_SBMStateManager.H:72
const SBMLayout & layout() const noexcept
Definition: ERF_SBMStateManager.H:20
int nlevels() const noexcept
Definition: ERF_SBMStateManager.H:21
Here is the call graph for this function:

Member Function Documentation

◆ accept_stage_target()

bool erf_sbm::SBMStateManager::accept_stage_target ( int  lev,
double  target_time,
bool  physical_step_complete,
std::string &  diagnostic 
)

Publish a candidate accepted by the host stage sequence.

173 {
174  diagnostic.clear();
175  auto& state = level(lev);
176  if (!state.old_state || !state.new_state || !state.step_active || !state.old_valid) {
177  diagnostic = "SBM stage target cannot be accepted without an active old/new lifecycle";
178  return false;
179  }
180  if (!std::isfinite(target_time)) {
181  diagnostic = "SBM stage target semantic time is nonfinite";
182  return false;
183  }
184  state.new_time = target_time;
185  state.new_valid = true;
186  if (physical_step_complete) state.step_active = false;
187  return true;
188 }
LevelState & level(int lev)
Definition: ERF_SBMStateManager.cpp:18

Referenced by erf_sbm::SBMTransport::advance_stage().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ begin_step()

bool erf_sbm::SBMStateManager::begin_step ( int  lev,
double  step_old_time,
std::string &  diagnostic 
)

Rotate accepted new state into old state at the ERF::Advance seam.

130 {
131  diagnostic.clear();
132  auto& state = level(lev);
133  if (!state.old_state || !state.new_state) {
134  diagnostic = "SBM begin-step requested for an undefined level";
135  return false;
136  }
137  if (!std::isfinite(step_old_time)) {
138  diagnostic = "SBM begin-step time is nonfinite";
139  return false;
140  }
141  if (state.step_active) {
142  diagnostic = "SBM begin-step requested while the prior physical step is active";
143  return false;
144  }
145  if (!state.new_valid) {
146  diagnostic = "SBM begin-step has no accepted current/new spectrum";
147  return false;
148  }
149  if (state.new_time != step_old_time) {
150  std::ostringstream message;
151  message.precision(17);
152  message << "SBM begin-step time mismatch at level " << lev
153  << ": expected host step-old time " << step_old_time
154  << ", accepted spectral time " << state.new_time
155  << ", lifecycle=accepted new state, step inactive";
156  diagnostic = message.str();
157  return false;
158  }
159 
160  // Match ERF::Advance: rotate storage by swapping ownership, never by
161  // copying the full spectral state.
162  std::swap(state.old_state, state.new_state);
163  state.old_time = state.new_time;
164  state.old_valid = true;
165  state.new_valid = false;
166  state.step_active = true;
167  return true;
168 }
Here is the call graph for this function:

◆ define()

void erf_sbm::SBMStateManager::define ( int  lev,
const amrex::BoxArray &  grids,
const amrex::DistributionMapping &  mapping,
double  current_time,
int  ngrow = 0 
)
39 {
40  if (ngrow < 0) throw std::invalid_argument("SBM ghost width cannot be negative");
41  if (!std::isfinite(current_time)) {
42  throw std::invalid_argument("SBM current semantic time must be finite");
43  }
44  auto& state = level(lev);
45  if (state.old_state || state.new_state) {
46  throw std::logic_error("SBM level state is already defined");
47  }
48 
49  state.old_state = std::make_unique<amrex::MultiFab>(
50  grids, mapping, m_layout.ncomp(), ngrow);
51  state.new_state = std::make_unique<amrex::MultiFab>(
52  grids, mapping, m_layout.ncomp(), ngrow);
53  // Both buffers are deterministic. Zero is a valid physical spectrum;
54  // validity is carried only by the semantic flags below.
55  state.old_state->setVal(amrex::Real(0.0));
56  state.new_state->setVal(amrex::Real(0.0));
57  state.old_valid = false;
58  state.new_valid = true;
59  state.old_time = 0.0;
60  state.new_time = current_time;
61  state.step_active = false;
62 }
amrex::Real Real
Definition: ERF_ShocInterface.H:19
int ncomp() const noexcept
Definition: ERF_SBMLayout.H:103
Here is the call graph for this function:

◆ destroy()

void erf_sbm::SBMStateManager::destroy ( int  lev)
65 {
66  level(lev) = LevelState{};
67 }
Here is the call graph for this function:

◆ is_defined()

bool erf_sbm::SBMStateManager::is_defined ( int  lev) const
31 {
32  const auto& state = level(lev);
33  return state.old_state != nullptr && state.new_state != nullptr;
34 }

Referenced by erf_sbm::SBMTransport::advance_stage().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ layout()

const SBMLayout& erf_sbm::SBMStateManager::layout ( ) const
inlinenoexcept
20 { return m_layout; }

◆ level() [1/2]

SBMStateManager::LevelState & erf_sbm::SBMStateManager::level ( int  lev)
private
19 {
20  if (lev < 0 || lev >= nlevels()) throw std::out_of_range("SBM level is outside the manager");
21  return m_levels[static_cast<std::size_t>(lev)];
22 }

Referenced by accept_stage_target(), begin_step(), define(), destroy(), is_defined(), new_state(), new_state_for_initialization(), new_target_storage(), new_time(), new_valid(), old_state(), old_time(), old_valid(), and step_active().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ level() [2/2]

const SBMStateManager::LevelState & erf_sbm::SBMStateManager::level ( int  lev) const
private
25 {
26  if (lev < 0 || lev >= nlevels()) throw std::out_of_range("SBM level is outside the manager");
27  return m_levels[static_cast<std::size_t>(lev)];
28 }
Here is the call graph for this function:

◆ new_state()

const amrex::MultiFab & erf_sbm::SBMStateManager::new_state ( int  lev) const

Accepted/current state. Throws while the target buffer is invalid.

90 {
91  const auto& state = level(lev);
92  if (!state.new_state || !state.new_valid) {
93  throw std::logic_error("SBM new spectral view is invalid until a stage is accepted");
94  }
95  return *state.new_state;
96 }

Referenced by erf_sbm::SBMTransport::advance_stage(), new_time(), and project_to_core().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ new_state_for_initialization()

amrex::MultiFab & erf_sbm::SBMStateManager::new_state_for_initialization ( int  lev)

Mutable accepted state for initialization and synchronized restart I/O.

110 {
111  auto& state = level(lev);
112  if (!state.new_state || !state.new_valid || state.old_valid || state.step_active) {
113  throw std::logic_error(
114  "SBM accepted new state can be edited only before the first physical step");
115  }
116  return *state.new_state;
117 }
Here is the call graph for this function:

◆ new_target_storage()

amrex::MultiFab & erf_sbm::SBMStateManager::new_target_storage ( int  lev)

Mutable target storage for transport; semantic reads remain invalid until accepted.

120 {
121  auto& state = level(lev);
122  if (!state.new_state || !state.step_active) {
123  throw std::logic_error("SBM new target storage requires an active physical step");
124  }
125  return *state.new_state;
126 }

Referenced by erf_sbm::SBMTransport::advance_stage().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ new_time()

double erf_sbm::SBMStateManager::new_time ( int  lev) const
99 {
100  static_cast<void>(new_state(lev));
101  return level(lev).new_time;
102 }
const amrex::MultiFab & new_state(int lev) const
Definition: ERF_SBMStateManager.cpp:89
double new_time
Definition: ERF_SBMStateManager.H:63

Referenced by erf_sbm::SBMTransport::advance_stage().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ new_valid()

bool erf_sbm::SBMStateManager::new_valid ( int  lev) const
105 {
106  return level(lev).new_state != nullptr && level(lev).new_valid;
107 }
std::unique_ptr< amrex::MultiFab > new_state
Definition: ERF_SBMStateManager.H:61
bool new_valid
Definition: ERF_SBMStateManager.H:65
Here is the call graph for this function:

◆ nlevels()

int erf_sbm::SBMStateManager::nlevels ( ) const
inlinenoexcept
21 { return static_cast<int>(m_levels.size()); }

Referenced by level(), and SBMStateManager().

Here is the caller graph for this function:

◆ old_state()

const amrex::MultiFab & erf_sbm::SBMStateManager::old_state ( int  lev) const

Accepted state at the beginning of an active physical step.

70 {
71  const auto& state = level(lev);
72  if (!state.old_state || !state.old_valid) {
73  throw std::logic_error("SBM old spectral view is invalid at this lifecycle point");
74  }
75  return *state.old_state;
76 }

Referenced by erf_sbm::SBMTransport::advance_stage(), and old_time().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ old_time()

double erf_sbm::SBMStateManager::old_time ( int  lev) const
79 {
80  static_cast<void>(old_state(lev));
81  return level(lev).old_time;
82 }
const amrex::MultiFab & old_state(int lev) const
Definition: ERF_SBMStateManager.cpp:69
double old_time
Definition: ERF_SBMStateManager.H:62

Referenced by erf_sbm::SBMTransport::advance_stage().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ old_valid()

bool erf_sbm::SBMStateManager::old_valid ( int  lev) const
85 {
86  return level(lev).old_state != nullptr && level(lev).old_valid;
87 }
std::unique_ptr< amrex::MultiFab > old_state
Definition: ERF_SBMStateManager.H:60
bool old_valid
Definition: ERF_SBMStateManager.H:64
Here is the call graph for this function:

◆ project_to_core()

void erf_sbm::SBMStateManager::project_to_core ( int  lev,
amrex::MultiFab &  core,
int  qc_component,
int  qr_component 
) const

One-way projection from the spectrum into ERF's compact qc and qr lanes.

198 {
199  const auto& spectrum = new_state(lev);
200  if (qc_component < 0 || qr_component < 0 ||
201  qc_component >= core.nComp() || qr_component >= core.nComp()) {
202  throw std::invalid_argument("SBM compact projection target is outside core state");
203  }
204  if (!(spectrum.boxArray() == core.boxArray()) ||
205  !(spectrum.DistributionMap() == core.DistributionMap())) {
206  throw std::invalid_argument("SBM spectrum and core state must share a level layout");
207  }
208  for (amrex::MFIter mfi(core); mfi.isValid(); ++mfi) {
209  m_projection.apply_to_core(mfi.validbox(), spectrum.const_array(mfi),
210  core.array(mfi), qc_component, qr_component);
211  }
212 }
void apply_to_core(const amrex::Box &box, const amrex::Array4< const amrex::Real > &auxiliary, const amrex::Array4< amrex::Real > &core, int qc_component, int qr_component) const
Definition: ERF_SBMBulkProjection.cpp:43

Referenced by erf_sbm::SBMTransport::advance_stage().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ step_active()

bool erf_sbm::SBMStateManager::step_active ( int  lev) const
191 {
192  return level(lev).step_active;
193 }
bool step_active
Definition: ERF_SBMStateManager.H:66

Referenced by erf_sbm::SBMTransport::advance_stage().

Here is the call graph for this function:
Here is the caller graph for this function:

Member Data Documentation

◆ m_layout

SBMLayout erf_sbm::SBMStateManager::m_layout
private

Referenced by define(), and layout().

◆ m_levels

std::vector<LevelState> erf_sbm::SBMStateManager::m_levels
private

Referenced by level(), nlevels(), and SBMStateManager().

◆ m_projection

SBMBulkProjection erf_sbm::SBMStateManager::m_projection
private

Referenced by project_to_core().


The documentation for this class was generated from the following files: