STAAD.Pro Physical Modeler Help

To add a custom circular tank template

This tutorial demonstrates how to add a custom template to the Structure Wizard in STAAD.Pro Physical Modeler. In particular, this short template demonstrates how to create a circular water tank template.

This will take you step-by-step through the process of creating a template for a circular tank template for use in the Structure Wizard. The full XML code is at the end of this topic and can be copy & pasted as a single set and saved into a .template.xml file to use or distribute. This can be included in your Structure Wizard.
  1. Make a copy of one of the existing two templates in the Structure Wizard and rename it to Circular Tank.
    Note: This can be placed in a new folder or the existing Tanks folder, based on how you choose to organize your templates.
  2. Select the new template and then click the Edit Template tool in the File group in the ribbon tab. The XML contents of the template are displayed in a Document Editor tab.
  3. Select the full contents of the Document Editor and press <Delete>. You will be writing this template from scratch, but starting with an existing template is a good way to start any new XML template.
  4. Type or paste the following framework elements within the XML template:
    <Template Name="Circular Tank">
    	<Variables>	
    	</Variables>
    	<Model>
    	</Model>
    </Template>
    Tip: XML is case-sensitive, so be careful to use the punctuation as noted in this example and in the XML schema documentation.
  5. Click the Save tool in the File group on the ribbon tab. Notice that the Properties panel indicates the model contains errors. This is because there are no values for the template yet.
  6. Within the Variables element, add a new element "Group" with "Input" child elements which have attributes as follows:
    <Group Name="Geometry" >
    	<Input Name="n" Description="Number of facets" Type="Int" Minimum="3" Default="36" />
    	<Input Name="d" Description="Diameter" Type="Quantity" DataType="Length" Minimum="0 m" Default="8m" />
    	<Input Name="h" Description="Height of walls" Type="Quantity" DataType="Length" Minimum="0 m" Default="4.5 m" />
    	<Input Name="bt" Description="Base thickness" Type="Quantity" DataType="SectionDimension" Minimum="0 mm" Default="400 mm" />
    	<Input Name="wt" Description="Walls thickness" Type="Quantity" DataType="SectionDimension" Minimum="0 mm" Default="300 mm" />
    	<Input Name="Material" Description="Material" Type="Material" />
    </Group>
    This adds user input parameters with the user-interface labels from the Description. Further, this provides value types, ranges, and default values for the fields.
    Note: The Material input type is used to select from the current physical model's material catalog. Just as with other template types, this drop-down list is populated only when materials have been added to the model.
    Note that the error message has disappeared and there are now several places for user input within a Geometry group.
  7. Within the Model element, add a new "Loop" element with a child element "Node" which have attributes as follows:
    <!-- Nodes -->
    <Loop Variable="i" Start="0" End="n-1">
    	<Node ID="1+2*i" X="d/2*Cos(Radians(360/n*i))" Z="d/2*Sin(Radians(360/n*i))" />
    	<Node ID="2+2*i" X="d/2*Cos(Radians(360/n*i))" Y="h" Z="d/2*Sin(Radians(360/n*i))" />
    </Loop>

    This adds a looping command which will generate nodes along the base and top of the tank outer wall.

    Tip: The use of the XML comment helps to annotate your code for others as well as for your own future reference.
    Note: The values of the ID, X, Y, and Z attributes are all formulas. The inputs of n (number of facets), d (tank diameter), and h (wall height) are used to calculate the coordinates. The loop counter variable, i, is used in formulas to increment the node ID values.
  8. Next, within the Model element, add a "Surface" element containing a loop to generate a surface for the base and assign the surface nodes to the surface ID:
    <!-- Base -->
    <Surface ID="1" Thickness="bt" Material="Material" Attribute="SLAB_TANK" Alignment="Bottom">
    	<Loop Variable="i" Start="0" End="n-1">
    		<Node ID="1+2*i" />
    	</Loop>
    </Surface>

    Notice that this loop uses the same formula for the ID attribute as the node generation did in the previous step. This will then use the same node IDs for the base surface object.

  9. Similarly, within the Model element following the base generation Surface, add a Surface element within a Loop in order to generate the wall around the tank:
    <!-- Walls -->
    <Loop Variable="i" Start="0" End="n-1">
    	<Surface ID="i+2" Thickness="wt" Material="Material" Attribute="WALL_TANK">
    		<Node ID="1+2*i" />
    		<Node ID="2+2*i" />
    		<Node ID="2+2*((i+1)%n)" />
    		<Node ID="1+2*((i+1)%n)" />
    	</Surface>
    </Loop>

    This loops through each of the surface IDs (using a loop counter variable) and assigns the vertex node IDs to each corner based on the formulas demonstrated below:

  10. Next add the supports. This is done in a couple of sub-steps; one to capture the user input and another to generate the
    1. Within the Input section, add a new Group which contains the user input parameters needed for the supports.
      <Group Name="Supports" >
      	<Input Name="allowTensile" Description="Allow tensile forces" Type="Bool" Default="false" />
      	<Input Name="soilMod" Description="Soil modulus" Type="Quantity" DataType="SubgradeModulus" Minimum="0 kN/m2/m" Default="80000 kN/m2/m" />
      </Group>

      The use of the Group element becomes a bit more evident here once you save these changes, as a new category of template input appears. The "Bool" type of Input is used to create a check box option.

    2. Next, following the Surface elements within the Model element, add the following code to generate supports:
      <!-- Base Support -->
      <Property Element="Surface" ID="1" Name="SupportDirection" Value="Y" />
      <Property Element="Surface" ID="1" Name="MatSubgradeModulus" Value="soilMod" />
      <If Condition="Not allowTensile">
      	<Then>
      		<Property Element="Surface" ID="1" Name="MatAxialBehaviour" Value="CompressionOnly" />
      	</Then>
      </If>

      This assigns the support and soil modulus values to the Surface using multiple Property elements. The "If / Then" statement is used to assign a compression only attribute to the base surface if the user has selected to not allow for tensile force.

  11. You will now add loads to the circular tank template. Similar to supports, this takes multiple steps as the template needs user input, to establish a load case, and then to generate the hydrostatic load on the wall and base surfaces.
    1. Within the Input section, add a new Group which contains the user input parameters needed for the fluid density and height.
      <Group Name="Loading" >
      	<Input Name="fluidUW" Description="Fluid density" Type="Quantity" DataType="Density" Minimum="0 kg/m3" Default="1000 kg/m3" />
      	<Input Name="compFluidH" Description="Compartment fluid height" Type="Quantity" DataType="Length" Default="3.75 m" />
      </Group>
    2. Next, following the support properties, add the following code to specify the load case:
      <!-- Load Case -->
      <LoadCase ID="1" Name="Fluid" Description="Fluid" Type="Staad_Fluids" />
      Tip: The load case attributes are all "hard coded" in this example in this "LoadCase" element's attributes, but you can also take user input for the Name and use that variable value here.
    3. Following the load case code, add the following code to specify the hydrostatic loads on the surfaces:
      <!-- Hydrostatic Load -->
      <Hydrostatic Y="compFluidH" Density="fluidUW" LoadConditionID="1">
      	<Polygon>
      		<Loop Variable="i" Start="0" End="n-1">
      			<Point X="d/2*Cos(Radians(360/n*i))" Z="d/2*Sin(Radians(360/n*i))" />
      		</Loop>
      	</Polygon>
      	<Surface ID="1" />
      	<Loop Variable="i" Start="0" End="n-1">
      		<Surface ID="i+2" />
      	</Loop>
      </Hydrostatic>

      This section specifies the hydrostatic load in the load case using the user input values using a "Hydrostatic" element. Further, the "Polygon" elements generate the values to determine the shape of the loading pattern. Lastly, the surface IDs are specified, with the wall surfaces being specified within a Loop.

  12. Finally, save your template and then close the Document Editor tab.
You now have a circular tank template which you can use to parametrically model such a tank.

Completed Code

The complete XML template is as follows:

<Template Name="Circular Tank">
	<Variables>
		<Group Name="Geometry" >
			<Input Name="n" Description="Number of facets" Type="Int" Minimum="3" Default="36" />
			<Input Name="d" Description="Diameter" Type="Quantity" DataType="Length" Minimum="0 m" Default="8m" />
			<Input Name="h" Description="Height of walls" Type="Quantity" DataType="Length" Minimum="0 m" Default="4.5 m" />
			<Input Name="bt" Description="Base thickness" Type="Quantity" DataType="SectionDimension" Minimum="0 mm" Default="400 mm" />
			<Input Name="wt" Description="Walls thickness" Type="Quantity" DataType="SectionDimension" Minimum="0 mm" Default="300 mm" />
			<Input Name="Material" Description="Material" Type="Material" />
		</Group>
		<Group Name="Supports" >
			<Input Name="allowTensile" Description="Allow tensile forces" Type="Bool" Default="false" />
			<Input Name="soilMod" Description="Soil modulus" Type="Quantity" DataType="SubgradeModulus" Minimum="0 kN/m2/m" Default="80000 kN/m2/m" />
		</Group>
		<Group Name="Loading" >
			<Input Name="fluidUW" Description="Fluid density" Type="Quantity" DataType="Density" Minimum="0 kg/m3" Default="1000 kg/m3" />
			<Input Name="compFluidH" Description="Compartment fluid height" Type="Quantity" DataType="Length" Default="3.75 m" />
		</Group>
	</Variables>
	<Model>

		<!-- Nodes -->
		<Loop Variable="i" Start="0" End="n-1">
			<Node ID="1+2*i" X="d/2*Cos(Radians(360/n*i))" Z="d/2*Sin(Radians(360/n*i))" />
			<Node ID="2+2*i" X="d/2*Cos(Radians(360/n*i))" Y="h" Z="d/2*Sin(Radians(360/n*i))" />
		</Loop>

		<!-- Base -->
		<Surface ID="1" Thickness="bt" Material="Material" Attribute="SLAB_TANK" Alignment="Bottom">
			<Loop Variable="i" Start="0" End="n-1">
				<Node ID="1+2*i" />
			</Loop>
		</Surface>

		<!-- Walls -->
		<Loop Variable="i" Start="0" End="n-1">
			<Surface ID="i+2" Thickness="wt" Material="Material" Attribute="WALL_TANK">
				<Node ID="1+2*i" />
				<Node ID="2+2*i" />
				<Node ID="2+2*((i+1)%n)" />
				<Node ID="1+2*((i+1)%n)" />
			</Surface>
		</Loop>

		<!-- Base Support -->
		<Property Element="Surface" ID="1" Name="SupportDirection" Value="Y" />
		<Property Element="Surface" ID="1" Name="MatSubgradeModulus" Value="soilMod" />
		<If Condition="Not allowTensile">
			<Then>
				<Property Element="Surface" ID="1" Name="MatAxialBehaviour" Value="CompressionOnly" />
			</Then>
		</If>

		<!-- Load Case -->
		<LoadCase ID="1" Name="Fluid" Description="Fluid" Type="Staad_Fluids" />

		<!-- Hydrostatic Load -->
		<Hydrostatic Y="compFluidH" Density="fluidUW" LoadConditionID="1">
			<Polygon>
				<Loop Variable="i" Start="0" End="n-1">
					<Point X="d/2*Cos(Radians(360/n*i))" Z="d/2*Sin(Radians(360/n*i))" />
				</Loop>
			</Polygon>
			<Surface ID="1" />
			<Loop Variable="i" Start="0" End="n-1">
				<Surface ID="i+2" />
			</Loop>
		</Hydrostatic>

	</Model>
</Template>