mirror of
https://github.com/openmc-dev/openmc.git
synced 2026-07-27 13:45:36 -04:00
Address @paulromano and @smharper comments
This commit is contained in:
parent
b4a2687af9
commit
2874b4a2f9
10 changed files with 782 additions and 959 deletions
|
|
@ -201,6 +201,10 @@ Various classes may be created when performing tally slicing and/or arithmetic:
|
|||
Coarse Mesh Finite Difference Acceleration
|
||||
------------------------------------------
|
||||
|
||||
CMFD is implemented in OpenMC and allows users to accelerate fission source
|
||||
convergence during inactive neutron batches. To run CMFD, the CMFDRun class
|
||||
should be used.
|
||||
|
||||
.. autosummary::
|
||||
:toctree: generated
|
||||
:nosignatures:
|
||||
|
|
@ -209,33 +213,6 @@ Coarse Mesh Finite Difference Acceleration
|
|||
openmc.CMFDMesh
|
||||
openmc.CMFDRun
|
||||
|
||||
CMFD is implemented in OpenMC and allows users to accelerate fission source
|
||||
convergence during inactive neutron batches. To run CMFD, the CMFDRun class should
|
||||
be used. The following properties can be set through the CMFDRun class:
|
||||
|
||||
.. autosummary::
|
||||
:toctree: generated
|
||||
:nosignatures:
|
||||
:template: myfunction.rst
|
||||
|
||||
openmc.CMFDRun.cmfd_begin
|
||||
openmc.CMFDRun.dhat_reset
|
||||
openmc.CMFDRun.cmfd_display
|
||||
openmc.CMFDRun.cmfd_downscatter
|
||||
openmc.CMFDRun.cmfd_feedback
|
||||
openmc.CMFDRun.cmfd_ktol
|
||||
openmc.CMFDRun.cmfd_mesh
|
||||
openmc.CMFDRun.norm
|
||||
openmc.CMFDRun.cmfd_adjoint_type
|
||||
openmc.CMFDRun.cmfd_power_monitor
|
||||
openmc.CMFDRun.cmfd_run_adjoint
|
||||
openmc.CMFDRun.cmfd_shift
|
||||
openmc.CMFDRun.cmfd_stol
|
||||
openmc.CMFDRun.cmfd_spectral
|
||||
openmc.CMFDRun.cmfd_reset
|
||||
openmc.CMFDRun.cmfd_write_matrices
|
||||
openmc.CMFDRun.gauss_seidel_tolerance
|
||||
|
||||
At the minimum, a CMFD mesh needs to be specified in order to run CMFD. Once
|
||||
these properties are set, an OpenMC simulation can be run with CMFD turned on
|
||||
with the function:
|
||||
|
|
|
|||
|
|
@ -120,6 +120,31 @@ extern "C" {
|
|||
int openmc_zernike_filter_set_params(int32_t index, const double* x,
|
||||
const double* y, const double* r);
|
||||
|
||||
//! Sets the fixed variables that are used for CMFD linear solver
|
||||
//! \param[in] CSR format index pointer array of loss matrix
|
||||
//! \param[in] length of indptr
|
||||
//! \param[in] CSR format index array of loss matrix
|
||||
//! \param[in] number of non-zero elements in CMFD loss matrix
|
||||
//! \param[in] dimension n of nxn CMFD loss matrix
|
||||
//! \param[in] spectral radius of CMFD matrices and tolerances
|
||||
//! \param[in] indices storing spatial and energy dimensions of CMFD problem
|
||||
//! \param[in] coremap for problem, storing accelerated regions
|
||||
extern "C" void openmc_initialize_linsolver(const int* indptr, int len_indptr,
|
||||
const int* indices, int n_elements,
|
||||
int dim, double spectral,
|
||||
const int* cmfd_indices,
|
||||
const int* map);
|
||||
|
||||
//! Runs a Gauss Seidel linear solver to solve CMFD matrix equations
|
||||
//! linear solver
|
||||
//! \param[in] CSR format data array of coefficient matrix
|
||||
//! \param[in] right hand side vector
|
||||
//! \param[out] unknown vector
|
||||
//! \param[in] tolerance on final error
|
||||
//! \return number of inner iterations required to reach convergence
|
||||
extern "C" int openmc_run_linsolver(const double* A_data, const double* b,
|
||||
double* x, double tol);
|
||||
|
||||
// Error codes
|
||||
extern int OPENMC_E_UNASSIGNED;
|
||||
extern int OPENMC_E_ALLOCATE;
|
||||
|
|
|
|||
|
|
@ -1,113 +0,0 @@
|
|||
#ifndef OPENMC_CMFD_SOLVER_H
|
||||
#define OPENMC_CMFD_SOLVER_H
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#include "xtensor/xtensor.hpp"
|
||||
|
||||
namespace openmc {
|
||||
|
||||
//===============================================================================
|
||||
// Global variables
|
||||
//===============================================================================
|
||||
|
||||
// CSR format index pointer array of loss matrix
|
||||
extern std::vector<int> indptr;
|
||||
|
||||
// CSR format index array of loss matrix
|
||||
extern std::vector<int> indices;
|
||||
|
||||
// Dimension n of nxn CMFD loss matrix
|
||||
extern int dim;
|
||||
|
||||
// Spectral radius of CMFD matrices and tolerances
|
||||
extern double spectral;
|
||||
|
||||
// Maximum dimension in x, y, and z directions
|
||||
extern int nx;
|
||||
extern int ny;
|
||||
extern int nz;
|
||||
|
||||
// Number of energy groups
|
||||
extern int ng;
|
||||
|
||||
// Indexmap storing all x, y, z positions of accelerated regions
|
||||
extern xt::xtensor<int, 2> indexmap;
|
||||
|
||||
//===============================================================================
|
||||
// Non-member functions
|
||||
//===============================================================================
|
||||
|
||||
//! returns the index in CSR index array corresponding to the diagonal element
|
||||
//! of a specified row
|
||||
//! \param[in] row of interest
|
||||
//! \return index in CSR index array corresponding to diagonal element
|
||||
int get_diagonal_index(int row);
|
||||
|
||||
//! sets the elements of indexmap based on input coremap
|
||||
//! \param[in] user-defined coremap
|
||||
void set_indexmap(int* coremap);
|
||||
|
||||
//! solves a one group CMFD linear system
|
||||
//! \param[in] CSR format data array of coefficient matrix
|
||||
//! \param[in] right hand side vector
|
||||
//! \param[out] unknown vector
|
||||
//! \param[in] tolerance on final error
|
||||
//! \return number of inner iterations required to reach convergence
|
||||
int cmfd_linsolver_1g(double* A_data, double* b, double* x, double tol);
|
||||
|
||||
//! solves a two group CMFD linear system
|
||||
//! \param[in] CSR format data array of coefficient matrix
|
||||
//! \param[in] right hand side vector
|
||||
//! \param[out] unknown vector
|
||||
//! \param[in] tolerance on final error
|
||||
//! \return number of inner iterations required to reach convergence
|
||||
int cmfd_linsolver_2g(double* A_data, double* b, double* x, double tol);
|
||||
|
||||
//! solves a general CMFD linear system
|
||||
//! \param[in] CSR format data array of coefficient matrix
|
||||
//! \param[in] right hand side vector
|
||||
//! \param[out] unknown vector
|
||||
//! \param[in] tolerance on final error
|
||||
//! \return number of inner iterations required to reach convergence
|
||||
int cmfd_linsolver_ng(double* A_data, double* b, double* x, double tol);
|
||||
|
||||
//! converts a matrix index to spatial and group indices
|
||||
//! \param[in] iteration counter over row
|
||||
//! \param[out] iteration counter for groups
|
||||
//! \param[out] iteration counter for x
|
||||
//! \param[out] iteration counter for y
|
||||
//! \param[out] iteration counter for z
|
||||
void matrix_to_indices(int irow, int& g, int& i, int& j, int& k);
|
||||
|
||||
//===============================================================================
|
||||
// External functions
|
||||
//===============================================================================
|
||||
|
||||
//! sets the fixed variables that are used for the linear solver
|
||||
//! \param[in] CSR format index pointer array of loss matrix
|
||||
//! \param[in] length of indptr
|
||||
//! \param[in] CSR format index array of loss matrix
|
||||
//! \param[in] number of non-zero elements in CMFD loss matrix
|
||||
//! \param[in] dimension n of nxn CMFD loss matrix
|
||||
//! \param[in] spectral radius of CMFD matrices and tolerances
|
||||
//! \param[in] indices storing spatial and energy dimensions of CMFD problem
|
||||
//! \param[in] coremap for problem, storing accelerated regions
|
||||
extern "C" void openmc_initialize_linsolver(int* indptr, int len_indptr,
|
||||
int* indices, int n_elements,
|
||||
int dim, double spectral,
|
||||
int* cmfd_indices, int* map);
|
||||
|
||||
//! runs a Gauss Seidel linear solver to solve CMFD matrix equations
|
||||
//! linear solver
|
||||
//! \param[in] CSR format data array of coefficient matrix
|
||||
//! \param[in] right hand side vector
|
||||
//! \param[out] unknown vector
|
||||
//! \param[in] tolerance on final error
|
||||
//! \return number of inner iterations required to reach convergence
|
||||
extern "C" int openmc_run_linsolver(double* A_data, double* b, double* x,
|
||||
double tol);
|
||||
|
||||
|
||||
} // namespace openmc
|
||||
#endif // OPENMC_CMFD_SOLVER_H
|
||||
|
|
@ -20,6 +20,13 @@ class _Bank(Structure):
|
|||
('delayed_group', c_int)]
|
||||
|
||||
|
||||
# Define input type for numpy arrays that will be passed into C++ functions
|
||||
# Must be an int or double array, with single dimension that is contiguous
|
||||
_array_1d_int = np.ctypeslib.ndpointer(dtype=np.int32, ndim=1,
|
||||
flags='CONTIGUOUS')
|
||||
_array_1d_dble = np.ctypeslib.ndpointer(dtype=np.double, ndim=1,
|
||||
flags='CONTIGUOUS')
|
||||
|
||||
_dll.openmc_calculate_volumes.restype = c_int
|
||||
_dll.openmc_calculate_volumes.errcheck = _error_handler
|
||||
_dll.openmc_finalize.restype = c_int
|
||||
|
|
@ -36,6 +43,10 @@ _dll.openmc_init.errcheck = _error_handler
|
|||
_dll.openmc_get_keff.argtypes = [POINTER(c_double*2)]
|
||||
_dll.openmc_get_keff.restype = c_int
|
||||
_dll.openmc_get_keff.errcheck = _error_handler
|
||||
_init_linsolver_argtypes = [_array_1d_int, c_int, _array_1d_int, c_int, c_int,
|
||||
c_double, _array_1d_int, _array_1d_int]
|
||||
_dll.openmc_initialize_linsolver.argtypes = _init_linsolver_argtypes
|
||||
_dll.openmc_initialize_linsolver.restype = None
|
||||
_dll.openmc_next_batch.argtypes = [POINTER(c_int)]
|
||||
_dll.openmc_next_batch.restype = c_int
|
||||
_dll.openmc_next_batch.errcheck = _error_handler
|
||||
|
|
@ -45,6 +56,10 @@ _dll.openmc_run.restype = c_int
|
|||
_dll.openmc_run.errcheck = _error_handler
|
||||
_dll.openmc_reset.restype = c_int
|
||||
_dll.openmc_reset.errcheck = _error_handler
|
||||
_run_linsolver_argtypes = [_array_1d_dble, _array_1d_dble, _array_1d_dble,
|
||||
c_double]
|
||||
_dll.openmc_run_linsolver.argtypes = _run_linsolver_argtypes
|
||||
_dll.openmc_run_linsolver.restype = c_int
|
||||
_dll.openmc_source_bank.argtypes = [POINTER(POINTER(_Bank)), POINTER(c_int64)]
|
||||
_dll.openmc_source_bank.restype = c_int
|
||||
_dll.openmc_source_bank.errcheck = _error_handler
|
||||
|
|
|
|||
1379
openmc/cmfd.py
1379
openmc/cmfd.py
File diff suppressed because it is too large
Load diff
|
|
@ -1,11 +1,16 @@
|
|||
#include <vector>
|
||||
#include <cmath>
|
||||
|
||||
#include "xtensor/xtensor.hpp"
|
||||
|
||||
#include "openmc/cmfd_solver.h"
|
||||
#include "openmc/error.h"
|
||||
#include "openmc/constants.h"
|
||||
#include "openmc/capi.h"
|
||||
|
||||
namespace openmc {
|
||||
|
||||
namespace cmfd {
|
||||
|
||||
//==============================================================================
|
||||
// Global variables
|
||||
//==============================================================================
|
||||
|
|
@ -22,14 +27,30 @@ int nx, ny, nz, ng;
|
|||
|
||||
xt::xtensor<int, 2> indexmap;
|
||||
|
||||
} // namespace cmfd
|
||||
|
||||
//==============================================================================
|
||||
// MATRIX_TO_INDICES converts a matrix index to spatial and group
|
||||
// indices
|
||||
//==============================================================================
|
||||
|
||||
void matrix_to_indices(int irow, int& g, int& i, int& j, int& k)
|
||||
{
|
||||
g = irow % cmfd::ng;
|
||||
i = cmfd::indexmap(irow/cmfd::ng, 0);
|
||||
j = cmfd::indexmap(irow/cmfd::ng, 1);
|
||||
k = cmfd::indexmap(irow/cmfd::ng, 2);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
// GET_DIAGONAL_INDEX returns the index in CSR index array corresponding to
|
||||
// the diagonal element of a specified row
|
||||
//==============================================================================
|
||||
|
||||
int get_diagonal_index(int row) {
|
||||
for (int j = indptr[row]; j < indptr[row+1]; j++) {
|
||||
if (indices[j] == row)
|
||||
int get_diagonal_index(int row)
|
||||
{
|
||||
for (int j = cmfd::indptr[row]; j < cmfd::indptr[row+1]; j++) {
|
||||
if (cmfd::indices[j] == row)
|
||||
return j;
|
||||
}
|
||||
|
||||
|
|
@ -41,15 +62,16 @@ int get_diagonal_index(int row) {
|
|||
// SET_INDEXMAP sets the elements of indexmap based on input coremap
|
||||
//==============================================================================
|
||||
|
||||
void set_indexmap(int* coremap) {
|
||||
for (int z = 0; z < nz; z++) {
|
||||
for (int y = 0; y < ny; y++) {
|
||||
for (int x = 0; x < nx; x++) {
|
||||
if (coremap[(z*ny*nx) + (y*nx) + x] != CMFD_NOACCEL) {
|
||||
int counter = coremap[(z*ny*nx) + (y*nx) + x];
|
||||
indexmap(counter, 0) = x;
|
||||
indexmap(counter, 1) = y;
|
||||
indexmap(counter, 2) = z;
|
||||
void set_indexmap(const int* coremap)
|
||||
{
|
||||
for (int z = 0; z < cmfd::nz; z++) {
|
||||
for (int y = 0; y < cmfd::ny; y++) {
|
||||
for (int x = 0; x < cmfd::nx; x++) {
|
||||
if (coremap[(z*cmfd::ny*cmfd::nx) + (y*cmfd::nx) + x] != CMFD_NOACCEL) {
|
||||
int counter = coremap[(z*cmfd::ny*cmfd::nx) + (y*cmfd::nx) + x];
|
||||
cmfd::indexmap(counter, 0) = x;
|
||||
cmfd::indexmap(counter, 1) = y;
|
||||
cmfd::indexmap(counter, 2) = z;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -60,23 +82,24 @@ void set_indexmap(int* coremap) {
|
|||
// CMFD_LINSOLVER_1G solves a one group CMFD linear system
|
||||
//==============================================================================
|
||||
|
||||
int cmfd_linsolver_1g(double* A_data, double* b, double* x, double tol) {
|
||||
int cmfd_linsolver_1g(const double* A_data, const double* b, double* x,
|
||||
double tol)
|
||||
{
|
||||
// Set overrelaxation parameter
|
||||
double w = 1.0;
|
||||
|
||||
// Perform Gauss-Seidel iterations
|
||||
for (int igs = 1; igs <= 10000; igs++) {
|
||||
double tmpx[dim];
|
||||
double err = 0.0;
|
||||
|
||||
// Copy over x vector
|
||||
std::copy(x, x+dim, tmpx);
|
||||
std::vector<double> tmpx {x, x+cmfd::dim};
|
||||
|
||||
// Perform red/black Gauss-Seidel iterations
|
||||
for (int irb = 0; irb < 2; irb++) {
|
||||
|
||||
// Loop around matrix rows
|
||||
for (int irow = 0; irow < dim; irow++) {
|
||||
for (int irow = 0; irow < cmfd::dim; irow++) {
|
||||
int g, i, j, k;
|
||||
matrix_to_indices(irow, g, i, j, k);
|
||||
|
||||
|
|
@ -88,10 +111,10 @@ int cmfd_linsolver_1g(double* A_data, double* b, double* x, double tol) {
|
|||
|
||||
// Perform temporary sums, first do left of diag, then right of diag
|
||||
double tmp1 = 0.0;
|
||||
for (int icol = indptr[irow]; icol < didx; icol++)
|
||||
tmp1 += A_data[icol] * x[indices[icol]];
|
||||
for (int icol = didx + 1; icol < indptr[irow + 1]; icol++)
|
||||
tmp1 += A_data[icol] * x[indices[icol]];
|
||||
for (int icol = cmfd::indptr[irow]; icol < didx; icol++)
|
||||
tmp1 += A_data[icol] * x[cmfd::indices[icol]];
|
||||
for (int icol = didx + 1; icol < cmfd::indptr[irow + 1]; icol++)
|
||||
tmp1 += A_data[icol] * x[cmfd::indices[icol]];
|
||||
|
||||
// Solve for new x
|
||||
double x1 = (b[irow] - tmp1) / A_data[didx];
|
||||
|
|
@ -106,12 +129,12 @@ int cmfd_linsolver_1g(double* A_data, double* b, double* x, double tol) {
|
|||
}
|
||||
|
||||
// Check convergence
|
||||
err = std::sqrt(err / dim);
|
||||
err = std::sqrt(err / cmfd::dim);
|
||||
if (err < tol)
|
||||
return igs;
|
||||
|
||||
// Calculate new overrelaxation parameter
|
||||
w = 1.0/(1.0 - 0.25 * spectral * w);
|
||||
w = 1.0/(1.0 - 0.25 * cmfd::spectral * w);
|
||||
}
|
||||
|
||||
// Throw error, as max iterations met
|
||||
|
|
@ -125,23 +148,24 @@ int cmfd_linsolver_1g(double* A_data, double* b, double* x, double tol) {
|
|||
// CMFD_LINSOLVER_2G solves a two group CMFD linear system
|
||||
//==============================================================================
|
||||
|
||||
int cmfd_linsolver_2g(double* A_data, double* b, double* x, double tol) {
|
||||
int cmfd_linsolver_2g(const double* A_data, const double* b, double* x,
|
||||
double tol)
|
||||
{
|
||||
// Set overrelaxation parameter
|
||||
double w = 1.0;
|
||||
|
||||
// Perform Gauss-Seidel iterations
|
||||
for (int igs = 1; igs <= 10000; igs++) {
|
||||
double tmpx[dim];
|
||||
double err = 0.0;
|
||||
|
||||
// Copy over x vector
|
||||
std::copy(x, x+dim, tmpx);
|
||||
std::vector<double> tmpx {x, x+cmfd::dim};
|
||||
|
||||
// Perform red/black Gauss-Seidel iterations
|
||||
for (int irb = 0; irb < 2; irb++) {
|
||||
|
||||
// Loop around matrix rows
|
||||
for (int irow = 0; irow < dim; irow+=2) {
|
||||
for (int irow = 0; irow < cmfd::dim; irow+=2) {
|
||||
int g, i, j, k;
|
||||
matrix_to_indices(irow, g, i, j, k);
|
||||
|
||||
|
|
@ -168,14 +192,14 @@ int cmfd_linsolver_2g(double* A_data, double* b, double* x, double tol) {
|
|||
// Perform temporary sums, first do left of diag, then right of diag
|
||||
double tmp1 = 0.0;
|
||||
double tmp2 = 0.0;
|
||||
for (int icol = indptr[irow]; icol < d1idx; icol++)
|
||||
tmp1 += A_data[icol] * x[indices[icol]];
|
||||
for (int icol = indptr[irow+1]; icol < d2idx-1; icol++)
|
||||
tmp2 += A_data[icol] * x[indices[icol]];
|
||||
for (int icol = d1idx + 2; icol < indptr[irow + 1]; icol++)
|
||||
tmp1 += A_data[icol] * x[indices[icol]];
|
||||
for (int icol = d2idx + 1; icol < indptr[irow + 2]; icol++)
|
||||
tmp2 += A_data[icol] * x[indices[icol]];
|
||||
for (int icol = cmfd::indptr[irow]; icol < d1idx; icol++)
|
||||
tmp1 += A_data[icol] * x[cmfd::indices[icol]];
|
||||
for (int icol = cmfd::indptr[irow+1]; icol < d2idx-1; icol++)
|
||||
tmp2 += A_data[icol] * x[cmfd::indices[icol]];
|
||||
for (int icol = d1idx + 2; icol < cmfd::indptr[irow + 1]; icol++)
|
||||
tmp1 += A_data[icol] * x[cmfd::indices[icol]];
|
||||
for (int icol = d2idx + 1; icol < cmfd::indptr[irow + 2]; icol++)
|
||||
tmp2 += A_data[icol] * x[cmfd::indices[icol]];
|
||||
|
||||
// Adjust with RHS vector
|
||||
tmp1 = b[irow] - tmp1;
|
||||
|
|
@ -196,12 +220,12 @@ int cmfd_linsolver_2g(double* A_data, double* b, double* x, double tol) {
|
|||
}
|
||||
|
||||
// Check convergence
|
||||
err = std::sqrt(err / dim);
|
||||
err = std::sqrt(err / cmfd::dim);
|
||||
if (err < tol)
|
||||
return igs;
|
||||
|
||||
// Calculate new overrelaxation parameter
|
||||
w = 1.0/(1.0 - 0.25 * spectral * w);
|
||||
w = 1.0/(1.0 - 0.25 * cmfd::spectral * w);
|
||||
}
|
||||
|
||||
// Throw error, as max iterations met
|
||||
|
|
@ -215,29 +239,30 @@ int cmfd_linsolver_2g(double* A_data, double* b, double* x, double tol) {
|
|||
// CMFD_LINSOLVER_NG solves a general CMFD linear system
|
||||
//==============================================================================
|
||||
|
||||
int cmfd_linsolver_ng(double* A_data, double* b, double* x, double tol) {
|
||||
int cmfd_linsolver_ng(const double* A_data, const double* b, double* x,
|
||||
double tol)
|
||||
{
|
||||
// Set overrelaxation parameter
|
||||
double w = 1.0;
|
||||
|
||||
// Perform Gauss-Seidel iterations
|
||||
for (int igs = 1; igs <= 10000; igs++) {
|
||||
double tmpx[dim];
|
||||
double err = 0.0;
|
||||
|
||||
// Copy over x vector
|
||||
std::copy(x, x+dim, tmpx);
|
||||
std::vector<double> tmpx {x, x+cmfd::dim};
|
||||
|
||||
// Loop around matrix rows
|
||||
for (int irow = 0; irow < dim; irow++) {
|
||||
for (int irow = 0; irow < cmfd::dim; irow++) {
|
||||
// Get index of diagonal for current row
|
||||
int didx = get_diagonal_index(irow);
|
||||
|
||||
// Perform temporary sums, first do left of diag, then right of diag
|
||||
double tmp1 = 0.0;
|
||||
for (int icol = indptr[irow]; icol < didx; icol++)
|
||||
tmp1 += A_data[icol] * x[indices[icol]];
|
||||
for (int icol = didx + 1; icol < indptr[irow + 1]; icol++)
|
||||
tmp1 += A_data[icol] * x[indices[icol]];
|
||||
for (int icol = cmfd::indptr[irow]; icol < didx; icol++)
|
||||
tmp1 += A_data[icol] * x[cmfd::indices[icol]];
|
||||
for (int icol = didx + 1; icol < cmfd::indptr[irow + 1]; icol++)
|
||||
tmp1 += A_data[icol] * x[cmfd::indices[icol]];
|
||||
|
||||
// Solve for new x
|
||||
double x1 = (b[irow] - tmp1) / A_data[didx];
|
||||
|
|
@ -251,12 +276,12 @@ int cmfd_linsolver_ng(double* A_data, double* b, double* x, double tol) {
|
|||
}
|
||||
|
||||
// Check convergence
|
||||
err = std::sqrt(err / dim);
|
||||
err = std::sqrt(err / cmfd::dim);
|
||||
if (err < tol)
|
||||
return igs;
|
||||
|
||||
// Calculate new overrelaxation parameter
|
||||
w = 1.0/(1.0 - 0.25 * spectral * w);
|
||||
w = 1.0/(1.0 - 0.25 * cmfd::spectral * w);
|
||||
}
|
||||
|
||||
// Throw error, as max iterations met
|
||||
|
|
@ -266,50 +291,40 @@ int cmfd_linsolver_ng(double* A_data, double* b, double* x, double tol) {
|
|||
return -1;
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
// MATRIX_TO_INDICES converts a matrix index to spatial and group
|
||||
// indices
|
||||
//==============================================================================
|
||||
|
||||
void matrix_to_indices(int irow, int& g, int& i, int& j, int& k) {
|
||||
g = irow % ng;
|
||||
i = indexmap(irow/ng, 0);
|
||||
j = indexmap(irow/ng, 1);
|
||||
k = indexmap(irow/ng, 2);
|
||||
}
|
||||
|
||||
//==============================================================================
|
||||
// OPENMC_INITIALIZE_LINSOLVER sets the fixed variables that are used for the
|
||||
// linear solver
|
||||
//==============================================================================
|
||||
|
||||
extern "C"
|
||||
void openmc_initialize_linsolver(int* indptr, int len_indptr, int* indices,
|
||||
int n_elements, int dim, double spectral,
|
||||
int* cmfd_indices, int* map) {
|
||||
void openmc_initialize_linsolver(const int* indptr, int len_indptr,
|
||||
const int* indices, int n_elements, int dim,
|
||||
double spectral, const int* cmfd_indices,
|
||||
const int* map)
|
||||
{
|
||||
// Store elements of indptr
|
||||
for (int i = 0; i < len_indptr; i++)
|
||||
openmc::indptr.push_back(indptr[i]);
|
||||
cmfd::indptr.push_back(indptr[i]);
|
||||
|
||||
// Store elements of indices
|
||||
for (int i = 0; i < n_elements; i++)
|
||||
openmc::indices.push_back(indices[i]);
|
||||
cmfd::indices.push_back(indices[i]);
|
||||
|
||||
// Set dimenion of CMFD problem and specral radius
|
||||
openmc::dim = dim;
|
||||
openmc::spectral = spectral;
|
||||
cmfd::dim = dim;
|
||||
cmfd::spectral = spectral;
|
||||
|
||||
// Set number of groups
|
||||
openmc::ng = cmfd_indices[3];
|
||||
cmfd::ng = cmfd_indices[3];
|
||||
|
||||
// Set problem dimensions and indexmap if 1 or 2 group problem
|
||||
if (openmc::ng == 1 || openmc::ng == 2) {
|
||||
openmc::nx = cmfd_indices[0];
|
||||
openmc::ny = cmfd_indices[1];
|
||||
openmc::nz = cmfd_indices[2];
|
||||
if (cmfd::ng == 1 || cmfd::ng == 2) {
|
||||
cmfd::nx = cmfd_indices[0];
|
||||
cmfd::ny = cmfd_indices[1];
|
||||
cmfd::nz = cmfd_indices[2];
|
||||
|
||||
// Resize indexmap and set its elements
|
||||
openmc::indexmap.resize({static_cast<size_t>(dim), 3});
|
||||
cmfd::indexmap.resize({static_cast<size_t>(dim), 3});
|
||||
set_indexmap(map);
|
||||
}
|
||||
}
|
||||
|
|
@ -320,8 +335,10 @@ void openmc_initialize_linsolver(int* indptr, int len_indptr, int* indices,
|
|||
//==============================================================================
|
||||
|
||||
extern "C"
|
||||
int openmc_run_linsolver(double* A_data, double* b, double* x, double tol) {
|
||||
switch (ng) {
|
||||
int openmc_run_linsolver(const double* A_data, const double* b, double* x,
|
||||
double tol)
|
||||
{
|
||||
switch (cmfd::ng) {
|
||||
case 1:
|
||||
return cmfd_linsolver_1g(A_data, b, x, tol);
|
||||
case 2:
|
||||
|
|
|
|||
|
|
@ -59,8 +59,6 @@ element settings {
|
|||
|
||||
element dagmc { xsd:boolean }? &
|
||||
|
||||
element run_cmfd { xsd:boolean }? &
|
||||
|
||||
element run_mode { xsd:string }? &
|
||||
|
||||
element seed { xsd:positiveInteger }? &
|
||||
|
|
|
|||
|
|
@ -687,11 +687,6 @@ void read_settings_xml()
|
|||
}
|
||||
}
|
||||
|
||||
// Check for cmfd run
|
||||
if (check_for_node(root, "run_cmfd")) {
|
||||
cmfd_run = get_node_value_bool(root, "run_cmfd");
|
||||
}
|
||||
|
||||
// Resonance scattering parameters
|
||||
if (check_for_node(root, "resonance_scattering")) {
|
||||
xml_node node_res_scat = root.child("resonance_scattering");
|
||||
|
|
|
|||
|
|
@ -23,7 +23,4 @@
|
|||
</mesh>
|
||||
<entropy_mesh>10</entropy_mesh>
|
||||
|
||||
<!-- Run CMFD -->
|
||||
<run_cmfd>true</run_cmfd>
|
||||
|
||||
</settings>
|
||||
|
|
|
|||
|
|
@ -23,7 +23,4 @@
|
|||
</mesh>
|
||||
<entropy_mesh>10</entropy_mesh>
|
||||
|
||||
<!-- Run CMFD -->
|
||||
<run_cmfd>true</run_cmfd>
|
||||
|
||||
</settings>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue