Skip to content

Commit 51cd5cd

Browse files
committed
fix: solver and mesh path loading in YAML runner
1 parent 45ac8cd commit 51cd5cd

3 files changed

Lines changed: 71 additions & 18 deletions

File tree

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,4 @@ build-config.json
6060
/tests/regression/run_hydrochrono/iea_sphere/decay/outputs
6161
/tests/regression/run_hydrochrono/oswec/decay/outputs
6262
/tests/regression/run_hydrochrono/rm3/decay/outputs
63+
/data/demos/run_hydrochrono/**/outputs

CMakeLists.txt

Lines changed: 33 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -619,27 +619,33 @@ endif()
619619
# Flat install tree for public distribution
620620
option(HC_INSTALL_DEV_DEMOS "Install developer demo executables" OFF)
621621

622-
# Install main CLI only (if built)
622+
# Install main CLI and project shared libraries (if built)
623623
if(TARGET run_hydrochrono)
624624
install(TARGETS run_hydrochrono CONFIGURATIONS Release DESTINATION bin COMPONENT runtime)
625625
endif()
626+
if(TARGET HydroChrono)
627+
install(TARGETS HydroChrono CONFIGURATIONS Release RUNTIME DESTINATION bin COMPONENT runtime)
628+
endif()
629+
if(TARGET HydroChronoGUI)
630+
install(TARGETS HydroChronoGUI CONFIGURATIONS Release RUNTIME DESTINATION bin COMPONENT runtime)
631+
endif()
626632

627633
# On Windows, install DLLs
628634
if(${CMAKE_SYSTEM_NAME} MATCHES "Windows")
629635
message(STATUS "Set DLLs for installation")
630636

631-
# Chrono DLLs
632-
foreach(tgt ${CHRONO_TARGETS})
633-
get_target_property(tgt_DLL ${tgt} IMPORTED_LOCATION_RELEASE)
634-
get_target_property(tgt_DLL_d ${tgt} IMPORTED_LOCATION_DEBUG)
635-
if(EXISTS ${tgt_DLL})
636-
message(STATUS " Chrono DLL ${tgt_DLL}")
637-
install(FILES ${tgt_DLL} DESTINATION bin COMPONENT runtime)
638-
endif()
639-
if(EXISTS ${tgt_DLL_d})
640-
install(FILES ${tgt_DLL_d} DESTINATION bin COMPONENT runtime)
641-
endif()
642-
endforeach()
637+
# Chrono DLLs — glob ALL DLLs from the Chrono bin directory to catch
638+
# transitive dependencies (e.g., Chrono_fsitdpf_vsg, yaml-cpp) that may
639+
# not be listed in CHRONO_TARGETS.
640+
get_target_property(_chrono_core_dll Chrono::Chrono_core IMPORTED_LOCATION_RELEASE)
641+
if(_chrono_core_dll)
642+
get_filename_component(_chrono_dll_dir "${_chrono_core_dll}" DIRECTORY)
643+
file(GLOB _chrono_dlls "${_chrono_dll_dir}/*.dll")
644+
foreach(_dll ${_chrono_dlls})
645+
message(STATUS " Chrono DLL ${_dll}")
646+
install(FILES "${_dll}" DESTINATION bin COMPONENT runtime)
647+
endforeach()
648+
endif()
643649

644650
# HDF5 DLLs
645651
foreach(tgt ${HDF5_TARGETS})
@@ -725,6 +731,20 @@ install(PROGRAMS ${PROJECT_SOURCE_DIR}/scripts/RUN-TESTS.ps1
725731
DESTINATION tests COMPONENT python-tests)
726732

727733
# MSVC runtime DLLs and ZIP packaging via CPack
734+
# InstallRequiredSystemLibraries handles msvcp/vcruntime/ucrt, but not vcomp (OpenMP).
735+
# Append the OpenMP runtime so it's included in the package.
736+
if(MSVC AND OpenMP_CXX_FOUND)
737+
get_filename_component(_msvc_dir "${CMAKE_CXX_COMPILER}" DIRECTORY)
738+
find_file(_vcomp_dll "vcomp140.dll"
739+
PATHS "${_msvc_dir}" "${_msvc_dir}/../../../redist/x64" "C:/Windows/System32"
740+
NO_DEFAULT_PATH)
741+
if(_vcomp_dll)
742+
list(APPEND CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS "${_vcomp_dll}")
743+
message(STATUS " OpenMP DLL ${_vcomp_dll}")
744+
else()
745+
message(WARNING "vcomp140.dll not found — OpenMP runtime will be missing from package")
746+
endif()
747+
endif()
728748
include(InstallRequiredSystemLibraries)
729749
set(CPACK_GENERATOR "ZIP")
730750
set(CPACK_PACKAGE_NAME "HydroChrono")

