-
Notifications
You must be signed in to change notification settings - Fork 47
Variable Robin boundary condition and generic boundary condition class #437
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
Merged
Merged
Changes from 23 commits
Commits
Show all changes
29 commits
Select commit
Hold shift + click to select a range
ec16cb1
Initial implementation and test case. Works with 1 processor, but fai…
aabrown100-git 30982a9
Put debugging statements inside debugging blocks
aabrown100-git f51fd2f
Add spatially_variable_robin test to pytest suite
aabrown100-git 29b06b1
Rename to VariableRobinBCData, initial VariableRobinBCData once, inst…
aabrown100-git c73758b
Add copyright statement
aabrown100-git 243a96b
Renamed to RobinBC, partial implementation of parallelization
aabrown100-git b832647
Refactored distribute method to use gatherv and scatterv. Dealing wit…
aabrown100-git a7c9aae
Passes test in parallel, fails with index error with 1 proc
aabrown100-git 1f4fa7d
Fixed bug, now passes test in serial
aabrown100-git 340ed6c
clean up debugging statements to make code more readable
aabrown100-git 88bcc8a
Refactor vtp file reading to accept vector of array names, more gener…
aabrown100-git 7317db3
Split implementation into a BC base class and a RobinBC derived class
aabrown100-git 36146d6
Update README.md and add ustruct test case. ustruct result is fairly …
aabrown100-git 1ba1de0
Merge branch 'SimVascular:main' into variable_Robin_BC
aabrown100-git a3c6718
Refactor BC class to improve error handling and code clarity. Introdu…
aabrown100-git 634e396
Rename BC and RobinBC classes as BoundaryCondition and RobinBoundaryC…
aabrown100-git 80138ee
Clean up constructors
aabrown100-git baa9734
Remove extraneous comments and debugging statements
aabrown100-git 0614ed9
Reformat code
aabrown100-git 9a1b579
Move flag to apply in normal direction only inside RobinBoundaryCondi…
aabrown100-git 1cd0112
Split up distribute method into smaller functions
aabrown100-git aacae9a
Add copyrights
aabrown100-git 3be8e84
Merge branch 'main' into variable_Robin_BC
aabrown100-git a385159
Merge branch 'main' into variable_Robin_BC
aabrown100-git 66f6417
Implement copy-and-swap idiom, add noexcept to appropriate methods
aabrown100-git 4756f0e
Catch exceptions in constructors
aabrown100-git f894ef8
Move generate_load.py and generate_spatially_variable_robin.py into u…
aabrown100-git 626788c
Initialize members with default values and use default default constr…
aabrown100-git ee43996
Remove defined_ flag, just check if arrays are allocated, add new exc…
aabrown100-git File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,273 @@ | ||
| /* Copyright (c) Stanford University, The Regents of the University of California, and others. | ||
| * | ||
| * All Rights Reserved. | ||
| * | ||
| * See Copyright-SimVascular.txt for additional details. | ||
| * | ||
| * Permission is hereby granted, free of charge, to any person obtaining | ||
| * a copy of this software and associated documentation files (the | ||
| * "Software"), to deal in the Software without restriction, including | ||
| * without limitation the rights to use, copy, modify, merge, publish, | ||
| * distribute, sublicense, and/or sell copies of the Software, and to | ||
| * permit persons to whom the Software is furnished to do so, subject | ||
| * to the following conditions: | ||
| * | ||
| * The above copyright notice and this permission notice shall be included | ||
| * in all copies or substantial portions of the Software. | ||
| * | ||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS | ||
| * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED | ||
| * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A | ||
| * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER | ||
| * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
| * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
| * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
| * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| */ | ||
|
|
||
| #ifndef BOUNDARY_CONDITION_H | ||
| #define BOUNDARY_CONDITION_H | ||
|
|
||
| #include "Array.h" | ||
| #include "Vector.h" | ||
| #include "CmMod.h" | ||
| #include "VtkData.h" | ||
| #include <string> | ||
| #include <memory> | ||
| #include <map> | ||
| #include <vector> | ||
| #include <stdexcept> | ||
|
|
||
| // Forward declarations. These are needed because including ComMod.h causes a | ||
| // circular header dependency. | ||
| class faceType; | ||
| class ComMod; | ||
|
|
||
| /// @brief Base class for boundary conditions with spatially variable arrays | ||
| /// | ||
| /// This class provides common functionality for boundary conditions that need to | ||
| /// read and manage arrays of values from VTP files or uniform values. It handles | ||
| /// distribution of data across processes and provides efficient access to values. | ||
| /// | ||
| /// This class is intended to be subclassed by specific boundary condition types. | ||
| /// | ||
| /// Development note: this class is intended to eventually be an object-oriented | ||
| /// replacement of the existing bcType, although it is not yet complete. | ||
| /// | ||
| /// Example usage: | ||
| /// ```cpp | ||
| /// class MyBoundaryCondition : public BoundaryCondition { | ||
| /// public: | ||
| /// MyBoundaryCondition(const std::string& vtp_file_path, const std::vector<std::string>& array_names, const faceType& face) | ||
| /// : BoundaryCondition(vtp_file_path, array_names, face) {} | ||
| /// | ||
| /// MyBoundaryCondition(const std::map<std::string, double>& uniform_values, const faceType& face) | ||
| /// : BoundaryCondition(uniform_values, face) {} | ||
| /// | ||
| /// // Add BC-specific functionality here | ||
| /// }; | ||
| /// ``` | ||
| class BoundaryCondition { | ||
| protected: | ||
| /// @brief Type alias for map of array names to array data | ||
| using StringArrayMap = std::map<std::string, Array<double>>; | ||
| using StringBoolMap = std::map<std::string, bool>; | ||
| using StringDoubleMap = std::map<std::string, double>; | ||
|
|
||
| /// @brief Data members for BC | ||
| const faceType* face_; ///< Face associated with the BC (can be null) | ||
| int global_num_nodes_; ///< Global number of nodes on the face | ||
| int local_num_nodes_; ///< Local number of nodes on this processor | ||
| std::vector<std::string> array_names_; ///< Names of arrays to read from VTP file | ||
| StringArrayMap local_data_; ///< Local array values for each node on this processor | ||
| StringArrayMap global_data_; ///< Global array values (only populated on master) | ||
| StringBoolMap flags_; ///< Named boolean flags for BC behavior | ||
| bool spatially_variable; ///< Flag indicating if data is from VTP file | ||
| std::string vtp_file_path_; ///< Path to VTP file (empty if uniform) | ||
| std::map<int, int> global_node_map_; ///< Maps global node IDs to local array indices | ||
| std::unique_ptr<VtkVtpData> vtp_data_; ///< VTP data object | ||
| bool defined_; ///< Whether this BC has been properly initialized | ||
|
|
||
| public: | ||
| /// @brief Tolerance for point matching in VTP files | ||
| static constexpr double POINT_MATCH_TOLERANCE = 1e-12; | ||
|
|
||
| /// @brief Default constructor - creates an empty BC | ||
| BoundaryCondition() : face_(nullptr), global_num_nodes_(0), local_num_nodes_(0), spatially_variable(false), defined_(false) {} | ||
|
|
||
| /// @brief Constructor - reads data from VTP file | ||
| /// @param vtp_file_path Path to VTP file containing arrays | ||
| /// @param array_names Names of arrays to read from VTP file | ||
| /// @param face Face associated with the BC | ||
| /// @throws std::runtime_error if file cannot be read or arrays are missing | ||
| BoundaryCondition(const std::string& vtp_file_path, const std::vector<std::string>& array_names, const StringBoolMap& flags, const faceType& face); | ||
|
|
||
| /// @brief Constructor for uniform values | ||
| /// @param uniform_values Map of array names to uniform values | ||
| /// @param face Face associated with the BC | ||
| BoundaryCondition(const StringDoubleMap& uniform_values, const StringBoolMap& flags, const faceType& face); | ||
|
|
||
| /// @brief Copy constructor | ||
| BoundaryCondition(const BoundaryCondition& other); | ||
aabrown100-git marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| /// @brief Copy assignment operator | ||
| BoundaryCondition& operator=(const BoundaryCondition& other); | ||
|
|
||
| /// @brief Move constructor | ||
| BoundaryCondition(BoundaryCondition&& other) noexcept; | ||
|
|
||
| /// @brief Move assignment operator | ||
| BoundaryCondition& operator=(BoundaryCondition&& other) noexcept; | ||
|
|
||
| /// @brief Virtual destructor | ||
| virtual ~BoundaryCondition() = default; | ||
|
|
||
|
|
||
| /// @brief Get value for a specific array and node | ||
| /// @param array_name Name of the array | ||
| /// @param node_id Node index on the face | ||
| /// @return Value for the array at the specified node | ||
| double get_value(const std::string& array_name, int node_id) const; | ||
|
|
||
| /// @brief Get a boolean flag by name | ||
| /// @param name Name of the flag | ||
| /// @return Value of the flag | ||
| /// @throws std::runtime_error if flag is not found | ||
| bool get_flag(const std::string& name) const; | ||
|
|
||
| /// @brief Get a string representation of the flags | ||
| /// @return String representation of the flags | ||
| std::string flags_to_string() const; | ||
|
|
||
| /// @brief Get global number of nodes | ||
| /// @return Global number of nodes on the face | ||
| int get_global_num_nodes() const { | ||
| return global_num_nodes_; | ||
| } | ||
|
|
||
| /// @brief Get local number of nodes | ||
| /// @return Local number of nodes on the face on this processor | ||
| int get_local_num_nodes() const { | ||
| return local_num_nodes_; | ||
| } | ||
|
|
||
| /// @brief Get local array index for a global node ID | ||
| /// @param global_node_id The global node ID defined on the face | ||
| /// @return Local array index for data arrays | ||
| /// @throws std::runtime_error if global_node_id is not found in the map | ||
| int get_local_index(int global_node_id) const; | ||
|
|
||
| /// @brief Check if data is loaded from VTP file | ||
| /// @return true if loaded from VTP, false if using uniform values | ||
| bool is_from_vtp() const { | ||
| return spatially_variable; | ||
| } | ||
|
|
||
| /// @brief Get the VTP file path (empty if using uniform values) | ||
| /// @return VTP file path | ||
| const std::string& get_vtp_path() const { | ||
| return vtp_file_path_; | ||
| } | ||
|
|
||
| /// @brief Check if this BC is properly defined | ||
| /// @return true if BC has been initialized with either VTP data or uniform values | ||
| bool is_defined() const { | ||
| return defined_; | ||
| } | ||
|
|
||
| /// @brief Distribute BC data from the master process to the slave processes | ||
| /// @param com_mod Reference to ComMod object for global coordinates | ||
| /// @param cm_mod Reference to CmMod object for MPI communication | ||
| /// @param cm Reference to cmType object for MPI communication | ||
| /// @param face Face associated with the BC | ||
| void distribute(const ComMod& com_mod, const CmMod& cm_mod, const cmType& cm, const faceType& face); | ||
aabrown100-git marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| protected: | ||
| /// @brief Read data from VTP file | ||
| /// @param vtp_file_path Path to VTP file | ||
| /// @param array_names Names of arrays to read | ||
| /// @return Map of array names to array data | ||
| StringArrayMap read_data_from_vtp_file(const std::string& vtp_file_path, const std::vector<std::string>& array_names); | ||
|
|
||
| /// @brief Find index of a point in the VTP points array | ||
| /// @param x X coordinate | ||
| /// @param y Y coordinate | ||
| /// @param z Z coordinate | ||
| /// @param vtp_points VTP points array | ||
| /// @return Index of the matching point in the VTP array | ||
| /// @throws std::runtime_error if no matching point is found | ||
| int find_vtp_point_index(double x, double y, double z, const Array<double>& vtp_points) const; | ||
|
|
||
| /// @brief Hook for derived classes to validate array values | ||
| /// @param array_name Name of the array being validated | ||
| /// @param value Value to validate | ||
| /// @throws std::runtime_error if validation fails | ||
| virtual void validate_array_value(const std::string& array_name, double value) const {} | ||
|
|
||
| // ---- distribute helpers ---- | ||
| void distribute_metadata(const CmMod& cm_mod, const cmType& cm, bool is_slave); | ||
| void distribute_spatially_variable(const ComMod& com_mod, const CmMod& cm_mod, const cmType& cm, bool is_slave); | ||
| void distribute_uniform(const CmMod& cm_mod, const cmType& cm, bool is_slave); | ||
| void distribute_flags(const CmMod& cm_mod, const cmType& cm, bool is_slave); | ||
|
|
||
| }; | ||
|
|
||
| /// @brief Base exception class for BC errors | ||
| class BoundaryConditionBaseException : public std::exception { | ||
| public: | ||
| /// @brief Constructor | ||
| /// @param msg Error message | ||
| explicit BoundaryConditionBaseException(const std::string& msg) : message_(msg) {} | ||
|
|
||
| /// @brief Get error message | ||
| /// @return Error message | ||
| const char* what() const noexcept override { | ||
| return message_.c_str(); | ||
| } | ||
|
|
||
| private: | ||
| std::string message_; | ||
| }; | ||
|
|
||
| /// @brief Exception thrown when VTP file cannot be read or is invalid | ||
| class BoundaryConditionFileException : public BoundaryConditionBaseException { | ||
| public: | ||
| /// @brief Constructor | ||
| /// @param file Path to VTP file | ||
| explicit BoundaryConditionFileException(const std::string& file) | ||
| : BoundaryConditionBaseException("Failed to open or read the VTP file '" + file + "'") {} | ||
| }; | ||
|
|
||
| /// @brief Exception thrown when node count mismatch between VTP and face | ||
| class BoundaryConditionNodeCountException : public BoundaryConditionBaseException { | ||
| public: | ||
| /// @brief Constructor | ||
| /// @param vtp_file VTP file path | ||
| /// @param face_name Face name | ||
| explicit BoundaryConditionNodeCountException(const std::string& vtp_file, const std::string& face_name) | ||
| : BoundaryConditionBaseException("Number of nodes in VTP file '" + vtp_file + | ||
| "' does not match number of nodes on face '" + face_name + "'") {} | ||
| }; | ||
|
|
||
| /// @brief Exception thrown when array validation fails | ||
| class BoundaryConditionValidationException : public BoundaryConditionBaseException { | ||
| public: | ||
| /// @brief Constructor | ||
| /// @param array_name Name of array that failed validation | ||
| /// @param value Value that failed validation | ||
| explicit BoundaryConditionValidationException(const std::string& array_name, double value) | ||
| : BoundaryConditionBaseException("Invalid value " + std::to_string(value) + | ||
| " for array '" + array_name + "'") {} | ||
| }; | ||
|
|
||
| /// @brief Exception thrown when a requested flag is not defined | ||
| class BoundaryConditionFlagException : public BoundaryConditionBaseException { | ||
| public: | ||
| explicit BoundaryConditionFlagException(const std::string& flag_name) | ||
| : BoundaryConditionBaseException("BoundaryCondition flag not found: '" + flag_name + "'") {} | ||
| }; | ||
|
|
||
| #endif // BOUNDARY_CONDITION_H | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.