const std::vector< std::pair<size_t,double> >& DirectConditionGenerator::directWithSurfaceIntegration(MeshLib::Mesh &mesh, const std::string &filename, double scaling)
{
	if (_direct_values.empty())
	{
		GeoLib::Raster* raster (GeoLib::Raster::readRaster(filename));
		if (!raster) {
			ERR("Error in DirectConditionGenerator::directWithSurfaceIntegration() - could not load raster file.");
			return _direct_values;
		}

		const MathLib::Vector3 dir(0,0,-1);
		MeshLib::Mesh* sfc_mesh (MeshLib::MeshSurfaceExtraction::getMeshSurface(mesh, dir, true));
		std::vector<double> node_area_vec;
		MeshLib::MeshSurfaceExtraction::getSurfaceAreaForNodes(*sfc_mesh, node_area_vec);
		const std::vector<MeshLib::Node*> &surface_nodes (sfc_mesh->getNodes());
		const size_t nNodes(sfc_mesh->getNNodes());
		const double no_data (raster->getNoDataValue());
		_direct_values.reserve(nNodes);
		for (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<size_t, double>(surface_nodes[i]->getID(), val));
		}

		delete raster;
	}
	else
		std::cout << "Error in DirectConditionGenerator::directWithSurfaceIntegration() - Data vector contains outdated values..." << std::endl;

	return _direct_values;
}
Exemple #2
0
void MshView::extractSurfaceMesh()
{
    QModelIndex index = this->selectionModel()->currentIndex();
    if (!index.isValid())
        return;

    const MeshLib::Mesh* mesh = static_cast<MshModel*>(this->model())->getMesh(index);
    SurfaceExtractionDialog dlg;
    if (dlg.exec() != QDialog::Accepted)
        return;

    MathLib::Vector3 const& dir (dlg.getNormal());
    int const tolerance (dlg.getTolerance());
    MeshLib::Mesh* sfc_mesh (MeshLib::MeshSurfaceExtraction::getMeshSurface(*mesh, dir, tolerance));
    if (sfc_mesh != nullptr)
        static_cast<MshModel*>(this->model())->addMesh(sfc_mesh);
    else
        OGSError::box(" No surfaces found to extract\n using the specified parameters.");
}
Exemple #3
0
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
        auto* const 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
    auto const* const node_id_pv =
        sfc_mesh->getProperties().getPropertyVector<std::size_t>(prop_name);
    if (!node_id_pv) {
        ERR(
            "Need subsurface node ids, but the property \"%s\" is not "
            "available.",
            prop_name.c_str());
        return nullptr;
    }

    // *** 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);

    auto const* const opt_materials =
        mesh.getProperties().getPropertyVector<int>("MaterialIDs");
    if (!opt_materials)
    {
        ERR("Could not copy the property \"MaterialIDs\" since the original "
            "mesh does not contain such a property.");
        return new_mesh;
    }

    auto* const new_materials =
        new_mesh->getProperties().createNewPropertyVector<int>(
            "MaterialIDs", MeshLib::MeshItemType::Cell, 1);
    if (!new_materials)
    {
        ERR("Can not set material properties for new layer");
        return new_mesh;
    }

    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);

    return new_mesh;
}
TEST(GeoLib, SurfaceIsPointInSurface)
{
    std::vector<std::function<double(double, double)>> surface_functions;
    surface_functions.push_back(constant);
    surface_functions.push_back(coscos);

    for (auto f : surface_functions) {
        std::random_device rd;

        std::string name("Surface");
        // generate ll and ur in random way
        std::mt19937 random_engine_mt19937(rd());
        std::normal_distribution<> normal_dist_ll(-10, 2);
        std::normal_distribution<> normal_dist_ur(10, 2);
        MathLib::Point3d ll(std::array<double,3>({{
                normal_dist_ll(random_engine_mt19937),
                normal_dist_ll(random_engine_mt19937),
                0.0
            }
        }));
        MathLib::Point3d ur(std::array<double,3>({{
                normal_dist_ur(random_engine_mt19937),
                normal_dist_ur(random_engine_mt19937),
                0.0
            }
        }));
        for (std::size_t k(0); k<3; ++k)
            if (ll[k] > ur[k])
                std::swap(ll[k], ur[k]);

        // random discretization of the domain
        std::default_random_engine re(rd());
        std::uniform_int_distribution<std::size_t> uniform_dist(2, 25);
        std::array<std::size_t,2> n_steps = {{uniform_dist(re),uniform_dist(re)}};

        std::unique_ptr<MeshLib::Mesh> sfc_mesh(
            MeshLib::MeshGenerator::createSurfaceMesh(
                name, ll, ur, n_steps, f
            )
        );

        // random rotation angles
        std::normal_distribution<> normal_dist_angles(
            0, boost::math::double_constants::two_pi);
        std::array<double,3> euler_angles = {{
                normal_dist_angles(random_engine_mt19937),
                normal_dist_angles(random_engine_mt19937),
                normal_dist_angles(random_engine_mt19937)
            }
        };

        MathLib::DenseMatrix<double, std::size_t> rot_mat(getRotMat(
                    euler_angles[0], euler_angles[1], euler_angles[2]));

        std::vector<MeshLib::Node*> const& nodes(sfc_mesh->getNodes());
        GeoLib::rotatePoints<MeshLib::Node>(rot_mat, nodes);

        MathLib::Vector3 const normal(0,0,1.0);
        MathLib::Vector3 const surface_normal(rot_mat * normal);
        double const eps(1e-6);
        MathLib::Vector3 const displacement(eps * surface_normal);

        GeoLib::GEOObjects geometries;
        MeshLib::convertMeshToGeo(*sfc_mesh, geometries);

        std::vector<GeoLib::Surface*> const& sfcs(*geometries.getSurfaceVec(name));
        GeoLib::Surface const*const sfc(sfcs.front());
        std::vector<GeoLib::Point*> const& pnts(*geometries.getPointVec(name));
        // test triangle edge point of the surface triangles
        for (auto const p : pnts) {
            EXPECT_TRUE(sfc->isPntInSfc(*p));
            MathLib::Point3d q(*p);
            for (std::size_t k(0); k<3; ++k)
                q[k] += displacement[k];
            EXPECT_FALSE(sfc->isPntInSfc(q));
        }
        // test edge middle points of the triangles
        for (std::size_t k(0); k<sfc->getNTriangles(); ++k) {
            MathLib::Point3d p, q, r;
            std::tie(p,q,r) = getEdgeMiddlePoints(*(*sfc)[k]);
            EXPECT_TRUE(sfc->isPntInSfc(p));
            EXPECT_TRUE(sfc->isPntInSfc(q));
            EXPECT_TRUE(sfc->isPntInSfc(r));
        }
    }
}