(sect:helmholtzlinearsolver)=
# Frequency response linear solver

This section is about using the Helmholtz linear solver. The reader is
assumed to be familiar with all the other documentation. Iterative
linear solvers for some other types of problems are discussed in Section
{numref}`%s <sect:linearsolver>`. At this time using `solver_tol` below
the default value is not recommended due to observed inconsistencies
suggesting that the wrong answer can be returned to the user. Clarifying
this issue has a low priority at this time.

**Insufficient virtual memory problems.** If insufficient memory
problems arise, users must determine their cause and explain them. This
is difficult.

Zeroing out `orthogH` conserves memory. Note that the Helmholtz linear
solver is less mature than some other parts of GDSW. I have noticed in
the past that setting `krylov_methodH` to $1$ changed `orthogH` to
$1000$ (of course $1000$ is the default value of `orthog` and $20$ is
the documented default value of `orthogH`). The Sierra/SD parser has
default value $0$ for `orthogH`. It is necessary to monitor the value
reported for `orthogH` in `dd_solver.dat`.

Experiments with alternative mesh partitioners have been surprisingly
productive for structures.

`precision_option_O` single conserves memory in theory, but in practice
it has been problematic. It would help to use it with Flexible GMRES.
Note that Flexible GMRES may interact with `orthogH` like
`krylov_methodH`.

**Divergence problems.** Address divergence either by adjusting the
preconditioner configuration parameters or by increasing the magnitude
of the damping matrix. The former has the disadvantage that there are
many parameters. Given time the variety of parameters exposed to the
user will decrease. The latter has the disadvantage that it can change
the solution.

Determining how much damping to use is beyond the scope of this note. If
the response is independent of the damping, then there is not too much
damping. The case of slight increases in the response due to the damping
are less clear.

Configuring the preconditioner may involve trial and error. One approach
is `useParallelDirectSolver` `yes`. As long as there is enough memory
available, the parallel direct solver will almost surely work.

The remainder of these notes concern the trial and error approach to
configuring the preconditioner. Start by decreasing the preconditioner
update frequency, despite the computational cost.

Increasing the number of levels of overlap may help, particularly with
shell elements. There is a theoretical explanation for this.

`Structural_damping` and `viscous_damping` apply to the custom and the
operator preconditioners. A formula for the dependence of the
preconditioner on these parameters appears in the documentation. The
code probably uses this formula. There are two important things to know
here. First: these parameters have nothing to do with the damping
matrix, and only change the preconditioner. The default values of the
structural and viscous damping are respectively $12/100$ and $0$.
Second: sometimes, changing (usually but not always increasing) the
structural damping improves the preconditioner (decreases iterations and
decreases overall time to solution).

The previous `max_previous_sols` solutions determine an initial guess
for the current linear system. The default is zero. I do not know the
default initial guess. If max previous sols is positive, then the
initial guess is effective.

The Krylov subspaces generated to solve the initial linear systems are
applied to the remaining linear systems. Only the first `orthogH` Krylov
vectors are used. In several studies, the value $100$ has proved
optimal.

`cull` `method` `eigen` is in theory the best way to refresh the Krylov
vectors, but in my experience it has never helped.

`SC_optionH` `yes` helps less often than the default, no, but is worth
trying. It is particularly important to type this option correctly. A
similar option for other types of linear systems, `SC_option`, is
silently ignored for direct frequency response problems.

Preconditioner effectiveness may vary with both input frequency and the
number of MPI ranks. Subdomain diameter is inversely proportional to the
cube root of the number of MPI ranks. Subdomain mode shape wavelength is
proportional to subdomain diameter, and frequency is inversely
proportional to wavelength. For these reasons increasing the number of
MPI ranks can improve simulation reliability at higher frequencies. My
observations are consistent with this prediction. For the same reason at
a fixed low number of MPI ranks, as the frequency increases, the
effectiveness of the coarse grid correction within the preconditioner
may deteriorate. Such deterioration theoretically may be mitigated by
setting the `coarse_option` to the non default value `none`. Due to
software defects, this strategy only became an option recently (9/2020).
However, this strategy has not helped so far.
