10.5. User Subroutine Library

Many user subroutines are used commonly and have been permanently incorporated into the code. These subroutines are used just like any other subroutines, but they do not need to be manually compiled into the code. (The user need be concerned only about the Sierra/SM command lines.) Additionally the subroutines listed here are regularly tested with Sierra/SM and formally maintained by the development team.

This section describes the usage of each of these user subroutine library subroutines.

10.5.1. aupst_preload_solver

Author: Nathan Crane

Note, use of the ‘aupst_preload_solver’ subroutine is also documented in the example manual chapter ‘Automated Adaptive Preloading.’

Purpose:

This subroutine is used to solve simple inverse problems for preload conditions determining the value of a working variable to achieve some target condition. Examples where this subroutine has been successfully used include: apply the target strain in bolts to yield specified clamping force in each bolt, find the force that must be applied to a pin to reach a target displacement in that pin, and to find the displacement at a fixture to yield a target contact force on a body.

There are a number of restrictions on the relations that can be effectively solved by this subroutine. The first is that the relationship is monotonic. For example adding more strain to bolt increases the clamping force. If the relationship is not monotonic the solution may stall at a local maximum. The second restriction is that the relationship is at least somewhat smooth. The relationship between changes in the working variable to the target condition does not need to be linear, but should be at least nominally \(C^0\) continuous. Third the relationship must be somewhat strong. Again as an example changing the artificial strain in a bolt strongly affects its clamping force.

The subroutine itself is generally called by a USER OUTPUT command block and often needs to be combined with a number of other commands as shown in this example:

#  Drive element preload as a variable set by
#  aupst_preload_solver subroutine
begin function bolt_preload
  type is analytic
  expression variable: v = element applied_strain
  evaluate expression = "v"
end
#  Internal variables needed by subroutine
begin user variable applied_strain
  type = element real length = 1
  use with restart
end
begin user variable bolt_preload_state
  type = element real length = 12
  use with restart
end
#  Use the 'working' variable to apply strain to bolt
begin artificial strain
  block = block_201
  r function = sierra_constant_function_zero
  s function = sierra_constant_function_zero
  t function = bolt_preload
end
#  Compute the currently obtained clamping force
#  on the bolt head.
begin user output
  surface = surface_200
  compute global bolt_force as sum of nodal force_contact(z)
end
# Solver for preload.  Update the working variable to try
# to make the target_variable equal to the target value
begin user output
  block = block_201
  subroutine real parameter:   target_value     = 1.0e+7
  subroutine real parameter:   initial_guess    = -3.06e-4
  subroutine real parameter:   iteration_time   = 5.0e-5
  subroutine string parameter: target_variable  = global bolt_force
  subroutine string parameter: working_variable = element applied_strain
  subroutine string parameter: state_variable   = element bolt_preload_state
  element block subroutine = aupst_preload_solver
  compute at every step
end

Parameters:

Table 10.27 Required aupst_preload_solver Parameters

Parameter Number

Type

Description

target_value

Real

The value that the target_variable is trying to reach. In this example the target clamping force in the bolt

initial_guess

Real

An initial guess for the working_variable. In this example the initial guess for artificial strain.

iteration_time

Real

Amount of analysis time each predictor-corrector iteration takes

target_variable

String

Type and name of the target_variable. In this example the current clamping force in the bolt as computed by the sum of contact force on the bolt head.

working_variable

String

Type and name of the working_variable. In this example the artificial strain magnitude applied to each element of the bolt

state_variable

String

Type and name of state variables used internally by the subroutine. State variable type must match working variable type.

The meaning of some of the parameters are shown visually in Fig. 10.2. For the bolt preload example the target artificial strain starts low and monotonically asymptotes up to the correct solution over several predictor corrector iteration cycles.

../../_images/bolt_preload_fig.png

Fig. 10.2 Example of preload iteration.

Subroutine Operation:

