Beispiel #1
0
GlobalSparsityPattern computeSparsityPatternNonPETSc(
    NumLib::LocalToGlobalIndexMap const& dof_table, MeshLib::Mesh const& mesh)
{
    MeshLib::NodeAdjacencyTable node_adjacency_table;
    node_adjacency_table.createTable(mesh.getNodes());

    // A mapping   mesh node id -> global indices
    // It acts as a cache for dof table queries.
    std::vector<std::vector<GlobalIndexType>> global_idcs;

    global_idcs.reserve(mesh.getNumberOfNodes());
    for (std::size_t n = 0; n < mesh.getNumberOfNodes(); ++n)
    {
        MeshLib::Location l(mesh.getID(), MeshLib::MeshItemType::Node, n);
        global_idcs.push_back(dof_table.getGlobalIndices(l));
    }

    GlobalSparsityPattern sparsity_pattern(dof_table.dofSizeWithGhosts());

    // Map adjacent mesh nodes to "adjacent global indices".
    for (std::size_t n = 0; n < mesh.getNumberOfNodes(); ++n)
    {
        unsigned n_connected_dof = 0;
        for (auto an : node_adjacency_table.getAdjacentNodes(n))
            n_connected_dof += global_idcs[an].size();
        for (auto global_index : global_idcs[n])
            sparsity_pattern[global_index] = n_connected_dof;
    }

    return sparsity_pattern;
}
Beispiel #2
0
NeumannBc::NeumannBc(
    NeumannBcConfig const& bc,
    unsigned const integration_order,
    NumLib::LocalToGlobalIndexMap const& local_to_global_index_map,
    int const variable_id,
    int const component_id)
    : _function(*bc.getFunction()),
      _integration_order(integration_order)
{
    assert(component_id < static_cast<int>(local_to_global_index_map.getNumberOfComponents()));

    // deep copy because the neumann bc config destroys the elements.
    std::transform(bc.elementsBegin(), bc.elementsEnd(),
            std::back_inserter(_elements),
            std::mem_fn(&MeshLib::Element::clone));

    std::vector<MeshLib::Node*> nodes = MeshLib::getUniqueNodes(_elements);

    auto const& mesh_subsets =
        local_to_global_index_map.getMeshSubsets(variable_id, component_id);

    // TODO extend the node intersection to all parts of mesh_subsets, i.e.
    // to each of the MeshSubset in the mesh_subsets.
    _mesh_subset_all_nodes =
        mesh_subsets.getMeshSubset(0).getIntersectionByNodes(nodes);
    std::unique_ptr<MeshLib::MeshSubsets> all_mesh_subsets{
        new MeshLib::MeshSubsets{_mesh_subset_all_nodes}};

    // Create local DOF table from intersected mesh subsets for the given
    // variable and component ids.
    _local_to_global_index_map.reset(
        local_to_global_index_map.deriveBoundaryConstrainedMap(
            variable_id, component_id, std::move(all_mesh_subsets),
            _elements));
}
std::unique_ptr<PythonBoundaryCondition> createPythonBoundaryCondition(
    BaseLib::ConfigTree const& config, MeshLib::Mesh const& boundary_mesh,
    NumLib::LocalToGlobalIndexMap const& dof_table, std::size_t bulk_mesh_id,
    int const variable_id, int const component_id,
    unsigned const integration_order, unsigned const shapefunction_order,
    unsigned const global_dim)
{
    //! \ogs_file_param{prj__process_variables__process_variable__boundary_conditions__boundary_condition__type}
    config.checkConfigParameter("type", "Python");

    //! \ogs_file_param{prj__process_variables__process_variable__boundary_conditions__boundary_condition__Python__bc_object}
    auto const bc_object = config.getConfigParameter<std::string>("bc_object");
    //! \ogs_file_param{prj__process_variables__process_variable__boundary_conditions__boundary_condition__Python__flush_stdout}
    auto const flush_stdout = config.getConfigParameter("flush_stdout", false);

    // Evaluate Python code in scope of main module
    pybind11::object scope =
        pybind11::module::import("__main__").attr("__dict__");

    if (!scope.contains(bc_object))
        OGS_FATAL(
            "Function `%s' is not defined in the python script file, or there "
            "was no python script file specified.",
            bc_object.c_str());

    auto* bc = scope[bc_object.c_str()]
                   .cast<PythonBoundaryConditionPythonSideInterface*>();

    if (variable_id >= static_cast<int>(dof_table.getNumberOfVariables()) ||
        component_id >= dof_table.getNumberOfVariableComponents(variable_id))
    {
        OGS_FATAL(
            "Variable id or component id too high. Actual values: (%d, %d), "
            "maximum values: (%d, %d).",
            variable_id, component_id, dof_table.getNumberOfVariables(),
            dof_table.getNumberOfVariableComponents(variable_id));
    }

    // In case of partitioned mesh the boundary could be empty, i.e. there is no
    // boundary condition.
#ifdef USE_PETSC
    // This can be extracted to createBoundaryCondition() but then the config
    // parameters are not read and will cause an error.
    // TODO (naumov): Add a function to ConfigTree for skipping the tags of the
    // subtree and move the code up in createBoundaryCondition().
    if (boundary_mesh.getDimension() == 0 &&
        boundary_mesh.getNumberOfNodes() == 0 &&
        boundary_mesh.getNumberOfElements() == 0)
    {
        return nullptr;
    }
#endif  // USE_PETSC

    return std::make_unique<PythonBoundaryCondition>(
        PythonBoundaryConditionData{
            bc, dof_table, bulk_mesh_id,
            dof_table.getGlobalComponent(variable_id, component_id),
            boundary_mesh},
        integration_order, shapefunction_order, global_dim, flush_stdout);
}
Beispiel #4
0
// TODO Copied from VectorMatrixAssembler. Could be provided by the DOF table.
inline NumLib::LocalToGlobalIndexMap::RowColumnIndices
getRowColumnIndices_(std::size_t const id,
                     NumLib::LocalToGlobalIndexMap const& dof_table,
                     std::vector<GlobalIndexType>& indices)
{
    assert(dof_table.size() > id);
    indices.clear();

    // Local matrices and vectors will always be ordered by component,
    // no matter what the order of the global matrix is.
    for (unsigned c = 0; c < dof_table.getNumberOfComponents(); ++c)
    {
        auto const& idcs = dof_table(id, c).rows;
        indices.reserve(indices.size() + idcs.size());
        indices.insert(indices.end(), idcs.begin(), idcs.end());
    }

    return NumLib::LocalToGlobalIndexMap::RowColumnIndices(indices,
                                                                 indices);
}
Beispiel #5
0
// TODO that essentially duplicates code which is also present in ProcessOutput.
double getNodalValue(GlobalVector const& x, MeshLib::Mesh const& mesh,
                     NumLib::LocalToGlobalIndexMap const& dof_table,
                     std::size_t const node_id,
                     std::size_t const global_component_id)
{
    MeshLib::Location const l{mesh.getID(), MeshLib::MeshItemType::Node,
                              node_id};

    auto const index = dof_table.getLocalIndex(
        l, global_component_id, x.getRangeBegin(), x.getRangeEnd());

    return x.get(index);
}
void DirichletBoundaryConditionWithinTimeInterval::config(
    NumLib::LocalToGlobalIndexMap const& dof_table_bulk)
{
    checkParametersOfDirichletBoundaryCondition(_bc_mesh, dof_table_bulk,
                                                _variable_id, _component_id);

    std::vector<MeshLib::Node*> const& bc_nodes = _bc_mesh.getNodes();
    MeshLib::MeshSubset bc_mesh_subset(_bc_mesh, bc_nodes);

    // Create local DOF table from the BC mesh subset for the given variable
    // and component id.
    _dof_table_boundary.reset(dof_table_bulk.deriveBoundaryConstrainedMap(
        _variable_id, {_component_id}, std::move(bc_mesh_subset)));
}
Beispiel #7
0
GlobalSparsityPattern computeSparsityPatternPETSc(
    NumLib::LocalToGlobalIndexMap const& dof_table,
    MeshLib::Mesh const& mesh)
{
    assert(dynamic_cast<MeshLib::NodePartitionedMesh const*>(&mesh));
    auto const& npmesh =
        *static_cast<MeshLib::NodePartitionedMesh const*>(&mesh);

    auto const max_nonzeroes =   dof_table.getNumberOfComponents()
                               * npmesh.getMaximumNConnectedNodesToNode();

    // The sparsity pattern is misused here in the sense that it will only
    // contain a single value.
    return GlobalSparsityPattern(1, max_nonzeroes);
}
LocalLinearLeastSquaresExtrapolator::LocalLinearLeastSquaresExtrapolator(
    NumLib::LocalToGlobalIndexMap const& dof_table)
    : _dof_table_single_component(dof_table)
{
    /* Note in case the following assertion fails:
     * If you copied the extrapolation code, for your processes from
     * somewhere, note that the code from the groundwater flow process might
     * not suit your needs: It is a special case and is therefore most
     * likely too simplistic. You better adapt the extrapolation code from
     * some more advanced process, like the TES process.
     */
    if (dof_table.getNumberOfComponents() != 1)
        OGS_FATAL(
            "The d.o.f. table passed must be for one variable that has "
            "only one component!");
}
Beispiel #9
0
void ProcessVariable::createBoundaryConditionsForDeactivatedSubDomains(
    const NumLib::LocalToGlobalIndexMap& dof_table, const int variable_id,
    std::vector<std::unique_ptr<ParameterBase>> const& parameters,
    std::vector<std::unique_ptr<BoundaryCondition>>& bcs)
{
    auto& parameter = findParameter<double>(
        DeactivatedSubdomain::name_of_paramater_of_zero, parameters, 1);

    for (auto const& deactivated_subdomain : _deactivated_subdomains)
    {
        auto const& deactivated_subdomain_meshes =
            deactivated_subdomain->deactivated_subdomain_meshes;
        for (auto const& deactivated_subdomain_mesh :
             deactivated_subdomain_meshes)
        {
            for (int component_id = 0;
                 component_id < dof_table.getNumberOfComponents();
                 component_id++)
            {
                // Copy the time interval.
                std::unique_ptr<BaseLib::TimeInterval> time_interval =
                    std::make_unique<BaseLib::TimeInterval>(
                        *deactivated_subdomain->time_interval);

                auto bc = std::make_unique<
                    DirichletBoundaryConditionWithinTimeInterval>(
                    std::move(time_interval), parameter,
                    *(deactivated_subdomain_mesh->mesh),
                    deactivated_subdomain_mesh->inactive_nodes, dof_table,
                    variable_id, component_id);

#ifdef USE_PETSC
                // TODO: make it work under PETSc too.
                if (bc == nullptr)
                {
                    continue;
                }
#endif  // USE_PETSC
                bcs.push_back(std::move(bc));
            }
        }
    }
}