-
Notifications
You must be signed in to change notification settings - Fork 659
Specify temperature from a field (structured mesh only) #3734
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from 18 commits
282ba43
cf19709
032275a
8a138da
d29e700
2e5e0c9
ba02d46
5c52c5f
06f27c7
d20e3ea
6c9b918
4b660d6
3b3b32f
6dd684d
76cdf20
49bfb76
5e79b7b
0c67016
2ee8edb
cd4443b
aef0709
091925a
b0b28ba
d886d44
cf903c8
b1e4fee
68d8d9c
614564b
7bee829
78529b5
d91a64d
068b92b
027c35c
1bd1b5c
9bd31c1
242a842
967090c
a8ddf99
3420117
5ddfca2
d73f0cf
1e104a9
5e6b409
c954785
7f79940
d6c7a26
7b7c80a
6eaef71
2c51de4
a6f6617
5e88589
3bde460
a5f63bf
7ca5f8f
bcd208a
92271f9
0150a02
2311beb
e020118
9949c56
de054db
6a9bd74
b4954d1
9cf6057
3c9a810
07ad591
d4b2140
f397a9a
cd906d7
6a8f4a8
549beb0
a9fff5a
2e10a5d
8f9f44a
1ed498a
2966590
2155926
1901a85
f2e1948
6009008
bd6a64f
0af48ac
24e3659
ded9baa
7f2fd78
22f4eb1
edb6fb9
f48b085
0edb912
a5952fb
7f96b45
c2bb44d
d3e2953
8b83aa2
b8e2148
8a86e7f
2a0ecf1
d696229
376c2c8
7ff1402
98401f6
c46c859
e517af4
b05aeac
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,94 @@ | ||
| #ifndef OPENMC_FIELD_H | ||
| #define OPENMC_FIELD_H | ||
|
|
||
| #include "openmc/mesh.h" | ||
| #include "openmc/vector.h" | ||
|
|
||
| namespace openmc { | ||
|
|
||
| class ScalarField { | ||
| public: | ||
| //---------------------------------------------------------------------------- | ||
| // Constructors | ||
| ScalarField() = default; | ||
| ScalarField( | ||
| Mesh* mesh_ptr, vector<double> values, const std::string& field_name); | ||
| ScalarField(Mesh* mesh_ptr, vector<double> values) | ||
| : ScalarField(mesh_ptr, values, "ScalarField") {}; | ||
|
|
||
| //---------------------------------------------------------------------------- | ||
| // Methods | ||
|
|
||
| //! Returns the distance to the next mesh boundary gien a particle position | ||
| //! and direction. If the particle is initially outside, the distance will | ||
| //! correspond to the nearest distance to the outer boundaries of the mesh. | ||
| // | ||
| //! \param[in] r Position of the particle | ||
| //! \param[in] u Direction of the particle | ||
| //! \return The distance in cm to the next mesh boundary | ||
| double distance_to_next_boundary(const Position& r, const Direction& d); | ||
|
|
||
| //---------------------------------------------------------------------------- | ||
| // Accessors | ||
|
|
||
| // Field type | ||
| const std::string& field_type() const { return this->field_type_; } | ||
|
|
||
| // Mesh pointer | ||
| Mesh* mesh_ptr() const | ||
| { | ||
| if (this->mesh_ptr_ == nullptr) { | ||
| fatal_error(fmt::format("No mesh found for {}!", this->field_type_)); | ||
| } else { | ||
| return this->mesh_ptr_; | ||
| } | ||
| } | ||
|
|
||
| // Values | ||
| double& value(int i) { return values_[i]; } | ||
| const double& value(int i) const { return values_[i]; } | ||
| const vector<double>& values() const { return values_; } | ||
|
|
||
| private: | ||
| //---------------------------------------------------------------------------- | ||
| // Data members | ||
| std::string field_type_; //! Name of field type | ||
| Mesh* mesh_ptr_; //!< Pointer to the geometric mesh | ||
| vector<double> values_; //!< Values associated with each mesh cell | ||
| }; | ||
|
|
||
| class TemperatureField : public ScalarField { | ||
| public: | ||
| //---------------------------------------------------------------------------- | ||
| // Constructors | ||
| TemperatureField() = default; | ||
| TemperatureField(Mesh* mesh_ptr, vector<double> values) | ||
| : ScalarField(mesh_ptr, values, "TemperatureField") {}; | ||
|
|
||
| //---------------------------------------------------------------------------- | ||
| // Methods | ||
|
|
||
| //! Returns the temperature in Kelvin corresponding to the given position. | ||
| // | ||
| //! \param[in] r Position of the particle | ||
| //! \return Temperature in Kelvin | ||
| double get_temperature(const Position& r); | ||
|
|
||
| //! Returns the square root of the temperature multiplied by the Boltzmann | ||
| //! constant in eV for the given position. | ||
| // | ||
| //! \param[in] r Position of the particle | ||
| //! \return Sqrt(k_Boltzmann * temperature) in eV | ||
| double get_sqrtkT(const Position& r); | ||
|
|
||
| //! Update the temperature of a particle based on its position and direction. | ||
| //! If the particle is inside the temperature field, its temperature is | ||
| //! updated. If outside, the particle takes the temperature value | ||
| //! associated with the current cell instance. | ||
| // | ||
| //! \param[inout] p Particle | ||
| void update_particle_temperature(Particle& p); | ||
| }; | ||
|
|
||
| } // namespace openmc | ||
| #endif // OPENMC_FIELD_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,67 @@ | ||
| from abc import ABC, abstractmethod | ||
|
|
||
| import openmc | ||
|
|
||
|
|
||
| class ScalarField(ABC): | ||
| """Scalar field defined on a geometric mesh. | ||
|
|
||
| Attributes | ||
| ---------- | ||
| mesh : Mesh | ||
| Spatial mesh associated with the field | ||
| values : iterable of float | ||
| List of values associated with each mesh cell | ||
|
|
||
| """ | ||
| def __init__(self, mesh, values): | ||
| """Initialization. | ||
|
|
||
| Parameters | ||
| ---------- | ||
| mesh : Mesh | ||
| Spatial mesh associated with the field | ||
| values : iterable of float | ||
| List of values associated with each mesh cell | ||
|
|
||
| """ | ||
| self.mesh = mesh | ||
| self.values = values | ||
|
|
||
| @classmethod | ||
| def from_exodus_file(cls, filepath): | ||
| """Construct a ScalarField from an Exodus mesh file | ||
|
|
||
| Parameters | ||
| ---------- | ||
| filepath : path-like or str | ||
| Path to the Exodus mesh file | ||
|
|
||
| """ | ||
| #TODO | ||
| raise NotImplementedError("Constructor not yet implemented.") | ||
|
|
||
|
|
||
| class TemperatureField(ScalarField): | ||
| """Temperature field. | ||
|
|
||
| Attributes | ||
| ---------- | ||
| mesh : Mesh | ||
| Spatial mesh associated with the field | ||
| values : iterable of float | ||
| List of values associated with each mesh cell | ||
|
|
||
| """ | ||
| def __init__(self, mesh, values): | ||
| """Initialization. | ||
|
|
||
| Parameters | ||
| ---------- | ||
| mesh : Mesh | ||
| Spatial mesh associated with the field | ||
| values : iterable of float | ||
| List of values associated with each mesh cell | ||
|
|
||
| """ | ||
| super().__init__(mesh, values) | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It would be good to have some validation here to check for cases that are not yet supported (unstructured mesh and, if I'm not mistaken, cylindrical/spherical mesh). Additionally, there could be some basic checks for consistency (number of values matches number of mesh elements, temperature values are positive).
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done |
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see that ScalarField inherit from ABC but right now it doesn't have any abstract methods. Were you planning on making this class have a defined interface that subclasses would have to implement?
Also, right now these classes don't really have much "behavior" (methods), which calls into question if they are needed as classes in the first place, but I understand that they are likely to be expanded in the future. Can you elaborate on what you see these classes providing beyond what we could achieve with built-in type? i.e., why should it not just be:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I originally had plans to add more features for the Python API like standardized I/O mechanisms for the values, values generators, and potentially visualization functions. With the changes I made in PR #3944, I realized that it would make more sense to expand the Python capabilities in PR #3944 so this is why the interface is rather minimal here.
I would still keep custom classes over built-in type, even if they are very minimalist for now, just because we will add more features in the future.