Пример #1
0
double compute_residual_norm2(fei::LinearSystem& fei_ls, fei::Vector& r)
{
  fei::SharedPtr<fei::Matrix> A = fei_ls.getMatrix();
  fei::SharedPtr<fei::Vector> x = fei_ls.getSolutionVector();
  fei::SharedPtr<fei::Vector> b = fei_ls.getRHS();

  //form r = A*x
  A->multiply(x.get(), &r);
  //form r = b - r   (i.e., r = b - A*x)
  r.update(1, b.get(), -1);

//!!!!!! fix this !!!!!!!!!
//terrible data copy. fei::Vector should provide a norm operation instead
//of making me roll my own here...

  std::vector<int> indices;
  r.getVectorSpace()->getIndices_Owned(indices);
  std::vector<double> coefs(indices.size());
  r.copyOut(indices.size(), &indices[0], &coefs[0]);
  double local_sum = 0;
  for(size_t i=0; i<indices.size(); ++i) {
    local_sum += coefs[i]*coefs[i];
  }
#ifdef HAVE_MPI
  MPI_Comm comm = r.getVectorSpace()->getCommunicator();
  double global_sum = 0;
  int num_doubles = 1;
  MPI_Allreduce(&local_sum, &global_sum, num_doubles, MPI_DOUBLE, MPI_SUM, comm);
#else
  double global_sum = local_sum;
#endif
  return std::sqrt(global_sum);
}
Пример #2
0
void copy_vector_to_mesh( fei::Vector & vec,
                          const DofMapper & dof,
                          stk_classic::mesh::BulkData & mesh_bulk_data
                        )
{
  vec.scatterToOverlap();

  std::vector<int> shared_and_owned_indices;

  vec.getVectorSpace()->getIndices_SharedAndOwned(shared_and_owned_indices);

  size_t num_values = shared_and_owned_indices.size();

  if(num_values == 0) {
    return;
  }

  std::vector<double> values(num_values);
  vec.copyOut(num_values,&shared_and_owned_indices[0],&values[0]);

  stk_classic::mesh::EntityRank ent_type;
  stk_classic::mesh::EntityId ent_id;
  const stk_classic::mesh::FieldBase * field;
  int offset_into_field;

  for(size_t i = 0; i < num_values; ++i)
  {

    dof.get_dof( shared_and_owned_indices[i],
                 ent_type,
                 ent_id,
                 field,
                 offset_into_field
                );

    stk_classic::mesh::Entity & entity = *mesh_bulk_data.get_entity(ent_type, ent_id);

    void * data = stk_classic::mesh::field_data(*field,entity);

    if(!(field->type_is<double>()) || data == NULL) {
      std::ostringstream oss;
      oss << "stk_classic::linsys::copy_vector_to_mesh ERROR, bad data type, or ";
      oss << " field (" << field->name() << ") not found on entity with type " << entity.entity_rank();
      oss << " and ID " << entity.identifier();
      std::string str = oss.str();
      throw std::runtime_error(str.c_str());
    }

    double * double_data = reinterpret_cast<double *>(data);

    double_data[offset_into_field] = values[i];

  }
}
bool confirm_vector_values(const fei::Vector& vec, double expected_value)
{
    std::vector<int> indices;
    fei::SharedPtr<fei::VectorSpace> vspace = vec.getVectorSpace();
    vspace->getIndices_Owned(indices);
    bool result = true;
    if (indices.size() > 0) {
        std::vector<double> coefs(indices.size());
        vec.copyOut(indices.size(), &indices[0], &coefs[0]);

        for(size_t i=0; i<indices.size(); ++i) {
            if (std::abs(coefs[i] - expected_value) > 1.e-13) {
                result = false;
                break;
            }
        }
    }
    return result;
}
Пример #4
0
void scale_vector(double scalar,
                  fei::Vector& vec)
{
  fei::SharedPtr<fei::VectorSpace> vspace = vec.getVectorSpace();

  int numIndices = vspace->getNumIndices_Owned();
  std::vector<int> indices(numIndices);
  vspace->getIndices_Owned(numIndices, &indices[0], numIndices);

  std::vector<double> coefs(numIndices);

  vec.copyOut(numIndices, &indices[0], &coefs[0]);

  for(size_t j=0; j<coefs.size(); ++j) {
    coefs[j] *= scalar;
  }

  vec.copyIn(numIndices, &indices[0], &coefs[0]);
}
Пример #5
0
void add_vector_to_vector(double scalar,
                          const fei::Vector& src_vector,
                          fei::Vector& dest_vector)
{
  fei::SharedPtr<fei::VectorSpace> vspace = src_vector.getVectorSpace();

  int numIndices = vspace->getNumIndices_Owned();
  std::vector<int> indices(numIndices);
  vspace->getIndices_Owned(numIndices, &indices[0], numIndices);

  std::vector<double> coefs(numIndices);

  src_vector.copyOut(numIndices, &indices[0], &coefs[0]);

  for(size_t j=0; j<coefs.size(); ++j) {
    coefs[j] *= scalar;
  }

  dest_vector.sumIn(numIndices, &indices[0], &coefs[0]);
}
Пример #6
0
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]);
    }
  }
}