Commit 23736b43 authored by Bob Obara's avatar Bob Obara

ENH:Initial Set of Workflows

parent 3555ef0f
<?xml version="1.0"?>
<cmb-resources>
<!-- Simulation attributes - augmented version of shallow water -->
<attribute id="simbuilder" role="template">
<SMTK_AttributeManager Version="1">
<Includes>
<File>AdHShallowWater.sbt</File>
</Includes>
</SMTK_AttributeManager>
</attribute>
<!-- Template for Shallow Water Export Dialog -->
<attribute id="export" role="template">
<SMTK_AttributeManager Version="1">
<Definitions>
<AttDef Type="ExportSpec" BaseType="" Version="0" Unique="true">
<ItemDefinitions>
<File Name="2DMeshFile" Label="Analysis Mesh File" Version="0" NumberOfRequiredValues="1"
ShouldExist="true"
FileFilters="2dm files (*.2dm);;All files (*.*)">
</File>
<File Name="HotStartFile" Label="Hot Start File" Version="0" NumberOfRequiredValues="1"
ShouldExist="true"
FileFilters="hot files (*.hot);;All files (*.*)">
</File>
<File Name="OutputFile" Label="Output boundary condition file (*.bc)"
Version="0" NumberOfRequiredValues="1"
FileFilters="BC files (*.bc);;All files (*.*)">
<BriefDescription>
Exporter will use same directory and base name for all output files.
</BriefDescription>
</File>
<!-- Advanced attributes -->
<String Name="AnalysisTypes" Label="Analysis Types" AdvanceLevel="99" Version="0"
Extensible="true" NumberOfRequiredValues="1"/>
<File Name="PythonScript" Label="Python script" AdvanceLevel="1" Version="0" NumberOfRequiredValues="1"
ShouldExist="true"
FileFilters="Python files (*.py);;All files (*.*)">
<DefaultValue>AdHShallowWater.py</DefaultValue>
</File>
<!--
<File Name="ExtrusionExecutable" Label="adh_2d_3d Executable" AdvanceLevel="1" Version="0" NumberOfRequiredValues="1"
AdvanceLevel="1" ShouldExist="true"
FileFilters="All files (*.*)">
<DefaultValue>adh_2d_3d</DefaultValue>
</File>
-->
</ItemDefinitions>
</AttDef>
</Definitions>
<Attributes />
<Views>
<InstancedView Title="ExportSpec" TopLevel="true">
<DefaultColor>1., 1., 0.5, 1.</DefaultColor>
<InvalidColor>1, 0.5, 0.5, 1</InvalidColor>
<AdvancedFontEffects Bold="0" Italic="0" />
<InstancedAttributes>
<Att Type="ExportSpec">Options</Att>
</InstancedAttributes>
</InstancedView>
</Views>
</SMTK_AttributeManager>
</attribute>
</cmb-resources>
#=============================================================================
#
# Copyright (c) Kitware, Inc.
# All rights reserved.
# See LICENSE.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even
# the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE. See the above copyright notice for more information.
#
#=============================================================================
"""
Export script for Shallow Water 3D applications
This script:
* First runs the *surface water* export script to generate 2D .bc files
* Then runs the adh_2d_3d extrusion software
"""
import imp
import os
import shutil
import subprocess
import sys
# For debug
#print
#print 'environ:'
#print 'PYTHONPATH', os.environ.get('PYTHONPATH')
#print 'ADH_2D_3D_EXE', os.environ.get('ADH_2D_3D_EXE')
#print
import smtk
# Explicitly load adhcommon and AdHSurfaceWater modules
# So that they reload each time
module_list = ['adhcommon', 'AdHSurfaceWater']
abs_path = os.path.abspath(__file__)
abs_dir = os.path.dirname(abs_path)
for module_name in module_list:
module_args = imp.find_module(module_name, [abs_dir])
imp.load_module(module_name, *module_args)
adh = sys.modules.get('adhcommon')
AdHSurfaceWater = sys.modules.get('AdHSurfaceWater')
# ---------------------------------------------------------------------
def ExportCMB(spec):
'''Entry function, called by CMB to write export files
Returns boolean indicating success
Parameters
----------
spec: Top-level object passed in from CMB
'''
#print 'Enter ExportCMB()'
# Run *surface* water exporter to generate 2D bc file
ok = AdHSurfaceWater.ExportCMB(spec)
if not ok:
print 'ERROR writing 2D boundary condition file -- exiting'
return false
# Init scope object to get output directory and base filename
scope = adh.init_scope(spec)
# Override output directory if file is specified as full path
head, tail = os.path.split(scope.output_filename)
if head is not None:
scope.output_directory = head
print 'Using \"%s\" as output directory' % scope.output_directory
#print 'output file', scope.output_filename
root, ext = os.path.splitext(scope.output_filename)
scope.output_basename = root
print 'Using basename \"%s\"" for output files' % scope.output_basename
# Get Extrusion attributes
ext_atts = scope.manager.findAttributes('Extrusion')
if not ext_atts:
print 'No extrusion attributes specified -- exiting'
return False
# Create dictionary of <mat id, num layers>
ext_dict = dict()
for ext_att in ext_atts:
item = ext_att.find('NumberOfLayers')
int_item = smtk.attribute.to_concrete(item)
num_layers = int_item.value(0)
model_ent_list = ext_att.associatedEntitiesSet()
for model_ent in model_ent_list:
ext_dict[model_ent.id()] = num_layers
#print 'ext_dict', ext_dict
# Construct .mt file with layer specifications
mt_filename = '%s.mt' % scope.output_basename
mt_path = os.path.join(scope.output_directory, mt_filename)
print 'Writing', mt_path
write_complete = False
with open(mt_filename, 'w') as f:
for t in sorted(ext_dict.items()):
f.write('%s %s\n' % t)
write_complete = True
if not write_complete:
print 'ERROR writing %s -- exiting' % mt_path
return False
# Get ExportSpec attribute
att_list = scope.export_manager.findAttributes('ExportSpec')
if len(att_list) > 1:
msg = 'More than one ExportSpec instance -- using first one'
print 'WARNING:', msg
scope.logger.addWarning(msg)
else:
export_spec_att = att_list[0]
# Copy .2dm file to output_directory if needed
mesh_file = '%s.2dm' % scope.output_basename
mesh_path = os.path.join(scope.output_directory, mesh_file)
if not os.path.isfile(mesh_path):
# Look up 2dm file in export attributes
item = export_spec_att.find('2DMeshFile')
file_item = smtk.attribute.to_concrete(item)
source = file_item.value(0)
if not os.path.isfile(source):
print 'Unable to find source mesh file at %s -- exiting' % source
return False
print 'Copying %s to %s' % (source, mesh_path)
shutil.copyfile(source, mesh_path)
# Copy host start file to output directory if needed
hotstart_file = '%s.hot' % scope.output_basename
hotstart_path = os.path.join(scope.output_directory, hotstart_file)
if not os.path.isfile(hotstart_path):
# Look up .hot file in export attributes
item = export_spec_att.find('HotStartFile')
file_item = smtk.attribute.to_concrete(item)
source = file_item.value(0)
if not os.path.isfile(source):
print 'Unable to find source hotstart file at %s -- exiting' % source
return False
print 'Copying %s to %s' % (source, hotstart_path)
shutil.copyfile(source, hotstart_path)
# Find the adh_2d_3d executable
adh_exe_name = 'adh_2d_3d'
if 'win32' == sys.platform:
adh_exe_name += '.exe'
exe_path = None
# Keep list of paths that were tried
msg_list = list()
# Look in same directory as current executable
exe_path = None
python_path = sys.executable
if python_path is None:
msg = 'Warning: executable directory not defined'
msg_list.append(msg)
print msg
scope.logger.addWarning(msg)
else:
# Check same directory as current executable
python_dir = os.path.dirname(python_path)
try_path = os.path.join(python_dir, adh_exe_name)
if os.path.isfile(try_path):
exe_path = try_path
else:
msg = 'Extrusion executable not found at \"%s\"' % try_path
msg_list.append(msg)
scope.logger.addDebug(msg)
# Check platform-specific install paths
if exe_path is None and 'darwin' == sys.platform:
try_path = os.path.join(python_dir, os.pardir, 'bin', adh_exe_name)
if os.path.isfile(try_path):
exe_path = try_path
else:
msg = 'Extrusion executable not found at \"%s\"' % try_path
msg_list.append(msg)
scope.logger.addDebug(msg)
# Also check env var, which was added for testing
if exe_path is None:
try_path = os.environ.get('ADH_2D_3D_EXE')
if try_path is not None:
if os.path.isfile(try_path):
exe_path = try_path
else:
msg = 'Extrusion executable not found at \"%s\"' % try_path
msg_list.append(msg)
scope.logger.addDebug(msg)
if exe_path is None:
msg = "Cannot locate extrusion executable (%s) -- aborting" % \
adh_exe_name
print msg
for msg in msg_list:
print msg
scope.logger.addError(msg)
return False
msg = 'Using extrusion executable at %s' % exe_path
print msg
scope.logger.addDebug(msg)
# Save current working directory
orig_cwd = os.getcwd()
# Switch to output_directory
os.chdir(scope.output_directory)
# Open temp files to capture stdout, stderr from adh_2d_3d executable
filename = '%s.stderr' % adh_exe_name
path = os.path.join(scope.output_directory, filename)
stderr_file = open(path, 'w')
filename = '%s.stdout' % adh_exe_name
path = os.path.join(scope.output_directory, filename)
stdout_file = open(path, 'w')
# Run the extrusion code
print 'Run', exe_path
ret = subprocess.call([exe_path, scope.output_basename], \
stdout=stdout_file, stderr=stderr_file)
# Close the temp files
stdout_file.close()
stderr_file.close()
if ret != 0:
print 'ERROR: %s returned errors.' % adh_exe_name,
print ' Check .stdout & .stdout files in output directory'
# Switch back to original working directory
os.chdir(orig_cwd)
print 'Wrote files to directory', scope.output_directory
return ok
<?xml version="1.0"?>
<SMTK_AttributeManager Version="1">
<Includes>
<!-- Uses same definitions as surface water -->
<File>AdHSurfaceWaterDefinitions.sbt</File>
</Includes>
<Categories>
<Cat>Meshing</Cat>
</Categories>
<Definitions>
<AttDef Type="Extrusion" Label="Extrusion" Unique="true" Associations="f">
<ItemDefinitions>
<Int Name="NumberOfLayers">
<Categories>Meshing</Categories>
<DefaultValue>1</DefaultValue>
<RangeInfo>
<Min Exclusive="false">1</Min>
</RangeInfo>
</Int>
</ItemDefinitions>
</AttDef>
</Definitions>
<!--********** Workflow Views ***********-->
<!-- Same as surface water PLUS meshing view -->
<RootView Title="SimBuilder">
<DefaultColor>1., 1., 0.5, 1.</DefaultColor>
<InvalidColor>1, 0.5, 0.5, 1</InvalidColor>
<InstancedView Title="Solvers">
<InstancedAttributes>
<Att Type="Solvers">Solvers</Att>
</InstancedAttributes>
</InstancedView>
<InstancedView Title="Time">
<InstancedAttributes>
<Att Type="Time">Time</Att>
</InstancedAttributes>
</InstancedView>
<InstancedView Title="Globals">
<InstancedAttributes>
<Att Type="Globals">Globals</Att>
</InstancedAttributes>
</InstancedView>
<SimpleExpressionView Title="Functions">
<Definition>PolyLinearFunction</Definition>
</SimpleExpressionView>
<AttributeView Title="Materials" ModelEntityFilter="f" CreateEntities="true">
<AttributeTypes>
<Type>SolidMaterial</Type>
</AttributeTypes>
</AttributeView>
<AttributeView Title="Constituents" CreateEntities="true">
<AttributeTypes>
<Type>Constituent</Type>
</AttributeTypes>
</AttributeView>
<AttributeView Title="Friction" ModelEntityFilter="f" CreateEntities="true">
<AttributeTypes>
<Type>Friction</Type>
</AttributeTypes>
</AttributeView>
<AttributeView Title="BoundaryConditions" ModelEntityFilter="e">
<AttributeTypes>
<Type>VelocityBound</Type>
<Type>LidElevation</Type>
<Type>VelocityAndDepthBound</Type>
<Type>WaterDepthLid</Type>
<Type>WaterSurfElev</Type>
<Type>UnitFlow</Type>
<Type>TotalDischarge</Type>
<Type>FloatingStationary</Type>
<Type>DirichletTransport</Type>
<Type>NaturalTransport</Type>
</AttributeTypes>
</AttributeView>
<AttributeView Title="Extrusions" ModelEntityFilter="f">
<AttributeTypes>
<Type>Extrusion</Type>
</AttributeTypes>
</AttributeView>
</RootView>
</SMTK_AttributeManager>
<?xml version="1.0"?>
<cmb-resources>
<!-- Include baseline template by reference -->
<attribute id="simbuilder" role="template">
<include href="AdHSurfaceWater.sbt" />
</attribute>
<!-- Template for Export Dialog -->
<attribute id="export" role="template">
<SMTK_AttributeManager Version="1">
<Definitions>
<AttDef Type="ExportSpec" BaseType="" Version="0" Unique="true">
<ItemDefinitions>
<File Name="OutputFile" Label="Output file (*.bc)" Version="0" NumberOfRequiredValues="1"
FileFilters="BC files (*.bc);;All files (*.*)">
<DefaultValue>output.bc</DefaultValue>
</File>
<String Name="AnalysisTypes" Label="Analysis Types" AdvanceLevel="99" Version="0"
Extensible="true" NumberOfRequiredValues="1"/>
<File Name="PythonScript" Label="Python script" AdvanceLevel="1" Version="0" NumberOfRequiredValues="1"
AdvanceLevel="1" ShouldExist="true"
FileFilters="Python files (*.py);;All files (*.*)">
<DefaultValue>AdHSurfaceWater.py</DefaultValue>
</File>
</ItemDefinitions>
</AttDef>
</Definitions>
<Attributes />
<RootView Title="Export">
<DefaultColor>1., 1., 0.5, 1.</DefaultColor>
<InvalidColor>1, 0.5, 0.5, 1</InvalidColor>
<AdvancedFontEffects Bold="0" Italic="0" />
<InstancedView Title="ExportSpec">
<InstancedAttributes>
<Att Type="ExportSpec">Options</Att>
</InstancedAttributes>
</InstancedView>
</RootView>
</SMTK_AttributeManager>
</attribute>
</cmb-resources>
#=============================================================================
#
# Copyright (c) Kitware, Inc.
# All rights reserved.
# See LICENSE.txt for details.
#
# This software is distributed WITHOUT ANY WARRANTY; without even
# the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
# PURPOSE. See the above copyright notice for more information.
#
#=============================================================================
"""
Export script for Shallow Water 2D applications
"""
import imp
import os
import sys
import smtk
# Explicitly load adhcommon.py, so that it reloads each time
module_name = 'adhcommon'
abs_path = os.path.abspath(__file__)
abs_dir = os.path.dirname(abs_path)
module_args = imp.find_module(module_name, [abs_dir])
imp.load_module(module_name, *module_args)
adh = sys.modules.get(module_name)
# Define placeholder/passthrough functions for custom writer functions
# Actual implementations, prefixed by "_", are further below
def write_outputseries(scope, item, card_format, context_id):
return _write_outputseries(scope, item, card_format, context_id)
# ---------------------------------------------------------------------
#
# Dictionary of formatters for each output card
#
# Card format types are: val, idval, bc, multival
# Arguments are: (item name, opcode, comment=None, subitems=None, \
# custom_writer=None)
#
# ---------------------------------------------------------------------
fmt = adh.CardFormat
format_table = {
'Solvers': [
fmt.val('MemoryIncrementBlockSize', 'OP INC'),
fmt.val('PreconditioningBlocks', 'OP BLK'),
fmt.val('PreconditionerType', 'OP PRE'),
fmt.val('TemporalSchemeCoefficient', 'OP TEM'),
fmt.val('PetrovGalerkinCoefficient', 'OP TPG'),
fmt.val('VesselMovement', 'OP BT'),
fmt.val('VesselEntrainment', 'OP BTS'),
fmt.val('SW2Gradients', 'OP NF2'),
fmt.val('NonLinearTolMaxNorm', 'IP NTL'),
fmt.val('MaxNonLinearIters', 'IP NIT'),
fmt.val('MaxLinearIters', 'IP MIT'),
fmt.val('NonLinearTolMaxChange', 'IP ITL'),
fmt.val('RungeKuttaTol', 'IP RTL'),
],
'Time': [
fmt.val('TimestepSize', 'TC IDT'),
fmt.val('StartTime', 'TC T0', subitem_names=['Value', 'Units']),
fmt.val('EndTime', 'TC TF', subitem_names=['Value', 'Units']),
fmt.val('SteadyStateSolveParams', 'TC STD'),
fmt.val('QuasiUnsteadyParams', 'TC STH',
subitem_names=['SteadyStateHydrodynamicCondition"', 'MaxIterations', 'InitialTimeStep']),
fmt.val('AutoTimeStepFind', 'TC ATF', subitem_names=['InitialTimeStep', 'TimeSeries']),
fmt.val('PrintAdaptedMeshes', 'PC ADP'),
fmt.val('HotStartFile', 'PC HOT'),
fmt.val('OutputSeries', 'OS', custom_writer=write_outputseries)
],
'SolidMaterial': [
fmt.idconval('TurbulentDiffusionRate', 'MP DF'),
fmt.idval('KinematicEddyViscosity', 'MP EVS',
subitem_names=['Value1', 'Value2', 'Value3']),
fmt.idval('CoriolisLatitude', 'MP COR'),
fmt.idval('MaxRefineLevels', 'MP ML'),
fmt.idval('HydroRefineTol', 'MP SRT'),
fmt.idconval('TransportRefineTol', 'MP TRT')
],
# Boundary Conditions
'VelocityBound':
fmt.bc('DirichletVelocity', 'DB OVL', subitem_names=['Value1', 'Value2']),
'VelocityAndDepthBound':
fmt.bc('Dirichlet transport', 'DB TRN',
subitem_names=['Value1', 'Value2', 'Value3']),
'LidElevation': fmt.bc('Value', 'DB LDE'),
'WaterDepthLid': fmt.bc('Value', 'DB LDH'),
'FloatingStationary': fmt.bc('Value', 'DB LID'),
'TotalDischarge': fmt.bc('Value', 'NB DIS'),
'UnitFlow': fmt.bc('Value', 'NB OVL'),
'WaterSurfElev': fmt.bc('Value', 'NB OTW'),
'StageDischargeBound': fmt.bc('Value', 'NB SDR'),
'SpillWayBound': fmt.bc('Value', 'NB SPL'),
'OutflowBound': fmt.bc('Value', 'OB OF'),
'DirichletTransport': fmt.conbc('Value', 'DB TRN'),
'NaturalTransport': fmt.conbc('Value', 'NB TRN'),
'FrictionType1': [ fmt.idval('Value', 'FR MNG') ],
'FrictionType2': [ fmt.idval('Value', 'FR ERH') ],
'FrictionType3': [ fmt.idval('Value', 'FR SAV') ],
'FrictionType4': [ fmt.idval('Value', 'FR URV') ],
'Globals': [
fmt.val('Gravity', 'MP G'),
fmt.val('KinMolViscosity', 'MP MU'),
fmt.val('ReferenceDensity', 'MP RHO'),
fmt.val('ManningsUnitConstant', 'MP MUC'),
fmt.val('WetDryLimits', 'MP DTL')
],
'GeneralConstituent': [ fmt.idval('GenConstituentParams', 'CN CON',
subitem_names=['ReferenceConcentration']) ],
'SalinityConstituent': [ fmt.idval('SalConstituentParams', 'CN SAL',
subitem_names=['ReferenceConcentration']) ],
'VorticityConstituent': [ fmt.idval('VortConstituentParams', 'CN VOR',
subitem_names=['NormalizationFactor', 'AsTerm', 'DsTerm']) ],
'TemperatureConstituent': [ fmt.idval('TempConstituentParams', 'CN TEM',
subitem_names=['ReferenceConcentration']) ],
}
# ---------------------------------------------------------------------
def ExportCMB(spec):
'''Entry function, called by CMB to write export files
Returns boolean indicating success
Parameters
----------
spec: Top-level object passed in from CMB
'''
#print 'Enter ExportCMB()'
# Initialize scope instance to store spec values and other info
scope = adh.init_scope(spec)
if scope.logger.hasErrors():
print scope.logger.convertToString()
print 'FILES NOT WRITTEN because of errors'
return False
scope.format_table = format_table
print 'Analysis types:', scope.analysis_types
if not scope.analysis_types:
msg = 'No analysis types selected'
print 'WARNING:', msg
scope.logger.addWarning(msg)
else:
print 'Categories:', sorted(list(scope.categories))
# Open output file and start exporting content
completed = False
with open(scope.output_filename, 'w') as scope.output:
scope.output.write('OP SW2\n')
n = len(scope.constituent_dict)
scope.output.write('OP TRN %d\n' % n)
# Call write-content functions in specified top-level order
att_type_list = [
'Solvers', 'Time', 'SolidMaterial', 'BoundaryCondition',
'Friction', 'Globals', 'Constituent'
]
for att_type in att_type_list:
ok = adh.write_section(scope, att_type)
#if not ok:
# break
# Write function attributes
adh.write_functions(scope)
# Write MTS cards (material id for each model domain)
adh.write_MTS_cards(scope)
# Write NDS & EGS cards for boundary conditions
adh.write_bc_sets(scope)
# Last line
scope.output.write('END\n')
print 'Wrote', scope.output_filename
completed = True
if not completed:
print 'WARNING: Export terminated unexpectedly -- output might be invalid.'
return completed
# ---------------------------------------------------------------------
def _write_outputseries(scope, item, card_format, context_id):
'''Custom writer (implementation) for OutputSeries attribute
Writes either OC or OS card, depending on item'd discrete value
0 == OC (Output Control Series)
1 == OS (Auto-Build Time Series)
'''
discrete_value = item.value(0)
if 0 == discrete_value:
output_item = adh.find_active_child(scope, item, 'OutputFunction')
exp_att = output_item.expression(0)
exp_id = adh.get_function_id(scope, exp_att)
scope.output.write('OC %d\n' % exp_id)
elif 1 == discrete_value:
# Get function (series) ID for TimeSeriesData
time_series_item = adh.find_active_child(scope, item, 'TimeSeriesData')
series_id = adh.get_function_id(scope, time_series_item)
# Get number of points
n = time_series_item.numberOfGroups()
# Get units
units_item = adh.find_active_child(scope, item, 'OutputUnits')
units_value = units_item.discreteIndex(0)
scope.output.write('OS %d %d %d\n' % (series_id, n, units_value))
# Process subgroup items, one line per
if n < 1: # but safety first
return
for i in range(n):
#print 'i', i
start_item = adh.find_subgroup_item(time_series_item, i, 'StartTime')
start = start_item.value(0)
end_item = adh.find_subgroup_item(time_series_item, i, 'EndTime')
end = end_item.value(0)
interval_item = adh.find_subgroup_item(time_series_item, i, 'TimeInterval')
interval = interval_item.value(0)
units_item = adh.find_subgroup_item(time_series_item, i, 'Units')
units = units_item.value(0)
scope.output.write('%8s %8s %8s %s\n' % (start, end, interval, units))
else:
msg = 'Unexpected value for OutputSeries: %d (expecting 0 or 1)' % \
discrete_value
print 'WARNING:', msg
scope.logger.addWarning(msg)
<?xml version="1.0"?>
<SMTK_AttributeManager Version="1">
<Includes>
<File>AdHSurfaceWaterDefinitions.sbt</File>
<File>AdHSurfaceWaterViews.sbt</File>
</Includes>
</SMTK_AttributeManager>
This diff is collapsed.
<?xml version="1.0"?>
<!--Created by XmlV1StringWriter-->
<SMTK_AttributeManager Version="1">
<!--********** Workflow Views ***********-->
<RootView Title="SimBuilder">
<DefaultColor>1., 1., 0.5, 1.</DefaultColor>
<InvalidColor>1, 0.5, 0.5, 1</InvalidColor>
<InstancedView Title="Solvers">
<InstancedAttributes>
<Att Type="Solvers">Solvers</Att>
</InstancedAttributes>
</InstancedView>
<InstancedView Title="Time">
<InstancedAttributes>
<Att Type="Time">Time</Att>
</InstancedAttributes>
</InstancedView>
<InstancedView Title=