Skip to content

Commit a25abaf

Browse files
committed
Refactor CalculateReactions method to streamline matrix structure assembly and improve efficiency
1 parent 4d4cbae commit a25abaf

1 file changed

Lines changed: 61 additions & 93 deletions

File tree

applications/TrilinosApplication/custom_strategies/builder_and_solvers/trilinos_block_builder_and_solver.h

Lines changed: 61 additions & 93 deletions
Original file line numberDiff line numberDiff line change
@@ -1507,131 +1507,99 @@ class TrilinosBlockBuilderAndSolver
15071507
// Number of local dofs
15081508
const IndexType number_of_local_rows = mLocalSystemSize;
15091509

1510-
// Generate map - use the "temp" array here
1511-
const int temp_size = (number_of_local_rows < 1000) ? 1000 : number_of_local_rows;
1512-
std::vector<int> temp_primary(temp_size, 0);
1513-
std::vector<int> temp_secondary(temp_size, 0);
1514-
for (IndexType i = 0; i != number_of_local_rows; i++) {
1515-
temp_primary[i] = mFirstMyId + i;
1516-
}
1517-
auto& r_map = GetMap();
1518-
std::fill(temp_primary.begin(), temp_primary.begin() + number_of_local_rows, 0);
1510+
// Ensure map is initialized
1511+
GetMap();
15191512

1520-
// Create and fill the graph of the matrix --> the temp array is
1521-
// reused here with a different meaning
1522-
Epetra_FECrsGraph Agraph(Copy, r_map, mGuessRowSize);
15231513
Element::EquationIdVectorType equation_ids_vector;
15241514
const ProcessInfo& r_current_process_info = rModelPart.GetProcessInfo();
15251515

1526-
// Trilinos error int definition
1527-
int ierr;
1516+
// Auxiliary vectors to construct the system matrix structure
1517+
std::vector<std::vector<int>> all_row_equation_ids;
1518+
std::vector<std::vector<int>> all_col_equation_ids;
1519+
const auto reserve_size = r_elements_array.size() + r_conditions_array.size() + 3 * r_constraints_array.size();
1520+
all_row_equation_ids.reserve(reserve_size);
1521+
all_col_equation_ids.reserve(reserve_size);
15281522

