NimbleSM
NimbleSM is a solid mechanics simulation code for dynamic systems
Loading...
Searching...
No Matches
nimble::TpetraContainer Class Reference

#include <nimble_tpetra_utils.h>

Public Member Functions

 TpetraContainer ()
 
void Initialize (GenesisMesh const &mesh, std::vector< int > const &global_node_ids, comm_type comm)
 
void Initialize (int d, unsigned int n, comm_type comm, std::vector< int > const &global_node_ids)
 
void AllocateTangentStiffnessMatrix (GenesisMesh const &mesh)
 
int TangentStiffnessMatrixNumNonzeros ()
 
void TangentStiffnessMatrixSetScalar (double value)
 
void TangentStiffnessMatrixReplaceValue (int row, int col, double value)
 
void VectorReduction (ModelData &model_data, std::string quantity_label)
 
void VectorReduction (int data_dimension, double *data)
 

Public Attributes

int dim_
 
std::vector< int > global_node_ids_
 

Constructor & Destructor Documentation

◆ TpetraContainer()

nimble::TpetraContainer::TpetraContainer ( )
inline
152{}

Member Function Documentation

◆ AllocateTangentStiffnessMatrix()

void nimble::TpetraContainer::AllocateTangentStiffnessMatrix ( GenesisMesh const & mesh)
111{
112#ifdef NIMBLE_HAVE_TRILINOS
113
114 // record the nonzero entries in each row
115 // the map key is the global id of the row
116 // the entries in the set are the global ids of the entries in a given row
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 // record the rows that have entries on this processor and count nonzeros
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 // create a row map
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 // create a crs graph based on the row map
170 Teuchos::RCP<graph_type> crs_graph =
171 Teuchos::rcp(new graph_type(row_map, Teuchos::arrayViewFromVector(num_matrix_nonzeros_per_row)));
172
173 // identify the nonzeros in the crs graph
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 // allocate the tangent stiffness matrix
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

◆ Initialize() [1/2]

void nimble::TpetraContainer::Initialize ( GenesisMesh const & mesh,
std::vector< int > const & global_node_ids,
comm_type comm )
56{
57 Initialize(mesh.GetDim(), mesh.GetNumNodes(), comm, global_node_ids);
58}
void Initialize(GenesisMesh const &mesh, std::vector< int > const &global_node_ids, comm_type comm)
Definition nimble_tpetra_utils.cc:55

◆ Initialize() [2/2]

void nimble::TpetraContainer::Initialize ( int d,
unsigned int n,
comm_type comm,
std::vector< int > const & global_node_ids )
62{
63#ifdef NIMBLE_HAVE_TRILINOS
64
65 comm_ = comm;
66 global_node_ids_ = global_node_ids;
67
68 unsigned int num_nodes = n;
69 dim_ = d;
70
71 const Tpetra::global_size_t num_global_elements = Teuchos::OrdinalTraits<Tpetra::global_size_t>::invalid();
72 const global_ordinal_type index_base = 0;
73
74 SimpleTieBreak<local_ordinal_type, global_ordinal_type> tie_break;
75
76 // tpetra vector for scalar data (e.g., lumped mass)
77 local_ordinal_type num_1d_entries = num_nodes;
78 std::vector<global_ordinal_type> my_1d_entries(num_1d_entries);
79 for (int i_node = 0; i_node < num_nodes; i_node++) { my_1d_entries[i_node] = global_node_ids_[i_node]; }
80 Teuchos::RCP<const map_type> map_1d =
81 Teuchos::rcp(new map_type(num_global_elements, my_1d_entries.data(), num_1d_entries, index_base, comm_));
82 vec_1d_ = Teuchos::rcp(new vector_type(map_1d));
83
84 Teuchos::RCP<const map_type> map_1d_one_to_one = Tpetra::createOneToOne(map_1d, tie_break);
85 vec_1d_one_to_one_ = Teuchos::rcp(new vector_type(map_1d_one_to_one));
86
87 export_into_vec_1d_one_to_one_ = Teuchos::rcp(new export_type(map_1d, map_1d_one_to_one));
88 import_from_vec_1d_one_to_one_ = Teuchos::rcp(new import_type(map_1d_one_to_one, map_1d));
89
90 // tpetra vector for vector data (e.g., internal force)
91 local_ordinal_type num_3d_entries = num_nodes * dim_;
92 std::vector<global_ordinal_type> my_3d_entries(num_3d_entries);
93 for (int i_node = 0; i_node < num_nodes; i_node++) {
94 for (int dof = 0; dof < dim_; dof++) { my_3d_entries[i_node * dim_ + dof] = global_node_ids_[i_node] * dim_ + dof; }
95 }
96 Teuchos::RCP<const map_type> map_3d =
97 Teuchos::rcp(new map_type(num_global_elements, my_3d_entries.data(), num_3d_entries, index_base, comm_));
98 vec_3d_ = Teuchos::rcp(new vector_type(map_3d));
99
100 Teuchos::RCP<const map_type> map_3d_one_to_one = Tpetra::createOneToOne(map_3d, tie_break);
101 vec_3d_one_to_one_ = Teuchos::rcp(new vector_type(map_3d_one_to_one));
102
103 export_into_vec_3d_one_to_one_ = Teuchos::rcp(new export_type(map_3d, map_3d_one_to_one));
104 import_from_vec_3d_one_to_one_ = Teuchos::rcp(new import_type(map_3d_one_to_one, map_3d));
105
106#endif
107}
int dim_
Definition nimble_tpetra_utils.h:186

◆ TangentStiffnessMatrixNumNonzeros()

int nimble::TpetraContainer::TangentStiffnessMatrixNumNonzeros ( )
191{
192#ifdef NIMBLE_HAVE_TRILINOS
193 return crs_matrix_->getGlobalNumEntries();
194#else
195 return 0;
196#endif
197}

◆ TangentStiffnessMatrixReplaceValue()

void nimble::TpetraContainer::TangentStiffnessMatrixReplaceValue ( int row,
int col,
double value )
209{
210#ifdef NIMBLE_HAVE_TRILINOS
211
212 local_ordinal_type local_row = static_cast<local_ordinal_type>(row);
213 Teuchos::ArrayRCP<local_ordinal_type> local_cols;
214 Teuchos::ArrayRCP<scalar_type> values;
215
216 local_ordinal_type success = crs_matrix_->sumIntoLocalValues(local_row, local_cols(), values());
217
218 if (success == Teuchos::OrdinalTraits<local_ordinal_type>::invalid()) {
220 "\nError in TangentStiffMatrixReplaceValue(), replaceLocalValues() "
221 "failed.\n");
222 } else if (success != 1) {
223 NIMBLE_ABORT("\nError in TangentStiffMatrixReplaceValue(), invalid index.\n");
224 }
225 std::cout << "DJL DEBUGGING " << success << std::endl;
226
227#endif
228}
#define NIMBLE_ABORT(...)
Definition nimble_macros.h:87