The subroutine drives a predictor correct iteration in time. Each predictor corrector cycle is performed over the input deck defined iteration_time. The step cycle is shown in Fig. 10.3 the value of the working variable produced by the subroutine is shown in blue and an example value of the response of the target variable shown in yellow. During the first and second quarter of the cycle the working variable is slowly increased from its old value to the new value. This ramp up is done with a smooth half cycloidal loading ramp. On the first cycle this new value will be half of the initial guess. During the third quarter of the cycle the working variable is held constant. Ideally damping terms will settle the value of the target variable to some relatively constant value during this time. In the fourth quarter of the load cycle the working variable is again held constant and the target variable is evaluated. The evaluation is the time average of the target variable over this fourth of the cycle time. Finally, at the end of the cycle, the new value for the next cycle working variable is defined based on the tangent of the response from the previous to the current iteration. The new working variable value is set such that the error in the target variable versus the target value will be roughly halved. This one half safety factor is used in an attempt to converge the solution monotonically from below. Additionally, regardless of the function tangent computed, the working variable can change by no more than the initial guess each iteration. This is an additional safety factor to prevent overshooting the solution.

It is important to consider that these predictor-corrector iterations only make sense if the target variable reaches a reasonably stable value by the fourth part of each iteration to make a reliable next prediction. For explicit transient dynamics these preload iterations should usually encompass several thousand time steps, but the actual number of steps needed may vary.

The preload solver subroutine will also operate with implicit statics (adagio). One consideration in this case is that each preload iteration cycle will take a minimum of three time steps: a ramp-up step, a hold step, and an evaluation step.

../../_images/preload_iteration_cycle.png

Fig. 10.3 Anatomy of the preload iteration cycle.

State Variables:

The subroutine state variables are used primarily for the internal operation of the subroutine. These variables can be also be post processed to understand how the subroutine is operating. The description of each variable is shown in the below Table Table 10.28. Depending on how the subroutine is used these state variables could be stored in a global variable or there could be a set of state variables at each node or element that is being loaded. The twelfth state variable, which indicates the current error in the preload solution can be particularly useful to look at.

Table 10.28 aupst_preload_solver Subroutine State Variables

State Number

Description

1

Start time of current preload iteration

2

End time of current preload iteration

3

Value of working variable at start of current preload iteration

4

Value of working variable at end of current preload iteration

5

Iteration Phase. 1=ramp up (1st and 2nd quarter), 2=hold (3rd quarter), 3=hold/evaluate (4th quarter)

6

Variables 6 and 7 are used to compute a running average of the target variable during the hold/evaluate phase

7

8

Initial (very first time) value of the working variable

9

Initial (very first time) value of the target variable

10

The time the subroutine was last evaluated

11

The target variable that was computed in the previous preload iteration

12

The relative solution error in target value versus variable error starts at 1.0 and ideally reaches 0.0

Usage Guidelines and Warnings:

Pay special care to the USE WITH RESTART and COMPUTE AT EVERY STEP commands present in the example input blocks. The USE WITH RESTART flag ensures the state variables are properly stored in any restart database ensuring the subroutine works correctly with a restart analysis. The COMPUTE AT EVERY STEP command ensures the preload solver correctly updates each an every step. Due to its presence in the USER OUTPUT command block without this command the preload solver would only evaluate at time steps where output is performed, likely yielding strange results in the analysis.

The iteration time must be long enough that the target variable can re-equilibrate to some relatively constant value in time in the target variable evaluation part of the cycle. The subroutine will compare previously found target variable values to current target variable values to make a new prediction for the working variable. If the target variable has a large dynamic oscillation that causes its value to change unrelated to the working variable change this prediction will be poor and the solver will not function correctly.

The analysis must run for enough time that a sufficient number of predictor corrector preload cycles are taken to converge the target variable to the target value. How many cycles are required will depend on how close the initial guess is. However, due to conservative assumptions in the solver usually at least 10 cycles will be required even if the initial guess is good.

This subroutine uses a simple predictor corrector approach and can only solve for conditions where the target versus working variable response is both monotonic and relatively smooth (i.e., at least \(C^0\) continuous).

It is strongly recommended that results be investigated both to ensure an acceptable error bound has been reached and that a reasonable history of the working variable was applied. For example greatly overshooting the target on the initial guess could cause spurious yield which would then be locked into the solution.

A few different combinations of variable types may be used. The working and state variable must be the same type. The target variable must be either a global or the same type as the working and state variables.

10.5.2. aupst_torque_calc

Author: Nathan Crane

Purpose:

This subroutine computes the net torque applied to a body by a set of forces. The torque is defined around an axis defined by two points. The output torque is given as a single value about this axis with a sign following the right hand rule. This subroutine is generally called by a USER OUTPUT command block. For example:

begin user output
  node set = nodelist_1
  compute global ns1 as average of nodal coordinates
end
begin user output
  node set = nodelist_2
  compute global ns2 as average of nodal coordinates
end
begin user variable moment1
  type = global real length = 1
  global operator = sum
end
begin user output
  surface = surface_1    #Contains nodes over which to do
                         # moment summation
  node set subroutine = aupst_torque_calc
  subroutine string parameter: axis_node_1 = ns1
  subroutine string parameter: axis_node_2 = ns2
  subroutine string parameter: force_field = reaction
  subroutine string parameter: output_var = moment1
end

Parameters:

Table 10.29 Required aupst_torque_calc Parameters

Parameter Name

Type

Description

axis_node_1

String

Name of global variable containing location of first axis node

axis_node_2

String

Name of global variable containing location of second axis node

force_field

String

Name of field containing force values to sum into the torque

output_var

String

Name of output global variable to store the computed moment

10.5.3. aupst_trans_rot_velocity

Author: Nathan Crane

Purpose:

This subroutine sets an initial velocity on a part that is the combination of an arbitrary rigid body spin rate superimposed on an arbitrary translational velocity. This subroutine is generally called by a INITIAL VELOCITY command block. For example:

begin initial velocity
   block = block_2
   node set subroutine = aupst_trans_rot_velocity
   subroutine real parameter: center_x = 0.0
   subroutine real parameter: center_y = 0.0
   subroutine real parameter: center_z = 2.0

   subroutine real parameter: rot_dir_x = 1.0
   subroutine real parameter: rot_dir_y = 1.0
   subroutine real parameter: rot_dir_z = 1.0

   subroutine real parameter: angular_velocity = 628.31853

   subroutine real parameter: tran_dir_x = 1.0
   subroutine real parameter: tran_dir_y = 1.0
   subroutine real parameter: tran_dir_z = 1.0

   subroutine real parameter: translational_velocity = 173.20508
 end

Parameters:

Table 10.30 Required aupst_trans_rot_velocity Parameters

Parameter Name

Type

Description

center_x, center_y, center_z

Real

Coordinates of center of rotation

rot_dir_x, rot_dir_y, rot_dir_z

Real

Direction of axis of rotation

tran_dir_x, tan_dir_y, tan_dir_z

Real

Direction of translational velocity

angular_velocity

Real

Spin rate in radians per time

translational_velocity

Real

translational velocity in distance per time

10.5.4. aupst_cyl_transform

Author: Nathan Crane

Purpose:

This subroutine transforms element stresses from a global rectangular coordinate system to a local cylindrical coordinate system. This subroutine is generally called by a USER OUTPUT command block. For example:

begin user output
  block = block_1
  element block subroutine = aupst_cyl_transform
  subroutine string parameter: origin_point = Point_O
  subroutine string parameter: z_point      = Point_Z
  subroutine string parameter: xz_point     = Point_XZ
  subroutine string parameter: input_stress = memb_stress
  subroutine string parameter: output_stress = cyl_stress
end user output

Requirements:

This subroutine requires a tensor variable to store the cylindrical stress into a variable for each element. The variable is created by the following command block in the Sierra/SM region:

begin user variable cyl_stress
   type = element sym_tensor length = 1
   initial value = 0.0 0.0 0.0 0.0 0.0 0.0
end user variable

Parameters:

Parameter Name

Usage

Description

origin_point

String

Name of the point at the cylinder origin.

z_point

String

Point on the cylinder axis.

xz_point

String

Point on the line that passes through theta = 0 on the cylinder.

input_stress

String

Name of the Sierra/SM internal input stress tensor variable.

output_stress

String

Name of the Sierra/SM internal output stress tensor variable.

10.5.5. aupst_rec_transform

Author: Daniel Hammerand

Purpose:

This subroutine transforms element stresses from a global rectangular coordinate system to a different local rectangular coordinate system. This subroutine is generally called by a USER OUTPUT command block. For example:

begin user output
  block = block_1
  element block subroutine = aupst_rec_transform
  subroutine string parameter: origin_point = Point_O
  subroutine string parameter: z_point      = Point_Z
  subroutine string parameter: xz_point     = Point_XZ
  subroutine string parameter: input_stress = memb_stress
  subroutine string parameter: output_stress = new_stress
