Three **DAEPACK** code generation components are described below. A small FORTRAN model of an electrical circuit is used to illustrate the code that is automatically generated. This example is purposefully small so that the reader can readily compare the original model and the generated code. Larger examples can be found in the Examples Page.

All of the generated code make calls to a variety of utility subroutines. These subroutines are contained in the **DAEPACK Utility Library** (daepack.a) which must be linked into the

executable using the generated code.

#### Sparsity pattern

This component constructs new code that determines the sparsity pattern of a given system of equations represented by the FORTRAN code. Although, the code in this example is simply a single subroutine containing a set of assignments, the **DAEPACK** component can be applied to far more complicated code which may include nested iterations and other sophisticated solution algorithms in addition to assignments. In order to generated the sparsity pattern code, the user must specify the independent and dependent variables. This specification can be done through a GUI or using preprocessor directives. In this case, the independent and dependent variables are specified using the preprocessor directives:

`!!independent { w, wdot }``!!dependent { delta } `

Since the generated code constructs the sparsity pattern as the model is evaluated, the resulting sparsity pattern depends on the program arguments. Thus, if the model is discontinuous (e.g., contains `IF` equations, `MIN`/`MAX` functions, etc.), the sparsity pattern will correspond to the correct set of equations.

The generated code can be examined by following the link below.

This new subroutine returns the the sparsity pattern of the model equations in the integer vectors `zzzirn` and `zzzjcn` (as row and column numbers of the incidence matrix) and the total number of nonzero entries in `zzzne`, in addition to the values of the dependent variables.

#### Discontinuity locking

This component constructs new code which extracts the *hidden discontinuities* from the model equations (in the form of discontinuity functions) and augments the original code so that the user may perform a *locked* residual evaluations.

During a normal execution, the code follows a path defined by the current values of the program inputs (e.g., subroutine arguments, contents read from a data file, etc.). Using the discontinuity-locking component, the user locks the model into a particular discrete mode defined by the current values of all of the inputs. During subsequent locked model evaluations, the same discrete mode is evaluated regardless of the current values of the inputs. This capability, along with the extraction of discontinuity functions, allows sophisticated *state event location* algorithms to be employed in the solution of hybrid discrete/continuous simulation and parametric senstivity calculation (see description of **DAEPACK** component DSL48E).

The generated code can be examined by following the link below.

More information about discontinuity functions and state event location can be found in the DSL48E Manual.

#### Automatic differentiation

Numerical derivatives are required by a large number of numerical calculations. Some examples include the solution of nonlinear algebraic equations using Newton's method, numerical integration of stiff ODEs and DAEs, many nonlinear optimization algorithms, and dynamic parametric sensitivity calculation. Furthermore, the performance of many of these calculations is often dramatically

improved using accurate partial derivatives obtained efficiently.

Automatic differentiation is a well established technology that can be used to obtain partial derivatives from FORTRAN code. The **DAEPACK** component which generates derivative code uses a modified forward mode (similar to that used by ADIFOR) with sparse accumulation of gradient vectors. As with the sparsity pattern generator, all the user must specify are the independent and dependent variables. The resulting code can be examined by following the link below.

As stated above, the current approach used by **DAEPACK** for generating derivatives uses a modified forward mode (assignment adjoints are computed with the reverse mode while using the forward mode for the overall accumulation) with sparse accumulation of gradient vectors. Current work involves implementation of a hybrid forward and reverse mode and other approaches for derivative evaluation. In addition, derivative evaluations will be optimized for the numeric components provided by **DAEPACK**.