Line data Source code
1 : 2 : /**********************************************************************/ 3 : /* DO NOT MODIFY THIS HEADER */ 4 : /* Swift, a Fourier spectral solver for MOOSE */ 5 : /* */ 6 : /* Copyright 2024 Battelle Energy Alliance, LLC */ 7 : /* ALL RIGHTS RESERVED */ 8 : /**********************************************************************/ 9 : 10 : #include "ReciprocalMatDiffusion.h" 11 : #include "SwiftUtils.h" 12 : #include <torch/torch.h> 13 : 14 : registerMooseObject("SwiftApp", ReciprocalMatDiffusion); 15 : 16 : InputParameters 17 16 : ReciprocalMatDiffusion::validParams() 18 : { 19 16 : InputParameters params = TensorOperator::validParams(); 20 16 : params.addClassDescription( 21 : "Calculates the divergence of flux for a variable mobility in reciprocal space."); 22 32 : params.addRequiredParam<TensorInputBufferName>("chemical_potential", 23 : "Chemical potential buffer name"); 24 32 : params.addRequiredParam<TensorInputBufferName>("mobility", "Mobility buffer name"); 25 32 : params.addParam<TensorInputBufferName>("psi", "Variable to impose Neuamnn BC."); 26 32 : params.addParam<bool>("always_update_psi", false, "Set to true if the BC changes ."); 27 16 : return params; 28 0 : } 29 : 30 8 : ReciprocalMatDiffusion::ReciprocalMatDiffusion(const InputParameters & parameters) 31 : : TensorOperator(parameters), 32 8 : _chem_pot(getInputBuffer("chemical_potential")), 33 8 : _M(getInputBuffer("mobility")), 34 8 : _imag(torch::tensor(c10::complex<double>(0.0, 1.0), MooseTensor::complexFloatTensorOptions())), 35 8 : _psi(getInputBuffer("psi")), 36 8 : _update_psi(true), 37 24 : _always_update_psi(getParam<bool>("always_update_psi")) 38 : { 39 8 : } 40 : 41 : void 42 80000 : ReciprocalMatDiffusion::computeBuffer() 43 : { 44 80000 : if (_update_psi || _always_update_psi) 45 : { 46 24 : _psi_thresh = _psi > 0.0; 47 : _grad_psi_x_by_psi = 48 32 : torch::where(_psi_thresh, _domain.ifft(_i * _domain.fft(_psi) * _imag) / _psi, 0.0); 49 : _grad_psi_y_by_psi = 50 32 : torch::where(_psi_thresh, _domain.ifft(_j * _domain.fft(_psi) * _imag) / _psi, 0.0); 51 : _grad_psi_z_by_psi = 52 32 : torch::where(_psi_thresh, _domain.ifft(_k * _domain.fft(_psi) * _imag) / _psi, 0.0); 53 8 : _update_psi = false; 54 : } 55 : 56 80000 : auto psi_M = _M * _psi_thresh; 57 160000 : auto J_x = psi_M * _domain.ifft(_i * _domain.fft(_chem_pot) * _imag); 58 160000 : auto J_y = psi_M * _domain.ifft(_j * _domain.fft(_chem_pot) * _imag); 59 160000 : auto J_z = psi_M * _domain.ifft(_k * _domain.fft(_chem_pot) * _imag); 60 : 61 480000 : auto div_J_hat = _imag * (_i * _domain.fft(J_x) + _j * _domain.fft(J_y) + _k * _domain.fft(J_z)); 62 : auto no_flux_hat = 63 400000 : _domain.fft(_grad_psi_x_by_psi * J_x + _grad_psi_y_by_psi * J_y + _grad_psi_z_by_psi * J_z); 64 : 65 160000 : _u = div_J_hat + no_flux_hat; 66 80000 : }