111{
112#ifdef NIMBLE_HAVE_TRILINOS
113
114
115
116
117 using global_ordinal_set = std::set<global_ordinal_type>;
118 std::map<global_ordinal_type, global_ordinal_set> matrix_nonzeros;
119
120 int dim = mesh.GetDim();
121 std::vector<int> block_ids = mesh.GetBlockIds();
122
123 for (auto const& block_id : block_ids) {
124 int num_elem_in_block = mesh.GetNumElementsInBlock(block_id);
125 int num_nodes_per_elem = mesh.GetNumNodesPerElement(block_id);
126 const int* const conn = mesh.GetConnectivity(block_id);
127 int conn_offset = 0;
128 for (int i_elem = 0; i_elem < num_elem_in_block; i_elem++) {
129 for (int i_node = 0; i_node < num_nodes_per_elem; i_node++) {
130 global_ordinal_type global_id_i =
global_node_ids_[conn[conn_offset + i_node]];
131 for (int j_node = 0; j_node < num_nodes_per_elem; j_node++) {
132 global_ordinal_type global_id_j =
global_node_ids_[conn[conn_offset + j_node]];
133 for (int i_dof = 0; i_dof < dim; i_dof++) {
134 for (int j_dof = 0; j_dof < dim; j_dof++) {
135 global_ordinal_type matrix_entry_i = global_id_i * dim + i_dof;
136 global_ordinal_type matrix_entry_j = global_id_j * dim + j_dof;
137 auto&& row_nonzeros = matrix_nonzeros[matrix_entry_i];
138 row_nonzeros.insert(matrix_entry_j);
139 }
140 }
141 }
142 }
143 conn_offset += num_nodes_per_elem;
144 }
145 }
146
147
148 std::vector<global_ordinal_type> my_entries(matrix_nonzeros.size());
149 {
150 int row_index = 0;
151 for (auto const& entry : matrix_nonzeros) {
152 my_entries[row_index] = entry.first;
153 ++row_index;
154 }
155 }
156 std::sort(my_entries.begin(), my_entries.end());
157 std::vector<global_ordinal_set::size_type> num_matrix_nonzeros_per_row(matrix_nonzeros.size());
158 {
159 int row_index = 0;
160 for (auto&& entry : my_entries) { num_matrix_nonzeros_per_row[row_index++] = matrix_nonzeros.at(entry).size(); }
161 }
162
163
164 const Tpetra::global_size_t num_global_elements = Teuchos::OrdinalTraits<Tpetra::global_size_t>::invalid();
165 const global_ordinal_type index_base = 0;
166 Teuchos::RCP<const map_type> row_map = Teuchos::rcp(new map_type(
167 num_global_elements, my_entries.data(), static_cast<local_ordinal_type>(my_entries.size()), index_base, comm_));
168
169
170 Teuchos::RCP<graph_type> crs_graph =
171 Teuchos::rcp(new graph_type(row_map, Teuchos::arrayViewFromVector(num_matrix_nonzeros_per_row)));
172
173
174 for (auto const& entry : matrix_nonzeros) {
175 auto global_row = entry.first;
176 auto&& nonzeros_in_row_set = entry.second;
177 std::vector<global_ordinal_type> nonzeros_in_row(nonzeros_in_row_set.begin(), nonzeros_in_row_set.end());
178 crs_graph->insertGlobalIndices(global_row, Teuchos::arrayViewFromVector(nonzeros_in_row));
179 }
180 crs_graph->fillComplete();
181
182
183 crs_matrix_ = Teuchos::rcp(new matrix_type(crs_graph));
184 crs_matrix_container_ = TpetraMatrixContainer<scalar_type, local_ordinal_type, global_ordinal_type>(crs_matrix_);
185
186#endif
187}
std::vector< int > global_node_ids_
Definition nimble_tpetra_utils.h:187