Line data Source code
1 : // SPDX-FileCopyrightText: 2024 Daniel Abele <daniel.abele@dlr.de> 2 : // 3 : // SPDX-License-Identifier: BSD-3-Clause 4 : 5 : #include "issm-precice/confreader.hpp" 6 : #include "issm-precice/logging.hpp" 7 : #include "shared/Enum/Enum.h" 8 : #include "yaml-cpp/yaml.h" 9 : #include "boost/algorithm/string/predicate.hpp" 10 : #include <fstream> 11 : #include <iostream> 12 : 13 : namespace ipc 14 : { 15 1 : IssmConfig issm_config(const YAML::Node& yaml) 16 : { 17 1 : IssmConfig issm; 18 1 : issm.root_path = yaml["root_path"].as<std::string>(); 19 1 : issm.model_name = yaml["model_name"].as<std::string>(); 20 1 : return issm; 21 0 : } 22 : 23 : template<class T> 24 7 : T get_or_default(const YAML::Node& yaml, const char* name, T def) 25 : { 26 14 : if (auto el = yaml[name]; yaml[name].IsDefined()) 27 : { 28 2 : return el.as<T>(); 29 : } 30 : else 31 : { 32 5 : return def; 33 : } 34 : } 35 : 36 1 : Config read_config(const std::filesystem::path& file, MPI_Comm comm) 37 : { 38 1 : IPC_LOG_INFO_0(comm, "Reading config file {}", file.string()); 39 : 40 1 : Config config; 41 : 42 1 : auto adapter_options = YAML::LoadFile(file); 43 : 44 : // precice options 45 1 : config.precice.config_file = adapter_options["precice_config_file_name"].as<std::string>(); 46 1 : config.precice.solver_name = adapter_options["participant_name"].as<std::string>(); 47 : 48 : // issm 49 1 : config.issm = issm_config(adapter_options["issm"]); 50 : 51 : // mesh 52 1 : if (adapter_options["interfaces"].size() != 1) 53 : { 54 0 : throw std::runtime_error("Must define exactly one coupling interface."); 55 : } 56 1 : auto interface_options = adapter_options["interfaces"][0]; 57 1 : config.mesh.name = interface_options["mesh_name"].as<std::string>(); 58 1 : if (interface_options["patches"].size() != 1) 59 : { 60 0 : throw std::runtime_error("Must have exactly one patch per coupling interface."); 61 : } 62 2 : auto patch = interface_options["patches"][0].as<std::string>(); 63 1 : if (boost::iequals(patch, "Base")) 64 : { 65 1 : config.mesh.type = Mesh2dDefinition{.layer = 0}; 66 : } 67 0 : else if (boost::iequals(patch, "Surface")) 68 : { 69 0 : config.mesh.type = Mesh2dDefinition{.layer = -1}; 70 : } 71 : else 72 : { 73 0 : throw std::runtime_error("Invalid patch. Must be one of [ base, surface ]"); 74 : } 75 : 76 1 : auto&& write_data = interface_options["write_data"]; 77 4 : for (auto&& e : write_data) 78 : { 79 3 : auto entry = VariableDefinition{ 80 6 : .id = definitions(StringToEnumx(e["solver_name"].as<std::string>().c_str())), 81 : .direction = DataDirection::Write, 82 : .data_name = e["name"].as<std::string>(), 83 : .flags = 84 6 : (boost::iequals(get_or_default(e, "operation", std::string("")), "DepthAverage") 85 : ? VariableFlags::DepthAverage 86 : : VariableFlags::None), 87 9 : }; 88 3 : config.variables.push_back(entry); 89 4 : } 90 1 : auto&& read_data = interface_options["read_data"]; 91 3 : for (auto&& e : read_data) 92 : { 93 2 : auto entry = VariableDefinition{ 94 4 : .id = definitions(StringToEnumx(e["solver_name"].as<std::string>().c_str())), 95 : .direction = DataDirection::Read, 96 : .data_name = e["name"].as<std::string>(), 97 : .flags = 98 4 : (boost::iequals(get_or_default(e, "operation", std::string("")), "Extrude") ? VariableFlags::Extrude 99 : : VariableFlags::None) | 100 4 : (boost::iequals(get_or_default(e, "constraint", std::string("")), "Constraint") 101 : ? VariableFlags::Constraint 102 4 : : VariableFlags::None), 103 4 : }; 104 2 : config.variables.push_back(entry); 105 3 : } 106 : 107 2 : return config; 108 1 : } 109 : 110 : } // namespace ipc