Keywords

These keywords were added by machine and not by the authors. This process is experimental and the keywords may be updated as the learning algorithm improves.

Parametric problems constitute perhaps the most relevant application of Proper Generalized Decomposition methods. Initially aimed at solving problems defined within a high dimensional phase space [6], PGD soon revealed an impressive ability to solve in the same setting parametric problems by just considering parameters as new dimensions, a sort of parametric phase space [27].

In this chapter we explore precisely these capabilities. Since they have also been included in a number of previous references, notably in former books (see [28], Chap. 5), we focus here on a particular instance of parametric problems: that of moving loads .

3.1 A Particularly Challenging Problem: A Moving Load as a Parameter

An influence line is a graphical representation of a given magnitude (a bending moment, for instance) at a given point of a beam caused by a unit load moving along the span of that beam. This concept has helped engineers through the years to design beam structures in an efficient manner. One can imagine, however, an extension of the concept of influence line to general, three-dimensional solids. This would give rise to a sort of response surface in which particularizing the parameter (the position of the load) provides in an immediate way the response of the solid (its deformed configuration, in this case). This sort of influence line has potentially many applications in science and engineering for real-time simulation in fields such as computational surgery [55], decision taking, or even augmented learning [60], see Fig. 3.1.

Fig. 3.1
figure 1

An application of the influence line concept for a hyperelastic beam. You can play interactively with the beam by just placing the load with your finger on a tablet. A web-based version of this same app can be reached at http://amb.unizar.es/barra03.htm

In fact, this problem has been frequently thought of as non separable , i.e., that the number of modes needed to express the solution is so big, that no gain is obtained by applying any kind of model order reduction technique and therefore it is better to simply simulate it in a straightforward manner, by finite element methods or any other numerical technique of your choice.

However, it can be easily found that this is not true. Consider the influence line sketched in Fig. 3.2. We consider a clamped beam with a moving load and try to compute its deformed configuration for the load acting at any point. In fact, by applying Proper Orthogonal Decomposition techniques to the results, it can readily be seen that the number of modes or shape functions needed to express this solution \(v=v(x,s)\) is in fact limited, see Fig. 3.3. Here, v denotes here the vertical displacement of the beam, x the particular point of the beam in which we want to know this displacement and s the position of the load,

Fig. 3.2
figure 2

A clamped beam with a moving load

Fig. 3.3
figure 3

(Left) resulting eigenvalues for the clamped beam problem and (right) first modes of the solution

As can be noticed from Fig. 3.3 (left), the eigenvalues decrease fast after a reasonable number of eigenmodes . Thus, even if we need to consider every possible load position, the number of functions needed to express the parametric solution is in fact reasonably limited.

3.2 The Problem Under the PGD Formalism

As will be noticed, under the PGD formalism, the influence line problem becomes simple. We generalize this problem so as to find the displacement field \(\varvec{u}(x,y,z)\) at any point of a three-dimensional solid \(\varOmega \), for any load position \(\varvec{s} \in {\bar{\varGamma }}\subset \partial \varOmega \).

Under these assumptions, the weak form of the problem will result after multiplying the strong form by an arbitrary test function \(\varvec{u}^*\) and integrating over the region occupied by the solid, \(\varOmega \), and the portion of its boundary which is accessible to the load, \({\bar{\varGamma }}\). It therefore consists in finding the displacement \(\varvec{u}\in \mathcal H^1\) such that for all \(\varvec{u}^*\in \mathcal H^1_0\):

$$\begin{aligned} \int _{{\bar{\varGamma }}}\int _\varOmega \varvec{\nabla }_s \varvec{u}^*: \varvec{\sigma }d\varOmega d{\bar{\varGamma }}=\int _{{\bar{\varGamma }}}\int _{\varGamma _{t2}} \varvec{u}^*\cdot \varvec{t} d\varGamma d{\bar{\varGamma }} \end{aligned}$$
(3.1)

where \(\varGamma =\varGamma _u \cup \varGamma _t\) represents the essential and natural portions of the boundary, and where \(\varGamma _t= \varGamma _{t1}\cup \varGamma _{t2}\), i.e., regions of homogeneous and non-homogeneous, respectively, natural boundary conditions. We assume, for simplicity of the exposition, that the load is of unity module and acts along the vertical axis: \(\varvec{t}=\varvec{e}_k \cdot \delta (\varvec{x}-\varvec{s})\), where \(\delta \) represents the Dirac-delta function and \(\varvec{e}_k\) the unit vector along the z-coordinate axis.

The Dirac-delta term needs to be approximated by a truncated series of separable functions in the spirit of the PGD method, i.e.,

$$\begin{aligned} t_j \approx \sum _{i=1}^m f^i_j(\varvec{x}) g^i_j(\varvec{s}) \end{aligned}$$
(3.2)

where m represents the order of truncation and \(f^i_j, g^i_j\) represent the j-th component of vectorial functions in space and boundary position, respectively.

The PGD approach to the problem consists in finding, in a greedy way , a finite sum of separable functions to approach the solution. Assuming that, at iteration n of this procedure, we have converged to such an approximation, we have

$$\begin{aligned} u^n_j(\varvec{x},\varvec{s})=\sum _{k=1}^n F_j^k(\varvec{x})\cdot G_j^k(\varvec{s}), \end{aligned}$$
(3.3)

where the term \(u_j\) refers to the jth component of the displacement vector, \(j=1,2,3\) and functions \(\varvec{F}^k\) and \(\varvec{G}^k\) represent the separated functions used to approximate the unknown field, obtained in previous iterations of the PGD algorithm.

If this rank- n approximation does not give the desired accuracy, we can proceed further and look for the (\(n+1\))th term, that will look like

$$\begin{aligned} u^{n+1}_j(\varvec{x},\varvec{s})= u^n_j(\varvec{x},\varvec{s})+ R_j(\varvec{x})\cdot S_j(\varvec{s}), \end{aligned}$$

where \(\varvec{R}(\varvec{x})\) and \(\varvec{S}(\varvec{s})\) are the sought functions that improve the approximation.

By just applying standard rules of variational calculus, the test function will be

$$\begin{aligned} u^*_j(\varvec{x},\varvec{s})=R_j^*(\varvec{x})\cdot S_j(\varvec{s})+ R_j(\varvec{x})\cdot S_j^*(\varvec{s}). \end{aligned}$$

To determine the new functions \(\varvec{R}\) and \(\varvec{S}\) any linearization strategy could in principle be applied. In our experience, a fixed-point algorithm in which functions \(\varvec{R}\) and \(\varvec{S}\) are determined iteratively gives very good results, even if convergence is not guaranteed, as is well known. We provide details of this strategy in the next section.

3.2.1 Computation of \(S(\varvec{s})\) Assuming \(R(\varvec{x})\) Is Known

In this case, the admissible variation of the displacement will be given by

$$\begin{aligned} u^*_j(\varvec{x},\varvec{s})= R_j(\varvec{x})\cdot S^*_j(\varvec{s}), \end{aligned}$$

or, equivalently, \(\varvec{u}^*(\varvec{x}, \varvec{s})=\varvec{R}\circ \varvec{S}^*\), where the symbol “\(\circ \)” denotes the so-called entry-wise, Hadamard or Schur multiplication for vectors. Once substituted into Eq. (3.1), gives

$$\begin{aligned} \int _{{\bar{\varGamma }}}\int _\varOmega \varvec{\nabla }_s (\varvec{R}\circ \varvec{S}^*): \varvec{ {\mathsf C}}: \varvec{\nabla }_s \left( \sum _{k=1}^n \varvec{F}^k\circ \varvec{G}^k+ \varvec{R}\circ \varvec{S}\right) d\varOmega d{\bar{\varGamma }}= \int _{{\bar{\varGamma }}}\int _{\varGamma _{t2}} (\varvec{R}\circ \varvec{S}^*) \cdot \left( \sum _{k=1}^m \varvec{f}^k \circ \varvec{g}^k \right) d\varGamma d{\bar{\varGamma }}, \end{aligned}$$
(3.4)

or, simply

$$\begin{aligned}&\int _{{\bar{\varGamma }}}\int _\varOmega \varvec{\nabla }_s (\varvec{R}\circ \varvec{S}^*):\varvec{\mathsf C}:\varvec{\nabla }_s (\varvec{R}\circ \varvec{S}) d\varOmega d{\bar{\varGamma }}\nonumber \\&=\int _{{\bar{\varGamma }}}\int _{\varGamma _{t2}} (\varvec{R}\circ \varvec{S}^*)\cdot \left( \sum _{k=1}^m \varvec{f}^k \circ \varvec{g}^k \right) d\varGamma d{\bar{\varGamma }} - \int _{{\bar{\varGamma }}}\int _{\varOmega } \varvec{\nabla }_s\left( \varvec{R}\circ \varvec{S}^* \right) \cdot \mathcal R^n d\varOmega d{\bar{\varGamma }}, \end{aligned}$$

where \(\mathcal R^n\) represents:

$$\begin{aligned} \mathcal R^n = \varvec{\mathsf C}:\varvec{\nabla }_s \varvec{u}^n. \end{aligned}$$

Since the symmetric gradient operates on spatial variables only, we have:

$$\begin{aligned}&\int _{{\bar{\varGamma }}}\int _\varOmega (\varvec{\nabla }_s \varvec{R}\circ \varvec{S}^*): \varvec{\mathsf C} :(\varvec{\nabla }_s \varvec{R}\circ \varvec{S}) d\varOmega d{\bar{\varGamma }}\nonumber \\&=\int _{{\bar{\varGamma }}}\int _{\varGamma _{t2}} (\varvec{R}\circ \varvec{S}^*)\cdot \left( \sum _{k=1}^m \varvec{f}^k \circ \varvec{g}^k \right) d\varGamma d{\bar{\varGamma }} - \int _{{\bar{\varGamma }}}\int _{\varOmega } \left( \varvec{\nabla }_s \varvec{R}\circ \varvec{S}^* \right) \cdot \mathcal R^n d\varOmega d{\bar{\varGamma }} \end{aligned}$$

where all the terms depending on \(\varvec{x}\) are known. Therefore, all integrals over \(\varOmega \) and \(\varGamma _{t2}\) (support of the regularization of the initially punctual load) can be computed to obtain an equation for \(\varvec{S}(\varvec{s})\).

3.2.2 Computation of \(R(\varvec{x})\) Assuming \(S(\varvec{s})\) Is Known

By proceeding in the same way, we have

$$\begin{aligned} u^*_j(\varvec{x},\varvec{s})= R^*_j(\varvec{x})\cdot S_j(\varvec{s}), \end{aligned}$$

which, once substituted into Eq. (3.1), gives

$$\begin{aligned} \int _{{\bar{\varGamma }}}\int _\varOmega \varvec{\nabla }_s (\varvec{R}^*\circ \varvec{S}):\varvec{\mathsf C} :\varvec{\nabla }_s \left( \sum _{k=1}^n \varvec{F}^k\circ \varvec{G}^k+ \varvec{R}\circ \varvec{S}\right) d\varOmega d{\bar{\varGamma }}= \int _{{\bar{\varGamma }}}\int _{\varGamma _{t2}} (\varvec{R}^*\circ \varvec{S}) \cdot \left( \sum _{k=1}^m \varvec{f}^k \circ \varvec{g}^k \right) d\varGamma d{\bar{\varGamma }}. \end{aligned}$$

Conversely, all the terms depending on \(\varvec{s}\) (load position) can be integrated over \({\bar{\varGamma }}\), leading to a generalized elastic problem to compute function \(\varvec{R}(\varvec{x})\).

3.3 Matrix Structure of the Problem

As stated before, see Eq. (3.3), the essential ingredient of PGD methods is to assume the variable (here, the displacement field) to be decomposed in the form of a finite sum of separable functions , i.e.,

$$\begin{aligned} \varvec{u}( \varvec{x},\varvec{s})= \sum _{i=1}^n \varvec{F}^i(\varvec{x}) \circ \varvec{G}^i(\varvec{s}), \end{aligned}$$

where a dependency on the physical position of the considered point, \(\varvec{x}\) and the position of the applied load, \(\varvec{s}\) is assumed.