src/hydro/runner/run_from_yaml.cpp

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -197,19 +197,52 @@ bool ResolveInputFiles(const std::filesystem::path& input_dir,
197197
return true;
198198
}
199199

200+
// ---------------------------------------------------------------------------
201+
// Thin subclass of ChParserMbsYAML that exposes the protected
202+
// m_script_directory member. When HydroChrono loads model and solver
203+
// data from separate YAML files (rather than via ChParserMbsYAML::LoadFile),
204+
// this directory is never set, which breaks relative-path resolution for
205+
// mesh files referenced in model YAML (e.g. "../../assets/geometry/flap.obj").
206+
// ---------------------------------------------------------------------------
207+
namespace {
208+
class HCParser : public chrono::parsers::ChParserMbsYAML {
209+
public:
210+
HCParser() : ChParserMbsYAML() {}
211+
/// Set the base directory used by GetDatafilePath() when data_path is RELATIVE.
212+
void SetScriptDir(const std::string& dir) { m_script_directory = dir; }
213+
};
214+
} // namespace
215+
200216
std::shared_ptr<chrono::ChSystem> InitializeChronoSystem(const std::string& model_file, const std::string& sim_file) {
201217
hydroc::debug::LogDebug("Initializing Chrono system from YAML inputs...");
202218

203219
try {
204220
hydroc::debug::LogDebug("Creating Chrono YAML parser");
205-
auto parser = chrono::parsers::ChParserMbsYAML();
221+
HCParser parser;
222+
223+
// Tell the parser where the model file lives so that relative mesh
224+
// paths (data_path type: RELATIVE) are resolved correctly.
225+
std::filesystem::path model_dir = std::filesystem::path(model_file).parent_path();
226+
parser.SetScriptDir(model_dir.generic_string());
227+
hydroc::debug::LogDebug(std::string("Script directory set to: ") + model_dir.generic_string());
206228

207-
// Load simulation settings (solver, integrator, visualization, etc.)
229+
// Load simulation settings (end_time, gravity, visualization, etc.)
208230
hydroc::debug::LogDebug(std::string("Loading simulation file: ") + sim_file);
209231
auto sim_yaml = YAML::LoadFile(sim_file);
210232
parser.LoadSimData(sim_yaml);
211-
if (sim_yaml["solver"])
212-
parser.LoadSolverData(sim_yaml);
233+
234+
// Load solver/integrator/contact-method settings.
235+
// HydroChrono nests these under the "simulation" key, while the Chrono
236+
// parser's LoadSolverData() expects them as direct children of the node.
237+
// Additionally, HydroChrono puts time_step at the simulation level,
238+
// while Chrono expects it inside the integrator block.
239+
auto sim_node = sim_yaml["simulation"];
240+
if (sim_node && sim_node["contact_method"]) {
241+
// Promote time_step into the integrator block if needed
242+
if (sim_node["time_step"] && sim_node["integrator"] && !sim_node["integrator"]["time_step"])
243+
sim_node["integrator"]["time_step"] = sim_node["time_step"];
244+
parser.LoadSolverData(sim_node);
245+
}
213246

214247
hydroc::debug::LogDebug("Creating system");
215248
auto system = parser.CreateSystem();
@@ -220,7 +253,6 @@ std::shared_ptr<chrono::ChSystem> InitializeChronoSystem(const std::string& mode
220253
parser.LoadModelData(model_yaml);
221254

222255
hydroc::debug::LogDebug("Analyzing mesh files referenced in YAML model");
223-
std::filesystem::path model_dir = std::filesystem::path(model_file).parent_path();
224256
hydroc::debug::LogDebug(std::string("Model directory: ") + model_dir.generic_string());
225257

226258
hydroc::debug::LogDebug("Populating system");

0 commit comments

Comments
 (0)