⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 discretefunction.cpp

📁 Dolfin provide a high-performance linear algebra library
💻 CPP
字号:
// Copyright (C) 2007 Anders Logg.// Licensed under the GNU LGPL Version 2.1.//// Modified by Garth N. Wells, 2007.//// First added:  2007-04-02// Last changed: 2007-08-27#include <dolfin/dolfin_log.h>#include <dolfin/Mesh.h>#include <dolfin/Form.h>#include <dolfin/DofMap.h>#include <dolfin/Vertex.h>#include <dolfin/Cell.h>#include <dolfin/UFCMesh.h>#include <dolfin/UFCCell.h>#include <dolfin/ElementLibrary.h>#include <dolfin/SubFunction.h>#include <dolfin/SubSystem.h>#include <dolfin/DiscreteFunction.h>using namespace dolfin;//-----------------------------------------------------------------------------DiscreteFunction::DiscreteFunction(Mesh& mesh, Vector& x, const Form& form, uint i)  : GenericFunction(mesh),    x(&x), finite_element(0), dof_map(0), ufc_dof_map(0), dofs(0),    local_mesh(false), local_vector(false){  init(mesh, x, form.form(), i);}//-----------------------------------------------------------------------------DiscreteFunction::DiscreteFunction(Mesh& mesh, Vector& x, const ufc::form& form, uint i)  : GenericFunction(mesh),    x(&x), finite_element(0), dof_map(0), ufc_dof_map(0), dofs(0),    local_mesh(false), local_vector(false){  init(mesh, x, form, i);}//-----------------------------------------------------------------------------DiscreteFunction::DiscreteFunction(Mesh& mesh, Vector& x,                                   std::string finite_element_signature,                                   std::string dof_map_signature)  : GenericFunction(mesh),    x(&x), finite_element(0), dof_map(0), ufc_dof_map(0), dofs(0),    local_mesh(false), local_vector(false){  // Create finite element  finite_element = ElementLibrary::create_finite_element(finite_element_signature);  if (!finite_element)  {    error("Unable to find finite element in library: \"%s\".",                  finite_element_signature.c_str());  }  // Create dof map  ufc_dof_map = ElementLibrary::create_dof_map(dof_map_signature);  if (!ufc_dof_map)  {    error("Unable to find dof map in library: \"%s\".",                  dof_map_signature.c_str());  }  dof_map = new DofMap(*ufc_dof_map, mesh);  // Check size of vector  if (x.size() != dof_map->global_dimension())    error("Size of vector does not match global dimension of finite element space.");  // Initialize local array for mapping of dofs  dofs = new uint[dof_map->local_dimension()];  for (uint i = 0; i < dof_map->local_dimension(); i++)    dofs[i] = 0;  // Assume responsibility for mesh and vector  local_mesh = &mesh;  local_vector = &x;}//-----------------------------------------------------------------------------DiscreteFunction::DiscreteFunction(SubFunction& sub_function)  : GenericFunction(sub_function.f->mesh),    x(0), finite_element(0), dof_map(0), ufc_dof_map(0), dofs(0),    local_mesh(false), local_vector(false){  // Create sub system  SubSystem sub_system(sub_function.i);  // Extract sub element  finite_element = sub_system.extractFiniteElement(*sub_function.f->finite_element);  // Extract sub dof map and offset  uint offset = 0;  ufc_dof_map = sub_system.extractDofMap(*sub_function.f->ufc_dof_map, mesh, offset);  dof_map = new DofMap(*ufc_dof_map, mesh);  // Create vector of dofs and copy values  const uint n = dof_map->global_dimension();  x = new Vector(n);  real* values = new real[n];  uint* get_rows = new uint[n];  uint* set_rows = new uint[n];  for (uint i = 0; i < n; i++)  {    get_rows[i] = offset + i;    set_rows[i] = i;  }  sub_function.f->x->get(values, n, get_rows);  x->set(values, n, set_rows);  x->apply();  delete [] values;  delete [] get_rows;  delete [] set_rows;  // Initialize local array for mapping of dofs  dofs = new uint[dof_map->local_dimension()];  for (uint i = 0; i < dof_map->local_dimension(); i++)    dofs[i] = 0;  // Assume responsibility for vector  local_vector = x;}//-----------------------------------------------------------------------------DiscreteFunction::DiscreteFunction(const DiscreteFunction& f)  : GenericFunction(f.mesh),    x(0), finite_element(0), dof_map(0), ufc_dof_map(0), dofs(0),    local_mesh(false), local_vector(false){  cout << "Copy constructor for discrete function" << endl;  // Create finite element  finite_element = ElementLibrary::create_finite_element(f.finite_element->signature());  if (!finite_element)  {    error("Unable to find finite element in library: \"%s\".",                  f.finite_element->signature());  }  // Create dof map  ufc_dof_map = ElementLibrary::create_dof_map(f.dof_map->signature());  if (!ufc_dof_map)  {    error("Unable to find dof map in library: \"%s\".",                  f.dof_map->signature());  }  dof_map = new DofMap(*ufc_dof_map, mesh);  // Create vector and copy values  x = new Vector(dof_map->global_dimension());  *x = *f.x;  // Initialize local array for mapping of dofs  dofs = new uint[dof_map->local_dimension()];  for (uint i = 0; i < dof_map->local_dimension(); i++)    dofs[i] = 0;  // Assume responsibility for vector  local_vector = x;}//-----------------------------------------------------------------------------DiscreteFunction::~DiscreteFunction(){  if (finite_element)    delete finite_element;        if (dof_map)    delete dof_map;  if (ufc_dof_map)    delete ufc_dof_map;  if (dofs)    delete [] dofs;  if (local_mesh)    delete local_mesh;  if (local_vector)    delete local_vector;}//-----------------------------------------------------------------------------dolfin::uint DiscreteFunction::rank() const{  dolfin_assert(finite_element);  return finite_element->value_rank();}//-----------------------------------------------------------------------------dolfin::uint DiscreteFunction::dim(uint i) const{  dolfin_assert(finite_element);  return finite_element->value_dimension(i);}//-----------------------------------------------------------------------------dolfin::uint DiscreteFunction::numSubFunctions() const{  dolfin_assert(finite_element);  return finite_element->num_sub_elements();}//-----------------------------------------------------------------------------const DiscreteFunction& DiscreteFunction::operator= (const DiscreteFunction& f){  cout << "Assignment in discrete function" << endl;  // Check that data matches  if (strcmp(finite_element->signature(), f.finite_element->signature()) != 0 ||       strcmp(dof_map->signature(), f.dof_map->signature()) != 0 ||      x->size() != f.x->size())  {    error("Assignment of discrete function failed. Finite element spaces or dimensions don't match.");  }  // Copy vector  *x = *f.x;  return *this;}//-----------------------------------------------------------------------------void DiscreteFunction::interpolate(real* values){  dolfin_assert(values);  dolfin_assert(finite_element);  dolfin_assert(dof_map);  dolfin_assert(dofs);    // Compute size of value (number of entries in tensor value)  uint size = 1;  for (uint i = 0; i < finite_element->value_rank(); i++)    size *= finite_element->value_dimension(i);  // Local data for interpolation on each cell  CellIterator cell(mesh);  UFCCell ufc_cell(*cell);  const uint num_cell_vertices = mesh.type().numVertices(mesh.topology().dim());  real* vertex_values = new real[size*num_cell_vertices];  real* dof_values = new real[finite_element->space_dimension()];  // Interpolate vertex values on each cell and pick the last value  // if two or more cells disagree on the vertex values  for (; !cell.end(); ++cell)  {    // Update to current cell    ufc_cell.update(*cell);    // Tabulate dofs    dof_map->tabulate_dofs(dofs, ufc_cell);        // Pick values from global vector    x->get(dof_values, dof_map->local_dimension(), dofs);    // Interpolate values at the vertices    finite_element->interpolate_vertex_values(vertex_values, dof_values, ufc_cell);    // Copy values to array of vertex values    for (VertexIterator vertex(*cell); !vertex.end(); ++vertex)      for (uint i = 0; i < size; ++i)        values[i*mesh.numVertices() + vertex->index()] = vertex_values[i*num_cell_vertices + vertex.pos()];  }  // Delete local data  delete [] vertex_values;  delete [] dof_values;}//-----------------------------------------------------------------------------void DiscreteFunction::interpolate(real* coefficients,                                   const ufc::cell& cell,                                   const ufc::finite_element& finite_element){  dolfin_assert(coefficients);  dolfin_assert(this->finite_element);  dolfin_assert(this->dof_map);  dolfin_assert(this->dofs);  // FIXME: Better test here, compare against the local element  // Check dimension  if (finite_element.space_dimension() != dof_map->local_dimension())    error("Finite element does not match for interpolation of discrete function.");  // Tabulate dofs  dof_map->tabulate_dofs(dofs, cell);    // Pick values from global vector  x->get(coefficients, dof_map->local_dimension(), dofs);}//-----------------------------------------------------------------------------Vector& DiscreteFunction::vector() const{  if( !x )    error("Vector associated with DiscreteFunction has not been initialised.");  return *x;}//-----------------------------------------------------------------------------void DiscreteFunction::init(Mesh& mesh, Vector& x, const ufc::form& form, uint i){  // Check argument  const uint num_arguments = form.rank() + form.num_coefficients();  if (i >= num_arguments)  {    error("Illegal function index %d. Form only has %d arguments.",                  i, num_arguments);  }  // Create finite element  finite_element = form.create_finite_element(i);  // Create dof map  ufc_dof_map = form.create_dof_map(i);  dof_map = new DofMap(*ufc_dof_map, mesh);  // Initialize vector  if (x.size() != dof_map->global_dimension())    x.init(dof_map->global_dimension());  // Initialize local array for mapping of dofs  dofs = new uint[dof_map->local_dimension()];  for (uint i = 0; i < dof_map->local_dimension(); i++)    dofs[i] = 0;}//-----------------------------------------------------------------------------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -