Skip to content
Snippets Groups Projects
Commit 69525cf1 authored by Christoph Lehmann's avatar Christoph Lehmann
Browse files

[PL] Added class ProcessOutputData

parent f0e586b7
No related branches found
No related tags found
No related merge requests found
/**
* \file
* \copyright
* Copyright (c) 2012-2021, OpenGeoSys Community (http://www.opengeosys.org)
* Distributed under a Modified BSD License.
* See accompanying file LICENSE.txt or
* http://www.opengeosys.org/project/license
*
*/
#include "ProcessOutputData.h"
#include "ProcessLib/Process.h"
namespace
{
/// Checks if the given \c mesh is the simulation domain of the given \c
/// process.
bool isSimulationDomain(MeshLib::Mesh const& mesh,
ProcessLib::Process const& process)
{
return mesh == process.getMesh();
}
std::vector<std::unique_ptr<NumLib::LocalToGlobalIndexMap>>
computeDofTablesForSubmesh(ProcessLib::Process const& process,
MeshLib::Mesh const& submesh,
std::size_t const n_processes)
{
std::vector<std::unique_ptr<NumLib::LocalToGlobalIndexMap>>
submesh_dof_tables;
submesh_dof_tables.reserve(n_processes);
for (std::size_t i = 0; i < n_processes; ++i)
{
submesh_dof_tables.push_back(
process.getDOFTable(i).deriveBoundaryConstrainedMap(
MeshLib::MeshSubset{submesh, submesh.getNodes()}));
}
return submesh_dof_tables;
}
std::vector<NumLib::LocalToGlobalIndexMap const*> toNonOwning(
std::vector<std::unique_ptr<NumLib::LocalToGlobalIndexMap>> const&
dof_tables)
{
std::vector<NumLib::LocalToGlobalIndexMap const*> dof_table_pointers;
dof_table_pointers.reserve(dof_tables.size());
transform(cbegin(dof_tables), cend(dof_tables),
back_inserter(dof_table_pointers),
[](std::unique_ptr<NumLib::LocalToGlobalIndexMap> const& p)
{ return p.get(); });
return dof_table_pointers;
}
std::vector<NumLib::LocalToGlobalIndexMap const*> getDofTablesOfAllProcesses(
ProcessLib::Process const& process, std::size_t const n_processes)
{
std::vector<NumLib::LocalToGlobalIndexMap const*> dof_tables_of_all_procs(
n_processes);
for (std::size_t proc_id = 0; proc_id < n_processes; ++proc_id)
{
dof_tables_of_all_procs[proc_id] = &process.getDOFTable(proc_id);
}
return dof_tables_of_all_procs;
}
/// Computes the d.o.f. tables for the given \c output_mesh.
///
/// These are the passed \c bulk_mesh_dof_tables for output of the entire
/// simulation domain of the given \c process. In the case of submesh output
/// d.o.f. tables for the submesh will be computed.
///
/// \return A pair of (vector of d.o.f. table pointers, vector of d.o.f. table
/// storage), where the latter is populated in the case of submesh output only.
///
/// Each element in the returned vectors corresponds to a specific \c process_id
/// of the \c process.
decltype(auto) computeOutputMeshDofTables(
ProcessLib::Process const& process,
MeshLib::Mesh const& output_mesh,
std::vector<NumLib::LocalToGlobalIndexMap const*> const&
bulk_mesh_dof_tables)
{
if (isSimulationDomain(output_mesh, process))
{
return std::pair(
bulk_mesh_dof_tables /* will be copied */,
std::vector<std::unique_ptr<NumLib::LocalToGlobalIndexMap>>{});
}
auto const n_processes = bulk_mesh_dof_tables.size();
// TODO Currently these d.o.f. tables will be recomputed everytime we write
// output. That should be avoided in the future.
auto container_that_owns_output_mesh_dof_tables =
computeDofTablesForSubmesh(process, output_mesh, n_processes);
auto output_mesh_dof_tables =
toNonOwning(container_that_owns_output_mesh_dof_tables);
return std::pair(std::move(output_mesh_dof_tables),
std::move(container_that_owns_output_mesh_dof_tables));
}
std::vector<std::reference_wrapper<
const std::vector<std::reference_wrapper<ProcessLib::ProcessVariable>>>>
getProcessVariablesOfAllProcesses(ProcessLib::Process const& process,
std::size_t const n_processes)
{
std::vector<std::reference_wrapper<
const std::vector<std::reference_wrapper<ProcessLib::ProcessVariable>>>>
pvs_of_all_procs;
pvs_of_all_procs.reserve(n_processes);
for (std::size_t proc_id = 0; proc_id < n_processes; ++proc_id)
{
pvs_of_all_procs.emplace_back(process.getProcessVariables(proc_id));
}
return pvs_of_all_procs;
}
std::vector<std::unique_ptr<ProcessLib::IntegrationPointWriter>> const*
getIntegrationPointWriters(ProcessLib::Process const& process,
MeshLib::Mesh const& output_mesh)
{
return isSimulationDomain(output_mesh, process)
? &process.getIntegrationPointWriters()
: nullptr;
}
} // namespace
namespace ProcessLib
{
ProcessOutputData createProcessOutputData(Process const& process,
std::size_t const n_processes,
MeshLib::Mesh& output_mesh)
{
auto bulk_mesh_dof_tables =
getDofTablesOfAllProcesses(process, n_processes);
auto [output_mesh_dof_tables, container_that_owns_output_mesh_dof_tables] =
computeOutputMeshDofTables(process, output_mesh, bulk_mesh_dof_tables);
return {getProcessVariablesOfAllProcesses(process, n_processes),
process.getSecondaryVariables(),
::getIntegrationPointWriters(process, output_mesh),
std::move(bulk_mesh_dof_tables),
std::move(output_mesh_dof_tables),
std::move(container_that_owns_output_mesh_dof_tables),
output_mesh};
}
ProcessOutputData::ProcessOutputData(
std::vector<std::reference_wrapper<
const std::vector<std::reference_wrapper<ProcessVariable>>>>&&
process_variables_of_all_processes,
const SecondaryVariableCollection& secondary_variables,
const std::vector<std::unique_ptr<IntegrationPointWriter>>*
integration_point_writers,
std::vector<const NumLib::LocalToGlobalIndexMap*>&&
bulk_mesh_dof_tables_of_all_processes,
std::vector<const NumLib::LocalToGlobalIndexMap*>&&
output_mesh_dof_tables_of_all_processes,
std::vector<std::unique_ptr<NumLib::LocalToGlobalIndexMap>>&&
container_that_owns_output_mesh_dof_tables,
MeshLib::Mesh& output_mesh)
: process_variables_of_all_processes_(
std::move(process_variables_of_all_processes)),
secondary_variables_(secondary_variables),
integration_point_writers_(integration_point_writers),
bulk_mesh_dof_tables_of_all_processes_(
std::move(bulk_mesh_dof_tables_of_all_processes)),
output_mesh_dof_tables_of_all_processes_(
std::move(output_mesh_dof_tables_of_all_processes)),
container_that_owns_output_mesh_dof_tables_(
std::move(container_that_owns_output_mesh_dof_tables)),
output_mesh_(output_mesh)
{
auto const n_proc_pvs = process_variables_of_all_processes_.size();
auto const n_proc_bulk = bulk_mesh_dof_tables_of_all_processes_.size();
auto const n_proc_out = output_mesh_dof_tables_of_all_processes_.size();
auto const n_proc_own = container_that_owns_output_mesh_dof_tables_.size();
if (n_proc_pvs != n_proc_bulk)
{
OGS_FATAL(
"Mismatch in number of processes (PVs vs. bulk mesh d.o.f. "
"tables): {} != {}",
n_proc_pvs, n_proc_bulk);
}
if (n_proc_pvs != n_proc_out)
{
OGS_FATAL(
"Mismatch in number of processes (PVs vs. output mesh d.o.f. "
"tables): {} != {}",
n_proc_pvs, n_proc_out);
}
// n_proc_own is nonzero only for submesh output
if (n_proc_own != 0 && n_proc_pvs != n_proc_own)
{
OGS_FATAL(
"Mismatch in number of processes (PVs vs. output mesh d.o.f. "
"tables, owning): {} != {}",
n_proc_pvs, n_proc_own);
}
}
} // namespace ProcessLib
/**
* \file
* \copyright
* Copyright (c) 2012-2021, OpenGeoSys Community (http://www.opengeosys.org)
* Distributed under a Modified BSD License.
* See accompanying file LICENSE.txt or
* http://www.opengeosys.org/project/license
*
*/
#pragma once
#include "MathLib/LinAlg/GlobalMatrixVectorTypes.h"
#include "NumLib/DOF/LocalToGlobalIndexMap.h"
namespace ProcessLib
{
class Process;
class ProcessVariable;
class SecondaryVariableCollection;
struct IntegrationPointWriter;
/// Holds all data of a process that are needed for output.
class ProcessOutputData final
{
public:
ProcessOutputData(
std::vector<std::reference_wrapper<
const std::vector<std::reference_wrapper<ProcessVariable>>>>&&
process_variables_of_all_processes,
const SecondaryVariableCollection& secondary_variables,
const std::vector<std::unique_ptr<IntegrationPointWriter>>*
integration_point_writers,
std::vector<const NumLib::LocalToGlobalIndexMap*>&&
bulk_mesh_dof_tables_of_all_processes,
std::vector<const NumLib::LocalToGlobalIndexMap*>&&
output_mesh_dof_tables_of_all_processes,
std::vector<std::unique_ptr<NumLib::LocalToGlobalIndexMap>>&&
container_that_owns_output_mesh_dof_tables,
MeshLib::Mesh& output_mesh);
std::vector<std::reference_wrapper<ProcessVariable>> const&
getProcessVariables(int const process_id) const
{
return process_variables_of_all_processes_[process_id].get();
}
SecondaryVariableCollection const& getSecondaryVariables() const
{
return secondary_variables_;
}
std::vector<std::unique_ptr<IntegrationPointWriter>> const*
getIntegrationPointWriters() const
{
return integration_point_writers_;
}
NumLib::LocalToGlobalIndexMap const& getBulkMeshDofTable(
int const process_id) const
{
return *bulk_mesh_dof_tables_of_all_processes_[process_id];
}
NumLib::LocalToGlobalIndexMap const& getOutputMeshDofTable(
int const process_id) const
{
return *output_mesh_dof_tables_of_all_processes_[process_id];
}
std::vector<const NumLib::LocalToGlobalIndexMap*> const&
getOutputMeshDofTablesOfAllProcesses() const
{
return output_mesh_dof_tables_of_all_processes_;
}
MeshLib::Mesh& getOutputMesh() const { return output_mesh_; }
private:
/// Process variables of all processes.
///
/// Each element of the container corresponds to a specific \c process_id of
/// the Process.
std::vector<std::reference_wrapper<
const std::vector<std::reference_wrapper<ProcessVariable>>>>
process_variables_of_all_processes_;
SecondaryVariableCollection const& secondary_variables_;
/// The list of integration point writers or \c nullptr if there are no
/// integration point writers defined on the #output_mesh_.
///
/// The latter is the case for output on submeshes.
std::vector<std::unique_ptr<IntegrationPointWriter>> const*
integration_point_writers_;
/// D.o.f. tables for the full simulation domain of the Process this
/// ProcessOutputData is associated with.
///
/// Each element of the container corresponds to a specific \c process_id of
/// the Process.
std::vector<NumLib::LocalToGlobalIndexMap const*>
bulk_mesh_dof_tables_of_all_processes_;
/// D.o.f tables for the given #output_mesh_.
///
/// In the case of submesh output these d.o.f. tables are different from the
/// #bulk_mesh_dof_tables_of_all_processes_.
///
/// Each element of the container corresponds to a specific \c process_id of
/// the Process this ProcessOutputData is associated with.
std::vector<NumLib::LocalToGlobalIndexMap const*>
output_mesh_dof_tables_of_all_processes_;
/// Actual data backing the pointers in
/// #output_mesh_dof_tables_of_all_processes_.
///
/// This container is populated in the case of submesh output only.
std::vector<std::unique_ptr<NumLib::LocalToGlobalIndexMap>>
container_that_owns_output_mesh_dof_tables_;
/// The mesh to which output shall be written.
///
/// This can be the entire simulation domain of the Process this
/// ProcessOutputData is associated with or a submesh thereof.
MeshLib::Mesh& output_mesh_;
};
/// Extracts data necessary for output from the given \c process.
ProcessOutputData createProcessOutputData(Process const& process,
std::size_t const n_processes,
MeshLib::Mesh& output_mesh);
} // namespace ProcessLib
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment