const std::vector< std::pair<std::size_t,double> >& DirectConditionGenerator::directWithSurfaceIntegration(MeshLib::Mesh &mesh, const std::string &filename, double scaling) { if (!_direct_values.empty()) { ERR( "Error in DirectConditionGenerator::directWithSurfaceIntegration()" "- Data vector contains outdated values..."); return _direct_values; } std::unique_ptr<GeoLib::Raster> raster( GeoLib::IO::AsciiRasterInterface::readRaster(filename)); if (!raster) { ERR( "Error in DirectConditionGenerator::directWithSurfaceIntegration()" "- could not load raster file."); return _direct_values; } MathLib::Vector3 const dir(0.0, 0.0, -1.0); double const angle(90); std::string const prop_name("OriginalSubsurfaceNodeIDs"); std::unique_ptr<MeshLib::Mesh> surface_mesh( MeshLib::MeshSurfaceExtraction::getMeshSurface( mesh, dir, angle, prop_name)); std::vector<double> node_area_vec = MeshLib::MeshSurfaceExtraction::getSurfaceAreaForNodes(*surface_mesh); const std::vector<MeshLib::Node*> &surface_nodes(surface_mesh->getNodes()); const std::size_t nNodes(surface_mesh->getNNodes()); const double no_data(raster->getHeader().no_data); boost::optional<MeshLib::PropertyVector<int> const&> opt_node_id_pv( surface_mesh->getProperties().getPropertyVector<int>(prop_name)); if (!opt_node_id_pv) { ERR( "Need subsurface node ids, but the property \"%s\" is not " "available.", prop_name.c_str()); return _direct_values; } MeshLib::PropertyVector<int> const& node_id_pv(*opt_node_id_pv); _direct_values.reserve(nNodes); for (std::size_t i=0; i<nNodes; ++i) { double val(raster->getValueAtPoint(*surface_nodes[i])); val = (val == no_data) ? 0 : ((val*node_area_vec[i])/scaling); _direct_values.push_back(std::pair<std::size_t, double>(node_id_pv[i], val)); } return _direct_values; }
const std::vector< std::pair<std::size_t,double> >& DirectConditionGenerator::directWithSurfaceIntegration(MeshLib::Mesh &mesh, const std::string &filename, double scaling) { if (!_direct_values.empty()) { ERR("Error in DirectConditionGenerator::directWithSurfaceIntegration()" "- Data vector contains outdated values..."); return _direct_values; } std::unique_ptr<GeoLib::Raster> raster( FileIO::AsciiRasterInterface::readRaster(filename)); if (!raster) { ERR("Error in DirectConditionGenerator::directWithSurfaceIntegration()" "- could not load raster file."); return _direct_values; } MathLib::Vector3 const dir(0.0, 0.0, -1.0); double const angle(90); std::string const prop_name("bulk_node_ids"); std::unique_ptr<MeshLib::Mesh> surface_mesh( MeshLib::MeshSurfaceExtraction::getMeshSurface( mesh, dir, angle, prop_name)); std::vector<double> node_area_vec = MeshLib::MeshSurfaceExtraction::getSurfaceAreaForNodes(*surface_mesh); const std::vector<MeshLib::Node*> &surface_nodes(surface_mesh->getNodes()); const std::size_t nNodes(surface_mesh->getNumberOfNodes()); const double no_data(raster->getHeader().no_data); MeshLib::PropertyVector<int> const* node_id_pv = nullptr; try { node_id_pv = surface_mesh->getProperties().getPropertyVector<int>( prop_name, MeshLib::MeshItemType::Node, 1); } catch (std::runtime_error const& e) { WARN("%s", e.what()); return _direct_values; } _direct_values.reserve(nNodes); for (std::size_t i = 0; i < nNodes; ++i) { double val(raster->getValueAtPoint(*surface_nodes[i])); val = (val == no_data) ? 0 : ((val * node_area_vec[i]) / scaling); _direct_values.emplace_back((*node_id_pv)[i], val); } return _direct_values; }
int main (int argc, char* argv[]) { ApplicationsLib::LogogSetup logog_setup; TCLAP::CmdLine cmd("Tool extracts the surface of the given mesh.", ' ', "0.1"); TCLAP::ValueArg<std::string> mesh_in( "i", "mesh-input-file", "the name of the file containing the input mesh", true, "", "file name of input mesh"); cmd.add(mesh_in); TCLAP::ValueArg<std::string> mesh_out( "o", "mesh-output-file", "the name of the file the surface mesh should be written to", false, "", "file name of output mesh"); cmd.add(mesh_out); TCLAP::ValueArg<double> x("x", "x-component", "x component of the normal", false, 0, "floating point value"); cmd.add(x); TCLAP::ValueArg<double> y("y", "y-component", "y component of the normal", false, 0, "floating point value"); cmd.add(y); TCLAP::ValueArg<double> z("z", "z-component", "z component of the normal", false, -1.0, "floating point value"); cmd.add(z); TCLAP::ValueArg<double> angle_arg( "a", "angle", "angle between given normal and element normal", false, 90, "floating point value"); cmd.add(angle_arg); cmd.parse(argc, argv); std::unique_ptr<MeshLib::Mesh const> mesh( MeshLib::IO::readMeshFromFile(mesh_in.getValue())); INFO("Mesh read: %u nodes, %u elements.", mesh->getNNodes(), mesh->getNElements()); // extract surface MathLib::Vector3 const dir(x.getValue(), y.getValue(), z.getValue()); double const angle(angle_arg.getValue()); std::unique_ptr<MeshLib::Mesh> surface_mesh( MeshLib::MeshSurfaceExtraction::getMeshSurface( *mesh, dir, angle, "OriginalSubsurfaceNodeIDs")); std::string out_fname(mesh_out.getValue()); if (out_fname.empty()) out_fname = BaseLib::dropFileExtension(mesh_in.getValue()) + "_sfc.vtu"; MeshLib::IO::writeMeshToFile(*surface_mesh, out_fname); return EXIT_SUCCESS; }
int main (int argc, char* argv[]) { ApplicationsLib::LogogSetup logog_setup; TCLAP::CmdLine cmd("Computes ids of mesh nodes that are in polygonal " "regions and resides on the top surface. The polygonal regions have to " "be given in a gml- or gli-file. The found mesh nodes and the associated" " area are written as txt and csv data." "The documentation is available at https://docs.opengeosys.org/docs/tools/model-preparation/computesurfacenodeidsinpolygonalregion", ' ', "0.1"); TCLAP::ValueArg<std::string> mesh_in("m", "mesh-input-file", "the name of the file containing the input mesh", true, "", "file name of input mesh"); cmd.add(mesh_in); TCLAP::ValueArg<std::string> geo_in("g", "geo-file", "the name of the gml file containing the polygons", true, "", "file name of input geometry"); cmd.add(geo_in); cmd.parse(argc, argv); std::unique_ptr<MeshLib::Mesh const> mesh(FileIO::readMeshFromFile(mesh_in.getValue())); INFO("Mesh read: %u nodes, %u elements.", mesh->getNNodes(), mesh->getNElements()); GeoLib::GEOObjects geo_objs; FileIO::readGeometryFromFile(geo_in.getValue(), geo_objs); std::vector<std::string> geo_names; geo_objs.getGeometryNames(geo_names); INFO("Geometry \"%s\" read: %u points, %u polylines.", geo_names[0].c_str(), geo_objs.getPointVec(geo_names[0])->size(), geo_objs.getPolylineVec(geo_names[0])->size()); MathLib::Vector3 const dir(0.0, 0.0, -1.0); double angle(90); auto computeElementTopSurfaceAreas = [](MeshLib::Mesh const& mesh, MathLib::Vector3 const& d, double angle) { std::unique_ptr<MeshLib::Mesh> surface_mesh( MeshLib::MeshSurfaceExtraction::getMeshSurface(mesh, d, angle)); return MeshLib::MeshSurfaceExtraction::getSurfaceAreaForNodes( *surface_mesh.get()); }; std::vector<double> areas(computeElementTopSurfaceAreas(*mesh, dir, angle)); std::vector<GeoLib::Point*> all_sfc_pnts( MeshLib::MeshSurfaceExtraction::getSurfaceNodes(*mesh, dir, angle) ); std::for_each(all_sfc_pnts.begin(), all_sfc_pnts.end(), [](GeoLib::Point* p) { (*p)[2] = 0.0; }); std::vector<MeshLib::Node*> const& mesh_nodes(mesh->getNodes()); GeoLib::PolylineVec const* ply_vec( geo_objs.getPolylineVecObj(geo_names[0]) ); std::vector<GeoLib::Polyline*> const& plys(*(ply_vec->getVector())); for (std::size_t j(0); j<plys.size(); j++) { if (! plys[j]->isClosed()) { continue; } std::string polygon_name; ply_vec->getNameOfElement(plys[j], polygon_name); if (polygon_name.empty()) polygon_name = "Polygon-" + std::to_string(j); // create Polygon from Polyline GeoLib::Polygon const& polygon(*(plys[j])); // ids of mesh nodes on surface that are within the given polygon std::vector<std::pair<std::size_t, double>> ids_and_areas; for (std::size_t k(0); k<all_sfc_pnts.size(); k++) { GeoLib::Point const& pnt(*(all_sfc_pnts[k])); if (polygon.isPntInPolygon(pnt)) { ids_and_areas.push_back(std::make_pair(pnt.getID(), areas[k])); } } if (ids_and_areas.empty()) { ERR("Polygonal part of surface \"%s\" doesn't contains nodes. No " "output will be generated.", polygon_name.c_str()); continue; } std::string const out_path(BaseLib::extractPath(geo_in.getValue())); std::string id_and_area_fname(out_path + polygon_name); std::string csv_fname(out_path + polygon_name); id_and_area_fname += std::to_string(j) + ".txt"; csv_fname += std::to_string(j) + ".csv"; INFO("Polygonal part of surface \"%s\" contains %ul nodes. Writting to" " files \"%s\" and \"%s\".", polygon_name.c_str(), ids_and_areas.size(), id_and_area_fname.c_str(), csv_fname.c_str() ); writeToFile(id_and_area_fname, csv_fname, ids_and_areas, mesh_nodes); } std::for_each(all_sfc_pnts.begin(), all_sfc_pnts.end(), std::default_delete<GeoLib::Point>()); return 0; }
int main (int argc, char* argv[]) { ApplicationsLib::LogogSetup logog_setup; TCLAP::CmdLine cmd( "Creates boundary conditions for mesh nodes along polylines." "The documentation is available at https://docs.opengeosys.org/docs/tools/model-preparation/create-boundary-conditions-along-a-polyline", ' ', "0.1"); TCLAP::ValueArg<bool> gml_arg("", "gml", "if switched on write found nodes to file in gml format", false, 0, "bool"); cmd.add(gml_arg); TCLAP::ValueArg<std::string> output_base_fname("o", "output-base-file-name", "the base name of the file the output (geometry (gli) and boundary"\ "condition (bc)) will be written to", true, "", "file name"); cmd.add(output_base_fname); TCLAP::ValueArg<std::string> bc_type("t", "type", "the process type the boundary condition will be written for "\ "currently LIQUID_FLOW (primary variable PRESSURE1) and "\ "GROUNDWATER_FLOW (primary variable HEAD, default) are supported", true, "", "process type as string (LIQUID_FLOW or GROUNDWATER_FLOW (default))"); cmd.add(bc_type); TCLAP::ValueArg<double> search_length_arg("s", "search-length", "The size of the search length. The default value is " "std::numeric_limits<double>::epsilon()", false, std::numeric_limits<double>::epsilon(), "floating point number"); cmd.add(search_length_arg); TCLAP::ValueArg<std::string> geometry_fname("i", "input-geometry", "the name of the file containing the input geometry", true, "", "file name"); cmd.add(geometry_fname); TCLAP::ValueArg<std::string> mesh_arg("m", "mesh-file", "the name of the file containing the mesh", true, "", "file name"); cmd.add(mesh_arg); cmd.parse(argc, argv); // *** read mesh INFO("Reading mesh \"%s\" ... ", mesh_arg.getValue().c_str()); MeshLib::Mesh * subsurface_mesh(FileIO::readMeshFromFile(mesh_arg.getValue())); INFO("done."); INFO("Extracting top surface of mesh \"%s\" ... ", mesh_arg.getValue().c_str()); const MathLib::Vector3 dir(0,0,-1); double const angle(90); std::unique_ptr<MeshLib::Mesh> surface_mesh( MeshLib::MeshSurfaceExtraction::getMeshSurface(*subsurface_mesh, dir, angle)); INFO("done."); delete subsurface_mesh; subsurface_mesh = nullptr; // *** read geometry GeoLib::GEOObjects geometries; FileIO::readGeometryFromFile(geometry_fname.getValue(), geometries); std::string geo_name; { std::vector<std::string> geo_names; geometries.getGeometryNames(geo_names); geo_name = geo_names[0]; } // *** check if the data is usable // *** get vector of polylines std::vector<GeoLib::Polyline*> const* plys(geometries.getPolylineVec(geo_name)); if (!plys) { ERR("Could not get vector of polylines out of geometry \"%s\".", geo_name.c_str()); return -1; } MeshGeoToolsLib::SearchLength search_length_strategy; if (search_length_arg.isSet()) { search_length_strategy = MeshGeoToolsLib::SearchLength(search_length_arg.getValue()); } GeoLib::GEOObjects geometry_sets; MeshGeoToolsLib::MeshNodeSearcher mesh_searcher(*surface_mesh, search_length_strategy); for(std::size_t k(0); k<plys->size(); k++) { std::vector<std::size_t> ids (mesh_searcher.getMeshNodeIDsAlongPolyline(*((*plys)[k]))); if (ids.empty()) continue; std::string geo_name("Polyline-"+std::to_string(k)); convertMeshNodesToGeometry(surface_mesh->getNodes(), ids, geo_name, geometry_sets); } // merge all together std::vector<std::string> geo_names; geometry_sets.getGeometryNames(geo_names); if (geo_names.empty()) { ERR("Did not find mesh nodes along polylines."); return -1; } std::string merge_name("AllMeshNodesAlongPolylines"); if (geometry_sets.mergeGeometries(geo_names, merge_name) == 2) merge_name = geo_names[0]; GeoLib::PointVec const* pnt_vec(geometry_sets.getPointVecObj(merge_name)); std::vector<GeoLib::Point*> const* merged_pnts(pnt_vec->getVector()); std::vector<GeoLib::Point> pnts_with_id; const std::size_t n_merged_pnts(merged_pnts->size()); for(std::size_t k(0); k<n_merged_pnts; ++k) { pnts_with_id.emplace_back(*((*merged_pnts)[k]), k); } std::sort(pnts_with_id.begin(), pnts_with_id.end(), [](GeoLib::Point const& p0, GeoLib::Point const& p1) { return p0 < p1; } ); double const eps (std::numeric_limits<double>::epsilon()); auto surface_pnts = std::unique_ptr<std::vector<GeoLib::Point*>>( new std::vector<GeoLib::Point*>); std::map<std::string, std::size_t> *name_id_map( new std::map<std::string, std::size_t> ); // insert first point surface_pnts->push_back( new GeoLib::Point(pnts_with_id[0], surface_pnts->size())); std::string element_name; pnt_vec->getNameOfElementByID(0, element_name); name_id_map->insert( std::pair<std::string, std::size_t>(element_name,0) ); for (std::size_t k(1); k < n_merged_pnts; ++k) { const GeoLib::Point& p0 (pnts_with_id[k-1]); const GeoLib::Point& p1 (pnts_with_id[k]); if (std::abs (p0[0] - p1[0]) > eps || std::abs (p0[1] - p1[1]) > eps) { surface_pnts->push_back(new GeoLib::Point(pnts_with_id[k], surface_pnts->size())); std::string element_name; pnt_vec->getNameOfElementByID(k, element_name); name_id_map->insert( std::pair<std::string, std::size_t>(element_name, surface_pnts->size()-1) ); } } std::string surface_name(BaseLib::dropFileExtension(mesh_arg.getValue())+"-MeshNodesAlongPolylines"); geometry_sets.addPointVec(std::move(surface_pnts), surface_name, name_id_map, 1e-6); // write the BCs and the merged geometry set to file std::string const base_fname( BaseLib::dropFileExtension(output_base_fname.getValue())); writeBCsAndGeometry(geometry_sets, surface_name, base_fname, bc_type.getValue(), gml_arg.getValue()); return 0; }
int main(int argc, char* argv[]) { ApplicationsLib::LogogSetup logo_setup; TCLAP::CmdLine cmd( "Integrates the given element property and outputs an OGS-5 direct " "Neumann boundary condition. The mesh has to contain a property " "'bulk_node_ids' that stores the original subsurface " "mesh node ids. Such surface meshes can be created using the OGS-6 " "tool ExtractSurface.\n\n" "OpenGeoSys-6 software, version " + BaseLib::BuildInfo::git_describe + ".\n" "Copyright (c) 2012-2019, OpenGeoSys Community " "(http://www.opengeosys.org)", ' ', BaseLib::BuildInfo::git_describe); TCLAP::ValueArg<std::string> in_mesh("i", "in-mesh", "the surface mesh that has an element " "property for the Neumann " "boundary condition", true, "", "filename for surface mesh input"); cmd.add(in_mesh); TCLAP::ValueArg<std::string> property_in_arg( "p", "property-in-name", "name of an element property used for the computation of the " "Neumann boundary condition", true, "", "string (property name)"); cmd.add(property_in_arg); TCLAP::ValueArg<std::string> property_out_arg( "", "property-out-name", "name of the node based property used for the output of the " "Neumann boundary condition", true, "", "string (property name)"); cmd.add(property_out_arg); TCLAP::ValueArg<std::string> result_file( "o", "result-out", "the file name the result will be written to ", true, "", "output file name"); cmd.add(result_file); cmd.parse( argc, argv ); // read surface mesh std::unique_ptr<MeshLib::Mesh> surface_mesh( MeshLib::IO::readMeshFromFile(in_mesh.getValue())); auto const* const node_id_pv = [&]() -> MeshLib::PropertyVector<std::size_t>* { try { return surface_mesh->getProperties().getPropertyVector<std::size_t>( "bulk_node_ids", MeshLib::MeshItemType::Node, 1); } catch (std::runtime_error const& e) { WARN("%s", e.what()); return nullptr; } }(); if (!node_id_pv) return EXIT_FAILURE; std::vector<double> integrated_values = getSurfaceIntegratedValuesForNodes( *surface_mesh, property_in_arg.getValue()); std::vector<std::pair<std::size_t, double>> direct_values; direct_values.reserve(surface_mesh->getNumberOfNodes()); for (auto const* node : surface_mesh->getNodes()) { auto const id(node->getID()); auto const subsurface_node_id((*node_id_pv)[id]); auto const val(integrated_values[id]); direct_values.push_back(std::make_pair(subsurface_node_id, val)); } auto* const pv = surface_mesh->getProperties().createNewPropertyVector<double>( property_out_arg.getValue(), MeshLib::MeshItemType::Node, 1); pv->resize(surface_mesh->getNodes().size()); for (std::size_t k(0); k < surface_mesh->getNodes().size(); ++k) { (*pv)[k] = direct_values[k].second; } MeshLib::IO::writeMeshToFile(*surface_mesh, result_file.getValue()); std::ofstream result_out(result_file.getValue() + ".txt"); result_out.precision(std::numeric_limits<double>::digits10); for (auto const& p : direct_values) result_out << p.first << " " << p.second << "\n"; return EXIT_SUCCESS; }
int main (int argc, char* argv[]) { ApplicationsLib::LogogSetup logog_setup; TCLAP::CmdLine cmd("The tool computes the area per node of the surface mesh" " and writes the information as txt and csv data.", ' ', "0.1"); TCLAP::ValueArg<std::string> mesh_in("i", "mesh-input-file", "the name of the file containing the input mesh", true, "", "file name of input mesh"); cmd.add(mesh_in); TCLAP::ValueArg<std::string> id_prop_name("", "id-prop-name", "the name of the property containing the id information", false, "OriginalSubsurfaceNodeIDs", "property name"); cmd.add(id_prop_name); TCLAP::ValueArg<std::string> out_base_fname("p", "output-base-name", "the path and base file name the output will be written to", false, "", "output path and base name as one string"); cmd.add(out_base_fname); cmd.parse(argc, argv); std::unique_ptr<MeshLib::Mesh> surface_mesh( MeshLib::IO::readMeshFromFile(mesh_in.getValue())); INFO("Mesh read: %u nodes, %u elements.", surface_mesh->getNNodes(), surface_mesh->getNElements()); // ToDo check if mesh is read correct and if the mesh is a surface mesh // check if a node property containing the subsurface ids is available boost::optional<MeshLib::PropertyVector<std::size_t> const&> orig_node_ids( surface_mesh->getProperties().getPropertyVector<std::size_t>( id_prop_name.getValue())); // if the node property is not available generate it if (!orig_node_ids) { boost::optional<MeshLib::PropertyVector<std::size_t>&> node_ids( surface_mesh->getProperties().createNewPropertyVector<std::size_t>( id_prop_name.getValue(), MeshLib::MeshItemType::Node, 1)); if (!node_ids) { ERR("Fatal error: could not create property."); return EXIT_FAILURE; } node_ids->resize(surface_mesh->getNNodes()); std::iota(node_ids->begin(), node_ids->end(), 0); orig_node_ids = node_ids; } std::vector<double> areas( MeshLib::MeshSurfaceExtraction::getSurfaceAreaForNodes(*surface_mesh)); // pack area and node id together std::vector<std::pair<std::size_t, double>> ids_and_areas; std::transform(orig_node_ids->cbegin(), orig_node_ids->cend(), areas.cbegin(), std::back_inserter(ids_and_areas), std::make_pair<std::size_t const&, double const&>); // generate file names for output std::string path(out_base_fname.getValue()); if (path.empty()) path = BaseLib::dropFileExtension(mesh_in.getValue()); std::string const id_and_area_fname(path+".txt"); std::string const csv_fname(path+".csv"); writeToFile(id_and_area_fname, csv_fname, ids_and_areas, surface_mesh->getNodes()); return EXIT_SUCCESS; }