1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
|
/*=========================================================================
Program: Insight Segmentation & Registration Toolkit
Module: $RCSfile: itkFEMLoadImplementationGenericBodyLoad.cxx,v $
Language: C++
Date: $Date: 2009-01-30 21:10:18 $
Version: $Revision: 1.9 $
Copyright (c) Insight Software Consortium. All rights reserved.
See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notices for more information.
=========================================================================*/
// disable debug warnings in MS compiler
#ifdef _MSC_VER
#pragma warning(disable: 4786)
#endif
#include "itkFEMLoadImplementationGenericBodyLoad.h"
namespace itk {
namespace fem {
/**
* Handle LoadGrav in element by integrating over the element domain.
* This implementation requires that the element has the shape functions
* and integration routines defined.
*
* It is also assumed, that element's local DOFs are numbered with respect
* to node ID. If this is not the case, you should not use this function.
*/
void
LoadImplementationGenericBodyLoad
::Implementation(Element::ConstPointer element, LoadGrav::Pointer load, Element::VectorType& Fe)
{
// Order of integration
// FIXME: Allow changing the order of integration by setting a
// static member within an element base class.
unsigned int order=0;
const unsigned int Nip=element->GetNumberOfIntegrationPoints(order);
const unsigned int Ndofs=element->GetNumberOfDegreesOfFreedomPerNode();
const unsigned int Nnodes=element->GetNumberOfNodes();
Element::VectorType force(Ndofs,0.0),
ip,gip,force_tmp,shapeF;
Fe.set_size(element->GetNumberOfDegreesOfFreedom());
Fe.fill(0.0);
Element::Float w,detJ;
for(unsigned int i=0; i<Nip; i++)
{
element->GetIntegrationPointAndWeight(i,ip,w,order);
gip=element->GetGlobalFromLocalCoordinates(ip);
shapeF=element->ShapeFunctions(ip);
detJ=element->JacobianDeterminant(ip);
// Adjust the size of a force vector returned from the load object so
// that it is equal to the number of DOFs per node. If the Fg returned
// a vector with less dimensions, we add zero elements. If the Fg
// returned a vector with more dimensions, we remove the extra dimensions.
force.fill(0.0);
// FIXME: Maybe Fg function should be declared as const in LoadGrav.
force_tmp=load->Fg(gip);
unsigned int Nd=Ndofs;
if(force_tmp.size()<Nd)
{
Nd=force_tmp.size();
}
for(unsigned int d=0; d<Nd; d++)
{
force[d] = force_tmp[d];
}
// Claculate the equivalent nodal loads
for(unsigned int n=0; n<Nnodes; n++)
{
for(unsigned int d=0; d<Ndofs; d++)
{
Fe[n*Ndofs+d] += shapeF[n]*force[d]*w*detJ;
}
}
}
}
}} // end namespace itk::fem
|