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()); // TODO move the two data members somewhere else. // for extrapolation of secondary variables of stress or strain std::vector<MeshLib::MeshSubset> all_mesh_subsets_single_component{ *_mesh_subset_all_nodes}; _local_to_global_index_map_single_component = std::make_unique<NumLib::LocalToGlobalIndexMap>( std::move(all_mesh_subsets_single_component), // by location order is needed for output NumLib::ComponentOrder::BY_LOCATION); assert(_local_to_global_index_map_single_component); if (_use_monolithic_scheme) { const int process_id = 0; // Only one process in the monolithic scheme. std::vector<MeshLib::MeshSubset> all_mesh_subsets; std::generate_n( std::back_inserter(all_mesh_subsets), getProcessVariables(process_id)[1].get().getNumberOfComponents() + 1, [&]() { return *_mesh_subset_all_nodes; }); std::vector<int> const vec_n_components{1, DisplacementDim}; _local_to_global_index_map = std::make_unique<NumLib::LocalToGlobalIndexMap>( std::move(all_mesh_subsets), vec_n_components, NumLib::ComponentOrder::BY_LOCATION); assert(_local_to_global_index_map); } else { // 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); } }
void RichardsComponentTransportProcess::initializeConcreteProcess( NumLib::LocalToGlobalIndexMap const& dof_table, MeshLib::Mesh const& mesh, unsigned const integration_order) { const int monolithic_process_id = 0; ProcessLib::ProcessVariable const& pv = getProcessVariables(monolithic_process_id)[0]; ProcessLib::createLocalAssemblers<LocalAssemblerData>( mesh.getDimension(), mesh.getElements(), dof_table, pv.getShapeFunctionOrder(), _local_assemblers, mesh.isAxiallySymmetric(), integration_order, _process_data); _secondary_variables.addSecondaryVariable( "darcy_velocity", makeExtrapolator(mesh.getDimension(), getExtrapolator(), _local_assemblers, &RichardsComponentTransportLocalAssemblerInterface:: getIntPtDarcyVelocity)); _secondary_variables.addSecondaryVariable( "saturation", makeExtrapolator(1, getExtrapolator(), _local_assemblers, &RichardsComponentTransportLocalAssemblerInterface:: getIntPtSaturation)); }
void PhaseFieldProcess<DisplacementDim>::postTimestepConcreteProcess( GlobalVector const& x, const double /*t*/, const double /*delta_t*/, int const process_id) { if (isPhaseFieldProcess(process_id)) { DBUG("PostTimestep PhaseFieldProcess."); _process_data.elastic_energy = 0.0; _process_data.surface_energy = 0.0; _process_data.pressure_work = 0.0; std::vector<std::reference_wrapper<NumLib::LocalToGlobalIndexMap>> dof_tables; 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]; GlobalExecutor::executeSelectedMemberOnDereferenced( &LocalAssemblerInterface::computeEnergy, _local_assemblers, pv.getActiveElementIDs(), dof_tables, x, _process_data.t, _process_data.elastic_energy, _process_data.surface_energy, _process_data.pressure_work, _coupled_solutions); INFO("Elastic energy: %g Surface energy: %g Pressure work: %g ", _process_data.elastic_energy, _process_data.surface_energy, _process_data.pressure_work); } }
// this is almost a copy of the implementation in the GroundwaterFlow void HTProcess::postTimestepConcreteProcess(GlobalVector const& x, const double t, const double /*delta_t*/, int const process_id) { // For the monolithic scheme, process_id is always zero. if (_use_monolithic_scheme && process_id != 0) { OGS_FATAL( "The condition of process_id = 0 must be satisfied for " "monolithic HTProcess, which is a single process."); } if (!_use_monolithic_scheme && process_id != _hydraulic_process_id) { DBUG("This is the thermal part of the staggered HTProcess."); return; } if (!_surfaceflux) // computing the surfaceflux is optional { return; } ProcessLib::ProcessVariable const& pv = getProcessVariables(process_id)[0]; _surfaceflux->integrate(x, t, *this, process_id, _integration_order, _mesh, pv.getActiveElementIDs()); _surfaceflux->save(t); }
void LiquidFlowProcess::initializeConcreteProcess( NumLib::LocalToGlobalIndexMap const& dof_table, MeshLib::Mesh const& mesh, unsigned const integration_order) { ProcessLib::ProcessVariable const& pv = getProcessVariables()[0]; ProcessLib::createLocalAssemblers<LiquidFlowLocalAssembler>( mesh.getDimension(), mesh.getElements(), dof_table, pv.getShapeFunctionOrder(), _local_assemblers, mesh.isAxiallySymmetric(), integration_order, _gravitational_axis_id, _gravitational_acceleration, _material_properties); _secondary_variables.addSecondaryVariable( "darcy_velocity_x", 1, makeExtrapolator( getExtrapolator(), _local_assemblers, &LiquidFlowLocalAssemblerInterface::getIntPtDarcyVelocityX)); if (mesh.getDimension() > 1) { _secondary_variables.addSecondaryVariable( "darcy_velocity_y", 1, makeExtrapolator( getExtrapolator(), _local_assemblers, &LiquidFlowLocalAssemblerInterface::getIntPtDarcyVelocityY)); } if (mesh.getDimension() > 2) { _secondary_variables.addSecondaryVariable( "darcy_velocity_z", 1, makeExtrapolator( getExtrapolator(), _local_assemblers, &LiquidFlowLocalAssemblerInterface::getIntPtDarcyVelocityZ)); } }
void HTProcess::initializeConcreteProcess( NumLib::LocalToGlobalIndexMap const& dof_table, MeshLib::Mesh const& mesh, unsigned const integration_order) { // For the staggered scheme, both processes are assumed to use the same // element order. Therefore the order of shape function can be fetched from // any set of the sets of process variables of the coupled processes. Here, // we take the one from the first process by setting process_id = 0. const int process_id = 0; ProcessLib::ProcessVariable const& pv = getProcessVariables(process_id)[0]; if (_use_monolithic_scheme) { ProcessLib::createLocalAssemblers<MonolithicHTFEM>( mesh.getDimension(), mesh.getElements(), dof_table, pv.getShapeFunctionOrder(), _local_assemblers, mesh.isAxiallySymmetric(), integration_order, *_material_properties); } else { ProcessLib::createLocalAssemblers<StaggeredHTFEM>( mesh.getDimension(), mesh.getElements(), dof_table, pv.getShapeFunctionOrder(), _local_assemblers, mesh.isAxiallySymmetric(), integration_order, *_material_properties, _heat_transport_process_id, _hydraulic_process_id); } _secondary_variables.addSecondaryVariable( "darcy_velocity", makeExtrapolator(mesh.getDimension(), getExtrapolator(), _local_assemblers, &HTLocalAssemblerInterface::getIntPtDarcyVelocity)); }
void PhaseFieldProcess<DisplacementDim>::assembleConcreteProcess( const double t, GlobalVector const& x, GlobalMatrix& M, GlobalMatrix& K, GlobalVector& b) { DBUG("Assemble PhaseFieldProcess."); std::vector<std::reference_wrapper<NumLib::LocalToGlobalIndexMap>> dof_tables; // For the staggered scheme if (_coupled_solutions->process_id == 1) { DBUG( "Assemble the equations of phase field in " "PhaseFieldProcess for the staggered scheme."); } else { DBUG( "Assemble the equations of deformation in " "PhaseFieldProcess for the staggered scheme."); } dof_tables.emplace_back(*_local_to_global_index_map_single_component); dof_tables.emplace_back(*_local_to_global_index_map); const int process_id = _coupled_solutions->process_id; ProcessLib::ProcessVariable const& pv = getProcessVariables(process_id)[0]; // Call global assembler for each local assembly item. GlobalExecutor::executeSelectedMemberDereferenced( _global_assembler, &VectorMatrixAssembler::assemble, _local_assemblers, pv.getActiveElementIDs(), dof_tables, t, x, M, K, b, _coupled_solutions); }
void SmallDeformationNonlocalProcess<DisplacementDim>:: assembleWithJacobianConcreteProcess(const double t, GlobalVector const& x, GlobalVector const& xdot, const double dxdot_dx, const double dx_dx, GlobalMatrix& M, GlobalMatrix& K, GlobalVector& b, GlobalMatrix& Jac) { DBUG("AssembleWithJacobian SmallDeformationNonlocalProcess."); std::vector<std::reference_wrapper<NumLib::LocalToGlobalIndexMap>> dof_table = {std::ref(*_local_to_global_index_map)}; const int process_id = 0; ProcessLib::ProcessVariable const& pv = getProcessVariables(process_id)[0]; // Call global assembler for each local assembly item. GlobalExecutor::executeSelectedMemberDereferenced( _global_assembler, &VectorMatrixAssembler::assembleWithJacobian, _local_assemblers, pv.getActiveElementIDs(), dof_table, t, x, xdot, dxdot_dx, dx_dx, M, K, b, Jac, _coupled_solutions); b.copyValues(*_nodal_forces); std::transform(_nodal_forces->begin(), _nodal_forces->end(), _nodal_forces->begin(), [](double val) { return -val; }); }
void HTProcess::assembleWithJacobianConcreteProcess( const double t, GlobalVector const& x, GlobalVector const& xdot, const double dxdot_dx, const double dx_dx, GlobalMatrix& M, GlobalMatrix& K, GlobalVector& b, GlobalMatrix& Jac) { DBUG("AssembleWithJacobian HTProcess."); std::vector<std::reference_wrapper<NumLib::LocalToGlobalIndexMap>> dof_tables; if (!_use_monolithic_scheme) { setCoupledSolutionsOfPreviousTimeStep(); dof_tables.emplace_back(std::ref(*_local_to_global_index_map)); } else { dof_tables.emplace_back(std::ref(*_local_to_global_index_map)); dof_tables.emplace_back(std::ref(*_local_to_global_index_map)); } // Call global assembler for each local assembly item. const int process_id = _use_monolithic_scheme ? 0 : _coupled_solutions->process_id; ProcessLib::ProcessVariable const& pv = getProcessVariables(process_id)[0]; 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); }
void Process::updateDeactivatedSubdomains(double const time, const int process_id) { auto const& variables_per_process = getProcessVariables(process_id); for (auto const& variable : variables_per_process) { variable.get().updateDeactivatedSubdomains(time); } }
void HeatTransportBHEProcess::computeSecondaryVariableConcrete( const double t, GlobalVector const& x, int const process_id) { DBUG("Compute heat flux for HeatTransportBHE process."); ProcessLib::ProcessVariable const& pv = getProcessVariables(process_id)[0]; GlobalExecutor::executeSelectedMemberOnDereferenced( &HeatTransportBHELocalAssemblerInterface::computeSecondaryVariable, _local_assemblers, pv.getActiveElementIDs(), getDOFTable(process_id), t, x, _coupled_solutions); }
void HTProcess::setCoupledTermForTheStaggeredSchemeToLocalAssemblers() { DBUG("Set the coupled term for the staggered scheme to local assembers."); const int process_id = _use_monolithic_scheme ? 0 : _coupled_solutions->process_id; ProcessLib::ProcessVariable const& pv = getProcessVariables(process_id)[0]; GlobalExecutor::executeSelectedMemberOnDereferenced( &HTLocalAssemblerInterface::setStaggeredCoupledSolutions, _local_assemblers, pv.getActiveElementIDs(), _coupled_solutions); }
void ThermoMechanicsProcess<DisplacementDim>::postTimestepConcreteProcess( GlobalVector const& x, const double /*t*/, const double /*delta_t*/, int const process_id) { DBUG("PostTimestep ThermoMechanicsProcess."); ProcessLib::ProcessVariable const& pv = getProcessVariables(process_id)[0]; GlobalExecutor::executeSelectedMemberOnDereferenced( &ThermoMechanicsLocalAssemblerInterface::postTimestep, _local_assemblers, pv.getActiveElementIDs(), *_local_to_global_index_map, x); }
void PhaseFieldProcess<DisplacementDim>::postNonLinearSolverConcreteProcess( GlobalVector const& x, const double t, const int process_id) { _process_data.crack_volume = 0.0; if (!isPhaseFieldProcess(process_id)) { std::vector<std::reference_wrapper<NumLib::LocalToGlobalIndexMap>> dof_tables; dof_tables.emplace_back(*_local_to_global_index_map); dof_tables.emplace_back(*_local_to_global_index_map_single_component); DBUG("PostNonLinearSolver crack volume computation."); ProcessLib::ProcessVariable const& pv = getProcessVariables(process_id)[0]; GlobalExecutor::executeSelectedMemberOnDereferenced( &LocalAssemblerInterface::computeCrackIntegral, _local_assemblers, pv.getActiveElementIDs(), dof_tables, x, t, _process_data.crack_volume, _coupled_solutions); INFO("Integral of crack: %g", _process_data.crack_volume); if (_process_data.propagating_crack) { _process_data.pressure_old = _process_data.pressure; _process_data.pressure = _process_data.injected_volume / _process_data.crack_volume; _process_data.pressure_error = std::fabs(_process_data.pressure_old - _process_data.pressure) / _process_data.pressure; INFO("Internal pressure: %g and Pressure error: %.4e", _process_data.pressure, _process_data.pressure_error); auto& u = _coupled_solutions->coupled_xs[0].get(); MathLib::LinAlg::scale(const_cast<GlobalVector&>(u), _process_data.pressure); } } else { if (_process_data.propagating_crack) { auto& u = _coupled_solutions->coupled_xs[0].get(); MathLib::LinAlg::scale(const_cast<GlobalVector&>(u), 1 / _process_data.pressure); } } }
void SmallDeformationNonlocalProcess< DisplacementDim>::preAssembleConcreteProcess(const double t, GlobalVector const& x) { DBUG("preAssemble SmallDeformationNonlocalProcess."); const int process_id = 0; ProcessLib::ProcessVariable const& pv = getProcessVariables(process_id)[0]; // Call global assembler for each local assembly item. GlobalExecutor::executeSelectedMemberDereferenced( _global_assembler, &VectorMatrixAssembler::preAssemble, _local_assemblers, pv.getActiveElementIDs(), *_local_to_global_index_map, t, x); }
void ThermoMechanicsProcess<DisplacementDim>::preTimestepConcreteProcess( GlobalVector const& x, double const t, double const dt, const int process_id) { DBUG("PreTimestep ThermoMechanicsProcess."); _process_data.dt = dt; _process_data.t = t; ProcessLib::ProcessVariable const& pv = getProcessVariables(process_id)[0]; GlobalExecutor::executeSelectedMemberOnDereferenced( &ThermoMechanicsLocalAssemblerInterface::preTimestep, _local_assemblers, pv.getActiveElementIDs(), *_local_to_global_index_map, x, t, dt); }
void PhaseFieldProcess<DisplacementDim>::preTimestepConcreteProcess( GlobalVector const& x, double const t, double const dt, const int process_id) { DBUG("PreTimestep PhaseFieldProcess %d.", process_id); _process_data.dt = dt; _process_data.t = t; _process_data.injected_volume = _process_data.t; ProcessLib::ProcessVariable const& pv = getProcessVariables(process_id)[0]; GlobalExecutor::executeSelectedMemberOnDereferenced( &LocalAssemblerInterface::preTimestep, _local_assemblers, pv.getActiveElementIDs(), getDOFTable(process_id), x, t, dt); }
void SmallDeformationNonlocalProcess<DisplacementDim>::assembleConcreteProcess( const double t, GlobalVector const& x, GlobalMatrix& M, GlobalMatrix& K, GlobalVector& b) { DBUG("Assemble SmallDeformationNonlocalProcess."); std::vector<std::reference_wrapper<NumLib::LocalToGlobalIndexMap>> dof_table = {std::ref(*_local_to_global_index_map)}; const int process_id = 0; ProcessLib::ProcessVariable const& pv = getProcessVariables(process_id)[0]; // 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); }
void RichardsFlowProcess::assembleWithJacobianConcreteProcess( const double t, GlobalVector const& x, GlobalVector const& xdot, const double dxdot_dx, const double dx_dx, GlobalMatrix& M, GlobalMatrix& K, GlobalVector& b, GlobalMatrix& Jac) { DBUG("AssembleWithJacobian RichardsFlowProcess."); std::vector<std::reference_wrapper<NumLib::LocalToGlobalIndexMap>> dof_table = {std::ref(*_local_to_global_index_map)}; const int process_id = 0; ProcessLib::ProcessVariable const& pv = getProcessVariables(process_id)[0]; // Call global assembler for each local assembly item. GlobalExecutor::executeSelectedMemberDereferenced( _global_assembler, &VectorMatrixAssembler::assembleWithJacobian, _local_assemblers, pv.getActiveElementIDs(), dof_table, t, x, xdot, dxdot_dx, dx_dx, M, K, b, Jac, _coupled_solutions); }
void SmallDeformationNonlocalProcess< DisplacementDim>::preTimestepConcreteProcess(GlobalVector const& x, double const t, double const dt, int const /*process_id*/) { DBUG("PreTimestep SmallDeformationNonlocalProcess."); _process_data.dt = dt; _process_data.t = t; const int process_id = 0; ProcessLib::ProcessVariable const& pv = getProcessVariables(process_id)[0]; GlobalExecutor::executeSelectedMemberOnDereferenced( &LocalAssemblerInterface::preTimestep, _local_assemblers, pv.getActiveElementIDs(), *_local_to_global_index_map, x, t, dt); }
void HTProcess::assembleConcreteProcess(const double t, GlobalVector const& x, GlobalMatrix& M, GlobalMatrix& K, GlobalVector& b) { std::vector<std::reference_wrapper<NumLib::LocalToGlobalIndexMap>> dof_tables; if (_use_monolithic_scheme) { DBUG("Assemble HTProcess."); dof_tables.emplace_back(*_local_to_global_index_map); } else { if (_coupled_solutions->process_id == _heat_transport_process_id) { DBUG( "Assemble the equations of heat transport process within " "HTProcess."); } else { DBUG( "Assemble the equations of single phase fully saturated " "fluid flow process within HTProcess."); } setCoupledSolutionsOfPreviousTimeStep(); dof_tables.emplace_back(*_local_to_global_index_map); dof_tables.emplace_back(*_local_to_global_index_map); } const int process_id = _use_monolithic_scheme ? 0 : _coupled_solutions->process_id; ProcessLib::ProcessVariable const& pv = getProcessVariables(process_id)[0]; // Call global assembler for each local assembly item. GlobalExecutor::executeSelectedMemberDereferenced( _global_assembler, &VectorMatrixAssembler::assemble, _local_assemblers, pv.getActiveElementIDs(), dof_tables, t, x, M, K, b, _coupled_solutions); }
NumLib::IterationResult SmallDeformationNonlocalProcess<DisplacementDim>::postIterationConcreteProcess( GlobalVector const& x) { _process_data.crack_volume_old = _process_data.crack_volume; _process_data.crack_volume = 0.0; DBUG("PostNonLinearSolver crack volume computation."); const int process_id = 0; ProcessLib::ProcessVariable const& pv = getProcessVariables(process_id)[0]; GlobalExecutor::executeSelectedMemberOnDereferenced( &LocalAssemblerInterface::computeCrackIntegral, _local_assemblers, pv.getActiveElementIDs(), *_local_to_global_index_map, x, _process_data.crack_volume); INFO("Integral of crack: %g", _process_data.crack_volume); return NumLib::IterationResult::SUCCESS; }
void RichardsComponentTransportProcess::assembleConcreteProcess( const double t, GlobalVector const& x, GlobalMatrix& M, GlobalMatrix& K, GlobalVector& b) { DBUG("Assemble RichardsComponentTransportProcess."); std::vector<std::reference_wrapper<NumLib::LocalToGlobalIndexMap>> dof_table = {std::ref(*_local_to_global_index_map)}; const int process_id = _use_monolithic_scheme ? 0 : _coupled_solutions->process_id; ProcessLib::ProcessVariable const& pv = getProcessVariables(process_id)[0]; // 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); }
void PhaseFieldProcess<DisplacementDim>::assembleWithJacobianConcreteProcess( const double t, GlobalVector const& x, GlobalVector const& xdot, const double dxdot_dx, const double dx_dx, GlobalMatrix& M, GlobalMatrix& K, GlobalVector& b, GlobalMatrix& Jac) { std::vector<std::reference_wrapper<NumLib::LocalToGlobalIndexMap>> dof_tables; // For the staggered scheme if (_coupled_solutions->process_id == 1) { DBUG( "Assemble the Jacobian equations of phase field in " "PhaseFieldProcess for the staggered scheme."); } else { DBUG( "Assemble the Jacobian equations of deformation in " "PhaseFieldProcess for the staggered scheme."); } dof_tables.emplace_back(*_local_to_global_index_map); dof_tables.emplace_back(*_local_to_global_index_map_single_component); const int process_id = _coupled_solutions->process_id; ProcessLib::ProcessVariable const& pv = getProcessVariables(process_id)[0]; // 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); if (_coupled_solutions->process_id == 0) { b.copyValues(*_nodal_forces); std::transform(_nodal_forces->begin(), _nodal_forces->end(), _nodal_forces->begin(), [](double val) { return -val; }); } }