15291523
// Assemble all elements
15301524
for (auto& r_elem : r_elements_array) {
15311525
pScheme->EquationId(r_elem, equation_ids_vector, r_current_process_info);
15321526

1533-
// Filling the list of active global indices (non fixed)
1534-
IndexType num_active_indices = 0;
1535-
for (auto& r_id : equation_ids_vector) {
1536-
temp_primary[num_active_indices] = r_id;
1537-
++num_active_indices;
1538-
}
1539-
1540-
if (num_active_indices != 0) {
1541-
ierr = Agraph.InsertGlobalIndices(num_active_indices, temp_primary.data(), num_active_indices, temp_primary.data());
1542-
KRATOS_ERROR_IF(ierr < 0) << ": Epetra failure in Graph.InsertGlobalIndices. Error code: " << ierr << std::endl;
1527+
if (!equation_ids_vector.empty()) {
1528+
std::vector<int> local_equation_ids;
1529+
local_equation_ids.reserve(equation_ids_vector.size());
1530+
for (const auto equation_id : equation_ids_vector) {
1531+
local_equation_ids.push_back(static_cast<int>(equation_id));
1532+
}
1533+
all_row_equation_ids.push_back(local_equation_ids);
1534+
all_col_equation_ids.push_back(std::move(local_equation_ids));
15431535
}
1544-
std::fill(temp_primary.begin(), temp_primary.begin() + num_active_indices, 0);
15451536
}
15461537

15471538
// Assemble all conditions
15481539
for (auto& r_cond : r_conditions_array) {
15491540
pScheme->EquationId(r_cond, equation_ids_vector, r_current_process_info);
15501541

1551-
// Filling the list of active global indices (non fixed)
1552-
IndexType num_active_indices = 0;
1553-
for (auto& r_id : equation_ids_vector) {
1554-
temp_primary[num_active_indices] = r_id;
1555-
++num_active_indices;
1556-
}
1557-
1558-
if (num_active_indices != 0) {
1559-
ierr = Agraph.InsertGlobalIndices(num_active_indices, temp_primary.data(), num_active_indices, temp_primary.data());
1560-
KRATOS_ERROR_IF(ierr < 0) << ": Epetra failure in Graph.InsertGlobalIndices. Error code: " << ierr << std::endl;
1542+
if (!equation_ids_vector.empty()) {
1543+
std::vector<int> local_equation_ids;
1544+
local_equation_ids.reserve(equation_ids_vector.size());
1545+
for (const auto equation_id : equation_ids_vector) {
1546+
local_equation_ids.push_back(static_cast<int>(equation_id));
1547+
}
1548+
all_row_equation_ids.push_back(local_equation_ids);
1549+
all_col_equation_ids.push_back(std::move(local_equation_ids));
15611550
}
1562-
std::fill(temp_primary.begin(), temp_primary.begin() + num_active_indices, 0);
15631551
}
15641552

15651553
// Assemble all constraints
15661554
Element::EquationIdVectorType slave_equation_ids_vector, master_equation_ids_vector;
15671555
for (auto& r_const : r_constraints_array) {
15681556
r_const.EquationIdVector(slave_equation_ids_vector, master_equation_ids_vector, r_current_process_info);
15691557

1570-
// Filling the list of active global indices (non fixed)
1571-
IndexType num_active_slave_indices = 0;
1572-
for (auto& r_slave_id : slave_equation_ids_vector) {
1573-
temp_primary[num_active_slave_indices] = r_slave_id;
1574-
++num_active_slave_indices;
1558+
std::vector<int> slave_equation_ids;
1559+
slave_equation_ids.reserve(slave_equation_ids_vector.size());
1560+
for (const auto slave_equation_id : slave_equation_ids_vector) {
1561+
slave_equation_ids.push_back(static_cast<int>(slave_equation_id));
15751562
}
1576-
IndexType num_active_master_indices = 0;
1577-
for (auto& r_master_id : master_equation_ids_vector) {
1578-
temp_secondary[num_active_master_indices] = r_master_id;
1579-
++num_active_master_indices;
1563+
1564+
std::vector<int> master_equation_ids;
1565+
master_equation_ids.reserve(master_equation_ids_vector.size());
1566+
for (const auto master_equation_id : master_equation_ids_vector) {
1567+
master_equation_ids.push_back(static_cast<int>(master_equation_id));
15801568
}
15811569

1582-
// First adding the pure slave dofs
1583-
if (num_active_slave_indices > 0) {
1584-
int index[1] = {0};
1585-
for (IndexType i = 0; i < num_active_slave_indices; ++i) {
1586-
index[0] = temp_primary[i];
1587-
ierr = Agraph.InsertGlobalIndices(1, index, 1, index);
1588-
KRATOS_ERROR_IF(ierr < 0) << ": Epetra failure in Graph.InsertGlobalIndices. Error code: " << ierr << std::endl;
1589-
}
1590-
// Now adding cross master-slave dofs
1591-
if (num_active_master_indices > 0) {
1592-
ierr = Agraph.InsertGlobalIndices(num_active_slave_indices, temp_primary.data(), num_active_master_indices, temp_secondary.data());
1593-
KRATOS_ERROR_IF(ierr < 0) << ": Epetra failure in Graph.InsertGlobalIndices. Error code: " << ierr << std::endl;
1594-
}
1570+
// First adding the pure slave dofs (diagonal entries)
1571+
for (const auto slave_equation_id : slave_equation_ids) {
1572+
all_row_equation_ids.push_back({slave_equation_id});
1573+
all_col_equation_ids.push_back({slave_equation_id});
1574+
}
1575+
1576+
// Now adding cross master-slave dofs
1577+
if (!slave_equation_ids.empty() && !master_equation_ids.empty()) {
1578+
all_row_equation_ids.push_back(slave_equation_ids);
1579+
all_col_equation_ids.push_back(master_equation_ids);
15951580
}
1581+
15961582
// Second adding pure master dofs
1597-
if (num_active_master_indices > 0) {
1598-
int index[1] = {0};
1599-
for (IndexType i = 0; i < num_active_master_indices; ++i) {
1600-
index[0] = temp_secondary[i];
1601-
ierr = Agraph.InsertGlobalIndices(1, index, 1, index);
1602-
KRATOS_ERROR_IF(ierr < 0) << ": Epetra failure in Graph.InsertGlobalIndices. Error code: " << ierr << std::endl;
1603-
}
1583+
for (const auto master_equation_id : master_equation_ids) {
1584+
all_row_equation_ids.push_back({master_equation_id});
1585+
all_col_equation_ids.push_back({master_equation_id});
16041586
}
1605-
std::fill(temp_primary.begin(), temp_primary.begin() + num_active_slave_indices, 0);
1606-
std::fill(temp_secondary.begin(), temp_secondary.begin() + num_active_master_indices, 0);
16071587
}
16081588

1609-
// Finalizing graph construction
1610-
ierr = Agraph.GlobalAssemble();
1611-
KRATOS_ERROR_IF(ierr < 0) << ": Epetra failure in Epetra_FECrsGraph.GlobalAssemble. Error code: " << ierr << std::endl;
1612-
ierr = Agraph.FillComplete();
1613-
KRATOS_ERROR_IF(ierr < 0) << ": Epetra failure in Epetra_FECrsGraph.FillComplete. Error code: " << ierr << std::endl;
1614-
ierr = Agraph.OptimizeStorage();
1615-
KRATOS_ERROR_IF(ierr < 0) << ": Epetra failure in Epetra_FECrsGraph.OptimizeStorage. Error code: " << ierr << std::endl;
1616-
1617-
// Generate a new matrix pointer according to this graph
1618-
TSystemMatrixPointerType p_new_A = TSystemMatrixPointerType(new TSystemMatrixType(Copy, Agraph));
1619-
rpA.swap(p_new_A);
1620-
1621-
// Generate new vector pointers according to the given map
1622-
if (rpb == nullptr || TSparseSpace::Size(*rpb) != BaseType::mEquationSystemSize) {
1623-
TSystemVectorPointerType p_new_b = TSystemVectorPointerType(new TSystemVectorType(r_map));
1624-
rpb.swap(p_new_b);
1625-
}
1626-
if (rpDx == nullptr || TSparseSpace::Size(*rpDx) != BaseType::mEquationSystemSize) {
1627-
TSystemVectorPointerType p_new_Dx = TSystemVectorPointerType(new TSystemVectorType(r_map));
1628-
rpDx.swap(p_new_Dx);
1629-
}
1630-
// If the pointer is not initialized initialize it to an empty matrix
1631-
if (BaseType::mpReactionsVector == nullptr) {
1632-
TSystemVectorPointerType pNewReactionsVector = TSystemVectorPointerType(new TSystemVectorType(r_map));
1633-
BaseType::mpReactionsVector.swap(pNewReactionsVector);
1634-
}
1589+
TSparseSpace::BuildSystemStructure(
1590+
mrComm,
1591+
number_of_local_rows,
1592+
mFirstMyId,
1593+
mGuessRowSize,
1594+
all_row_equation_ids,
1595+
all_col_equation_ids,
1596+
rpA,
1597+
rpb,
1598+
rpDx,
1599+
BaseType::mpReactionsVector,
1600+
BaseType::mEquationSystemSize,
1601+
mpMap
1602+
);
16351603

16361604
STOP_TIMER("MatrixStructure", 0)
16371605
}

0 commit comments

Comments
 (0)