/*========================================================================= * * Copyright NumFOCUS * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * https://www.apache.org/licenses/LICENSE-2.0.txt * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *=========================================================================*/ #ifndef itkFEMLoadLandmark_h #define itkFEMLoadLandmark_h #include "itkFEMLoadElementBase.h" #include "ITKFEMExport.h" #include "vnl/vnl_vector.h" namespace itk { namespace fem { /** * \class LoadLandmark * \brief This load is derived from the motion of a specific landmark * * This load depends on the motion of a point from an undeformed * configuration to a deformed configuration. * \ingroup ITKFEM */ class ITKFEM_EXPORT LoadLandmark : public LoadElement { public: /** Standard class type aliases. */ using Self = LoadLandmark; using Superclass = LoadElement; using Pointer = SmartPointer; using ConstPointer = SmartPointer; /** Method for creation through the object factory. */ itkSimpleNewMacro(Self); /** \see LightObject::GetNameOfClass() */ itkOverrideGetNameOfClassMacro(LoadLandmark); /** CreateAnother method will clone the existing instance of this type, * including its internal member variables. */ itk::LightObject::Pointer CreateAnother() const override; /** * Methods to access the most recent solution vector */ void SetSolution(Solution::ConstPointer ptr) override { m_Solution = ptr; } Solution::ConstPointer GetSolution() override { return m_Solution; } Float GetSolution(unsigned int i, unsigned int v = 0) { return m_Solution->GetSolutionValue(i, v); } /** * Access the location of the point load */ Element::VectorType & GetPoint() { return m_Point; } /** * Set the force vector */ void SetPoint(const vnl_vector & pt) { m_Point = pt; } /** * Access the location of the point load */ Element::VectorType & GetSource() { return m_Source; } const Element::VectorType & GetSource() const { return m_Source; } /** * Get the force vector */ Element::VectorType & GetForce() { return m_Force; } const Element::VectorType & GetForce() const { return m_Force; } /** * Set the force vector */ void SetForce(const vnl_vector & force) { if (m_Force.size() != force.size()) { m_Force.set_size(force.size()); } for (unsigned int i = 0; i < force.size(); ++i) { m_Force[i] = force[i]; } } /** * Set the force vector */ void SetSource(const vnl_vector & source) { if (m_Source.size() != source.size()) { m_Source.set_size(source.size()); } for (unsigned int i = 0; i < source.size(); ++i) { m_Source[i] = source[i]; } } /** * Access the location of the point load */ Element::VectorType & GetTarget() { return m_Target; } const Element::VectorType & GetTarget() const { return m_Target; } /** * Set the force vector */ void SetTarget(const vnl_vector & target) { if (m_Target.size() != target.size()) { m_Target.set_size(target.size()); } for (unsigned int i = 0; i < target.size(); ++i) { m_Target[i] = target[i]; } } void ScalePointAndForce(double * spacing, double fwt) { for (unsigned int i = 0; i < m_Target.size(); ++i) { m_Target[i] /= spacing[i]; m_Source[i] /= spacing[i]; this->m_Eta *= fwt; } } /** * Set the element containing the landmark */ void SetContainedElement(const Element * e) { this->m_Element[0] = e; } /** * Get the element containing the landmark */ const Element * GetContainedElement() const { return this->m_Element[0]; } /** * Assign the LoadLandmark to an element */ virtual bool AssignToElement(Element::ArrayType::Pointer elements); virtual bool AssignToElement(Element::ArrayType1::Pointer elements); virtual Element::ConstPointer GetAssignedElement(Element::ArrayType1::Pointer elements); /** * Default constructors */ LoadLandmark() : m_Target(0) , m_Source(0) , m_Force(0) {} /** Get/Set the eta parameter, square root of the variance, for the load */ void SetEta(double e); double GetEta() const; /** Apply the load to the specified element */ void ApplyLoad(Element::ConstPointer element, Element::VectorType & Fe) override; protected: void PrintSelf(std::ostream & os, Indent indent) const override; /** * Square root of the variance (eta) */ double m_Eta{ 0 }; /** * Point in __local coordinates__ in the undeformed configuration */ vnl_vector m_Point{}; /** * Point in __global coordinates__ in the deformed configuration */ vnl_vector m_Target{}; vnl_vector m_Source{}; vnl_vector m_Force{}; /** * Pointer to the element which contains the undeformed * configuration of the landmark */ // Element::ConstPointer m_element; /** * Pointer to the solution object */ Solution::ConstPointer m_Solution{ nullptr }; }; } // namespace fem } // namespace itk #endif // itkFEMLoadLandmark_h