Skip to content

Commit

Permalink
for #7332 rework field slicing
Browse files Browse the repository at this point in the history
  • Loading branch information
moellep committed Oct 25, 2024
1 parent a8fd98f commit ddc54e2
Show file tree
Hide file tree
Showing 3 changed files with 133 additions and 124 deletions.
207 changes: 119 additions & 88 deletions sirepo/package_data/static/js/openmc.js
Original file line number Diff line number Diff line change
Expand Up @@ -445,7 +445,6 @@ SIREPO.app.controller('VisualizationController', function(appState, errorService
openmcService.invalidateRange('thresholds');
openmcService.invalidateRange('colorRange');
r.isEnergySelected = "0";
panelState.clear('tallyReport');
self.simState.saveAndRunSimulation('openmcAnimation');
};
self.simState.logFileURL = function() {
Expand Down Expand Up @@ -537,6 +536,18 @@ SIREPO.app.factory('tallyService', function(appState, openmcService, utilities,
sourceParticles: [],
};

function initMesh() {
self.mesh = null;
const t = openmcService.findTally();
for (let k = 1; k <= SIREPO.APP_SCHEMA.constants.maxFilters; k++) {
const f = t[`filter${k}`];
if (f && f._type === 'meshFilter') {
self.mesh = f;
return;
}
}
}

function normalizer(score, numParticles) {
if (numParticles === undefined || ! openmcService.canNormalizeScore(score)) {
return x => x;
Expand Down Expand Up @@ -603,19 +614,6 @@ SIREPO.app.factory('tallyService', function(appState, openmcService, utilities,

self.getSourceParticles = () => self.sourceParticles;

self.initMesh = () => {
const t = openmcService.findTally();
for (let k = 1; k <= SIREPO.APP_SCHEMA.constants.maxFilters; k++) {
const f = t[`filter${k}`];
if (f && f._type === 'meshFilter') {
self.mesh = f;
return true;
}
}
self.mesh = null;
return false;
};

self.setFieldData = (fieldData, min, max, numParticles) => {
const n = normalizer(appState.models.openmcAnimation.score, numParticles);
self.fieldData = fieldData.map(n);
Expand All @@ -633,6 +631,8 @@ SIREPO.app.factory('tallyService', function(appState, openmcService, utilities,
f.stop,
];
}
appState.models.tallyReport.planePos = 0;
initMesh();
};

self.setOutlines = (tally, outlines) => {
Expand Down Expand Up @@ -959,6 +959,7 @@ SIREPO.app.directive('geometry2d', function(appState, openmcService, panelState,
controller: function($scope) {
$scope.tallyService = tallyService;
const displayRanges = {};
let lastTally = [null, null];
const sources = openmcService.getSourceVisualizations(
{
box: space => {
Expand Down Expand Up @@ -994,7 +995,7 @@ SIREPO.app.directive('geometry2d', function(appState, openmcService, panelState,
}

function buildTallyReport() {
if (! tallyService.mesh) {
if (! tallyService.fieldData) {
return;
}
const [z, x, y] = tallyReportAxes();
Expand Down Expand Up @@ -1022,23 +1023,22 @@ SIREPO.app.directive('geometry2d', function(appState, openmcService, panelState,
x_range: ranges[l],
y_label: `${y} [m]`,
y_range: ranges[m],
z_matrix: reorderFieldData(tallyService.mesh.dimension)[fieldIndex(pos, ranges[n], n)],
z_matrix: sliceFieldData(),
z_range: ranges[n],
overlayData: getOutlines(pos, ranges[n], n),
selectedCoords: $scope.energyFilter ? tallyService.getEnergyReportCoords() : null,
};
panelState.setData('tallyReport', r);
$scope.$broadcast('tallyReport.reload', r);
}

function displayRangeIndices() {
const r = tallyService.getMeshRanges();
return [
displayRanges.x,
displayRanges.y,
displayRanges.z,
]
.map((x, i) => [fieldIndex(x.min, r[i], i), fieldIndex(x.max, r[i], i)]);
if (
(lastTally[0] != appState.models.openmcAnimation.tally)
|| (lastTally[1] != appState.models.tallyReport.planePos)
) {
const newTally = [appState.models.openmcAnimation.tally, appState.models.tallyReport.planePos];
//console.log('HERE request outlines', lastTally, newTally);
lastTally = newTally;
}
}

function energySumLabel() {
Expand Down Expand Up @@ -1168,32 +1168,51 @@ SIREPO.app.directive('geometry2d', function(appState, openmcService, panelState,
return outlines;
}

function reorderFieldData(dims) {
const [n, m, l] = tallyReportAxisIndices();
const fd = tallyService.fieldData;
const d = SIREPO.UTILS.reshape(fd, dims.slice().reverse());
const inds = displayRangeIndices();
let N = 1;
for (const idx of inds) {
N *= (idx[1] - idx[0] + 1);
}
const ff = SIREPO.UTILS.reshape(
new Array(N),
[(inds[n][1] - inds[n][0] + 1), (inds[m][1] - inds[m][0] + 1), (inds[l][1] - inds[l][0] + 1)]
function sliceFieldData() {
const a = appState.models.tallyReport.axis;
const [nx, ny, nz] = tallyService.getMeshRanges().map(r => r[2]);
const f = tallyService.fieldData;
const v = [];

//TODO(pjm): change tallyReport.planePos to an index
const n = SIREPO.GEOMETRY.GeometryUtils.BASIS().indexOf(a);
const slice = fieldIndex(
appState.models.tallyReport.planePos,
tallyService.getMeshRanges()[n],
n,
);

for (let k = 0; k <= (inds[n][1] - inds[n][0]); ++k) {
for (let j = 0; j <= (inds[m][1] - inds[m][0]); ++j) {
for (let i = 0; i <= (inds[l][1] - inds[l][0]); ++i) {
const v = [0, 0, 0];
v[l] = inds[l][0] + i;
v[m] = inds[m][0] + j;
v[n] = inds[n][0] + k;
ff[k][j][i] = d[v[2]][v[1]][v[0]];
if (a === 'x') {
const x = slice;
for (let y = 0; y < ny; y++) {
const r = [];
for (let z = 0; z < nz; z++) {
r[z] = f[z * nx * ny + y * nx + x];
}
v.push(r);
}
}
return ff;
else if (a === 'y') {
const y = slice * nx;
for (let z = 0; z < nz; z++) {
const r = [];
for (let x = 0; x < nx; x++) {
r[x] = f[z * nx * ny + y + x];
}
v.push(r);
}
}
else if (a === 'z') {
const z = slice * nx * ny;
for (let x = 0; x < nx; x++) {
const r = [];
for (let y = 0; y < ny; y++) {
r[y] = f[z + y * nx + x];
}
v.push(r);
}
}
return v;
}

function sourceColor(color) {
Expand Down Expand Up @@ -1228,22 +1247,9 @@ SIREPO.app.directive('geometry2d', function(appState, openmcService, panelState,
}

function updateDisplayRange() {
if (! tallyService.initMesh()) {
return;
}
SIREPO.GEOMETRY.GeometryUtils.BASIS().forEach(dim => {
displayRanges[dim] = tallyService.tallyRange(dim);
});
updateSliceAxis();
}

function updateSliceAxis() {
if (! tallyService.fieldData) {
return;
}
if (! tallyService.initMesh()) {
return ;
}
buildTallyReport();
}

Expand Down Expand Up @@ -1271,14 +1277,14 @@ SIREPO.app.directive('geometry2d', function(appState, openmcService, panelState,
});

$scope.$on('sr-volume-visibility-toggle-all', buildTallyReport);
appState.watchModelFields($scope, ['tallyReport.axis'], updateSliceAxis);
appState.watchModelFields($scope, ['openmcAnimation.colorMap', 'openmcAnimation.sourceColorMap'], updateDisplay);
appState.watchModelFields($scope, ['tallyReport.planePos', 'openmcAnimation.showSources'], buildTallyReport);
$scope.$watch('tallyService.fieldData', (newValue, oldValue) => {
if (newValue && newValue !== oldValue) {
updateDisplayRange();
}
});
appState.watchModelFields($scope, [
'openmcAnimation.colorMap',
'openmcAnimation.showSources',
'openmcAnimation.sourceColorMap',
'tallyReport.axis',
'tallyReport.planePos',
], updateDisplay);
$scope.$watch('tallyService.fieldData', updateDisplayRange);

$scope.$on('sr-plotLinked', () => {
if (tallyService.fieldData) {
Expand Down Expand Up @@ -1446,9 +1452,6 @@ SIREPO.app.directive('geometry3d', function(appState, openmcService, plotting, p
picker.deletePickList(tallyBundle.actor);
tallyBundle = null;
}
if (! tallyService.initMesh()) {
return;
}
const [nx, ny, nz] = tallyService.mesh.dimension;
const [wx, wy, wz] = [
(tallyService.mesh.upper_right[0] - tallyService.mesh.lower_left[0]) / tallyService.mesh.dimension[0],
Expand Down Expand Up @@ -2075,6 +2078,9 @@ SIREPO.app.directive('volumeSelector', function(appState, openmcService, panelSt
appState.cancelChanges('volumes');
unloadMaterial();
}
if (name == 'volumes') {
loadRows();
}
});

loadRows();
Expand Down Expand Up @@ -2839,9 +2845,6 @@ SIREPO.viewLogic('tallyView', function(appState, openmcService, panelState, vali
}

function validateEnergyFilter(filter) {
if (! filter) {
return;
}
const rangeFields = ['start', 'stop'];
if (rangeFields.map(x => filter[x]).some(x => x == null)) {
return;
Expand All @@ -2868,8 +2871,12 @@ SIREPO.viewLogic('tallyView', function(appState, openmcService, panelState, vali
}

function validateFilter(field) {
const f = appState.models[$scope.modelName][field.split('.')[1]];
if (f._type === 'None') {
const m = appState.models[$scope.modelName];
if (! m) {
return;
}
const f = m[field.split('.')[1]];
if (! f || f._type === 'None') {
return;
}
if (f._type === 'energyFilter' || f._type === 'energyoutFilter') {
Expand Down Expand Up @@ -3172,16 +3179,14 @@ SIREPO.viewLogic('tallySettingsView', function(appState, openmcService, panelSta
'opacity', ! is2D,
]);

panelState.showFields('tallyReport', [
'axis', is2D,
'planePos', is2D && tallyService.tallyRange(appState.models.tallyReport.axis, true).steps > 1,
]);

panelState.showField('openmcAnimation', 'energyRangeSum', ! ! openmcService.findFilter('energyFilter'));
panelState.showField('openmcAnimation', 'sourceNormalization', openmcService.canNormalizeScore(appState.models.openmcAnimation.score));
panelState.showField('openmcAnimation', 'numSampleSourceParticles', showSources);
panelState.showField('openmcAnimation', 'sourceColorMap', showSources && appState.models.openmcAnimation.numSampleSourceParticles);
updateVisibleAxes();
panelState.showFields('tallyReport', [
'axis', is2D,
'planePos', is2D && tallyService.tallyRange(updateVisibleAxes(), true).steps > 1,
]);
}

function updateEnergyPlot() {
Expand All @@ -3191,7 +3196,7 @@ SIREPO.viewLogic('tallySettingsView', function(appState, openmcService, panelSta

function updateVisibleAxes() {
if (! tallyService.mesh) {
return;
return appState.models.tallyReport.axis;
}
const v = {};
SIREPO.GEOMETRY.GeometryUtils.BASIS().forEach(dim => {
Expand All @@ -3209,6 +3214,7 @@ SIREPO.viewLogic('tallySettingsView', function(appState, openmcService, panelSta
appState.models.tallyReport.axis = Object.keys(v)[0];
}
});
return appState.models.tallyReport.axis;
}

function validateTally() {
Expand Down Expand Up @@ -3290,22 +3296,47 @@ SIREPO.app.directive('planePositionSlider', function(appState, panelState, tally
dim: '<',
},
template: `
<div data-ng-if="steps">
<div data-slider="" data-model="model" data-field="field" data-min="min" data-max="max" data-steps="steps"></div>
<div data-ng-if="hasRange()">
<div data-slider="" data-model="model" data-field="field" data-min="range.min" data-max="range.max" data-steps="range.steps"></div>
</div>
`,
controller: function($scope) {
$scope.tallyService = tallyService;
let newRange;
let oldAxis = appState.models.tallyReport.axis;

function updateRange() {
if ($scope.dim) {
const r = tallyService.tallyRange($scope.dim, true);
$scope.min = r.min;
$scope.max = r.max;
$scope.steps = r.steps;
newRange = tallyService.tallyRange($scope.dim, true);
newRange.axis = appState.models.tallyReport.axis;
}
}

$scope.hasRange = () => {
// the slider component has fixed range, so the component needs to get recreated
// when the range or axis changes
if (newRange) {
if ($scope.range && $scope.range.min === newRange.min
&& $scope.range.max === newRange.max
&& $scope.range.steps === newRange.steps
&& $scope.range.axis === oldAxis
) {
return true;
}
if (newRange.steps > 1) {
$scope.range = newRange;
if (! appState.models.tallyReport.planePos
|| $scope.range.axis !== oldAxis) {
appState.models.tallyReport.planePos = $scope.range.min;
oldAxis = $scope.range.axis;
}
}
}
return false;
};

updateRange();
$scope.$watch('dim', updateRange);
$scope.$watch('tallyService.fieldData', updateRange);
},
};
Expand Down
22 changes: 0 additions & 22 deletions sirepo/package_data/static/js/sirepo-utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -148,28 +148,6 @@ class SirepoUtils {
return SirepoUtils.arrayMin(arr.map(x => x[i]));
}

static reshape(arr, dims) {
if (dims.length === 0) {
return arr;
}
const a = Array.from(arr).slice();
if (dims.length === 1) {
return a;
}
const n = dims.reduce((p, c) => p * c, 1);
if (a.length !== n) {
throw new Error(`Product of shape dimensions must equal array length: ${a.length} != ${n}`);
}
const b = [];
const d = dims[0];
const m = a.length / d;
for (let i = 0; i < d; ++i) {
const s = a.slice(m * i, m * (i + 1));
b.push(SirepoUtils.reshape(s, dims.slice(1)));
}
return b;
}

static wordSplits(s) {
const wds = s.split(/(\s+)/);
return wds.map(function (value, index) {
Expand Down
Loading

0 comments on commit ddc54e2

Please sign in to comment.