end user output

Requirements:

This subroutine requires a tensor variable to store the new stress into a variable for each element. The variable is created by the following command block in the Sierra/SM region:

begin user variable new_stress
  type = element sym_tensor length = 1
  initial value = 0.0 0.0 0.0 0.0 0.0 0.0
end user variable

Parameters:

Parameter Name

Usage

Description

origin_point

String

Name of the point at the cylinder origin.

z_point

String

Point on the cylinder axis.

xz_point

String

Point on the line that passes through theta = 0 on the cylinder.

input_stress

String

Name of the Sierra/SM internal input stress tensor variable.

output_stress

String

Name of the Sierra/SM internal output stress tensor variable.

10.5.6. copy_data

Author: Jason Hales

Purpose:

This subroutine copies data from one variable to another with offsets given for both variables. This subroutine is generally called by a USER OUTPUT command block. For example:

begin user output
  block = block_1
  element block subroutine = copy_data
  subroutine integer parameter: source_offset = 4
  subroutine string parameter:  source_name = stress
  subroutine integer parameter: destination_offset = 1
  subroutine string parameter:  destination_name = uservarxy
end user output

Requirements:

This subroutine requires that the source and destination fields exist and have lengths at least as great as the values supplied as offsets. The fields used may be defined by the user as variables. In this example, the variable is created by the following command block in the Sierra/SM region:

begin user variable uservarxy
  type = element real length = 1
  initial value = 0.0
end user variable

Parameters:

Parameter Name

Usage

Description

source_offset

Integer

The offset into the source variable.

source_name

String

The name of the source variable.

destination_offset

Integer

The offset into the destination variable.

destination_name

String

The name of the destination variable.

10.5.7. trace

Author: Jason Hales

Purpose:

This subroutine computes the trace of a tensor. This subroutine is generally called by a USER OUTPUT command block. For example:

begin user output
  block = block_1
  element block subroutine = trace
  subroutine string parameter:  source_name = log_strain
  subroutine string parameter:  destination_name = uvarbulkstrain
end user output

Requirements:

This subroutine requires that the source and destination fields exist. The source field should have a length of six. The destination field should have a length of one. The destination field will typically be defined by the user as a variable. In this example, the variable is created by the following command block in the Sierra/SM region:

begin user variable uvarbulkstrain
  type = element real length = 1
  initial value = 0.0
end user variable

Parameters:

Parameter Name

Usage

Description

source_name

String

The name of the source variable.

destination_name

String

The name of the destination variable.

10.5.8. aupst_cavity_volume

Author: Nathan Crane

Purpose:

Compute the volume of an enclosed side set. This subroutine is generally called by a USER OUTPUT command block. For example:

begin user output
  SURFACE = surface_4000
  SURFACE SUBROUTINE = aupst_cavity_volume
  subroutine string parameter: outputVarName = s4000_vol

  SUBROUTINE REAL PARAMETER: cavitySymmetryPoint_x = 0.0
  SUBROUTINE REAL PARAMETER: cavitySymmetryPoint_y = 0.0
  SUBROUTINE REAL PARAMETER: cavitySymmetryPoint_z = 0.0
  SUBROUTINE REAL PARAMETER: volumeScale           = 2.0

  compute at every step
end

Availability:

Compiled into Adagio 4.24 and later.

Compatible with Presto 2.2 / Adagio 2.2 and later.

Parameters:

Name

Type

Description

outputVarName

String

Name of global variable in which to store the computed volume.

cavitySymmetryPoint_x

Real

Optional: X coordinate of a point on the intersection of all model symmetry planes. Needed if the cavity is not fully enclosed due to open symmetry planes.

cavitySymmetryPoint_y

Real

Optional: Y coordinate of a point on the intersection of all model symmetry planes. Needed if the cavity is not fully enclosed due to open symmetry planes.

cavitySymmetryPoint_z

Real

Optional: Z coordinate of a point on the intersection of all model symmetry planes. Needed if the cavity is not fully enclosed due to open symmetry planes.

volumeScale

Real

Optional: Value to multiple the final cavity volume by. Defaults to 1.0. May be used to adjust for symmetry boundary conditions.