diff --git a/ProcessLib/PhaseField/PhaseFieldProcess.cpp b/ProcessLib/PhaseField/PhaseFieldProcess.cpp index 897b11e8fe85250ff821b7568a3286c3934b9710..2c9108f151e8520859e287c43e71c7115ccc18a7 100644 --- a/ProcessLib/PhaseField/PhaseFieldProcess.cpp +++ b/ProcessLib/PhaseField/PhaseFieldProcess.cpp @@ -95,9 +95,9 @@ PhaseFieldProcess<DisplacementDim>::getDOFTable(const int process_id) const template <int DisplacementDim> void PhaseFieldProcess<DisplacementDim>::constructDofTable() { - // Create single component dof in every of the mesh's nodes. - _mesh_subset_all_nodes = - std::make_unique<MeshLib::MeshSubset>(_mesh, _mesh.getNodes()); + // For displacement equation. + const int mechanics_process_id = 0; + constructDofTableOfSpecifiedProsessStaggerdScheme(mechanics_process_id); // TODO move the two data members somewhere else. // for extrapolation of secondary variables of stress or strain @@ -111,20 +111,6 @@ void PhaseFieldProcess<DisplacementDim>::constructDofTable() assert(_local_to_global_index_map_single_component); - // For displacement equation. - const int process_id = 0; - std::vector<MeshLib::MeshSubset> all_mesh_subsets; - std::generate_n( - std::back_inserter(all_mesh_subsets), - getProcessVariables(process_id)[0].get().getNumberOfComponents(), - [&]() { return *_mesh_subset_all_nodes; }); - - std::vector<int> const vec_n_components{DisplacementDim}; - _local_to_global_index_map = - std::make_unique<NumLib::LocalToGlobalIndexMap>( - std::move(all_mesh_subsets), vec_n_components, - NumLib::ComponentOrder::BY_LOCATION); - // For phase field equation. _sparsity_pattern_with_single_component = NumLib::computeSparsityPattern( *_local_to_global_index_map_single_component, _mesh); @@ -237,8 +223,8 @@ void PhaseFieldProcess<DisplacementDim>::assembleWithJacobianConcreteProcess( // Call global assembler for each local assembly item. GlobalExecutor::executeSelectedMemberDereferenced( _global_assembler, &VectorMatrixAssembler::assembleWithJacobian, - _local_assemblers, pv.getActiveElementIDs(), dof_tables, t, - x, xdot, dxdot_dx, dx_dx, M, K, b, Jac, _coupled_solutions); + _local_assemblers, pv.getActiveElementIDs(), dof_tables, t, x, xdot, + dxdot_dx, dx_dx, M, K, b, Jac, _coupled_solutions); if (_coupled_solutions->process_id == 0) { @@ -285,8 +271,8 @@ void PhaseFieldProcess<DisplacementDim>::postTimestepConcreteProcess( dof_tables.emplace_back(*_local_to_global_index_map); dof_tables.emplace_back(*_local_to_global_index_map_single_component); - ProcessLib::ProcessVariable const& pv - = getProcessVariables(process_id)[0]; + ProcessLib::ProcessVariable const& pv = + getProcessVariables(process_id)[0]; GlobalExecutor::executeSelectedMemberOnDereferenced( &LocalAssemblerInterface::computeEnergy, _local_assemblers, @@ -316,8 +302,8 @@ void PhaseFieldProcess<DisplacementDim>::postNonLinearSolverConcreteProcess( DBUG("PostNonLinearSolver crack volume computation."); - ProcessLib::ProcessVariable const& pv - = getProcessVariables(process_id)[0]; + ProcessLib::ProcessVariable const& pv = + getProcessVariables(process_id)[0]; GlobalExecutor::executeSelectedMemberOnDereferenced( &LocalAssemblerInterface::computeCrackIntegral, _local_assemblers, pv.getActiveElementIDs(), dof_tables, x, t, diff --git a/ProcessLib/Process.cpp b/ProcessLib/Process.cpp index 8e50afc2450d33f624fd471f769ea67a10668161..37a256ba3568da1bd50a33f6b216be5a6fd6cd26 100644 --- a/ProcessLib/Process.cpp +++ b/ProcessLib/Process.cpp @@ -232,7 +232,21 @@ void Process::assembleWithJacobian(const double t, GlobalVector const& x, void Process::constructDofTable() { - // Create single component dof in every of the mesh's nodes. + if (_use_monolithic_scheme) + { + constructMonolithicProcessDofTable(); + + return; + } + + // For staggered scheme: + const int specified_prosess_id = 0; + constructDofTableOfSpecifiedProsessStaggerdScheme(specified_prosess_id); +} + +void Process::constructMonolithicProcessDofTable() +{ + // Create single component dof in every of the mesh nodes. _mesh_subset_all_nodes = std::make_unique<MeshLib::MeshSubset>(_mesh, _mesh.getNodes()); @@ -241,41 +255,58 @@ void Process::constructDofTable() // Vector of the number of variable components std::vector<int> vec_var_n_components; - if (_use_monolithic_scheme) + // Collect the mesh subsets in a vector for the components of each + // variables. + for (ProcessVariable const& pv : _process_variables[0]) { - // Collect the mesh subsets in a vector for each variables' components. - for (ProcessVariable const& pv : _process_variables[0]) - { - std::generate_n(std::back_inserter(all_mesh_subsets), - pv.getNumberOfComponents(), - [&]() { return *_mesh_subset_all_nodes; }); - } - - // Create a vector of the number of variable components - for (ProcessVariable const& pv : _process_variables[0]) - { - vec_var_n_components.push_back(pv.getNumberOfComponents()); - } - } - else // for staggered scheme - { - // Assuming that all equations of the coupled process use the same - // element order. Other cases can be considered by overloading this - // member function in the derived class. - - // Collect the mesh subsets in a vector for each variables' components. std::generate_n(std::back_inserter(all_mesh_subsets), - _process_variables[0][0].get().getNumberOfComponents(), + pv.getNumberOfComponents(), [&]() { return *_mesh_subset_all_nodes; }); + } - // Create a vector of the number of variable components. - vec_var_n_components.push_back( - _process_variables[0][0].get().getNumberOfComponents()); + // Create a vector of the number of variable components + for (ProcessVariable const& pv : _process_variables[0]) + { + vec_var_n_components.push_back(pv.getNumberOfComponents()); } + + _local_to_global_index_map = + std::make_unique<NumLib::LocalToGlobalIndexMap>( + std::move(all_mesh_subsets), vec_var_n_components, + NumLib::ComponentOrder::BY_LOCATION); + + assert(_local_to_global_index_map); +} + +void Process::constructDofTableOfSpecifiedProsessStaggerdScheme( + const int specified_prosess_id) +{ + // Create single component dof in every of the mesh nodes. + _mesh_subset_all_nodes = + std::make_unique<MeshLib::MeshSubset>(_mesh, _mesh.getNodes()); + + // Vector of mesh subsets. + std::vector<MeshLib::MeshSubset> all_mesh_subsets; + + // Vector of the number of variable components + std::vector<int> vec_var_n_components; + // Collect the mesh subsets in a vector for each variables' components. + std::generate_n(std::back_inserter(all_mesh_subsets), + _process_variables[specified_prosess_id][0] + .get() + .getNumberOfComponents(), + [&]() { return *_mesh_subset_all_nodes; }); + + // Create a vector of the number of variable components. + vec_var_n_components.push_back(_process_variables[specified_prosess_id][0] + .get() + .getNumberOfComponents()); _local_to_global_index_map = std::make_unique<NumLib::LocalToGlobalIndexMap>( std::move(all_mesh_subsets), vec_var_n_components, NumLib::ComponentOrder::BY_LOCATION); + + assert(_local_to_global_index_map); } std::tuple<NumLib::LocalToGlobalIndexMap*, bool> diff --git a/ProcessLib/Process.h b/ProcessLib/Process.h index 5aaa5c523446b43ee1851fc8e140578a49c746ed..bfd1d077be7dd40dedbb28d34a3e3a27b18c17e6 100644 --- a/ProcessLib/Process.h +++ b/ProcessLib/Process.h @@ -235,8 +235,30 @@ private: } protected: + /** This function is for general cases, in which all equations of the + coupled processes have the same number of unknowns. For the general cases + with the staggered scheme, all equations of the coupled processes share one + DOF table hold by \verb{_local_to_global_index_map}. Other cases can be + considered by overloading this member function in the + derived class. + */ virtual void constructDofTable(); + /** + * Construct the DOF table for the monolithic scheme, + * which is stored in the + * member of this class, \verb{_local_to_global_index_map}. + */ + void constructMonolithicProcessDofTable(); + + /** + * Construct the DOF table for a specified process in the staggered scheme, + * which is stored in the + * member of this class, \verb{_local_to_global_index_map}. + */ + void constructDofTableOfSpecifiedProsessStaggerdScheme( + const int specified_prosess_id); + /** * Get the address of a LocalToGlobalIndexMap, and the status of its memory. * If the LocalToGlobalIndexMap is created as new in this function, the diff --git a/ProcessLib/ThermoMechanicalPhaseField/ThermoMechanicalPhaseFieldProcess.cpp b/ProcessLib/ThermoMechanicalPhaseField/ThermoMechanicalPhaseFieldProcess.cpp index 825f0dabd20ce0099ac2d946a97198edf20ce1eb..69be04191079022ccfab7e0964ad25b637764ce2 100644 --- a/ProcessLib/ThermoMechanicalPhaseField/ThermoMechanicalPhaseFieldProcess.cpp +++ b/ProcessLib/ThermoMechanicalPhaseField/ThermoMechanicalPhaseFieldProcess.cpp @@ -105,9 +105,9 @@ ThermoMechanicalPhaseFieldProcess<DisplacementDim>::getDOFTableByProcessID( template <int DisplacementDim> void ThermoMechanicalPhaseFieldProcess<DisplacementDim>::constructDofTable() { - // Create single component dof in every of the mesh's nodes. - _mesh_subset_all_nodes = - std::make_unique<MeshLib::MeshSubset>(_mesh, _mesh.getNodes()); + // For displacement equation. + constructDofTableOfSpecifiedProsessStaggerdScheme( + _mechanics_related_process_id); // TODO move the two data members somewhere else. // for extrapolation of secondary variables of stress or strain @@ -121,20 +121,6 @@ void ThermoMechanicalPhaseFieldProcess<DisplacementDim>::constructDofTable() assert(_local_to_global_index_map_single_component); - // For displacement equation. - std::vector<MeshLib::MeshSubset> all_mesh_subsets; - std::generate_n(std::back_inserter(all_mesh_subsets), - getProcessVariables(_mechanics_related_process_id)[0] - .get() - .getNumberOfComponents(), - [&]() { return *_mesh_subset_all_nodes; }); - - std::vector<int> const vec_n_components{DisplacementDim}; - _local_to_global_index_map = - std::make_unique<NumLib::LocalToGlobalIndexMap>( - std::move(all_mesh_subsets), vec_n_components, - NumLib::ComponentOrder::BY_LOCATION); - // For phase field equation or the heat conduction. _sparsity_pattern_with_single_component = NumLib::computeSparsityPattern( *_local_to_global_index_map_single_component, _mesh); @@ -214,8 +200,7 @@ void ThermoMechanicalPhaseFieldProcess< // Call global assembler for each local assembly item. GlobalExecutor::executeSelectedMemberDereferenced( _global_assembler, &VectorMatrixAssembler::assemble, _local_assemblers, - pv.getActiveElementIDs(), dof_table, t, x, M, K, b, - _coupled_solutions); + pv.getActiveElementIDs(), dof_table, t, x, M, K, b, _coupled_solutions); } template <int DisplacementDim> @@ -267,8 +252,8 @@ void ThermoMechanicalPhaseFieldProcess<DisplacementDim>:: GlobalExecutor::executeSelectedMemberDereferenced( _global_assembler, &VectorMatrixAssembler::assembleWithJacobian, - _local_assemblers, pv.getActiveElementIDs(), dof_tables, t, x, - xdot, dxdot_dx, dx_dx, M, K, b, Jac, _coupled_solutions); + _local_assemblers, pv.getActiveElementIDs(), dof_tables, t, x, xdot, + dxdot_dx, dx_dx, M, K, b, Jac, _coupled_solutions); } template <int DisplacementDim> @@ -292,8 +277,8 @@ void ThermoMechanicalPhaseFieldProcess< GlobalExecutor::executeSelectedMemberOnDereferenced( &ThermoMechanicalPhaseFieldLocalAssemblerInterface::preTimestep, - _local_assemblers, pv.getActiveElementIDs(), - getDOFTable(process_id), x, t, dt); + _local_assemblers, pv.getActiveElementIDs(), getDOFTable(process_id), x, + t, dt); } template <int DisplacementDim> @@ -309,8 +294,8 @@ void ThermoMechanicalPhaseFieldProcess< GlobalExecutor::executeSelectedMemberOnDereferenced( &ThermoMechanicalPhaseFieldLocalAssemblerInterface::postTimestep, - _local_assemblers, pv.getActiveElementIDs(), - getDOFTable(process_id), x); + _local_assemblers, pv.getActiveElementIDs(), getDOFTable(process_id), + x); } template <int DisplacementDim> diff --git a/ProcessLib/ThermoMechanics/ThermoMechanicsProcess.cpp b/ProcessLib/ThermoMechanics/ThermoMechanicsProcess.cpp index 5de891465fa24418c0bccb336d4b43869c3cea0d..6a5dae576a33b85eb2cda1e4fe7c4c0e069c1315 100644 --- a/ProcessLib/ThermoMechanics/ThermoMechanicsProcess.cpp +++ b/ProcessLib/ThermoMechanics/ThermoMechanicsProcess.cpp @@ -135,15 +135,24 @@ ThermoMechanicsProcess<DisplacementDim>::getMatrixSpecifications( &l.getGhostIndices(), &_sparsity_pattern_with_single_component}; } +// TODO [WW]: remove if (_use_monolithic_scheme) during the refactoring of the +// coupling part. template <int DisplacementDim> void ThermoMechanicsProcess<DisplacementDim>::constructDofTable() { - // Note: the heat conduction process and the mechnical process use the same + // Note: the heat conduction process and the mechanical process use the same // order of shape functions. - // Create single component dof in every of the mesh's nodes. - _mesh_subset_all_nodes = - std::make_unique<MeshLib::MeshSubset>(_mesh, _mesh.getNodes()); + if (_use_monolithic_scheme) + { + constructMonolithicProcessDofTable(); + return; + } + else + { + constructDofTableOfSpecifiedProsessStaggerdScheme( + _process_data.mechanics_process_id); + } // TODO move the two data members somewhere else. // for extrapolation of secondary variables of stress or strain @@ -155,52 +164,12 @@ void ThermoMechanicsProcess<DisplacementDim>::constructDofTable() // by location order is needed for output NumLib::ComponentOrder::BY_LOCATION)); - // Vector of mesh subsets. - std::vector<MeshLib::MeshSubset> all_mesh_subsets; - - // Vector of the number of variable components - std::vector<int> vec_var_n_components; - if (_use_monolithic_scheme) + if (!_use_monolithic_scheme) { - // Collect the mesh subsets in a vector for each variables' components. - for (ProcessVariable const& pv : _process_variables[0]) - { - std::generate_n(std::back_inserter(all_mesh_subsets), - pv.getNumberOfComponents(), - [&]() { return *_mesh_subset_all_nodes; }); - } - - // Create a vector of the number of variable components - for (ProcessVariable const& pv : _process_variables[0]) - { - vec_var_n_components.push_back(pv.getNumberOfComponents()); - } - } - else // for staggered scheme - { - // Collect the mesh subsets in a vector for each variable components for - // the mechanical process. - std::generate_n( - std::back_inserter(all_mesh_subsets), - _process_variables[_process_data.mechanics_process_id][0] - .get() - .getNumberOfComponents(), - [&]() { return *_mesh_subset_all_nodes; }); - - // Create a vector of the number of variable components. - vec_var_n_components.push_back( - _process_variables[_process_data.mechanics_process_id][0] - .get() - .getNumberOfComponents()); - _sparsity_pattern_with_single_component = NumLib::computeSparsityPattern( *_local_to_global_index_map_single_component, _mesh); } - _local_to_global_index_map = - std::make_unique<NumLib::LocalToGlobalIndexMap>( - std::move(all_mesh_subsets), vec_var_n_components, - NumLib::ComponentOrder::BY_LOCATION); } template <int DisplacementDim>