52 std::vector<std::string> required_keys = {
"anchor_stiffness",
53 "anchor_cross_sectional_area"};
54 std::vector<std::string> optional_keys = {
"maximum_anchor_stress",
55 "initial_anchor_stress",
56 "residual_anchor_stress"};
57 if (number_of_anchors == 0)
59 OGS_FATAL(
"No anchors found in the json.");
61 for (
const auto& key : required_keys)
63 if (!data.contains(key))
65 OGS_FATAL(
"JSON file does not contain required key '{:s}'", key);
67 if (number_of_anchors != data[key].size())
70 "Number of anchor start points does not match the number of {} "
74 for (
size_t i = 0; i < number_of_anchors; ++i)
76 if (!data[key][i].is_number())
78 OGS_FATAL(
"Non-numeric element in JSON array for key {}!", key);
82 for (
const auto& key : optional_keys)
84 if (data.contains(key))
86 if (number_of_anchors != data[key].size())
89 "Number of anchor start points does not match the number "
94 for (
size_t i = 0; i < number_of_anchors; ++i)
96 if (!data[key][i].is_number())
98 OGS_FATAL(
"Non-numeric element in JSON array for key {}!",
107 TCLAP::ValueArg<std::string>
const& input_filename)
109 using json = nlohmann::json;
110 std::ifstream f(input_filename.getValue());
113 OGS_FATAL(
"Could not open file '{:s}'", input_filename.getValue());
115 json
const data = json::parse(f);
117 auto const number_of_anchors = data[
"anchor_start_points"].size();
118 if (number_of_anchors != data[
"anchor_end_points"].size())
121 "Number of anchor start points does not match the number of "
122 "anchor end points.");
126 Eigen::MatrixX3d realcoords(2 * number_of_anchors, 3);
128 auto get_coordinates = [&data](
const char* key, std::size_t
const i)
130 const auto& v = data[key][i].get_ref<json::array_t
const&>();
134 "Expected a vector of length three for {:s} {}. Got vector of "
138 return Eigen::RowVector3d{v[0].get<
double>(), v[1].get<double>(),
142 for (std::size_t i = 0; i < number_of_anchors; i++)
144 realcoords.row(2 * i).noalias() =
145 get_coordinates(
"anchor_start_points", i);
146 realcoords.row(2 * i + 1).noalias() =
147 get_coordinates(
"anchor_end_points", i);
149 Eigen::VectorXd initial_anchor_stress(number_of_anchors);
150 Eigen::VectorXd maximum_anchor_stress(number_of_anchors);
151 Eigen::VectorXd residual_anchor_stress(number_of_anchors);
152 Eigen::VectorXd anchor_cross_sectional_area(number_of_anchors);
153 Eigen::VectorXd anchor_stiffness(number_of_anchors);
154 if (!data.contains(
"initial_anchor_stress"))
156 initial_anchor_stress.setZero();
160 for (
size_t i = 0; i < number_of_anchors; ++i)
162 initial_anchor_stress(i) =
163 data[
"initial_anchor_stress"][i].get<
double>();
166 if (!data.contains(
"maximum_anchor_stress"))
168 maximum_anchor_stress = Eigen::VectorXd::Constant(
169 number_of_anchors, std::numeric_limits<double>::max());
173 for (
size_t i = 0; i < number_of_anchors; ++i)
175 maximum_anchor_stress(i) =
176 data[
"maximum_anchor_stress"][i].get<
double>();
179 if (!data.contains(
"residual_anchor_stress"))
181 residual_anchor_stress = Eigen::VectorXd::Constant(
182 number_of_anchors, std::numeric_limits<double>::max());
186 for (
size_t i = 0; i < number_of_anchors; ++i)
188 residual_anchor_stress(i) =
189 data[
"residual_anchor_stress"][i].get<
double>();
192 for (
size_t i = 0; i < number_of_anchors; ++i)
194 anchor_cross_sectional_area(i) =
195 data[
"anchor_cross_sectional_area"][i].get<
double>();
196 anchor_stiffness(i) = data[
"anchor_stiffness"][i].get<
double>();
213 "Computes natual coordinates from given real coordinates\n\n"
215 "OpenGeoSys-6 software, version " +
218 "Copyright (c) 2012-2025, OpenGeoSys Community "
219 "(http://www.opengeosys.org)",
223 cmd.add(log_level_arg);
225 TCLAP::ValueArg<std::string> input_filename_arg(
226 "i",
"input",
"Input (.vtu) bulk mesh file",
true,
"",
"INPUT_FILE",
229 TCLAP::ValueArg<std::string> output_filename_arg(
230 "o",
"output",
"Output (.vtu). Anchor mesh file",
true,
"",
233 TCLAP::ValueArg<std::string> json_filename_arg(
235 "Input (.json) JSON file containing anchor start and end points",
true,
236 "",
"INPUT_FILE", cmd);
238 TCLAP::ValueArg<double> tolerance_arg(
239 "",
"tolerance",
"Tolerance/Search length",
false,
240 std::numeric_limits<double>::epsilon(),
"float", cmd);
242 TCLAP::ValueArg<unsigned> max_iter_arg(
244 "maximum number of iterations of the internal root-finding "
245 "algorithm, (min = 0)",
246 false, 5,
"MAX_ITER", cmd);
248 cmd.parse(argc, argv);
255 auto const bulk_mesh =
readGrid(input_filename_arg.getValue());
260 max_iter_arg.getValue());
263 writeGrid(output_mesh, output_filename_arg.getValue());
267 OGS_FATAL(
"Failed to compute natural coordinates.");