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

📄 dirichletbc.cpp

📁 利用C
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// Copyright (C) 2007-2008 Anders Logg and Garth N. Wells.// Licensed under the GNU LGPL Version 2.1.//// Modified by Kristian Oelgaard, 2007//// First added:  2007-04-10// Last changed: 2008-05-22#include <dolfin/common/constants.h>#include <dolfin/log/log.h>#include <dolfin/mesh/Mesh.h>#include <dolfin/mesh/MeshData.h>#include <dolfin/mesh/Vertex.h>#include <dolfin/mesh/Cell.h>#include <dolfin/mesh/Facet.h>#include <dolfin/mesh/Point.h>#include <dolfin/mesh/SubDomain.h>#include <dolfin/la/GenericMatrix.h>#include <dolfin/la/GenericVector.h>#include "Form.h"#include "UFCMesh.h"#include "UFCCell.h"#include "SubSystem.h"#include "DirichletBC.h"using namespace dolfin;//-----------------------------------------------------------------------------DirichletBC::DirichletBC(Function& g,                         Mesh& mesh,                         SubDomain& sub_domain,                         BCMethod method)  : BoundaryCondition(), g(g), _mesh(mesh),    method(method), user_sub_domain(&sub_domain){  initFromSubDomain(sub_domain);}//-----------------------------------------------------------------------------DirichletBC::DirichletBC(Function& g,                         MeshFunction<uint>& sub_domains,                         uint sub_domain,                         BCMethod method)  : BoundaryCondition(), g(g), _mesh(sub_domains.mesh()),    method(method), user_sub_domain(0){  initFromMeshFunction(sub_domains, sub_domain);}//-----------------------------------------------------------------------------DirichletBC::DirichletBC(Function& g,                         Mesh& mesh,                         uint sub_domain,                         BCMethod method)  : BoundaryCondition(), g(g), _mesh(mesh),    method(method), user_sub_domain(0){  initFromMesh(sub_domain);}//-----------------------------------------------------------------------------DirichletBC::DirichletBC(Function& g,                         Mesh& mesh,                         SubDomain& sub_domain,                         const SubSystem& sub_system,                         BCMethod method)  : BoundaryCondition(), g(g), _mesh(mesh),    method(method), user_sub_domain(&sub_domain),    sub_system(sub_system){  initFromSubDomain(sub_domain);}//-----------------------------------------------------------------------------DirichletBC::DirichletBC(Function& g,                         MeshFunction<uint>& sub_domains,                         uint sub_domain,                         const SubSystem& sub_system,                         BCMethod method)  : BoundaryCondition(), g(g), _mesh(sub_domains.mesh()),    method(method), user_sub_domain(0),    sub_system(sub_system){  initFromMeshFunction(sub_domains, sub_domain);}//-----------------------------------------------------------------------------DirichletBC::DirichletBC(Function& g,                         Mesh& mesh,                         uint sub_domain,                         const SubSystem& sub_system,                         BCMethod method)  : BoundaryCondition(), g(g), _mesh(mesh),    method(method), user_sub_domain(0),    sub_system(sub_system){  initFromMesh(sub_domain);}//-----------------------------------------------------------------------------DirichletBC::~DirichletBC(){  // Do nothing}//-----------------------------------------------------------------------------void DirichletBC::apply(GenericMatrix& A, GenericVector& b, const Form& form){  apply(A, b, 0, form.dofMaps()[1], form.form());}//-----------------------------------------------------------------------------void DirichletBC::apply(GenericMatrix& A, GenericVector& b, const DofMap& dof_map,                        const ufc::form& form){  apply(A, b, 0, dof_map, form);}//-----------------------------------------------------------------------------void DirichletBC::apply(GenericMatrix& A, GenericVector& b,                        const GenericVector& x, const Form& form){  apply(A, b, &x, form.dofMaps()[1], form.form());}//-----------------------------------------------------------------------------void DirichletBC::apply(GenericMatrix& A, GenericVector& b,                        const GenericVector& x, const DofMap& dof_map, const ufc::form& form){  apply(A, b, &x, dof_map, form);}//-----------------------------------------------------------------------------void DirichletBC::apply(GenericMatrix& A, GenericVector& b,                        const GenericVector* x, const DofMap& dof_map, const ufc::form& form){  // Simple check  const uint N = dof_map.global_dimension();  if (N != A.size(0) /*  || N != A.size(1) alow for rectangular matrices */)    error("Incorrect dimension of matrix for application of boundary conditions. Did you assemble it on a different mesh?");  if (N != b.size())    error("Incorrect dimension of matrix for application of boundary conditions. Did you assemble it on a different mesh?");  // A map to hold the mapping from boundary dofs to boundary values  std::map<uint, real> boundary_values;  // Create local data for application of boundary conditions  BoundaryCondition::LocalData data(form, _mesh, dof_map, sub_system);  // Compute dofs and values  computeBC(boundary_values, data);  // Copy boundary value data to arrays  uint* dofs = new uint[boundary_values.size()];  real* values = new real[boundary_values.size()];  std::map<uint, real>::const_iterator boundary_value;  uint i = 0;  for (boundary_value = boundary_values.begin(); boundary_value != boundary_values.end(); ++boundary_value)  {    dofs[i]     = boundary_value->first;    values[i++] = boundary_value->second;  }    // Modify boundary values for nonlinear problems  if (x)  {    real* x_values = new real[boundary_values.size()];    x->get(x_values, boundary_values.size(), dofs);    for (uint i = 0; i < boundary_values.size(); i++)      values[i] -= x_values[i];  }    message("Applying boundary conditions to linear system.");    // Modify RHS vector (b[i] = value)  b.set(values, boundary_values.size(), dofs);    // Modify linear system (A_ii = 1)  A.ident(boundary_values.size(), dofs);    // Clear temporary arrays  delete [] dofs;  delete [] values;    // Finalise changes to A  A.apply();    // Finalise changes to b  b.apply();}//-----------------------------------------------------------------------------void DirichletBC::zero(GenericMatrix& A, const Form& form){  zero(A, form.dofMaps()[1], form.form());}//-----------------------------------------------------------------------------void DirichletBC::zero(GenericMatrix& A, const DofMap& dof_map, const ufc::form& form){  // Simple check  const uint N = dof_map.global_dimension();  if (N != A.size(0))    error("Incorrect dimension of matrix for application of boundary conditions. Did you assemble it on a different mesh?");  // A map to hold the mapping from boundary dofs to boundary values  std::map<uint, real> boundary_values;  // Create local data for application of boundary conditions  BoundaryCondition::LocalData data(form, _mesh, dof_map, sub_system);  // Compute dofs and values  computeBC(boundary_values, data);  // Copy boundary value data to arrays  uint* dofs = new uint[boundary_values.size()];  std::map<uint, real>::const_iterator boundary_value;  uint i = 0;  for (boundary_value = boundary_values.begin(); boundary_value != boundary_values.end(); ++boundary_value)    dofs[i++] = boundary_value->first;  // Modify linear system (A_ii = 1)  A.zero(boundary_values.size(), dofs);  // Finalise changes to A  A.apply();  // Clear temporary arrays  delete [] dofs;}//-----------------------------------------------------------------------------Mesh& DirichletBC::mesh(){  return _mesh;}//-----------------------------------------------------------------------------void DirichletBC::initFromSubDomain(SubDomain& sub_domain){  dolfin_assert(facets.size() == 0);  // FIXME: This can be made more efficient, we should be able to  // FIXME: extract the facets without first creating a MeshFunction on  // FIXME: the entire mesh and then extracting the subset. This is done  // FIXME: mainly for convenience (we may reuse mark() in SubDomain).  // Make sure the mesh has been ordered  _mesh.order();  // Create mesh function for sub domain markers on facets  const uint dim = _mesh.topology().dim();  _mesh.init(dim - 1);  MeshFunction<uint> sub_domains(_mesh, dim - 1);  // Mark everything as sub domain 1  sub_domains = 1;    // Mark the sub domain as sub domain 0  sub_domain.mark(sub_domains, 0);  // Initialize from mesh function  initFromMeshFunction(sub_domains, 0);}//-----------------------------------------------------------------------------void DirichletBC::initFromMeshFunction(MeshFunction<uint>& sub_domains,                                       uint sub_domain){  dolfin_assert(facets.size() == 0);  // Make sure we have the facet - cell connectivity  const uint dim = _mesh.topology().dim();  _mesh.init(dim - 1, dim);  // Make sure the mesh has been ordered  _mesh.order();  // Build set of boundary facets  for (FacetIterator facet(_mesh); !facet.end(); ++facet)  {    // Skip facets not on this boundary    if (sub_domains(*facet) != sub_domain)      continue;    // Get cell to which facet belongs (there may be two, but pick first)    Cell cell(_mesh, facet->entities(dim)[0]);    

⌨️ 快捷键说明

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