◆ TangentStiffnessMatrixSetScalar()

void nimble::TpetraContainer::TangentStiffnessMatrixSetScalar ( double value)
201{
202#ifdef NIMBLE_HAVE_TRILINOS
203 crs_matrix_->setAllToScalar(value);
204#endif
205}

◆ VectorReduction() [1/2]

void nimble::TpetraContainer::VectorReduction ( int data_dimension,
double * data )
246{
247#ifdef NIMBLE_HAVE_TRILINOS
248 Length length = SCALAR;
249 if (data_dimension == dim_) length = VECTOR;
250
251 if (length == SCALAR) {
252 // load the data into a tpetra vector
253 Teuchos::ArrayRCP<scalar_type> vec_1d_data = vec_1d_->getDataNonConst();
254 for (unsigned int i_node = 0; i_node < global_node_ids_.size(); i_node++) { vec_1d_data[i_node] = data[i_node]; }
255
256 // use tpetra import/export to allreduce over the vector
257 vec_1d_one_to_one_->doExport(*vec_1d_, *export_into_vec_1d_one_to_one_, Tpetra::CombineMode::ADD);
258 vec_1d_->doImport(*vec_1d_one_to_one_, *import_from_vec_1d_one_to_one_, Tpetra::CombineMode::INSERT);
259
260 // copy the reduced values back into the original container
261 for (unsigned int i_node = 0; i_node < global_node_ids_.size(); i_node++) { data[i_node] = vec_1d_data[i_node]; }
262 } else if (length == VECTOR) {
263 // load the data into a tpetra vector
264 Teuchos::ArrayRCP<scalar_type> vec_3d_data = vec_3d_->getDataNonConst();
265 int num_dof = LengthToInt(length, dim_);
266 for (unsigned int i_node = 0; i_node < global_node_ids_.size(); i_node++) {
267 for (int dof = 0; dof < num_dof; dof++) { vec_3d_data[i_node * dim_ + dof] = data[i_node * dim_ + dof]; }
268 }
269
270 // use tpetra import/export to allreduce over the vector
271 vec_3d_one_to_one_->doExport(*vec_3d_, *export_into_vec_3d_one_to_one_, Tpetra::CombineMode::ADD);
272 vec_3d_->doImport(*vec_3d_one_to_one_, *import_from_vec_3d_one_to_one_, Tpetra::CombineMode::INSERT);
273
274 // copy the reduced values back into the original container
275 for (unsigned int i_node = 0; i_node < global_node_ids_.size(); i_node++) {
276 for (int dof = 0; dof < num_dof; dof++) { data[i_node * dim_ + dof] = vec_3d_data[i_node * dim_ + dof]; }
277 }
278 }
279
280#endif
281}
Length
Definition nimble_data_utils.h:66
@ SCALAR
Definition nimble_data_utils.h:88
@ VECTOR
Definition nimble_data_utils.h:89
int LengthToInt(Length length, int dim)
Definition nimble_data_utils.cc:57

◆ VectorReduction() [2/2]

void nimble::TpetraContainer::VectorReduction ( ModelData & model_data,
std::string quantity_label )
232{
233#ifdef NIMBLE_HAVE_TRILINOS
234 int field_id = model_data.GetFieldId(quantity_label);
235 Field field = model_data.GetField(field_id);
236 Length length = field.length_;
237 double* data = model_data.GetNodeData(field_id);
238 //
239 int data_dimension = LengthToInt(length, dim_);
240 VectorReduction(data_dimension, data);
241#endif
242}
void VectorReduction(ModelData &model_data, std::string quantity_label)
Definition nimble_tpetra_utils.cc:231

Member Data Documentation

◆ dim_

int nimble::TpetraContainer::dim_

◆ global_node_ids_

std::vector<int> nimble::TpetraContainer::global_node_ids_

The documentation for this class was generated from the following files: