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; }
MeshLib::Mesh* addLayerToMesh(MeshLib::Mesh const& mesh, double thickness, std::string const& name, bool on_top) { INFO("Extracting top surface of mesh \"%s\" ... ", mesh.getName().c_str()); int const flag = (on_top) ? -1 : 1; const MathLib::Vector3 dir(0, 0, flag); double const angle(90); std::unique_ptr<MeshLib::Mesh> sfc_mesh (nullptr); std::string const prop_name("OriginalSubsurfaceNodeIDs"); if (mesh.getDimension() == 3) sfc_mesh.reset(MeshLib::MeshSurfaceExtraction::getMeshSurface( mesh, dir, angle, prop_name)); else { sfc_mesh = (on_top) ? std::unique_ptr<MeshLib::Mesh>(new MeshLib::Mesh(mesh)) : std::unique_ptr<MeshLib::Mesh>(MeshLib::createFlippedMesh(mesh)); // add property storing node ids boost::optional<MeshLib::PropertyVector<std::size_t>&> pv( sfc_mesh->getProperties().createNewPropertyVector<std::size_t>( prop_name, MeshLib::MeshItemType::Node, 1)); if (pv) { pv->resize(sfc_mesh->getNumberOfNodes()); std::iota(pv->begin(), pv->end(), 0); } else { ERR("Could not create and initialize property."); return nullptr; } } INFO("done."); // *** add new surface nodes std::vector<MeshLib::Node*> subsfc_nodes = MeshLib::copyNodeVector(mesh.getNodes()); std::vector<MeshLib::Element*> subsfc_elements = MeshLib::copyElementVector(mesh.getElements(), subsfc_nodes); std::size_t const n_subsfc_nodes(subsfc_nodes.size()); std::vector<MeshLib::Node*> const& sfc_nodes(sfc_mesh->getNodes()); std::size_t const n_sfc_nodes(sfc_nodes.size()); // fetch subsurface node ids PropertyVector boost::optional<MeshLib::PropertyVector<std::size_t> const&> opt_node_id_pv( sfc_mesh->getProperties().getPropertyVector<std::size_t>(prop_name)); if (!opt_node_id_pv) { ERR( "Need subsurface node ids, but the property \"%s\" is not " "available.", prop_name.c_str()); return nullptr; } MeshLib::PropertyVector<std::size_t> const& node_id_pv(*opt_node_id_pv); // *** copy sfc nodes to subsfc mesh node std::map<std::size_t, std::size_t> subsfc_sfc_id_map; for (std::size_t k(0); k<n_sfc_nodes; ++k) { std::size_t const subsfc_id(node_id_pv[k]); std::size_t const sfc_id(k+n_subsfc_nodes); subsfc_sfc_id_map.insert(std::make_pair(subsfc_id, sfc_id)); MeshLib::Node const& node(*sfc_nodes[k]); subsfc_nodes.push_back(new MeshLib::Node( node[0], node[1], node[2] - (flag * thickness), sfc_id)); } // *** insert new layer elements into subsfc_mesh std::vector<MeshLib::Element*> const& sfc_elements(sfc_mesh->getElements()); std::size_t const n_sfc_elements(sfc_elements.size()); for (std::size_t k(0); k<n_sfc_elements; ++k) subsfc_elements.push_back(extrudeElement(subsfc_nodes, *sfc_elements[k], node_id_pv, subsfc_sfc_id_map)); auto new_mesh = new MeshLib::Mesh(name, subsfc_nodes, subsfc_elements); boost::optional<MeshLib::PropertyVector<int> const&> opt_materials( mesh.getProperties().getPropertyVector<int>("MaterialIDs") ); if (opt_materials) { boost::optional<PropertyVector<int> &> new_materials( new_mesh->getProperties().createNewPropertyVector<int>("MaterialIDs", MeshLib::MeshItemType::Cell, 1)); if (!new_materials) { ERR("Can not set material properties for new layer"); } else { new_materials->reserve(subsfc_elements.size()); int new_layer_id (*(std::max_element(opt_materials->cbegin(), opt_materials->cend()))+1); std::copy(opt_materials->cbegin(), opt_materials->cend(), std::back_inserter(*new_materials)); auto const n_new_props(subsfc_elements.size()-mesh.getNumberOfElements()); std::fill_n(std::back_inserter(*new_materials), n_new_props, new_layer_id); } } else { ERR( "Could not copy the property \"MaterialIDs\" since the original " "mesh does not contain such a property."); } return new_mesh; }