1 //#************************************************************** 2 //# 3 //# filename: XGProvider.h 4 //# 5 //# author: Vetyukov Yury 6 //# 7 //# generated: February 2011 8 //# description: Utility class 9 //# remarks: 10 //# 11 //# Copyright (c) 2003-2013 Johannes Gerstmayr, Linz Center of Mechatronics GmbH, Austrian 12 //# Center of Competence in Mechatronics GmbH, Institute of Technical Mechanics at the 13 //# Johannes Kepler Universitaet Linz, Austria. All rights reserved. 14 //# 15 //# This file is part of HotInt. 16 //# HotInt is free software: you can redistribute it and/or modify it under the terms of 17 //# the HOTINT license. See folder 'licenses' for more details. 18 //# 19 //# bug reports are welcome!!! 20 //# WWW: www.hotint.org 21 //# email: bug_reports@hotint.org or support@hotint.org 22 //#*************************************************************************************** 23 24 #pragma once 25 26 // this structure and its derived versions switch the behavior of various functions, 27 // which are implemented by finite elements, between "compute", "draw", displacement, total and initial coordinates; 28 // the architecture is specialized for the scenario, used by ANCFThinPlate3D element: 29 // the initial values of the degrees of freedom for the reference configuration are stored separately, 30 // and XG() of the element operate with the increments of the degrees of freedom (displacements) 31 // and their time derivatives (velocities); 32 // such behavior is more consistent for the geometrically linear solutions. 33 34 struct XGProvider 35 { SetXGProviderXGProvider36 void SetXGProvider(Element * element_, const Vector * xgReferenceConfiguration_) 37 { 38 element = element_; 39 xgReferenceConfiguration = xgReferenceConfiguration_; 40 assert(xgReferenceConfiguration->Length() == element->FlexDOF()); 41 } 42 43 // "displacement" of the degree of freedom from the reference configuration 44 virtual double XGdispl(int iloc) const = 0; 45 // total value of the degree of freedom 46 virtual double XGcoord(int iloc) const = 0; 47 // time derivative of the degree of freedom 48 virtual double XGP(int iloc) const = 0; 49 // sometimes it is necessary to know whether this is a "draw" configuration 50 virtual bool IsDrawConfiguration() const = 0; 51 52 protected: 53 Element * element; 54 const Vector * xgReferenceConfiguration; // degrees of freedom in the reference configuration (without time derivatives) 55 }; 56 57 // initial state of the element 58 struct XGProviderInit : public XGProvider 59 { XGdisplXGProviderInit60 virtual double XGdispl(int iloc) const { return 0; } XGcoordXGProviderInit61 virtual double XGcoord(int iloc) const { return (*xgReferenceConfiguration)(iloc); } XGPXGProviderInit62 virtual double XGP(int iloc) const { return element->GetXInit()(iloc + element->SOS()); } IsDrawConfigurationXGProviderInit63 virtual bool IsDrawConfiguration() const { return false; } 64 }; 65 66 // accessing "compute" displacements and coordinates 67 struct XGProviderCompute : public XGProvider 68 { XGdisplXGProviderCompute69 virtual double XGdispl(int iloc) const { return element->XG(iloc); } XGcoordXGProviderCompute70 virtual double XGcoord(int iloc) const { return (*xgReferenceConfiguration)(iloc) + element->XG(iloc); } XGPXGProviderCompute71 virtual double XGP(int iloc) const { return element->XGP(iloc); } IsDrawConfigurationXGProviderCompute72 virtual bool IsDrawConfiguration() const { return false; } 73 }; 74 75 // accessing "draw" displacements and coordinates 76 struct XGProviderDraw : public XGProvider 77 { XGdisplXGProviderDraw78 virtual double XGdispl(int iloc) const { return element->XGD(iloc); } XGcoordXGProviderDraw79 virtual double XGcoord(int iloc) const { return (*xgReferenceConfiguration)(iloc) + element->XGD(iloc); } XGPXGProviderDraw80 virtual double XGP(int iloc) const { return element->XGPD(iloc); } IsDrawConfigurationXGProviderDraw81 virtual bool IsDrawConfiguration() const { return true; } 82 }; 83 84 // "caching" the current state of another XGProvider for the accelerated access; 85 // only the coordinate values are cached; 86 // for optimal performance the object should be created on the stack similar to ConstVector; 87 // the performance should be the same or even better as with the ConstVector, 88 // as double& Vector::operator() is also virtual 89 template <int data_size> 90 struct XGProviderCoordCached : public XGProvider 91 { XGProviderCoordCachedXGProviderCoordCached92 XGProviderCoordCached(const XGProvider & xg, int length) 93 { 94 draw = xg.IsDrawConfiguration(); 95 for(int i = 1; i <= length; i++) 96 data[i-1] = xg.XGcoord(i); 97 } 98 XGdisplXGProviderCoordCached99 virtual double XGdispl(int iloc) const { assert(0); return 0; } XGcoordXGProviderCoordCached100 virtual double XGcoord(int iloc) const { return data[iloc-1]; } XGPXGProviderCoordCached101 virtual double XGP(int iloc) const { assert(0); return 0; } IsDrawConfigurationXGProviderCoordCached102 virtual bool IsDrawConfiguration() const { return draw; } 103 104 protected: 105 double data[data_size]; 106 bool draw; 107 }; 108 109 // the same as before, but all data are cached 110 template <int data_size> 111 struct XGProviderCached : public XGProvider 112 { XGProviderCachedXGProviderCached113 XGProviderCached(const XGProvider & xg, int length) 114 { 115 draw = xg.IsDrawConfiguration(); 116 for(int i = 1; i <= length; i++) 117 { 118 dataDispl[i-1] = xg.XGdispl(i); 119 dataCoord[i-1] = xg.XGcoord(i); 120 dataVel[i-1] = xg.XGP(i); 121 } 122 } 123 XGdisplXGProviderCached124 virtual double XGdispl(int iloc) const { return dataDispl[iloc-1]; } XGcoordXGProviderCached125 virtual double XGcoord(int iloc) const { return dataCoord[iloc-1]; } XGPXGProviderCached126 virtual double XGP(int iloc) const { return dataVel[iloc-1]; } IsDrawConfigurationXGProviderCached127 virtual bool IsDrawConfiguration() const { return draw; } 128 129 protected: 130 double dataDispl[data_size]; 131 double dataCoord[data_size]; 132 double dataVel[data_size]; 133 bool draw; 134 };