Skip to content

Commit ce01c6a

Browse files
committed
start of a tool to compute spectral radius from a plotfile
this can be used to find the zone that makes the network stiff
1 parent 17b7cea commit ce01c6a

File tree

5 files changed

+238
-0
lines changed

5 files changed

+238
-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-li
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: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
1+
//
2+
// Process a sedov problem to produce rho, u, and p as a
3+
// function of r, for comparison to the analytic solution.
4+
//
5+
#include <iostream>
6+
// #include <stringstream>
7+
#include <regex>
8+
#include <string>
9+
#include <AMReX_PlotFileUtil.H>
10+
#include <AMReX_MultiFabUtil.H>
11+
#include <AMReX_ParallelDescriptor.H>
12+
13+
#include <amrex_astro_util.H>
14+
15+
#include <extern_parameters.H>
16+
17+
#include <network.H>
18+
#include <eos.H>
19+
20+
using namespace amrex;
21+
22+
23+
int main(int argc, char* argv[])
24+
{
25+
26+
amrex::Initialize(argc, argv);
27+
28+
// initialize the runtime parameters
29+
30+
init_extern_parameters();
31+
32+
// initialize C++ Microphysics
33+
34+
eos_init(diag_rp::small_temp, diag_rp::small_dens);
35+
network_init();
36+
37+
// timer for profiling
38+
39+
BL_PROFILE_VAR("main()", pmain);
40+
41+
// read the plotfile metadata
42+
43+
PlotFileData pf(diag_rp::plotfile);
44+
45+
int fine_level = pf.finestLevel();
46+
const int dim = pf.spaceDim();
47+
48+
// find variable indices -- we want density, temperature, and species.
49+
// we will assume here that the species are contiguous, so we will find
50+
// the index of the first species
51+
52+
// the plotfile can store either (rho X) or just X alone. Here we'll assume
53+
// that we have just X alone
54+
55+
const Vector<std::string>& var_names_pf = pf.varNames();
56+
57+
int dens_comp = get_dens_index(var_names_pf);
58+
int temp_comp = get_temp_index(var_names_pf);
59+
int spec_comp = get_spec_index(var_names_pf);
60+
61+
// we will use a mask that tells us if a zone on the current level
62+
// is covered by data on a finer level.
63+
64+
for (int ilev = 0; ilev <= fine_level; ++ilev) {
65+
66+
if (ilev < fine_level) {
67+
IntVect ratio{pf.refRatio(ilev)};
68+
for (int idim = dim; idim < AMREX_SPACEDIM; ++idim) {
69+
ratio[idim] = 1;
70+
}
71+
const iMultiFab mask = makeFineMask(pf.boxArray(ilev), pf.DistributionMap(ilev),
72+
pf.boxArray(ilev+1), ratio);
73+
74+
const MultiFab& lev_data_mf = pf.get(ilev);
75+
76+
for (MFIter mfi(lev_data_mf); mfi.isValid(); ++mfi) {
77+
const Box& bx = mfi.validbox();
78+
if (bx.ok()) {
79+
const auto& m = mask.array(mfi);
80+
const auto& fab = lev_data_mf.array(mfi);
81+
const auto lo = amrex::lbound(bx);
82+
const auto hi = amrex::ubound(bx);
83+
84+
for (int k = lo.z; k <= hi.z; ++k) {
85+
for (int j = lo.y; j <= hi.y; ++j) {
86+
for (int i = lo.x; i <= hi.x; ++i) {
87+
88+
// if we only wanted to work on the zones not covered
89+
// by finer grids (e.g., for computing a global sum)
90+
// we'd uncomment this mask check
91+
92+
//if (m(i,j,k) == 0) { // not covered by fine
93+
94+
// compute the coordinate of the current zone
95+
96+
eos_t eos_state;
97+
98+
eos_state.rho = fab(i,j,k,dens_comp);
99+
eos_state.T = fab(i,j,k,temp_comp);
100+
for (int n = 0; n < NumSpec; ++n) {
101+
eos_state.xn[n] = fab(i,j,k,spec_comp+n);
102+
}
103+
104+
eos(eos_input_rt, eos_state);
105+
106+
// } // mask
107+
108+
}
109+
}
110+
}
111+
112+
} // bx.ok()
113+
114+
} // MFIter
115+
116+
} else {
117+
// this is the finest level
118+
119+
const MultiFab& lev_data_mf = pf.get(ilev);
120+
121+
for (MFIter mfi(lev_data_mf); mfi.isValid(); ++mfi) {
122+
const Box& bx = mfi.validbox();
123+
if (bx.ok()) {
124+
const auto& fab = lev_data_mf.array(mfi);
125+
const auto lo = amrex::lbound(bx);
126+
const auto hi = amrex::ubound(bx);
127+
128+
for (int k = lo.z; k <= hi.z; ++k) {
129+
for (int j = lo.y; j <= hi.y; ++j) {
130+
for (int i = lo.x; i <= hi.x; ++i) {
131+
132+
eos_t eos_state;
133+
134+
eos_state.rho = fab(i,j,k,dens_comp);
135+
eos_state.T = fab(i,j,k,temp_comp);
136+
for (int n = 0; n < NumSpec; ++n) {
137+
eos_state.xn[n] = fab(i,j,k,spec_comp+n);
138+
}
139+
140+
eos(eos_input_rt, eos_state);
141+
142+
}
143+
}
144+
}
145+
146+
} // bx.ok()
147+
148+
} // MFIter
149+
150+
151+
}
152+
153+
} // level loop
154+
155+
156+
157+
// destroy timer for profiling
158+
BL_PROFILE_VAR_STOP(pmain);
159+
160+
amrex::Finalize();
161+
}
162+

0 commit comments

Comments
 (0)