57 std::vector<std::string> required_keys = {
"anchor_stiffness",
58 "anchor_cross_sectional_area"};
59 std::vector<std::string> optional_keys = {
"maximum_anchor_stress",
60 "initial_anchor_stress",
61 "residual_anchor_stress"};
62 if (number_of_anchors == 0)
64 OGS_FATAL(
"No anchors found in the json.");
66 for (
const auto& key : required_keys)
68 if (!data.contains(key))
70 OGS_FATAL(
"JSON file does not contain required key '{:s}'", key);
72 if (number_of_anchors != data[key].size())
75 "Number of anchor start points does not match the number of {} "
79 for (
size_t i = 0; i < number_of_anchors; ++i)
81 if (!data[key][i].is_number())
83 OGS_FATAL(
"Non-numeric element in JSON array for key {}!", key);
87 for (
const auto& key : optional_keys)
89 if (data.contains(key))
91 if (number_of_anchors != data[key].size())
94 "Number of anchor start points does not match the number "
99 for (
size_t i = 0; i < number_of_anchors; ++i)
101 if (!data[key][i].is_number())
103 OGS_FATAL(
"Non-numeric element in JSON array for key {}!",
112 TCLAP::ValueArg<std::string>
const& input_filename)
114 using json = nlohmann::json;
115 std::ifstream f(input_filename.getValue());
118 OGS_FATAL(
"Could not open file '{:s}'", input_filename.getValue());
120 json
const data = json::parse(f);
122 auto const number_of_anchors = data[
"anchor_start_points"].size();
123 if (number_of_anchors != data[
"anchor_end_points"].size())
126 "Number of anchor start points does not match the number of "
127 "anchor end points.");
131 Eigen::MatrixX3d realcoords(2 * number_of_anchors, 3);
133 auto get_coordinates = [&data](
const char* key, std::size_t
const i)
135 const auto& v = data[key][i].get_ref<json::array_t
const&>();
139 "Expected a vector of length three for {:s} {}. Got vector of "
143 return Eigen::RowVector3d{v[0].get<
double>(), v[1].get<double>(),
147 for (std::size_t i = 0; i < number_of_anchors; i++)
149 realcoords.row(2 * i).noalias() =
150 get_coordinates(
"anchor_start_points", i);
151 realcoords.row(2 * i + 1).noalias() =
152 get_coordinates(
"anchor_end_points", i);
154 Eigen::VectorXd initial_anchor_stress(number_of_anchors);
155 Eigen::VectorXd maximum_anchor_stress(number_of_anchors);
156 Eigen::VectorXd residual_anchor_stress(number_of_anchors);
157 Eigen::VectorXd anchor_cross_sectional_area(number_of_anchors);
158 Eigen::VectorXd anchor_stiffness(number_of_anchors);
159 if (!data.contains(
"initial_anchor_stress"))
161 initial_anchor_stress.setZero();
165 for (
size_t i = 0; i < number_of_anchors; ++i)
167 initial_anchor_stress(i) =
168 data[
"initial_anchor_stress"][i].get<
double>();
171 if (!data.contains(
"maximum_anchor_stress"))
173 maximum_anchor_stress = Eigen::VectorXd::Constant(
174 number_of_anchors, std::numeric_limits<double>::max());
178 for (
size_t i = 0; i < number_of_anchors; ++i)
180 maximum_anchor_stress(i) =
181 data[
"maximum_anchor_stress"][i].get<
double>();
184 if (!data.contains(
"residual_anchor_stress"))
186 residual_anchor_stress = Eigen::VectorXd::Constant(
187 number_of_anchors, std::numeric_limits<double>::max());
191 for (
size_t i = 0; i < number_of_anchors; ++i)
193 residual_anchor_stress(i) =
194 data[
"residual_anchor_stress"][i].get<
double>();
197 for (
size_t i = 0; i < number_of_anchors; ++i)
199 anchor_cross_sectional_area(i) =
200 data[
"anchor_cross_sectional_area"][i].get<
double>();
201 anchor_stiffness(i) = data[
"anchor_stiffness"][i].get<
double>();
218 "Computes natual coordinates from given real coordinates\n\n"
220 "OpenGeoSys-6 software, version " +
223 "Copyright (c) 2012-2025, OpenGeoSys Community "
224 "(http://www.opengeosys.org)",
227 TCLAP::ValueArg<std::string> log_level_arg(
229 "the verbosity of logging messages: none, error, warn, info, debug, "
239 TCLAP::ValueArg<std::string> input_filename_arg(
240 "i",
"input",
"Input bulk mesh",
true,
"",
"VTU_FILE", cmd);
242 TCLAP::ValueArg<std::string> output_filename_arg(
243 "o",
"output",
"Anchor mesh",
true,
"",
"VTU_FILE", cmd);
245 TCLAP::ValueArg<std::string> json_filename_arg(
246 "f",
"json-file",
"JSON file containing anchor start and end points",
247 true,
"",
"JSON_FILE", cmd);
249 TCLAP::ValueArg<double> tolerance_arg(
250 "",
"tolerance",
"Tolerance/Search length",
false,
251 std::numeric_limits<double>::epsilon(),
"float", cmd);
253 TCLAP::ValueArg<unsigned> max_iter_arg(
255 "maximum number of iterations of the internal root-finding algorithm",
256 false, 5,
"int", cmd);
258 cmd.parse(argc, argv);
261 spdlog::set_pattern(
"%^%l:%$ %v");
262 spdlog::set_error_handler(
263 [](
const std::string& msg)
265 std::cerr <<
"spdlog error: " << msg << std::endl;
266 OGS_FATAL(
"spdlog logger error occurred.");
271 auto const bulk_mesh =
readGrid(input_filename_arg.getValue());
276 max_iter_arg.getValue());
279 writeGrid(output_mesh, output_filename_arg.getValue());
283 OGS_FATAL(
"Failed to compute natural coordinates.");