From 850c8b374533ba324e0119f23d0f993b7dbb1083 Mon Sep 17 00:00:00 2001 From: Daniel Schwen Date: Wed, 5 Feb 2025 11:27:52 -0700 Subject: [PATCH] Add tests, fix odd size back transforms (#6) --- include/tensor_computes/ParsedCompute.h | 2 + include/tensor_computes/TensorOperatorBase.h | 3 ++ scripts/TestHarness/tests/test_HDF5Diff.py | 2 +- src/actions/DomainAction.C | 6 +-- src/tensor_computes/ComputeGroup.C | 9 +++- src/tensor_computes/FFTGradient.C | 1 - src/tensor_computes/ParsedCompute.C | 22 ++++++--- src/tensor_computes/TensorOperatorBase.C | 3 +- src/tensor_solver/SecantSolver.C | 2 +- test/tests/cahnhilliard/cahnhilliard.i | 2 +- .../gold/interface_velocity_out.csv | 12 +++++ .../tests/postprocessors/interface_velocity.i | 45 +++++++++++++++++ test/tests/postprocessors/tests | 9 ++++ test/tests/tensor_compute/backandforth.i | 43 +++++++++++----- .../tests/tensor_compute/gold/backandforth.h5 | Bin 23031 -> 0 bytes test/tests/tensor_compute/tests | 46 ++++++++++++++++-- 16 files changed, 175 insertions(+), 32 deletions(-) create mode 100644 test/tests/postprocessors/gold/interface_velocity_out.csv create mode 100644 test/tests/postprocessors/interface_velocity.i delete mode 100644 test/tests/tensor_compute/gold/backandforth.h5 diff --git a/include/tensor_computes/ParsedCompute.h b/include/tensor_computes/ParsedCompute.h index 8ab7c36..2cf9d6f 100644 --- a/include/tensor_computes/ParsedCompute.h +++ b/include/tensor_computes/ParsedCompute.h @@ -32,5 +32,7 @@ class ParsedCompute : public TensorOperator ParsedJITTensor _jit; ParsedTensor _no_jit; + torch::Tensor _time_tensor; std::vector _params; + const bool _real_space; }; diff --git a/include/tensor_computes/TensorOperatorBase.h b/include/tensor_computes/TensorOperatorBase.h index 70d8fbd..324ef83 100644 --- a/include/tensor_computes/TensorOperatorBase.h +++ b/include/tensor_computes/TensorOperatorBase.h @@ -61,4 +61,7 @@ class TensorOperatorBase : public MooseObject, public DependencyResolverInterfac /// reciprocal axes const torch::Tensor &_i, &_j, &_k; + + /// substep time + const Real & _time; }; diff --git a/scripts/TestHarness/tests/test_HDF5Diff.py b/scripts/TestHarness/tests/test_HDF5Diff.py index bc6b71c..cfeb5c4 100644 --- a/scripts/TestHarness/tests/test_HDF5Diff.py +++ b/scripts/TestHarness/tests/test_HDF5Diff.py @@ -41,5 +41,5 @@ def testDataSetMismatch(self): self.runTests('-i', 'hdf5diffs', '--re', 'dataset_mismatch') e = cm.exception - self.assertRegex(e.output, "tester\.dataset_mismatch:.*\['c\.0', 'c\.1', 'c\.2', 'mu\.0', 'mu\.1', 'mu\.2'\]") + self.assertRegex(e.output, r"tester\.dataset_mismatch:.*\['c\.0', 'c\.1', 'c\.2', 'mu\.0', 'mu\.1', 'mu\.2'\]") self.checkStatus(e.output, failed=1) diff --git a/src/actions/DomainAction.C b/src/actions/DomainAction.C index ac9dbae..cc9894d 100644 --- a/src/actions/DomainAction.C +++ b/src/actions/DomainAction.C @@ -477,11 +477,11 @@ DomainAction::ifft(const torch::Tensor & t) const switch (_dim) { case 1: - return torch::fft::irfft(t); + return torch::fft::irfft(t, getShape()[0]); case 2: - return torch::fft::irfft2(t); + return torch::fft::irfft2(t, getShape()); case 3: - return torch::fft::irfftn(t, c10::nullopt, {0, 1, 2}); + return torch::fft::irfftn(t, getShape(), {0, 1, 2}); default: mooseError("Unsupported mesh dimension"); } diff --git a/src/tensor_computes/ComputeGroup.C b/src/tensor_computes/ComputeGroup.C index 6c54a11..6254f20 100644 --- a/src/tensor_computes/ComputeGroup.C +++ b/src/tensor_computes/ComputeGroup.C @@ -42,7 +42,14 @@ void ComputeGroup::computeBuffer() { for (const auto & cmp : _computes) - cmp->computeBuffer(); + try + { + cmp->computeBuffer(); + } + catch (const std::exception& e) + { + cmp->mooseError("Exception: ", e.what()); + } } void diff --git a/src/tensor_computes/FFTGradient.C b/src/tensor_computes/FFTGradient.C index f03da65..1b458e8 100644 --- a/src/tensor_computes/FFTGradient.C +++ b/src/tensor_computes/FFTGradient.C @@ -36,7 +36,6 @@ FFTGradient::FFTGradient(const InputParameters & parameters) void FFTGradient::computeBuffer() { - std::cout << std::endl; _u = _domain.ifft((_input_is_reciprocal ? _input : _domain.fft(_input)) * _domain.getReciprocalAxis(_direction) * _i); } diff --git a/src/tensor_computes/ParsedCompute.C b/src/tensor_computes/ParsedCompute.C index 439999b..422cf1a 100644 --- a/src/tensor_computes/ParsedCompute.C +++ b/src/tensor_computes/ParsedCompute.C @@ -32,7 +32,7 @@ ParsedCompute::validParams() false, "Provide i (imaginary unit), kx,ky,kz (reciprocal space frequency), k2 " "(square of the k-vector), x,y,z " - "(real space coordinates), and pi,e."); + "(real space coordinates), time t, pi, and e."); // Constants and their values params.addParam>( "constant_names", @@ -42,14 +42,15 @@ ParsedCompute::validParams() "constant_expressions", std::vector(), "Vector of values for the constants in constant_names (can be an FParser expression)"); - + params.addParam("real_space", true, "Is the tensor being computed a real space tensor?"); return params; } ParsedCompute::ParsedCompute(const InputParameters & parameters) : TensorOperator(parameters), _use_jit(getParam("enable_jit")), - _extra_symbols(getParam("extra_symbols")) + _extra_symbols(getParam("extra_symbols")), + _real_space(getParam("real_space")) { const auto & expression = getParam("expression"); const auto & names = getParam>("inputs"); @@ -69,7 +70,7 @@ ParsedCompute::ParsedCompute(const InputParameters & parameters) _params.push_back(&getInputBufferByName(name)); static const std::vector reserved_symbols = { - "i", "x", "kx", "y", "ky", "z", "kz", "k2"}; + "i", "x", "kx", "y", "ky", "z", "kz", "k2", "t"}; // helper function to check if the name given is one of the reserved_names auto isReservedName = [this](const auto & name) @@ -108,7 +109,8 @@ ParsedCompute::ParsedCompute(const InputParameters & parameters) // append extra symbols variables_vec.insert(variables_vec.end(), reserved_symbols.begin(), reserved_symbols.end()); - _constant_tensors.push_back(torch::tensor(c10::complex(0.0, 1.0))); + _constant_tensors.push_back( + torch::tensor(c10::complex(0.0, 1.0), MooseTensor::complexFloatTensorOptions())); _params.push_back(&_constant_tensors[0]); for (const auto dim : make_range(3u)) @@ -118,6 +120,7 @@ ParsedCompute::ParsedCompute(const InputParameters & parameters) } _params.push_back(&_domain.getKSquare()); + _params.push_back(&_time_tensor); fp.AddConstant("pi", libMesh::pi); fp.AddConstant("e", std::exp(Real(1.0))); @@ -185,8 +188,13 @@ ParsedCompute::ParsedCompute(const InputParameters & parameters) void ParsedCompute::computeBuffer() { + if (_extra_symbols) + _time_tensor = torch::tensor(_time, MooseTensor::floatTensorOptions()); + + // use local shape if we add parallel support, and add option for reciprocal shape if (_use_jit) - _u = _jit.Eval(_params); + _u = _jit.Eval(_params).expand(_real_space ? _domain.getShape() : _domain.getReciprocalShape()); else - _u = _no_jit.Eval(_params); + _u = _no_jit.Eval(_params).expand(_real_space ? _domain.getShape() + : _domain.getReciprocalShape()); } diff --git a/src/tensor_computes/TensorOperatorBase.C b/src/tensor_computes/TensorOperatorBase.C index dcd0f0f..0a9226c 100644 --- a/src/tensor_computes/TensorOperatorBase.C +++ b/src/tensor_computes/TensorOperatorBase.C @@ -33,7 +33,8 @@ TensorOperatorBase::TensorOperatorBase(const InputParameters & parameters) _z(_domain.getAxis(2)), _i(_domain.getReciprocalAxis(0)), _j(_domain.getReciprocalAxis(1)), - _k(_domain.getReciprocalAxis(2)) + _k(_domain.getReciprocalAxis(2)), + _time(_tensor_problem.subTime()) { } diff --git a/src/tensor_solver/SecantSolver.C b/src/tensor_solver/SecantSolver.C index 8e0196a..cfccc21 100644 --- a/src/tensor_solver/SecantSolver.C +++ b/src/tensor_solver/SecantSolver.C @@ -140,7 +140,7 @@ SecantSolver::secantSolve() if (_verbose) { const auto unorm = torch::norm(du).item(); - std::cout << _iterations << " |du| = " << unorm << " |R|=" << Rnorm << std::endl; + _console << _iterations << " |du| = " << unorm << " |R|=" << Rnorm << std::endl; } // nan check diff --git a/test/tests/cahnhilliard/cahnhilliard.i b/test/tests/cahnhilliard/cahnhilliard.i index 1b3b537..ceac3b7 100644 --- a/test/tests/cahnhilliard/cahnhilliard.i +++ b/test/tests/cahnhilliard/cahnhilliard.i @@ -14,7 +14,6 @@ device_names = cpu [] - [TensorBuffers] [c] [] @@ -81,6 +80,7 @@ enable_jit = true expression = 'Mbar*mubar' inputs = 'Mbar mubar' + real_space = false [] [cbar] type = ForwardFFT diff --git a/test/tests/postprocessors/gold/interface_velocity_out.csv b/test/tests/postprocessors/gold/interface_velocity_out.csv new file mode 100644 index 0000000..0026614 --- /dev/null +++ b/test/tests/postprocessors/gold/interface_velocity_out.csv @@ -0,0 +1,12 @@ +time,v +0,0 +0.01,0 +0.02,0.2006196179713 +0.03,0.2006238853419 +0.04,0.20062820630563 +0.05,0.20063258191329 +0.06,0.20063701324401 +0.07,0.200641501405 +0.08,0.20064604753323 +0.09,0.20065065279606 +0.1,0.20065531839251 diff --git a/test/tests/postprocessors/interface_velocity.i b/test/tests/postprocessors/interface_velocity.i new file mode 100644 index 0000000..e09d586 --- /dev/null +++ b/test/tests/postprocessors/interface_velocity.i @@ -0,0 +1,45 @@ +[Domain] + dim = 2 + nx = 10 + ny = 2 + xmax = ${fparse pi*4} + mesh_mode = DUMMY + device_names = cpu +[] + +[TensorBuffers] + [c] + [] +[] + +[TensorComputes] + [Solve] + [c] + type = ParsedCompute + buffer = c + extra_symbols = true + expression = sin(x+0.2*t) + [] + [] +[] + +[Postprocessors] + [v] + type = TensorInterfaceVelocityPostprocessor + buffer = c + [] +[] + +[Problem] + type = TensorProblem +[] + +[Executioner] + type = Transient + num_steps = 10 + dt = 0.01 +[] + +[Outputs] + csv = true +[] diff --git a/test/tests/postprocessors/tests b/test/tests/postprocessors/tests index 296cae7..74ccef5 100644 --- a/test/tests/postprocessors/tests +++ b/test/tests/postprocessors/tests @@ -37,4 +37,13 @@ issues = '#6' design = 'ReciprocalIntegral.md' [] + + [interface_velocity] + type = CSVDiff + input = interface_velocity.i + csvdiff = interface_velocity_out.csv + requirement = 'The system shall be able to measure the maximum interfacial velocity for a given tensor.' + issues = '#6' + design = 'TensorInterfaceVelocityPostprocessor.md' + [] [] diff --git a/test/tests/tensor_compute/backandforth.i b/test/tests/tensor_compute/backandforth.i index b76a409..41ae5db 100644 --- a/test/tests/tensor_compute/backandforth.i +++ b/test/tests/tensor_compute/backandforth.i @@ -1,7 +1,4 @@ [Domain] - dim = 2 - nx = 20 - ny = 20 xmax = ${fparse pi*4} ymax = ${fparse pi*4} device_names = 'cpu' @@ -9,6 +6,8 @@ [] [TensorBuffers] + [eta_gold] + [] [eta] [] [eta_bar] @@ -17,16 +16,24 @@ [] [zero] [] + [diff] + [] [] [TensorComputes] [Initialize] - [eta] + [eta_gold] type = ParsedCompute - buffer = eta + buffer = eta_gold expression = 'sin(x)+sin(y)+sin(z)' extra_symbols = true [] + [eta] + type = ParsedCompute + buffer = eta + expression = eta_gold + inputs = eta_gold + [] [eta2] type = ConstantTensor buffer = eta2 @@ -52,6 +59,22 @@ input = eta_bar [] [] + + [Postprocess] + [diff] + type = ParsedCompute + buffer = diff + expression = 'abs(eta - eta2) + abs(eta - eta_gold)' + inputs = 'eta eta2 eta_gold' + [] + [] +[] + +[Postprocessors] + [norm] + type = TensorIntegralPostprocessor + buffer = diff + [] [] [TensorSolver] @@ -68,13 +91,9 @@ [Executioner] type = Transient - num_steps = 2 + num_steps = 4 [] -[TensorOutputs] - [xdmf] - type = XDMFTensorOutput - buffer = 'eta eta2' - enable_hdf5 = true - [] +[Outputs] + csv = true [] diff --git a/test/tests/tensor_compute/gold/backandforth.h5 b/test/tests/tensor_compute/gold/backandforth.h5 deleted file mode 100644 index 6251f46b2014018826c724a1ed752392caac1198..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 23031 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 diff --git a/test/tests/tensor_compute/tests b/test/tests/tensor_compute/tests index ffa853f..d8881f1 100644 --- a/test/tests/tensor_compute/tests +++ b/test/tests/tensor_compute/tests @@ -1,12 +1,50 @@ [Tests] [backandforth] - type = HDF5Diff - input = backandforth.i - hdf5diff = backandforth.h5 - abs_tol = 1e-13 issues = '#6' requirement = 'The system shall be able to transform a buffer from real space to reciprocal space and back and recover the original tensor' design = PerformFFT.md + [even_1d] + type = CSVDiff + input = backandforth.i + csvdiff = backandforth_out.csv + cli_args = 'Domain/dim=1 Domain/nx=10' + detail = 'in one dimension with an even number of grid cells' + [] + [odd_1d] + type = CSVDiff + input = backandforth.i + csvdiff = backandforth_out.csv + cli_args = 'Domain/dim=1 Domain/nx=11' + detail = 'in one dimension with an odd number of grid cells' + [] + [even_2d] + type = CSVDiff + input = backandforth.i + csvdiff = backandforth_out.csv + cli_args = 'Domain/dim=2 Domain/nx=10 Domain/ny=8' + detail = 'in two dimensions with an even number of grid cells' + [] + [odd_2d] + type = CSVDiff + input = backandforth.i + csvdiff = backandforth_out.csv + cli_args = 'Domain/dim=1 Domain/nx=9 Domain/ny=11' + detail = 'in two dimensions with an odd number of grid cells' + [] + [even_3d] + type = CSVDiff + input = backandforth.i + csvdiff = backandforth_out.csv + cli_args = 'Domain/dim=2 Domain/nx=10 Domain/ny=8 Domain/nz=12' + detail = 'in three dimensions with an even number of grid cells' + [] + [odd_3d] + type = CSVDiff + input = backandforth.i + csvdiff = backandforth_out.csv + cli_args = 'Domain/dim=1 Domain/nx=9 Domain/ny=13 Domain/nz=11' + detail = 'in three dimensions with an odd number of grid cells' + [] [] [rotating_grain_secant] type = HDF5Diff