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 };