void Process::setInitialConditions(const int process_id, double const t, GlobalVector& x) { // getDOFTableOfProcess can be overloaded by the specific process. auto const& dof_table_of_process = getDOFTable(process_id); auto const& per_process_variables = _process_variables[process_id]; for (std::size_t variable_id = 0; variable_id < per_process_variables.size(); variable_id++) { SpatialPosition pos; auto const& pv = per_process_variables[variable_id]; DBUG("Set the initial condition of variable %s of process %d.", pv.get().getName().data(), process_id); auto const& ic = pv.get().getInitialCondition(); auto const num_comp = pv.get().getNumberOfComponents(); for (int component_id = 0; component_id < num_comp; ++component_id) { auto const& mesh_subset = dof_table_of_process.getMeshSubset(variable_id, component_id); auto const mesh_id = mesh_subset.getMeshID(); for (auto const* node : mesh_subset.getNodes()) { MeshLib::Location const l(mesh_id, MeshLib::MeshItemType::Node, node->getID()); pos.setNodeID(node->getID()); auto const& ic_value = ic(t, pos); auto global_index = std::abs(dof_table_of_process.getGlobalIndex(l, variable_id, component_id)); #ifdef USE_PETSC // The global indices of the ghost entries of the global // matrix or the global vectors need to be set as negative // values for equation assembly, however the global indices // start from zero. Therefore, any ghost entry with zero // index is assigned an negative value of the vector size // or the matrix dimension. To assign the initial value for // the ghost entries, the negative indices of the ghost // entries are restored to zero. if (global_index == x.size()) global_index = 0; #endif x.set(global_index, ic_value[component_id]); } } } }
void Process::setInitialConditions(double const t, GlobalVector& x) { DBUG("Set initial conditions."); SpatialPosition pos; for (int variable_id = 0; variable_id < static_cast<int>(_process_variables.size()); ++variable_id) { ProcessVariable& pv = _process_variables[variable_id]; auto const& ic = pv.getInitialCondition(); auto const num_comp = pv.getNumberOfComponents(); for (int component_id = 0; component_id < num_comp; ++component_id) { auto const& mesh_subsets = _local_to_global_index_map->getMeshSubsets(variable_id, component_id); for (auto const& mesh_subset : mesh_subsets) { auto const mesh_id = mesh_subset->getMeshID(); for (auto const* node : mesh_subset->getNodes()) { MeshLib::Location const l( mesh_id, MeshLib::MeshItemType::Node, node->getID()); pos.setNodeID(node->getID()); auto const& ic_value = ic(t, pos); auto global_index = std::abs(_local_to_global_index_map->getGlobalIndex( l, variable_id, component_id)); #ifdef USE_PETSC // The global indices of the ghost entries of the global matrix // or the global vectors need to be set as negative values for // equation assembly, however the global indices start from // zero. Therefore, any ghost entry with zero index is assigned // an negative value of the vector size or the matrix dimension. // To assign the initial value for the ghost entries, the // negative indices of the ghost entries are restored to zero. if (global_index == x.size()) global_index = 0; #endif x.set(global_index, ic_value[component_id]); } } } } }
void DirichletBoundaryCondition::getEssentialBCValues( const double t, NumLib::IndexValueVector<GlobalIndexType>& bc_values) const { // TODO: Reenable when fixed ;) //if (_already_computed) //return; _already_computed = true; SpatialPosition pos; bc_values.ids.clear(); bc_values.values.clear(); // convert mesh node ids to global index for the given component bc_values.ids.reserve(bc_values.ids.size() + _mesh_node_ids.size()); bc_values.values.reserve(bc_values.values.size() + _mesh_node_ids.size()); for (auto const id : _mesh_node_ids) { pos.setNodeID(id); MeshLib::Location l(_mesh_id, MeshLib::MeshItemType::Node, id); // TODO: that might be slow, but only done once const auto g_idx = _dof_table.getGlobalIndex(l, _variable_id, _component_id); if (g_idx == NumLib::MeshComponentMap::nop) continue; // For the DDC approach (e.g. with PETSc option), the negative // index of g_idx means that the entry by that index is a ghost one, // which should be dropped. Especially for PETSc routines MatZeroRows // and MatZeroRowsColumns, which are called to apply the Dirichlet BC, // the negative index is not accepted like other matrix or vector // PETSc routines. Therefore, the following if-condition is applied. if (g_idx >= 0) { bc_values.ids.emplace_back(g_idx); bc_values.values.emplace_back(_parameter(t, pos).front()); } } }
void DirichletBoundaryCondition::getEssentialBCValues( const double t, GlobalVector const& /*x*/, NumLib::IndexValueVector<GlobalIndexType>& bc_values) const { SpatialPosition pos; bc_values.ids.clear(); bc_values.values.clear(); // convert mesh node ids to global index for the given component bc_values.ids.reserve(bc_values.ids.size() + _bc_mesh.getNumberOfNodes()); bc_values.values.reserve(bc_values.values.size() + _bc_mesh.getNumberOfNodes()); for (auto const* const node : _bc_mesh.getNodes()) { auto const id = node->getID(); pos.setNodeID(node->getID()); // TODO: that might be slow, but only done once auto const global_index = _dof_table_boundary->getGlobalIndex( {_bc_mesh.getID(), MeshLib::MeshItemType::Node, id}, _variable_id, _component_id); if (global_index == NumLib::MeshComponentMap::nop) continue; // For the DDC approach (e.g. with PETSc option), the negative // index of global_index means that the entry by that index is a ghost // one, which should be dropped. Especially for PETSc routines // MatZeroRows and MatZeroRowsColumns, which are called to apply the // Dirichlet BC, the negative index is not accepted like other matrix or // vector PETSc routines. Therefore, the following if-condition is // applied. if (global_index >= 0) { bc_values.ids.emplace_back(global_index); bc_values.values.emplace_back(_parameter(t, pos).front()); } } }