119int main(
int argc,
char* argv[])
122 "Creates boundary conditions for mesh nodes along polylines."
123 "The documentation is available at "
124 "https://docs.opengeosys.org/docs/tools/model-preparation/"
125 "create-boundary-conditions-along-a-polyline.\n\n"
126 "OpenGeoSys-6 software, version " +
129 "Copyright (c) 2012-2026, OpenGeoSys Community "
130 "(http://www.opengeosys.org)",
132 TCLAP::SwitchArg gml_arg(
"",
"gml",
"Write found nodes to gml file.");
135 TCLAP::ValueArg<std::string> output_base_fname(
136 "o",
"output-base-file-name",
137 "Output (.gli | .bc). The base name of the file the output (geometry "
138 "(gli) and boundary condition (bc)) will be written to",
139 true,
"",
"BASE_FILENAME_OUTPUT");
140 cmd.add(output_base_fname);
142 std::vector<std::string> allowed_types_vector{
"LIQUID_FLOW",
144 TCLAP::ValuesConstraint<std::string> allowed_types(allowed_types_vector);
145 TCLAP::ValueArg<std::string> bc_type(
147 "the process type the boundary condition will be written for currently "
148 "LIQUID_FLOW (primary variable PRESSURE1) and GROUNDWATER_FLOW "
149 "(primary variable HEAD, default) are supported, ",
150 true,
"", &allowed_types);
153 TCLAP::ValueArg<double> search_length_arg(
154 "s",
"search-length",
"The size of the search length ",
false,
155 std::numeric_limits<double>::epsilon(),
"SEARCH_LENGTH");
156 cmd.add(search_length_arg);
158 TCLAP::ValueArg<std::string> geometry_fname(
159 "i",
"input-geometry",
160 "Input (.gml | .gli). The name of the input file containing the "
162 true,
"",
"INPUT_FILE");
163 cmd.add(geometry_fname);
165 TCLAP::ValueArg<std::string> mesh_arg(
167 "Input (.vtu). The name of the input file containing the mesh",
true,
171 TCLAP::ValueArg<std::string> gmsh_path_arg(
172 "g",
"gmsh-path",
"Input (.msh). The path to the gmsh binary",
false,
174 cmd.add(gmsh_path_arg);
177 cmd.add(log_level_arg);
178 cmd.parse(argc, argv);
184 INFO(
"Reading mesh '{:s}' ... ", mesh_arg.getValue());
185 std::unique_ptr<MeshLib::Mesh> subsurface_mesh(
188 INFO(
"Extracting top surface of mesh '{:s}' ... ", mesh_arg.getValue());
189 Eigen::Vector3d
const dir({0, 0, -1});
190 double const angle(90);
191 std::unique_ptr<MeshLib::Mesh> surface_mesh(
195 subsurface_mesh.reset(
nullptr);
200 gmsh_path_arg.getValue());
206 std::vector<GeoLib::Polyline*>
const* plys(
210 ERR(
"Could not get vector of polylines out of geometry '{:s}'.",
215 auto search_length_strategy =
216 std::make_unique<MeshGeoToolsLib::SearchLength>();
217 if (search_length_arg.isSet())
219 search_length_strategy.reset(
225 *surface_mesh, std::move(search_length_strategy),
227 for (std::size_t k(0); k < plys->size(); k++)
234 std::string polyline_name(
"Polyline-" + std::to_string(k));
241 if (geo_names.empty())
243 ERR(
"Did not find mesh nodes along polylines.");
247 std::string merge_name(
"AllMeshNodesAlongPolylines");
250 merge_name = geo_names[0];
254 auto const& merged_pnts(pnt_vec->
getVector());
256 std::vector<GeoLib::Point> pnts_with_id;
257 const std::size_t n_merged_pnts(merged_pnts.size());
258 for (std::size_t k(0); k < n_merged_pnts; ++k)
260 pnts_with_id.emplace_back(*(merged_pnts[k]), k);
263 std::sort(pnts_with_id.begin(), pnts_with_id.end(),
265 { return p0 < p1; });
267 double const eps(std::numeric_limits<double>::epsilon());
268 std::vector<GeoLib::Point*> surface_pnts;
272 surface_pnts.push_back(
275 std::string element_name;
277 name_id_map[element_name] = 0;
279 for (std::size_t k(1); k < n_merged_pnts; ++k)
283 if (std::abs(p0[0] - p1[0]) > eps || std::abs(p0[1] - p1[1]) > eps)
285 surface_pnts.push_back(
287 std::string element_name;
289 name_id_map[element_name] = surface_pnts.size() - 1;
294 "-MeshNodesAlongPolylines");
295 geometry_sets.
addPointVec(std::move(surface_pnts), surface_name,
296 std::move(name_id_map), 1e-6);
299 std::string
const base_fname(
302 bc_type.getValue(), gml_arg.getValue());