In the implementation introduced in Sect. 3.4 below, we enforce functions \(\varvec{G}^i\) to have unity norm. By doing that, the weighting parameter \(\alpha _i\) (see Eq. (2.2) is not computed explicitly, but assumed to multiply the \(\varvec{F}^i\) functions (which, therefore, do not have unity norm).

As in the previous chapter, \(\varvec{F}^i(\varvec{x})\) and \(\varvec{G}^i(\varvec{s})\) are approximated by employing (linear in this case) finite elements, so that, at iteration n, the i-th sum of the approximation will be given by

$$\begin{aligned} \varvec{u}^h(\varvec{x}, \varvec{s}) = \sum _{i=1}^n \varvec{F}^i(\varvec{x}) \cdot \varvec{G}^i(\varvec{s}) = \sum _{i=1}^n \left[ \varvec{N}^T(\varvec{x}) \varvec{F}^i \varvec{M}^T (\varvec{s}) \varvec{G}^i \right] , \end{aligned}$$

with \(\varvec{N}\) and \(\varvec{M}\) the vectors containing the finite element shape functions defined in each separated space and \(\varvec{F}^i\) and \(\varvec{G}^i\) the vectors of nodal values at the FE mesh for the functions \(\varvec{F}^i(\varvec{x})\) and \(\varvec{G}^i(\varvec{s})\), respectively. For simplicity and ease of reading, we have maintained the same notation employed in Eq. (2.8). The superscript h for the discrete, finite element approximation of a variable will no longer be employed, for clarity, if there is no risk of confusion.

The code included below solves the problem of a two-dimensional cantilever beam under a load placed at an arbitrary position along its upper face. Therefore, we assume a 2D spatial approximation on \(\varvec{x}\) (given by simple linear triangular elements) and 1D approximation for the \(\varvec{s}\) direction.

When we look for a new couple of functions in the approximation, we assume that

$$\begin{aligned} \varvec{u}^{n+1}(\varvec{x}, \varvec{s}) = \varvec{u}^{n}(\varvec{x}, \varvec{s})+ \varvec{R}(\varvec{x}) \varvec{S}(\varvec{s}) = \sum _{i=1}^n \varvec{F}^{i}(\varvec{x}) \varvec{G}^i(\varvec{s}) + \varvec{R}(\varvec{x}) \varvec{S}(\varvec{s}), \end{aligned}$$
(3.5)

while

$$\begin{aligned} \varvec{u}^*(\varvec{x}, \varvec{s})= \varvec{R}^*(\varvec{x})\varvec{S}(\varvec{s})+ \varvec{R}(\varvec{x})\varvec{S}^*(\varvec{s}). \end{aligned}$$

Very often, in parametric problems (like in this example) the derivatives appearing in the weak form of the problem, given by Eq. (3.4), are acting only spatial coordinates and not on the parameters, despite that in the PGD framework they are considered as actual “extra” coordinates. Therefore,

$$\begin{aligned} \varvec{\nabla }_s \varvec{u}&= \varvec{\nabla }_s \left[ \sum _{i=1}^n \varvec{F}^i(\varvec{x}) \cdot \varvec{G}^i(\varvec{s}) \right] + \varvec{\nabla }_s \left[ \varvec{R}(\varvec{x}) \cdot \varvec{S}(\varvec{s}) \right] = \sum _{i=1}^n \left[ \varvec{\nabla }_s \varvec{F}^i(\varvec{x}) \right] \cdot \varvec{G}^i(\varvec{s}) + \left[ \varvec{\nabla }_s \varvec{R}(\varvec{x}) \right] \cdot \varvec{S}(\varvec{s}) \\&= \sum _{i=1}^n \left[ \varvec{\nabla }_s \varvec{N}^T(\varvec{x}) \varvec{F}^i \right] \cdot \varvec{M}^T (\varvec{s}) \varvec{G}^i + \left[ \varvec{\nabla }_s \varvec{N}^T(\varvec{x}) \varvec{R} \right] \cdot \varvec{M}^T (\varvec{s}) \varvec{S}. \end{aligned}$$

The terms defined before and depending on nodal values \(\varvec{F}_i\) and \(\varvec{G}_i\) (i.e., those corresponding to the already computed \(\varvec{u}^n\) approximation) are known, so they should be moved to the right-hand side of the final algebraic equation.

In a similar way,

$$\begin{aligned} \varvec{\nabla }_s \varvec{u}^* = \varvec{\nabla }_s \varvec{N}^T(\varvec{x}) \varvec{R} \cdot \varvec{M}^T (\varvec{s}) \varvec{S}^* + \varvec{\nabla }_s \varvec{N}^T(\varvec{x}) \varvec{R}^* \cdot \varvec{M}^T (\varvec{s}) \varvec{S}. \end{aligned}$$

The L.H.S. of the weak form, Eq. (3.4), can be easily expressed in separated form,

$$\begin{aligned}&\int _{{\bar{\varGamma }}}\int _\varOmega \varvec{\nabla }_s \varvec{u}^*:\varvec{\mathsf C} :\varvec{\nabla }_s \varvec{R}(\varvec{x}) \varvec{S}(\varvec{s}) d\varOmega d{\bar{\varGamma }}\nonumber \\&= \int _\varOmega \varvec{R}^T \varvec{\nabla }_s \varvec{N}(\varvec{x}) :\varvec{\mathsf C} :\varvec{\nabla }_s \varvec{N}^T(\varvec{x}) \varvec{R} d\varOmega \cdot \int _{{\bar{\varGamma }}} \varvec{S^*}^T \varvec{M} (\varvec{s}) \varvec{M}^T (\varvec{s}) \varvec{S} d{\bar{\varGamma }} \nonumber \\&\quad + \int _\varOmega \varvec{R^*}^T \varvec{\nabla }_s \varvec{N}(\varvec{x}) :\varvec{\mathsf C} :\varvec{\nabla }_s \varvec{N}^T(\varvec{x}) \varvec{R} d\varOmega \cdot \int _{{\bar{\varGamma }}} \varvec{S}^T \varvec{M} (\varvec{s}) \varvec{M}^T (\varvec{s}) \varvec{S} d{\bar{\varGamma }} \end{aligned}$$
(3.6)

Since \(\varvec{R}\) and \(\varvec{S}\) represent vectors of nodal values for functions \(\varvec{R}(\varvec{x})\) and \( \varvec{S}(\varvec{s})\), respectively, they can be extracted from the integrals in Eq. (3.6), so as to give,

$$\begin{aligned}&\int _{{\bar{\varGamma }}}\int _\varOmega \varvec{\nabla }_s \varvec{u}^*:\varvec{\mathsf C} :\varvec{\nabla }_s \varvec{R}(\varvec{x}) \varvec{S}(\varvec{s}) d\varOmega d{\bar{\varGamma }}\nonumber \\&= \varvec{R}^T \left[ \int _\varOmega \varvec{\nabla }_s \varvec{N}(\varvec{x}) :\varvec{\mathsf C} :\varvec{\nabla }_s \varvec{N}^T(\varvec{x}) d\varOmega \right] \varvec{R} \cdot \varvec{S^*}^T \left[ \int _{{\bar{\varGamma }}} \varvec{M} (\varvec{s}) \varvec{M}^T (\varvec{s}) \right] \varvec{S} d{\bar{\varGamma }} \nonumber \\&\quad + \varvec{R^*}^T \left[ \int _\varOmega \varvec{\nabla }_s \varvec{N}(\varvec{x}) :\varvec{\mathsf C} :\varvec{\nabla }_s \varvec{N}^T(\varvec{x}) d\varOmega \right] \varvec{R} \cdot \varvec{S}^T \left[ \int _{{\bar{\varGamma }}} \varvec{M} (\varvec{s}) \varvec{M}^T (\varvec{s}) d{\bar{\varGamma }} \right] \varvec{S} \nonumber \\&= \varvec{R}^T \varvec{K1}(\varvec{x}) \varvec{R} \cdot \varvec{S^*}^T \varvec{M2}(\varvec{s}) \varvec{S} + \varvec{R^*}^T \varvec{K1}(\varvec{x}) \varvec{R} \cdot \varvec{S}^T \varvec{M2}(\varvec{s}) \varvec{S} \nonumber \\ \end{aligned}$$
(3.7)

where \(\varvec{K1}(\varvec{x})\) represents a sort of stiffness matrix on the spatial coordinates \(\varvec{x}\), while \(\varvec{M2}(\varvec{s})\) represents a mass matrix for the 1D discretization problem in the \(\varvec{s}\) variable. Both of them are computed in routine elemstiff (see the call [K1,M2] = elemstiff(coors) in the main file of the code in Sect. 3.4).

We proceed similarly for the RHS term of the weak form, Eq. (3.4), and taking into account that the integrals involved in it do not depend on spatial coordinates, but only on the \(\varvec{s}\) coordinate, we arrive at

$$\begin{aligned} \int _{{\bar{\varGamma }}}\int _{\varGamma _{t2}} \varvec{u}^*\cdot \varvec{t} d\varGamma d{\bar{\varGamma }}&= \int _{{\bar{\varGamma }}}\int _{\varGamma _{t2}} \left[ \varvec{R}^*(\varvec{x})\varvec{S}(\varvec{s})+ \varvec{R}(\varvec{x})\varvec{S}^*(\varvec{s}) \right] \cdot \left[ \sum _{i=1}^m \varvec{f}^i(\varvec{x}) \varvec{g}^i (\varvec{s}) \right] d\varGamma d{\bar{\varGamma }} \nonumber \\&= \int _{\varGamma _{t2}} \sum _{i=1}^m \varvec{R}^*(\varvec{x}) \varvec{f}^i(\varvec{x}) \int _{\bar{\varGamma }} \varvec{S}(\varvec{s}) \varvec{g}^i (\varvec{s}) d{\bar{\varGamma }} + \int _{\varGamma _{t2}}\sum _{i=1}^m \varvec{R}(\varvec{x}) \varvec{f}^i(\varvec{x}) \int _{\bar{\varGamma }} \varvec{S}^*(\varvec{s}) \varvec{g}^i (\varvec{s}) d{\bar{\varGamma }} . \end{aligned}$$
(3.8)

Denoting by \(\varvec{FR1}\) the nodal values of the source term decomposition for the spatial variables and by \(\varvec{FR2}\) for the load direction, Eq. (3.8) has the form,

$$\begin{aligned} \sum _{i=1}^m \varvec{R^*}^T \varvec{FR1} \cdot \varvec{S}^T \left[ \int _{{\bar{\varGamma }}} \varvec{M}(\varvec{s}) \varvec{M}^T(\varvec{s}) \varvec{d}{\bar{\varGamma }} \right] \varvec{FR2} + \sum _{i=1}^m \varvec{R}^T \varvec{FR1} \cdot \varvec{S^*}^T \left[ \int _{{\bar{\varGamma }}} \varvec{M}(\varvec{s}) \varvec{M}^T(\varvec{s}) \varvec{d}{\bar{\varGamma }} \right] \varvec{FR2}. \end{aligned}$$
(3.9)

As discussed in the introduction to this chapter, the problem of expressing the moving load as a finite sum of separable functions, i.e., \(\varvec{t} (\varvec{x}, \varvec{s})\approx \sum _{i=1}^m \varvec{f}^i(\varvec{x}) \varvec{g}^i(\varvec{s})\) is not separable. In other words, it can only be done in the discrete setting by choosing \(\varvec{FR1}\) to be a matrix of zeros (of size [# dof of the whole problem \(\times \) dof along the loaded boundary] and whose only non-vanishing entries are, for each column, the position of nodes that can receive a load. These entries will be equal to the value of the applied force. Respectively, \(\varvec{FR2}\) will be an identity matrix (eye(# dof along the loaded boundary) in Matlab terms). Each column in \(\varvec{FR1}\) thus includes the corresponding degree of freedom that is loaded. Note that, therefore,

$$\begin{aligned} \sum _{i=1}^m \varvec{f}^i(\varvec{x}) \varvec{g}^i (\varvec{s}) = \sum _{i=1}^m \varvec{N}(\varvec{x}) \varvec{FR1}^i \cdot \varvec{M} (\varvec{s}) \varvec{FR2}^i. \end{aligned}$$

To this R.H.S. vector we should add the terms related to the known solution up to iteration n, \(\varvec{u}^n(\varvec{x}, \varvec{s})\), Eq. (3.5),

$$\begin{aligned}&\int _{{\bar{\varGamma }}}\int _\varOmega \varvec{\nabla }_s \varvec{u}^*:\varvec{\mathsf C} :\varvec{\nabla }_s \varvec{u}^n d\varOmega d{\bar{\varGamma }}\nonumber \\&= \sum _{i=1}^n \varvec{R}^T \left[ \int _\varOmega \varvec{\nabla }_s \varvec{N}(\varvec{x}) :\varvec{\mathsf C} :\varvec{\nabla }_s \varvec{N}^T(\varvec{x}) d\varOmega \right] \varvec{F}^i \cdot \varvec{S^*}^T \left[ \int _{\bar{\varGamma }} \varvec{M} (\varvec{s}) \varvec{M}^T (\varvec{s}) \right] \varvec{G}^i d{\bar{\varGamma }} + \nonumber \\&\quad + \sum _{i=1}^n \varvec{R^*}^T \left[ \int _\varOmega \varvec{\nabla }_s \varvec{N}(\varvec{x}) :\varvec{\mathsf C} :\varvec{\nabla }_s \varvec{N}^T(\varvec{x}) d\varOmega \right] \varvec{F}^i \cdot \varvec{S}^T \left[ \int _{{\bar{\varGamma }}} \varvec{M} (\varvec{s}) \varvec{M}^T (\varvec{s}) d{\bar{\varGamma }} \right] \varvec{G}^i \nonumber \\&= \sum _{i=1}^n \varvec{R}^T \varvec{K1}(\varvec{x}) \varvec{F}^i \cdot \varvec{S^*}^T \varvec{M2}(\varvec{s}) \varvec{G}^i + \sum _{i=1}^n \varvec{R^*}^T \varvec{K1}(\varvec{x}) \varvec{F}^i \cdot \varvec{S}^T \varvec{M2}(\varvec{s}) \varvec{G}^i . \end{aligned}$$
(3.10)

In the Matlab code included in Sect. 3.4 we are employing the following notation: \(\varvec{V1}^i = \varvec{FR1}^i\) and \(\varvec{V2}^i = \varvec{M2} (\varvec{s}) \varvec{FR2}^i\) for \(i=1, \ldots , m\), so that Eq. (3.9) is expressed in the form

$$\begin{aligned} \sum _{i=1}^m \varvec{R^*}^T \varvec{V1} \cdot \varvec{S}^T \varvec{V2} + \sum _{i=1}^m \varvec{R}^T \varvec{V1} \cdot \varvec{S^*}^T \varvec{V2}. \end{aligned}$$
(3.11)

After some gymnastics, the weak form, Eq. (3.4), taking into account Eqs. (3.7), (3.10) and (3.11), will look in matrix form like

$$\begin{aligned}&\varvec{R}^T \varvec{K1}(\varvec{x}) \varvec{R} \cdot \varvec{S^*}^T \varvec{M2}(\varvec{s}) \varvec{S} + \varvec{R^*}^T \varvec{K1}(\varvec{x}) \varvec{R} \cdot \varvec{S}^T \varvec{M2}(\varvec{s}) \varvec{S} = \nonumber \\&= \sum _{i=1}^m \varvec{R^*}^T \varvec{V1} \cdot \varvec{S}^T \varvec{V2} + \sum _{i=1}^m \varvec{R}^T \varvec{V1} \cdot \varvec{S^*}^T \varvec{V2} - \sum _{i=1}^n \varvec{R}^T \varvec{K1}(\varvec{x}) \varvec{F}^i \cdot \varvec{S^*}^T \varvec{M2}(\varvec{s}) \varvec{G}^i \\&\quad - \sum _{i=1}^n \varvec{R^*}^T \varvec{K1}(\varvec{x}) \varvec{F}^i \cdot \varvec{S}^T \varvec{M2}(\varvec{s}) \varvec{G}^i. \end{aligned}$$

As mentioned before, in order to determine the new functional pair \(\varvec{R}\) and \(\varvec{S}\), any linearization strategy could be envisaged. Remember that the fact that we look for a product of functions makes the problem of enriching the approximation non-linear. In the code of Sect. 3.4, a fixed-point algorithm in which functions \(\varvec{R}\) and \(\varvec{S}\) are sought iteratively is implemented. Other strategies, like Newton-Raphson, for instance, could work equally well.

The final matrix form of the fixed-point alternating directions algorithm, in which the computation of \(\varvec{S}(\varvec{s})\) is performed, assuming that \(\varvec{R}(\varvec{x})\) is known, will look like

$$\begin{aligned} \varvec{R}^T \varvec{K1}(\varvec{x}) \varvec{R} \cdot \varvec{S^*}^T \varvec{M2}(\varvec{s}) \varvec{S} = \sum _{i=1}^m \varvec{R}^T \varvec{V1} \cdot \varvec{S^*}^T \varvec{V2} - \sum _{i=1}^n \varvec{R}^T \varvec{K1}(\varvec{x}) \varvec{F}^i \cdot \varvec{S^*}^T \varvec{M2}(\varvec{s}) \varvec{G}^i . \end{aligned}$$
(3.12)

Equivalently, when we look for \(\varvec{R}(\varvec{x})\) assuming \(\varvec{S}(\varvec{s})\) is known, the resulting problem will have the following matrix form,

$$\begin{aligned} \varvec{R^*}^T \varvec{K1}(\varvec{x}) \varvec{R} \cdot \varvec{S}^T \varvec{M2}(\varvec{s}) \varvec{S} = \sum _{i=1}^m \varvec{R^*}^T \varvec{V1} \cdot \varvec{S}^T \varvec{V2} - \sum _{i=1}^n \varvec{R^*}^T \varvec{K1}(\varvec{x}) \varvec{F}^i \cdot \varvec{S}^T \varvec{M2}(\varvec{s}) \varvec{G}^i. \end{aligned}$$
(3.13)

In next section the detailed Matlab code implementing this strategy is provided.

3.4 Matlab Code for the Influence Line Problem

As always, the code begins at file main.m, whose content is reproduced below. It solves the problem of a cantilever beam under a load placed at an arbitrary location along its top boundary. Small strains assumption is made. The code provides the solution under plane stress or plane strain conditions.

figure a

As in Chap. 2, what we call stiffness and mass matrices are computed in function elemstiff.m:

figure b

The enrichment procedure, i.e., the computation of a new functional pair \(\varvec{R}\), \(\varvec{S}\), is detailed in function enrichment.m:

figure c

The code makes use of a traditional, two-dimensional FEM code, whose structure is reproduced below. In fact, it returns the stiffness matrix \(\varvec{K}\) typical of these FEM programs.

figure d

Once executed, the code allows the user to choose interactively with the mouse the point in which the load is applied. It is implemented in an off-line/on-line approach , such that the modes (functional pairs) approximating the solution are first computed and (eventually) stored in memory. Then, in the on-line phase, the user can interactively play with the position of the load and see in real time the deformed configuration of the solid.

At a first instance, the mesh of the problem is shown, see Fig. 3.4. By clicking on it, the user can choose the particular placement of the load. The program gives immediately the deformed configuration of the beam, see Fig. 3.5.

Fig. 3.4
figure 4

Mesh for the moving load problem

Fig. 3.5
figure 5

Once a point along the upper side of the beam has been chosen, the problem depicts the deformed configuration of the beam

Note that by simply typing on the Matlab command line the instruction trisurf(triangles.ConnectivityList,coords(:,1),coords(:,2),F(1:2:end,1)), the first spatial mode of the solution, namely \(\varvec{F}^1(\varvec{x})\) is represented, see Fig. 3.6. Equivalently, by typing plot(G(:,1)) the load modes \(\varvec{G}^i(\varvec{s})\) can be plotted, see Fig. 3.7. Notice the increasing frequency content of the modes in the load variable.

Fig. 3.6
figure 6

Spatial modes \(\varvec{F}^i(\varvec{x})\), \(i= 1, 2, 3\) and 11. The magnitude of each mode is represented in the vertical axis

Fig. 3.7
figure 7

Load modes \(\varvec{G}^i(\varvec{s})\), \(i= 1, 2, 3\) and 11. Node labels refer to the relative position along the upper boundary of the beam

This algorithm has revealed to be very powerful. In fact, it is essentially the same employed to construct our virtual surgery simulator, see Fig. 3.8, able to provide response feedback in the order of kHz, thus amenable to be employed in haptic environments [56, 57] .

Fig. 3.8
figure 8

A virtual surgery simulator based on the same algorithm explained in this chapter