void add_matrix_to_matrix(double scalar, const fei::Matrix& src_matrix, fei::Matrix& dest_matrix) { fei::SharedPtr<fei::VectorSpace> vspace = src_matrix.getMatrixGraph()->getRowSpace(); int numRows = vspace->getNumIndices_Owned(); std::vector<int> rows(numRows); vspace->getIndices_Owned(numRows, &rows[0], numRows); std::vector<int> indices; std::vector<double> coefs; for(size_t i=0; i<rows.size(); ++i) { int rowlen = 0; src_matrix.getRowLength(rows[i], rowlen); if ((int)indices.size() < rowlen) { indices.resize(rowlen); coefs.resize(rowlen); } src_matrix.copyOutRow(rows[i], rowlen, &coefs[0], &indices[0]); for(int j=0; j<rowlen; ++j) { coefs[j] *= scalar; } double* coefPtr = &coefs[0]; dest_matrix.sumIn(1, &rows[i], rowlen, &indices[0], &coefPtr); } }
int DirichletBCManager::finalizeBCEqns(fei::Matrix& matrix, bool throw_if_bc_slave_conflict) { fei::SharedPtr<fei::Reducer> reducer = matrix.getMatrixGraph()->getReducer(); bool haveSlaves = reducer.get()!=NULL; //copy the boundary-condition prescribed values into the matrix, in //an equation-number obtained by using the matrix' VectorSpace to map //from the BC's idtype,id,fieldID,component to an equation-number. The //bc values will go on the diagonal of the matrix, i.e., column-index //will be the same equation-number. bc_map::iterator iter = bcs_.begin(), iter_end = bcs_.end(); for(; iter!=iter_end; ++iter) { int eqn = iter->first; if (haveSlaves) { if (reducer->isSlaveEqn(eqn)) { if (throw_if_bc_slave_conflict) { FEI_OSTRINGSTREAM osstr; osstr << "fei BCManager::finalizeBCeqns ERROR, eqn="<<eqn << " is both a BC eqn and slave-constraint eqn."; throw std::runtime_error(osstr.str()); } continue; } } double* ptr = &iter->second; CHK_ERR( matrix.copyIn(1, &eqn, 1, &eqn, &ptr) ); } bcs_.clear(); return(0); }
bool confirm_matrix_values(const fei::Matrix& mat, double expected_value) { std::vector<int> rows; fei::SharedPtr<fei::VectorSpace> rspace = mat.getMatrixGraph()->getRowSpace(); rspace->getIndices_Owned(rows); bool result = true; std::vector<int> indices; std::vector<double> coefs; for(size_t i=0; i<rows.size(); ++i) { int rowlength = 0; mat.getRowLength(rows[i], rowlength); indices.resize(rowlength); coefs.resize(rowlength); mat.copyOutRow(rows[i], rowlength, &coefs[0], &indices[0]); for(size_t j=0; j<indices.size(); ++j) { if (std::abs(coefs[j] - expected_value) > 1.e-13) { result = false; break; } } } return result; }
void assemble_elem_matrices_and_vectors(stk::mesh::BulkData& mesh, stk::mesh::FieldBase& field, stk::linsys::DofMapper& dof_mapper, fei::Matrix& matrix, fei::Vector& rhs) { stk::mesh::fem::FEMMetaData &fem = stk::mesh::fem::FEMMetaData::get(mesh); const stk::mesh::EntityRank element_rank = fem.element_rank(); const std::vector<stk::mesh::Bucket*>& mesh_buckets = mesh.buckets(element_rank); std::vector<stk::mesh::Bucket*> part_buckets; stk::mesh::Selector select_owned(stk::mesh::MetaData::get(mesh).locally_owned_part()); stk::mesh::get_buckets(select_owned, mesh_buckets, part_buckets); int field_id = dof_mapper.get_field_id(field); stk::mesh::Entity& first_entity = *(part_buckets[0]->begin()); stk::mesh::PairIterRelation rel = first_entity.relations(stk::mesh::fem::FEMMetaData::NODE_RANK); int num_nodes_per_elem = rel.second - rel.first; fei::SharedPtr<fei::MatrixGraph> matgraph = matrix.getMatrixGraph(); int pattern_id = matgraph->definePattern(num_nodes_per_elem, stk::mesh::fem::FEMMetaData::NODE_RANK, field_id); std::vector<int> node_ids(num_nodes_per_elem); const int field_size = dof_mapper.get_fei_VectorSpace()->getFieldSize(field_id); const int matsize = num_nodes_per_elem*field_size*num_nodes_per_elem*field_size; const int vecsize = num_nodes_per_elem*field_size; std::vector<double> elem_matrix_1d(matsize, 0); std::vector<double*> elem_matrix_2d(vecsize); std::vector<double> elem_vector(vecsize, 0); for(size_t i=0; i<elem_matrix_2d.size(); ++i) { elem_matrix_2d[i] = &elem_matrix_1d[i*vecsize]; } //fill our dummy elem-matrix: //This dummy matrix will be the same for every element. A real application //would form a different elem-matrix for each element. for(size_t i=0; i<elem_matrix_2d.size(); ++i) { double* row = elem_matrix_2d[i]; if (i>=1) row[i-1] = -1; row[i] = 2; if (i<elem_matrix_2d.size()-1) row[i+1] = -1; elem_vector[i] = 1; } std::vector<int> eqn_indices(vecsize); for(size_t i=0; i<part_buckets.size(); ++i) { stk::mesh::Bucket::iterator b_iter = part_buckets[i]->begin(), b_end = part_buckets[i]->end(); for(; b_iter != b_end; ++b_iter) { stk::mesh::Entity& elem = *b_iter; rel = elem.relations(stk::mesh::fem::FEMMetaData::NODE_RANK); for(int j=0; rel.first != rel.second; ++rel.first, ++j) { node_ids[j] = rel.first->entity()->identifier(); } matgraph->getPatternIndices(pattern_id, &node_ids[0], eqn_indices); matrix.sumIn(vecsize, &eqn_indices[0], vecsize, &eqn_indices[0], &elem_matrix_2d[0]); rhs.sumIn(vecsize, &eqn_indices[0], &elem_vector[0]); } } }