Skip to content

Commit a41330f

Browse files
authored
start of a tool to compute spectral radius from a plotfile (#11)
this can be used to find the zone that makes the network stiff
1 parent 1357da8 commit a41330f

File tree

5 files changed

+212
-0
lines changed

5 files changed

+212
-0
lines changed

source/spectral_radius/GNUmakefile

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
PRECISION = DOUBLE
2+
PROFILE = FALSE
3+
4+
DEBUG = FALSE
5+
6+
DIM = 2
7+
8+
COMP = g++
9+
10+
BL_NO_FORT = TRUE
11+
12+
USE_MPI = FALSE
13+
USE_OMP = FALSE
14+
15+
USE_REACT = TRUE
16+
USE_CXX_EOS = TRUE
17+
18+
MAX_ZONES := 16384
19+
20+
DEFINES += -DNPTS_MODEL=$(MAX_ZONES)
21+
22+
# programs to be compiled
23+
EBASE := sprad
24+
25+
# EOS and network
26+
EOS_DIR := helmholtz
27+
28+
# this should match what we used for the simulation
29+
NETWORK_DIR := nova
30+
31+
# this should be RKC so we have access to the circle theorem function
32+
INTEGRATOR_DIR := RKC
33+
34+
Bpack := ./Make.package
35+
Blocs := . ..
36+
37+
EXTERN_SEARCH += . ..
38+
39+
include $(MICROPHYSICS_HOME)/Make.Microphysics
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
CEXE_sources += main.cpp

source/spectral_radius/README.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
# `spectral_radius`
2+
3+
This tool returns the thermodynamic state information about for
4+
the zone where the reaction network Jacobian has the largest
5+
spectral radius (maximum absolute value eigenvalue). This can be
6+
used to help assess the stiffness of the network for a particular
7+
problems.
8+
9+
To build, do:
10+
11+
```
12+
make DIM=2
13+
```
14+
15+
changing the `DIM` line to match the dimension of your plotfile.
16+
17+
It is also important that the network you build with matches
18+
the one used for generating the plotfile. This is set via
19+
the `NETWORK_DIR` parameter in the `GNUmakefile`.
20+
21+
Runtime parameters are managed by AMReX's ParmParse. To run,
22+
you specify the plotfile via `diag.plotfile`, either in an inputs
23+
file or on the command line, e.g.:
24+
25+
```
26+
./sprad2d.gnu.ex diag.plotfile=plt00000
27+
```
28+
29+
30+

source/spectral_radius/_parameters

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
@namespace: diag
2+
3+
small_temp real -1.e200
4+
small_dens real -1.e200
5+
6+
plotfile string ""

source/spectral_radius/main.cpp

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
//
2+
// loop over zones and compute the spectral radius of the reaction
3+
// network Jacobian and then output the thermodynamic state of the
4+
// zone with the largest spectral radius.
5+
//
6+
#include <iostream>
7+
// #include <stringstream>
8+
#include <regex>
9+
#include <string>
10+
#include <AMReX_PlotFileUtil.H>
11+
#include <AMReX_MultiFabUtil.H>
12+
#include <AMReX_ParallelDescriptor.H>
13+
14+
#include <amrex_astro_util.H>
15+
16+
#include <extern_parameters.H>
17+
18+
#include <network.H>
19+
#include <eos.H>
20+
#include <burn_type.H>
21+
#include <rkc_type.H>
22+
#include <integrator_data.H>
23+
#include <circle_theorem.H>
24+
25+
using namespace amrex;
26+
27+
28+
int main(int argc, char* argv[])
29+
{
30+
31+
amrex::Initialize(argc, argv);
32+
33+
// initialize the runtime parameters
34+
35+
init_extern_parameters();
36+
37+
// initialize C++ Microphysics
38+
39+
eos_init(diag_rp::small_temp, diag_rp::small_dens);
40+
network_init();
41+
42+
// timer for profiling
43+
44+
BL_PROFILE_VAR("main()", pmain);
45+
46+
// read the plotfile metadata
47+
48+
PlotFileData pf(diag_rp::plotfile);
49+
50+
int fine_level = pf.finestLevel();
51+
const int dim = pf.spaceDim();
52+
53+
// find variable indices -- we want density, temperature, and species.
54+
// we will assume here that the species are contiguous, so we will find
55+
// the index of the first species
56+
57+
// the plotfile can store either (rho X) or just X alone. Here we'll assume
58+
// that we have just X alone
59+
60+
const Vector<std::string>& var_names_pf = pf.varNames();
61+
62+
int dens_comp = get_dens_index(var_names_pf);
63+
int temp_comp = get_temp_index(var_names_pf);
64+
int spec_comp = get_spec_index(var_names_pf);
65+
66+
amrex::Real sprad_max{-1.0};
67+
burn_t burn_state_max;
68+
69+
for (int ilev = 0; ilev <= fine_level; ++ilev) {
70+
71+
IntVect ratio{pf.refRatio(ilev)};
72+
for (int idim = dim; idim < AMREX_SPACEDIM; ++idim) {
73+
ratio[idim] = 1;
74+
}
75+
76+
const MultiFab& lev_data_mf = pf.get(ilev);
77+
78+
for (MFIter mfi(lev_data_mf); mfi.isValid(); ++mfi) {
79+
const Box& bx = mfi.validbox();
80+
if (bx.ok()) {
81+
const auto& fab = lev_data_mf.array(mfi);
82+
const auto lo = amrex::lbound(bx);
83+
const auto hi = amrex::ubound(bx);
84+
85+
for (int k = lo.z; k <= hi.z; ++k) {
86+
for (int j = lo.y; j <= hi.y; ++j) {
87+
for (int i = lo.x; i <= hi.x; ++i) {
88+
89+
burn_t burn_state;
90+
91+
burn_state.rho = fab(i,j,k,dens_comp);
92+
burn_state.T = fab(i,j,k,temp_comp);
93+
for (int n = 0; n < NumSpec; ++n) {
94+
burn_state.xn[n] = fab(i,j,k,spec_comp+n);
95+
}
96+
97+
// we also need internal energy
98+
eos(eos_input_rt, burn_state);
99+
burn_state.e_scale = burn_state.e;
100+
101+
// we need to load up the integrator type
102+
constexpr int int_neqs = integrator_neqs<burn_t>();
103+
rkc_t<int_neqs> rstate;
104+
burn_to_integrator(burn_state, rstate);
105+
rstate.t = 0.0;
106+
107+
amrex::Real sprad{};
108+
circle_theorem_sprad(rstate.t, burn_state, rstate, sprad);
109+
110+
if (std::abs(sprad) > sprad_max) {
111+
sprad_max = std::abs(sprad);
112+
burn_state_max = burn_state;
113+
}
114+
}
115+
}
116+
}
117+
118+
} // bx.ok()
119+
120+
} // MFIter
121+
122+
} // level loop
123+
124+
std::cout << "maximum spectral radius = " << sprad_max << std::endl;
125+
std::cout << "T = " << burn_state_max.T << std::endl;
126+
std::cout << "rho = " << burn_state_max.rho << std::endl;
127+
for (int n = 0; n < NumSpec; ++n) {
128+
std::cout << "X(" << short_spec_names_cxx[n] << ") = " << burn_state_max.xn[n] << std::endl;
129+
}
130+
131+
// destroy timer for profiling
132+
BL_PROFILE_VAR_STOP(pmain);
133+
134+
amrex::Finalize();
135+
}
136+

0 commit comments

Comments
 (0)