Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## latest

- Added support to load multiple pyFANS builds in the same Python session [#142](https://github.com/DataAnalyticsEngineering/FANS/pull/142)
- Added large strain support for pyFANS [#141](https://github.com/DataAnalyticsEngineering/FANS/pull/141)
- Bugfix: fixes GBDiffusion post MaterialManager update and adds a test case [#147](https://github.com/DataAnalyticsEngineering/FANS/pull/147)
- Bugfix: mem-leak while reading microstructure and added wider CMake support [#140](https://github.com/DataAnalyticsEngineering/FANS/pull/140)
Expand Down
17 changes: 9 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -186,14 +186,15 @@ cd ../test

**Build options:**

| CMake Option | Description | Default |
| -------------- | ------------- | --------- |
| `CMAKE_BUILD_TYPE` | Build type: `Debug`, `Release`, `RelWithDebInfo` | `NONE` |
| `CMAKE_INTERPROCEDURAL_OPTIMIZATION` | Enable link-time optimization (LTO) | `ON` (if supported) |
| `FANS_BUILD_STATIC` | Build static library | `OFF` |
| `CMAKE_INSTALL_PREFIX` | Installation directory | System default |
| `FANS_LIBRARY_FOR_MICRO_MANAGER` | Build Python bindings using Pybind11 (needed) | `OFF` |
| `FANS_ENABLE_SANITIZERS` | Enable runtime sanitizers (AddressSanitizer and LeakSanitizer) for memory debugging | `OFF` |
| CMake Option | Description | Default |
|--------------------------------------|-------------------------------------------------------------------------------------------------------|---------------------|
| `CMAKE_BUILD_TYPE` | Build type: `Debug`, `Release`, `RelWithDebInfo` | `NONE` |
| `CMAKE_INTERPROCEDURAL_OPTIMIZATION` | Enable link-time optimization (LTO) | `ON` (if supported) |
| `FANS_BUILD_STATIC` | Build static library | `OFF` |
| `CMAKE_INSTALL_PREFIX` | Installation directory | System default |
| `FANS_LIBRARY_FOR_MICRO_MANAGER` | Build Python bindings (pyFANS) using Pybind11 (needed) | `OFF` |
| `FANS_ENABLE_SANITIZERS` | Enable runtime sanitizers (AddressSanitizer and LeakSanitizer) for memory debugging | `OFF` |
| `MicroSimulationSuffix` | Numeric suffix for pyFANS registration within Pybind11. Required when loading multiple pyFANS builds. | `NONE` |

---

Expand Down
30 changes: 30 additions & 0 deletions pyfans/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,36 @@ pybind11_add_module(PyFANS micro.hpp micro.cpp)
target_include_directories(PyFANS PRIVATE ${HDF5_INCLUDE_DIRS} ${FFTW3_INCLUDE_DIRS})
target_link_libraries(PyFANS PRIVATE FANS::FANS)

# Optional integer option (empty by default)
set(MicroSimulationSuffix "" CACHE STRING "Optional numeric variant suffix")

# Validate: must be empty or integer
if(MicroSimulationSuffix STREQUAL "")
set(CLASS_NAME MicroSimulation)
set(INPUT_NAME input.json)
set(CONFIG_NAME pyfans-config.json)
set(MODULE_NAME PyFANS)
else()
if(NOT MicroSimulationSuffix MATCHES "^[0-9]+$")
message(FATAL_ERROR "MicroSimulationSuffix must be an integer, got '${MicroSimulationSuffix}'")
endif()

set(CLASS_NAME MicroSimulation${MicroSimulationSuffix})
set(INPUT_NAME input${MicroSimulationSuffix}.json)
set(CONFIG_NAME pyfans-config${MicroSimulationSuffix}.json)
set(MODULE_NAME PyFANS${MicroSimulationSuffix})
message("Using MicroSimulationSuffix: ${MicroSimulationSuffix}")
endif()

# Add compile definitions
target_compile_definitions(PyFANS PRIVATE
PyFANS_CLASS_NAME=${CLASS_NAME}
PyFANS_CLASS_NAME_STR="${CLASS_NAME}"
PyFANS_INPUT_NAME="${INPUT_NAME}"
PyFANS_CONFIG_NAME="${CONFIG_NAME}"
PyFANS_MODULE_NAME=${MODULE_NAME}
)

add_custom_command(
TARGET PyFANS
POST_BUILD
Expand Down
26 changes: 13 additions & 13 deletions pyfans/micro.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ PyFANSConfig load_config(const std::string &file_path)
return config;
}

MicroSimulation::MicroSimulation(int sim_id, bool late_init, const std::string &input_file, const std::string &config_file)
PyFANS_CLASS_NAME::PyFANS_CLASS_NAME(int sim_id, bool late_init, const std::string &input_file, const std::string &config_file)
: _sim_id(sim_id)
{
// initialize fftw mpi
Expand Down Expand Up @@ -76,7 +76,7 @@ std::vector<double> conv_to_vector(const py::array_t<double> &arr, const int siz
return res;
}

py::dict MicroSimulation::solve(const py::dict &macro_data, double dt)
py::dict PyFANS_CLASS_NAME::solve(const py::dict &macro_data, double dt)
{
const bool is_small_strain = std::holds_alternative<MaterialManager<3, 6> *>(matmanager);
// Time step value dt is not used currently, but is available for future use
Expand Down Expand Up @@ -160,14 +160,14 @@ py::dict MicroSimulation::solve(const py::dict &macro_data, double dt)
return micro_write_data;
}

py::dict MicroSimulation::get_state()
py::dict PyFANS_CLASS_NAME::get_state()
{
// TODO populate state
py::dict state;
return state;
}

void MicroSimulation::set_state(const py::dict &state)
void PyFANS_CLASS_NAME::set_state(const py::dict &state)
{
// TODO read from state, not file
reader.FreeMS();
Expand All @@ -191,26 +191,26 @@ void MicroSimulation::set_state(const py::dict &state)
}
}

int MicroSimulation::get_id()
int PyFANS_CLASS_NAME::get_id()
{
return _sim_id;
}

void MicroSimulation::set_id(const int id)
void PyFANS_CLASS_NAME::set_id(const int id)
{
_sim_id = id;
}

PYBIND11_MODULE(PyFANS, m)
PYBIND11_MODULE(PyFANS_MODULE_NAME, m)
{
// optional docstring
m.doc() = "FANS for Micro Manager";

py::class_<MicroSimulation>(m, "MicroSimulation")
py::class_<PyFANS_CLASS_NAME>(m, PyFANS_CLASS_NAME_STR)
.def(py::init<int>())
.def("solve", &MicroSimulation::solve, py::return_value_policy::automatic)
.def("set_state", &MicroSimulation::set_state)
.def("get_state", &MicroSimulation::get_state, py::return_value_policy::automatic)
.def("get_global_id", &MicroSimulation::get_id)
.def("set_global_id", &MicroSimulation::set_id);
.def("solve", &PyFANS_CLASS_NAME::solve, py::return_value_policy::automatic)
.def("set_state", &PyFANS_CLASS_NAME::set_state)
.def("get_state", &PyFANS_CLASS_NAME::get_state, py::return_value_policy::automatic)
.def("get_global_id", &PyFANS_CLASS_NAME::get_id)
.def("set_global_id", &PyFANS_CLASS_NAME::set_id);
}
20 changes: 18 additions & 2 deletions pyfans/micro.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,25 @@

namespace py = pybind11;

class MicroSimulation {
#ifndef PyFANS_CLASS_NAME
#define PyFANS_CLASS_NAME MicroSimulation
#endif
#ifndef PyFANS_CLASS_NAME_STR
#define PyFANS_CLASS_NAME_STR "MicroSimulation"
#endif
#ifndef PyFANS_INPUT_NAME
#define PyFANS_INPUT_NAME "input.json"
#endif
#ifndef PyFANS_CONFIG_NAME
#define PyFANS_CONFIG_NAME "pyfans-config.json"
#endif
#ifndef PyFANS_MODULE_NAME
#define PyFANS_MODULE_NAME PyFANS
#endif

class PyFANS_CLASS_NAME {
public:
MicroSimulation(int sim_id, bool late_init = false, const std::string &input_file = "input.json", const std::string &config_file = "pyfans-config.json");
PyFANS_CLASS_NAME(int sim_id, bool late_init = false, const std::string &input_file = PyFANS_INPUT_NAME, const std::string &config_file = PyFANS_CONFIG_NAME);
py::dict solve(const py::dict &macro_write_data, double dt);

py::dict get_state();
Expand Down