<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<?xml-stylesheet type="text/xsl" href="xs3p.xsl"?>
<xs:annotation>
  <xs:documentation xml:lang="en">
Schema for amanzi input files.  This is version 2.0.  1.x predates the use of XML Schema

Design choices:
  * For all user element/attribute names, we will use only lower case letters and _ to separate words.

Some standards to think about:
  * Explicitly constrain elements intended to be empty to actually be empty.
  * where to make things optional
  * best practices for XML schemas (TBD)
  * how to deal with structured vs unstructured (omit structured only for now?)
  **  should domain be included if we only do unstructured?
  *
  * This version excludes (from 1.1 spec)::
  *   Domain, Diagnostics 
  *   Structured specific items except an example of how it could work
  
Changes by TDS June 2013:
  	* TDS1: Changed typedef_constant to include a third attribute with name "type" 
  	    and changed the type for the attribute "value" to string (was decimal). This allows reading of 
  	    a variety of generic constants, and then when used
  	    the type attribute can be used to determine how to validate.  Also added the option of using 
  	    specifically-typed constants (e.g., time_constant, numerical_constant,...) which then are 
  	    easier to validate and do not require the "type" attribute.  We may want to move away from 
  	    the general "constant" and only allow specifically-typed constants to facilitate validation.
  	* TDS1: Changed comment tag in model_description to "comments" for consistent usage throughout
  	* Removed regionlist tag and associated definitions
  	* Added optional surrounding parentheses to the coordinate definition (typedef_coordinate)
  	* Added maximum restriction of 1.0 to porosity (see restriction_porosity type definition)
  	* Modified format for cap_pressure element to use model attribute to determine parameter attributes
  	* Modified format for rel_perm element to use model attribute to determine parameter attributes.
  		TODO: Need to verify correct parameters are specified for Mualem model - see mathematical formulation
  	* Modified initial conditions to use separate elements for aqueous_component and solute_component; allow multiple 
  		solute_component elements; allow filename attribute in solute_component element
  		TODO: Assertion on function threw exception if function attribute was not used. How to allow alternative
  			attributes while validating ones that may or may not actually be used?
  		NOTE: When the assertion failed, the error message went to console and did not appear in the jar window,
  			giving the false impression that the file validated completely...
  	* Modified typedef_bc_uniform_pressure - function value must be uniform or constant for this element by definition
  	* Should exponential format allow 1.e-5 ? (currently doesn't).  We decided not to allow this format.
  	        Must use either 1e-5 or 1.0e-5.
  	* Added numerical controls section with validation of all entries in the BC Cribs instance.  Still needs a lot
  	 	of work in terms of specific validation of entries and adding other options 
  	** The BC Cribs instance file now validates against the schema 6/27/2013
  	* Modified phase section to use phase-specific elements (e.g., fluid_phase and solid_phase) rather 
  	 	than a generic phase tag.  Since the elements of phase vary widely depending on what type of phase
  	 	it is, this will greatly simplify validation.  This also provides extensibility when new phases
  	 	are added (e.g., other fluid phases than water or gas phases).
  	* Modified initial and boundary condition sections to use phase-specific elements consistent with the 
  		modified phase section.
  	** All three instance files now validate against the schema (6/28/2013)
  	** NEXT: Two main tasks remain 1) add validation tests for values on existing elements where relevant, an
  		2) identify any missing options
  	* 7/11/2013 (TDS): Changed order of phase and boundary/initial condition elements to put phase inside the BC or IC
  		Revised the way solutes and diffusion coefficients are defined
  		Added based on new instance file from Elizabeth Keating:
  		- Hydrostatic B.C. option
  		- Verbosity element in execution controls
       Changes by VLF August 2013:
        * Added additional numerical controls
        * Added restart
        * Added regions:  plane
       Changes by VLF September 2013:
       	* Modified observations
	* Added sources
	* Modified hydrostatic boundary to include relative/absolute attribute
	* Changed sequence to all, when type allowed.  Ordering should not be enforced unless necessary.
	* Added dispersivity, diffusion and tortuosity
	* DID NOT Add spatial_function; modified function --> time_function ***TODO****
  </xs:documentation>
</xs:annotation>


<!-- =====================================Simple Type Global Definitions ==================================== -->
<xs:simpleType name="typedef_version">
  <xs:restriction base="xs:token">
	<!-- 2.0.0 -->
    <xs:pattern value="[0-9]{1,2}\.[0-9]{1,2}\.[0-9]{1,2}"/>
  </xs:restriction>
</xs:simpleType>

<!-- http://www.regular-expressions.info/floatingpoint.html -->
<xs:simpleType name="typedef_exponential">
  <xs:restriction base="xs:token">
    <xs:pattern value="[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?"/>
  </xs:restriction>
</xs:simpleType>

<xs:simpleType name="typedef_labeled_time">
  <xs:restriction base="xs:token">
    <!-- <xs:pattern value="[+-]?[0-9]*\.?[0-9]+(;[s|h|d|y]?)?"/> -->
    <!-- <xs:pattern value="[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?(;[s|h|d|y]?)?)"/> -->
    <!--<xs:pattern value="[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?([\s|;]?[s|h|d|y]?)?)"/>-->
    <xs:pattern value="[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?([\s;,]?[s|h|d|y]?)?)"/>
  </xs:restriction>
</xs:simpleType>

<!-- Units -->
<xs:simpleType name="typedef_unit_length">
     <xs:restriction base="xs:string">
            <xs:enumeration value="m" />
            <xs:enumeration value="cm" />
     </xs:restriction>
</xs:simpleType>		

<xs:simpleType name="typedef_unit_time">
     <xs:restriction base="xs:string">
            <xs:enumeration value="y" />
            <xs:enumeration value="d" />
            <xs:enumeration value="h" />
            <xs:enumeration value="s" />
     </xs:restriction>
</xs:simpleType>	
	
<xs:simpleType name="typedef_unit_mass">
     <xs:restriction base="xs:string">
            <xs:enumeration value="kg" />
     </xs:restriction>
</xs:simpleType>	
	
<xs:simpleType name="typedef_unit_conc">
     <xs:restriction base="xs:string">
            <xs:enumeration value="molar" />
     </xs:restriction>
</xs:simpleType>		

<xs:simpleType name="typedef_dimension">
	<xs:restriction base="xs:integer">
		<xs:minInclusive value="1"/>
		<xs:maxInclusive value="3"/>
	</xs:restriction>
</xs:simpleType>	

<xs:simpleType name="typedef_coordinate">
  <xs:annotation>
      <xs:documentation xml:lang="en">
         Coordinates are tuples of the following form number,number,number where
         each number is potentially optional for 2d or 1d systems.
      </xs:documentation>
  </xs:annotation>
  <xs:restriction base="xs:token">
      <xs:pattern value="[(]?( *[-+]?([0-9]*\.?[0-9]+)([eE][-+]?[0-9]+)?)( *,( *[-+]?([0-9]*\.?[0-9]+)([eE][-+]?[0-9]+)?))?( *,( *[-+]?([0-9]*\.?[0-9]+)([eE][-+]?[0-9]+)?))? *[)]?"/> 
  </xs:restriction>
</xs:simpleType>

<xs:simpleType name="typedef_normal">
  <xs:annotation>
      <xs:documentation xml:lang="en">
         Coordinates are tuples (1 or -1 or 0)of the following form number,number,number where
         each number is potentially optional for 2d or 1d systems.
      </xs:documentation>
  </xs:annotation>
  <xs:restriction base="xs:token">
    <xs:pattern value="[(]?([-+]?[01]*\.?[0]+)?, *([-+]?[01]*\.?[0]+)?, *([-+]?[01]*\.?[0]+)?[)]?"/>
  </xs:restriction>
</xs:simpleType>

<!-- =========================================== Macro Types ========================================== -->

<xs:complexType name="typedef_variable_macro">
    <xs:annotation>
      <xs:documentation xml:lang="en">
* Volumetric water content [volume water / bulk volume]
* Aqueous saturation [volume water / volume pore space]
* Aqueous pressure [Pa]
* Aqueous concentration [moles of solute XXX / volume water in MKS] (name formed by string concatenation, given the definitions in "Phase Definition" section)
* X-, Y-, Z- Aqueous volumetric fluxe [m/s]
* MaterialID
* Gravimetric water content [volumetric water content * water density / bulk density, in kg/m^3]
* Hydraulic Head [ (aqueous pressure - atmospheric pressure)/(rho * gravity) + z ]

TODO do we want to convert all of these name to lower case? 
         also perhaps we cannot validate since we don't know the list of solutes a priori nor the 
         material ids. 
TODO Can we do validation on known names plus allow unrecognised ones.  Well I think we can but should we?
      </xs:documentation>
    </xs:annotation>
    <xs:all>
       <xs:element name="variable" type="xs:string" minOccurs="1" maxOccurs="unbounded"/>
    </xs:all>
    <xs:attribute type="xs:string" name="name"/>
</xs:complexType>

<xs:complexType name="typedef_time_macro">
    <xs:annotation>
      <xs:documentation xml:lang="en">
        Time macros can be a set of specific times or a time interval.
      </xs:documentation>
    </xs:annotation>
	 <xs:choice minOccurs="1" maxOccurs="1">
		<xs:element name="time" type="typedef_labeled_time" minOccurs="1" maxOccurs="unbounded"/>
         <xs:sequence>
           <xs:element type="typedef_labeled_time" name="start" minOccurs="1"/>
           <xs:element type="typedef_labeled_time" name="timestep_interval" minOccurs="0" />
           <xs:element type="typedef_labeled_time" name="stop" minOccurs="0" default="-1"/>
         </xs:sequence>
		</xs:choice>
    <xs:attribute type="xs:string" name="name"/>
</xs:complexType>

<xs:complexType name="typedef_cycle_macro">
    <xs:annotation>
      <xs:documentation xml:lang="en">
      </xs:documentation>
    </xs:annotation>
    <xs:all>
      <xs:element type="xs:integer" name="start" minOccurs="1"/>
      <xs:element type="xs:integer" name="timestep_interval" minOccurs="0" />
      <xs:element type="xs:integer" name="stop" minOccurs="0" default="-1"/>
    </xs:all>
    <xs:attribute type="xs:string" name="name"/>
</xs:complexType>

<xs:complexType name="typedef_macros">
	<xs:all>
		<xs:element name="time_macro" type="typedef_time_macro" minOccurs="0" maxOccurs="unbounded"/>
		<xs:element name="cycle_macro" type="typedef_cycle_macro" minOccurs="0" maxOccurs="unbounded"/>
		<xs:element name="variable_macro" type="typedef_variable_macro" minOccurs="0" maxOccurs="unbounded"/>
	</xs:all>
</xs:complexType>

<!-- ===================================== Complex Type Global Definitions =================================== -->

<xs:complexType name="typedef_time">
  <xs:simpleContent>
  <xs:extension base="xs:string">
      <xs:attribute type="xs:string" name="name"/>
      <xs:attribute type="typedef_labeled_time" name="value"/>
  </xs:extension>
  </xs:simpleContent>
</xs:complexType>

<xs:complexType name="typedef_named_times">
  <xs:all>
  <xs:element name="time" type="typedef_time" maxOccurs="unbounded"/>
  </xs:all>
</xs:complexType>

<xs:complexType name="typedef_constant">
	<xs:simpleContent>
	<xs:extension base="xs:string">
		<xs:attribute type="xs:string" name="name"/>
                <xs:attribute type="xs:string" name="value"/>
		<xs:attribute type="xs:string" name="type"/>
	</xs:extension>
	</xs:simpleContent>
</xs:complexType>

<xs:complexType name="typedef_numerical_constant">
	<xs:simpleContent>
	<xs:extension base="xs:string">
		<xs:attribute type="xs:string" name="name"/>
                <xs:attribute type="typedef_exponential" name="value"/>
	</xs:extension>
	</xs:simpleContent>
</xs:complexType>

<xs:complexType name="typedef_area_mass_flux_constant">
	<xs:simpleContent>
	<xs:extension base="xs:string">
		<xs:attribute type="xs:string" name="name"/>
                <xs:attribute type="typedef_exponential" name="value"/>
	</xs:extension>
	</xs:simpleContent>
</xs:complexType>

<xs:complexType name="typedef_constants">
	<xs:all>
		<xs:element name="constant" type="typedef_constant" minOccurs="0" maxOccurs="unbounded"/>
		<xs:element name="time_constant" type="typedef_time" minOccurs="0" maxOccurs="unbounded"/>
		<xs:element name="numerical_constant" type="typedef_numerical_constant" minOccurs="0" maxOccurs="unbounded"/>
		<xs:element name="area_mass_flux_constant" type="typedef_area_mass_flux_constant" minOccurs="0" maxOccurs="unbounded"/>
	</xs:all>
</xs:complexType>

<xs:complexType name="typedef_box">
	<xs:attribute name="low_coordinates" type="typedef_coordinate"/>
	<xs:attribute name="high_coordinates" type="typedef_coordinate"/>
</xs:complexType>

<xs:complexType name="typedef_labeled_box">
	<xs:complexContent>
		<xs:extension base="typedef_box">
			<xs:attribute name="name" type="xs:string"/>
		</xs:extension>
	</xs:complexContent>
</xs:complexType>

<xs:complexType name="typedef_point">
	<xs:attribute name="coordinate" type="typedef_coordinate"/>
</xs:complexType>

<xs:complexType name="typedef_labeled_point">
	<xs:complexContent>
		<xs:extension base="typedef_point">
			<xs:attribute name="name" type="xs:string"/>
		</xs:extension>
	</xs:complexContent>
</xs:complexType>

<xs:complexType name="typedef_plane">
	<xs:attribute name="location" type="typedef_coordinate"/>
	<xs:attribute name="normal" type="typedef_normal"/>
</xs:complexType>

<xs:complexType name="typedef_labeled_plane">
	<xs:complexContent>
		<xs:extension base="typedef_plane">
			<xs:attribute name="name" type="xs:string"/>
		</xs:extension>
	</xs:complexContent>
</xs:complexType>

<xs:complexType name="typedef_region_file">
	<xs:attribute name="name" type="xs:string"/>
	<xs:attribute name="type" type="typedef_region_file_types"/>
	<xs:attribute name="format" type="typedef_region_file_formats"/>
	<xs:attribute name="entity" type="typedef_region_file_entities"/>
	<xs:attribute name="label" type="xs:integer"/>  <!-- TDS: Should this be a string rather than a number? -->
</xs:complexType>

<xs:complexType name="typedef_property_file">
	<xs:attribute name="filename" type="xs:string"/>
        <xs:attribute name="type" type="typedef_property_file_formats"/>
        <xs:attribute name="attribute" type="xs:string"/>
</xs:complexType>

<xs:simpleType name="typedef_property_file_formats">
	<xs:restriction base="xs:string">
		<xs:enumeration value="file"/> <!-- TODO: what type should property files be? -->
                <!--
                <xs:enumeration value="color"/>
                <xs:enumeration value="exodus ii"/>
                -->
	</xs:restriction>
</xs:simpleType>

<xs:simpleType name="typedef_region_file_types">
	<xs:restriction base="xs:string">
		<xs:enumeration value="color"/>
		<xs:enumeration value="labeled set"/>
	</xs:restriction>
</xs:simpleType>

<xs:simpleType name="typedef_region_file_formats">
	<xs:restriction base="xs:string">
		<xs:enumeration value="exodus ii"/>
		<xs:enumeration value="exodus II"/>
		<xs:enumeration value="Exodus II"/>
		<xs:enumeration value="Exodus ii"/>
	</xs:restriction>
</xs:simpleType>

<xs:simpleType name="typedef_region_file_entities">
	<xs:restriction base="xs:string">
		<xs:enumeration value="cell"/>
		<xs:enumeration value="face"/>
	</xs:restriction>
</xs:simpleType>

<xs:simpleType name="typedef_mesh_file_formats">
	<xs:restriction base="xs:string">
		<xs:enumeration value="exodus ii"/>
		<xs:enumeration value="exodus II"/>
		<xs:enumeration value="Exodus II"/>
		<xs:enumeration value="Exodus ii"/>
	</xs:restriction>
</xs:simpleType>

<!-- TODO: If we use a list here we can't make sure the regions exist -->
<xs:simpleType name="typedef_assigned_regions"> 
	<xs:restriction base="xs:string"/>
</xs:simpleType>

<xs:complexType name="typedef_default_units">
   <xs:all>
	   <xs:element name="length_unit" type="typedef_unit_length" maxOccurs="1"/>
	   <xs:element name="time_unit" type="typedef_unit_time" maxOccurs="1"/>
	   <xs:element name="mass_unit" type="typedef_unit_mass" maxOccurs="1"/>
	   <xs:element name="conc_unit" type="typedef_unit_conc" maxOccurs="1"/>
   </xs:all>
</xs:complexType>

<!-- The time type with various unit options -->
<xs:complexType name="time">
  <xs:simpleContent>
    <xs:extension base="xs:double">
      <xs:attribute name="units" default="y" type="typedef_unit_time"/>
    </xs:extension>
  </xs:simpleContent>
</xs:complexType>

<xs:complexType name="solution_time">
	<xs:all>
		<xs:element name="start" type="xs:string" />
		<xs:element name="end" type="xs:string"/>
		<xs:element name="initial_time_step" type="typedef_labeled_time"/>
	</xs:all>
</xs:complexType>

<!-- =========================================== Overall Structure ========================================== -->

<!-- Example tag: <amanzi_input version="2.1.0" type="unstructured"> -->

<xs:element name="amanzi_input">
	<xs:alternative test="@type eq 'structured'" type="typedef_structured"/>
	<xs:alternative test="@type eq 'unstructured'" type="typedef_unstructured"/>
	<xs:alternative type="xs:error"/>
</xs:element>

<!-- Type definitions -->
<xs:complexType name="typedef_amanzi_input">
	<xs:all>		
		<xs:element name="model_description" type="typedef_model_description" minOccurs="1" maxOccurs="1"/>
		<xs:element name="definitions" type="typedef_definitions" minOccurs="0" maxOccurs="1"/>
		<xs:element name="process_kernels" type="typedef_process_kernels" minOccurs="1" maxOccurs="1"/>
		<xs:element name="phases" type="typedef_phases" minOccurs="1" maxOccurs="1"/>
		<xs:element name="execution_controls" type="typedef_execution_controls" minOccurs="1" maxOccurs="1"/>
		<xs:element name="numerical_controls" type="typedef_numerical_controls" minOccurs="0" maxOccurs="1"/>
		<xs:element name="geochemistry" type="typedef_main_geochemistry" minOccurs="0" maxOccurs="1"/>
		<xs:element name="materials" type="typedef_materials" minOccurs="1" maxOccurs="1"/>
		<xs:element name="initial_conditions" type="typedef_initial_conditions" minOccurs="1" maxOccurs="1"/>
		<xs:element name="boundary_conditions" type="typedef_boundary_conditions" minOccurs="0" maxOccurs="1"/>
		<xs:element name="sources" type="typedef_sources" minOccurs="0" maxOccurs="1"/>
		<xs:element name="output" type="typedef_outputs" minOccurs="0" maxOccurs="1"/>
	</xs:all>
	<xs:attribute name="version" type="typedef_version" use="required"/>
	<xs:attribute name="type" type="xs:string" use="required"/>
	<xs:assert  test="@type = ('structured','unstructured')"/>
</xs:complexType>

<xs:complexType name="typedef_unstructured">
    <xs:complexContent>
	<xs:extension base="typedef_amanzi_input">
	    <xs:all>
		<xs:element name="mesh" type="typedef_mesh_unstructured" minOccurs="1" maxOccurs="1"/>
		<xs:element name="regions" type="typedef_regions_unstructured" minOccurs="1" maxOccurs="1"/>
	    </xs:all>
	</xs:extension>
    </xs:complexContent>
</xs:complexType>

<xs:complexType name="typedef_structured">
    <xs:complexContent>
	<xs:extension base="typedef_amanzi_input">
	    <xs:all>
		<xs:element name="mesh" type="typedef_mesh_structured" minOccurs="1" maxOccurs="1"/>
		<xs:element name="regions" type="typedef_regions_structured" minOccurs="1" maxOccurs="1"/>
	    </xs:all>
	</xs:extension>
    </xs:complexContent>
</xs:complexType>
	
<!-- ========================================== General Description ========================================== -->
<xs:complexType name="typedef_model_description">
    <xs:annotation>
      <xs:documentation xml:lang="en">
         This shows how to annotate the schema with descriptive information on a type
      </xs:documentation>
    </xs:annotation>
    <xs:all>
      <xs:element type="xs:string" name="comments" minOccurs="0"/>
      <xs:element type="xs:string" name="author" minOccurs="0"/>
      <xs:element type="xs:date" name="created" minOccurs="0"/>
      <xs:element type="xs:date" name="modified" minOccurs="0"/>
      <xs:element type="xs:string" name="model_id" minOccurs="0"/>
      <xs:element type="xs:string" name="description" minOccurs="0"/>
      <xs:element type="xs:string" name="purpose" minOccurs="0"/>
      <xs:element type="typedef_default_units" name="units" minOccurs="0"/>
    </xs:all>
    <xs:attribute type="xs:string" name="name"/>
</xs:complexType>

<!-- ========================================== Definitions ================================================= -->
<xs:complexType name="typedef_definitions">
    <xs:annotation id="xxx">
      <xs:documentation xml:lang="en">
         This section allows for definitions of constants, named times, and macros.
      </xs:documentation>
    </xs:annotation>
    <xs:all>
      <xs:element type="xs:string" name="comments" minOccurs="0"/>
      <xs:element type="typedef_named_times" name="named_times" minOccurs="0"/>
      <xs:element type="typedef_constants" name="constants" minOccurs="0"/>
      <xs:element type="typedef_macros" name="macros" minOccurs="0"/>
    </xs:all>
</xs:complexType>

<!-- ========================================== Execution Control  ========================================== -->
<xs:complexType name="typedef_execution_controls">
	<xs:all>
		<xs:element name="comments" minOccurs="0" maxOccurs="1"/>
		<xs:element name="verbosity" type="typedef_verbosity" minOccurs="0" maxOccurs="1"/>
<!--		<xs:element name="simulation_start" type="typedef_exponential" minOccurs="1" maxOccurs="1"/>
		<xs:element name="simulation_end" type="typedef_exponential" minOccurs="1" maxOccurs="1"/> -->
		<xs:element name="execution_control_defaults" type="typedef_execution_control_defaults" minOccurs="1" maxOccurs="1"/>
		<xs:element name="execution_control" type="typedef_execution_control" minOccurs="1" maxOccurs="unbounded"/>
	</xs:all>
</xs:complexType>

<xs:complexType name="typedef_verbosity">
	<xs:attribute name="level" type="typedef_verbosity_level"/>
</xs:complexType>

<xs:simpleType name="typedef_verbosity_level">
	<xs:restriction base="xs:string">
		<xs:enumeration value="extreme"/>
		<xs:enumeration value="high"/>
		<xs:enumeration value="medium"/>
		<xs:enumeration value="low"/>
		<xs:enumeration value="none"/>
	</xs:restriction>
</xs:simpleType>

<xs:complexType name="typedef_execution_control_defaults">
	<xs:attribute name="init_dt" type="typedef_labeled_time"/>
	<xs:attribute name="max_dt" type="typedef_labeled_time"/>
	<xs:attribute name="reduction_factor" type="typedef_exponential"/>
	<xs:attribute name="increase_factor" type="typedef_exponential"/>
	<xs:attribute name="mode" type="typedef_mode"/>
	<xs:attribute name="method" type="typedef_method"/>
</xs:complexType>

<xs:complexType name="typedef_execution_control">
	<xs:attribute name="restart" type="xs:string"/>
	<xs:attribute name="start" type="xs:string" use="required"/>
	<xs:attribute name="end" type="xs:string"/>
	<xs:attribute name="init_dt" type="xs:string"/>
	<xs:attribute name="max_dt" type="xs:string"/>
	<xs:attribute name="reduction_factor" type="typedef_exponential"/>
	<xs:attribute name="increase_factor" type="typedef_exponential"/>	
	<xs:attribute name="mode" type="typedef_mode"/>
	<xs:attribute name="method" type="typedef_method"/>
	<xs:attribute name="max_cycles" type="xs:integer"/>
</xs:complexType>

<xs:simpleType name="typedef_mode">
	<xs:restriction base="xs:string">
		<xs:enumeration value="steady"/>
        <xs:enumeration value="transient"/>
	</xs:restriction>
</xs:simpleType>

<xs:simpleType name="typedef_method">
	<xs:restriction base="xs:string">
		<xs:enumeration value="bdf1"/>
		<xs:enumeration value="picard"/>
	</xs:restriction>
</xs:simpleType>

<!-- ========================================== Numerical Controls  ========================================== -->
<xs:complexType name="typedef_numerical_controls">
	<xs:sequence>
		<xs:element name="comments" minOccurs="0" maxOccurs="1"/>
		<xs:element name="common_controls" type="typedef_common_controls" minOccurs="0" maxOccurs="1"/>
        <xs:choice minOccurs="1" maxOccurs="1">
			<xs:element name="unstructured_controls" type="typedef_unstructured_controls"/>
			<xs:element name="structured_controls" type="typedef_structured_controls"/>
		</xs:choice>
	</xs:sequence>
</xs:complexType>

<xs:complexType name="typedef_common_controls">
  <xs:all minOccurs = "0" maxOccurs = "1">
    <xs:element name="comments" minOccurs="0" maxOccurs="1"/>
  </xs:all>
</xs:complexType>

<xs:complexType name="typedef_unstructured_controls">
  <xs:all minOccurs = "0" maxOccurs = "1">
    <xs:element name="comments" minOccurs="0" maxOccurs="1"/>
    <xs:element name="unstr_steady-state_controls" type="typedef_unstr_steady-state_controls" minOccurs="0" maxOccurs="1"/>
    <xs:element name="unstr_transient_controls" type="typedef_unstr_transient_controls" minOccurs="0" maxOccurs="1"/>
    <xs:element name="unstr_linear_solver" type="typedef_unstr_linear_solver" minOccurs="0" maxOccurs="1"/>
    <xs:element name="unstr_nonlinear_solver" type="typedef_unstr_nonlinear_solver" minOccurs="0" maxOccurs="1"/>
    <xs:element name="unstr_chemistry_controls" type="typedef_unstr_chemistry_controls" minOccurs="0" maxOccurs="1"/>
  </xs:all>
</xs:complexType>

<xs:complexType name="typedef_unstr_chemistry_controls">
	<xs:all minOccurs = "0" maxOccurs = "1">
		<xs:element name="chem_tolerance" type="typedef_exponential"/>
		<xs:element name="chem_max_newton_iterations" type="xs:integer"/>
	</xs:all>
</xs:complexType>

<xs:complexType name="typedef_unstr_steady-state_controls">
    <xs:all minOccurs = "0" maxOccurs = "1">
        <xs:element name="comments" minOccurs = "0" maxOccurs = "1"/>
        <xs:element name="min_iterations" type="xs:integer" minOccurs = "0" maxOccurs = "1"/>
        <xs:element name="limit_iterations" type="xs:integer" minOccurs = "0" maxOccurs = "1"/>
	<xs:element name="max_iterations" type="xs:integer" minOccurs = "0" maxOccurs = "1"/>
	<xs:element name="max_preconditioner_lag_iterations" type="xs:integer" minOccurs = "0" maxOccurs = "1"/>
        <xs:element name="nonlinear_tolerance" type="typedef_exponential" minOccurs = "0" maxOccurs = "1"/>
        <xs:element name="error_control_options" type="xs:string" minOccurs = "0" maxOccurs = "1"/>
	<xs:element name="unstr_pseudo_time_integrator" type="typedef_unstr_pseudo_time_integrator" minOccurs = "0" maxOccurs = "1"/>
	<xs:element name="nonlinear_iteration_damping_factor" type="typedef_exponential" minOccurs = "0" maxOccurs = "1"/>
	<xs:element name="nonlinear_iteration_divergence_factor" type="typedef_exponential" minOccurs = "0" maxOccurs = "1"/>
	<xs:element name="max_divergent_iterations" type="xs:integer" minOccurs = "0" maxOccurs = "1"/>
	<xs:element name="initialize_with_darcy" type="xs:boolean" minOccurs = "0" maxOccurs = "1"/>
	<xs:element name="restart_tolerance_factor" type="typedef_exponential"/>
	<xs:element name="restart_tolerance_relaxation_factor" type="typedef_exponential"/>
        <xs:assert  test="@error_control_options = ('pressure','residual')"/>
    </xs:all>
</xs:complexType>

<xs:complexType name="typedef_unstr_pseudo_time_integrator">
	<xs:all minOccurs = "0" maxOccurs = "1">
		<xs:element name="initialize_with_darcy" type="xs:boolean" minOccurs = "0" maxOccurs = "1"/>
		<xs:element name="clipping_saturation" type="typedef_exponential" minOccurs = "0" maxOccurs = "1"/>
		<xs:element name="method" type="typedef_unstr_pseudo_time_method" minOccurs = "0" maxOccurs = "1"/>
		<xs:element name="preconditioner" type="typedef_unstr_pseudo_time_preconditioner" minOccurs = "0" maxOccurs = "1"/>
		<xs:element name="linear_solver" type="typedef_unstr_pseudo_time_linear_solver" minOccurs = "0" maxOccurs = "1"/>
		<xs:element name="error_control_options" type="xs:string" minOccurs = "0" maxOccurs = "1"/>
		<xs:element name="convergence_tolerance" type="typedef_exponential" minOccurs = "0" maxOccurs = "1"/>
                <xs:element name="max_iterations" type="xs:integer" minOccurs = "0" maxOccurs = "1"/>
                <xs:assert  test="@error_control_options = ('pressure')"/>
	</xs:all>
</xs:complexType>

<xs:simpleType name="typedef_unstr_pseudo_time_method">
	<xs:restriction base="xs:string">
		<xs:enumeration value="picard"/>
	</xs:restriction>
</xs:simpleType>

<xs:simpleType name="typedef_unstr_pseudo_time_linear_solver">
	<xs:restriction base="xs:string">
		<xs:enumeration value="aztec00"/>
	</xs:restriction>
</xs:simpleType>

<xs:simpleType name="typedef_unstr_pseudo_time_preconditioner">
	<xs:restriction base="xs:string">
		<xs:enumeration value="trilinos_ml"/>
		<xs:enumeration value="hypre_amg"/>
		<xs:enumeration value="block_ilu"/>
	</xs:restriction>
</xs:simpleType>

<xs:complexType name="typedef_unstr_transient_controls">
	<xs:all minOccurs = "0" maxOccurs = "1">
		<xs:element name="comments" minOccurs = "0" maxOccurs = "1"/>
		<xs:element name="bdf1_integration_method" type="typedef_unstr_bdf1_integration_method" minOccurs = "0" maxOccurs = "1"/>
		<xs:element name="preconditioner" minOccurs="0" maxOccurs="1">
			<xs:alternative test="@name eq 'trilinos_ml'" type="typedef_trilinos_ml"/>
			<xs:alternative test="@name eq 'hypre_amg'" type="typedef_hypre_amg"/>
			<xs:alternative test="@name eq 'block_ilu'" type="typedef_block_ilu"/>
			<xs:alternative type="xs:error"/>
		</xs:element>
	</xs:all>
</xs:complexType>

<xs:complexType name="typedef_unstr_bdf1_integration_method">
	<xs:attribute name="min_iterations" type="xs:integer"/>   
        <xs:attribute name="max_iterations" type="xs:integer"/>
        <xs:attribute name="limit_iterations" type="xs:integer"/>
        <xs:attribute name="nonlinear_tolerance" type="typedef_exponential"/>
	<xs:attribute name="nonlinear_iteration_damping_factor" type="typedef_exponential"/>
	<xs:attribute name="max_preconditioner_lag_iterations" type="xs:integer"/> 
	<xs:attribute name="max_divergent_iterations" type="xs:integer"/>   
	<xs:attribute name="nonlinear_iteration_divergence_factor" type="typedef_exponential"/>
	<xs:attribute name="restart_tolerance_factor" type="typedef_exponential"/>
	<xs:attribute name="restart_tolerance_relaxation_factor" type="typedef_exponential"/>
        <xs:attribute name="initialize_with_darcy" type="xs:boolean" />
        <xs:attribute name="error_control_options" type="xs:string" />
</xs:complexType>

<xs:complexType name="typedef_unstr_nonlinear_solver">
	<xs:attribute name="name" type="xs:string"/>
	<xs:assert  test="@name = ('nka','newton', 'inexact newton')"/>	 
</xs:complexType>

<xs:complexType name="typedef_unstr_linear_solver">
	<xs:all minOccurs = "0" maxOccurs = "1">
	<xs:element name="method" type="xs:string" minOccurs="0" maxOccurs="1"/>
	<xs:element name="comments" minOccurs="0" maxOccurs="1"/>
	<xs:element name="max_iterations" type="xs:integer" minOccurs="0" maxOccurs="1"/>
	<xs:element name="tolerance" type="typedef_exponential" minOccurs="0" maxOccurs="1"/>
        <xs:element name="cfl" type="typedef_exponential" minOccurs="0" maxOccurs="1"/>
	<xs:element name="preconditioner" minOccurs="0" maxOccurs="1">
		<xs:alternative test="@name eq 'trilinos_ml'" type="typedef_trilinos_ml"/>
		<xs:alternative test="@name eq 'hypre_amg'" type="typedef_hypre_amg"/>
		<xs:alternative test="@name eq 'block_ilu'" type="typedef_block_ilu"/>
		<xs:alternative type="xs:error"/>
	</xs:element>
	</xs:all>
</xs:complexType>

<xs:complexType name="typedef_hypre_amg">
        <xs:complexContent>
                <xs:extension base="typedef_ls_preconditioner">
			<xs:all>
				<xs:element name="hypre_cycle_applications" type="xs:integer" minOccurs = "0" maxOccurs = "1"/>
				<xs:element name="hypre_smoother_sweeps" type="xs:integer" minOccurs = "0" maxOccurs = "1"/>
				<xs:element name="hypre_tolerance" type="typedef_exponential" minOccurs = "0" maxOccurs = "1"/>
				<xs:element name="hypre_strong_threshold" type="typedef_exponential" minOccurs = "0" maxOccurs = "1"/>
			</xs:all>
                </xs:extension>
        </xs:complexContent>
</xs:complexType>

<xs:complexType name="typedef_ls_preconditioner">
	<xs:attribute name="name" type="xs:string"/>
	<xs:assert  test="@name = ('trilinos_ml','hypre_amg', 'block_ilu')"/>	 
</xs:complexType>

<xs:complexType name="typedef_trilinos_ml">
        <xs:complexContent>
                <xs:extension base="typedef_ls_preconditioner">
			<xs:all>
				<xs:element name="trilinos_smoother_type" minOccurs="0" maxOccurs="1">
					<xs:alternative test="@type eq 'jacobi'" type="xs:string"/>
					<xs:alternative test="@type eq 'gauss_seidel'" type="xs:string"/>
					<xs:alternative test="@type eq 'ilu'" type="xs:string"/>
				</xs:element>
				<xs:element name="trilinos_threshold" type="typedef_exponential" minOccurs = "0" maxOccurs = "1"/>
				<xs:element name="trilinos_smoother_sweeps" type="xs:integer" minOccurs = "0" maxOccurs = "1"/>
				<xs:element name="trilinos_cycle_applications" type="xs:integer" minOccurs = "0" maxOccurs = "1"/>
			</xs:all>
                </xs:extension>
        </xs:complexContent>
</xs:complexType>

<xs:complexType name="typedef_block_ilu">
        <xs:complexContent>
                <xs:extension base="typedef_ls_preconditioner">
			<xs:all>
				<xs:element name="ilu_overlap" type="xs:integer" minOccurs = "0" maxOccurs = "1"/>
				<xs:element name="ilu_relax" type="typedef_exponential" minOccurs = "0" maxOccurs = "1"/>
				<xs:element name="ilu_rel_threshold" type="typedef_exponential" minOccurs = "0" maxOccurs = "1"/>
				<xs:element name="ilu_abs_threshold" type="typedef_exponential" minOccurs = "0" maxOccurs = "1"/>
				<xs:element name="ilu_level_of_fill" type="xs:integer" minOccurs = "0" maxOccurs = "1"/>
			</xs:all>
                </xs:extension>
        </xs:complexContent>
</xs:complexType>

<xs:complexType name="typedef_structured_controls">
  <xs:all minOccurs = "0" maxOccurs = "1">
    <xs:element name="comments" minOccurs="0" maxOccurs="1"/>
    <xs:element name="str_steady-state_controls" type="typedef_str_steady-state_controls" minOccurs="0" maxOccurs="1"/>
    <xs:element name="str_transient_controls" type="typedef_str_transient_controls" minOccurs="0" maxOccurs="1"/>
    <xs:element name="str_amr_controls" type="typedef_amr_controls" minOccurs="0" maxOccurs="1"/>
    <xs:element name="max_n_subcycle_transport" type="xs:integer" minOccurs="0" maxOccurs="1"/>
  </xs:all>
</xs:complexType>

<xs:complexType name="typedef_str_steady-state_controls">
  <xs:all minOccurs = "0" maxOccurs = "1">
    <xs:element name="comments" minOccurs = "0" maxOccurs = "1"/>
    <xs:element name="max_pseudo_time" type="typedef_exponential" minOccurs = "0" maxOccurs = "1"/>
    <xs:element name="min_iterations" type="xs:integer" minOccurs = "0" maxOccurs = "1"/>
    <xs:element name="limit_iterations" type="xs:integer" minOccurs = "0" maxOccurs = "1"/>
    <xs:element name="min_iterations_2" type="xs:integer" minOccurs = "0" maxOccurs = "1"/>
    <xs:element name="time_step_increase_factor" type="typedef_exponential" minOccurs = "0" maxOccurs = "1"/>
    <xs:element name="time_step_increase_factor_2" type="typedef_exponential" minOccurs = "0" maxOccurs = "1"/>
    <xs:element name="max_consecutive_failures_1" type="xs:integer" minOccurs = "0" maxOccurs = "1"/>
    <xs:element name="time_step_retry_factor_1" type="typedef_exponential" minOccurs = "0" maxOccurs = "1"/>
    <xs:element name="max_consecutive_failures_2" type="xs:integer" minOccurs = "0" maxOccurs = "1"/>
    <xs:element name="time_step_retry_factor_2" type="typedef_exponential" minOccurs = "0" maxOccurs = "1"/>
    <xs:element name="time_step_retry_factor_f" type="typedef_exponential" minOccurs = "0" maxOccurs = "1"/>
    <xs:element name="max_num_consecutive_success" type="xs:integer" minOccurs = "0" maxOccurs = "1"/>
    <xs:element name="extra_time_step_increase_factor" type="typedef_exponential" minOccurs = "0" maxOccurs = "1"/>
    <xs:element name="abort_on_psuedo_timestep_failure" type="xs:boolean" minOccurs = "0" maxOccurs = "1"/>
    <xs:element name="limit_function_evals" type="xs:integer" minOccurs = "0" maxOccurs = "1"/>
    <xs:element name="do_grid_sequence" type="xs:boolean" minOccurs = "0" maxOccurs = "1"/>
    <xs:element name="grid_sequence_new_level_dt_factor" type="typedef_grid_sequence" minOccurs = "0" maxOccurs = "1"/>
  </xs:all>
</xs:complexType>

<xs:complexType name="typedef_grid_sequence">
  <xs:sequence>
    <xs:element name="dt_factor" type="typedef_exponential" minOccurs="0" maxOccurs="unbounded"/>
  </xs:sequence>
</xs:complexType>

<xs:complexType name="typedef_str_transient_controls">
  <xs:all minOccurs = "0" maxOccurs = "1">
    <xs:element name="comments" minOccurs = "0" maxOccurs = "1"/>
    <xs:element name="max_ls_iterations" type="xs:integer" minOccurs = "0" maxOccurs = "1"/>
    <xs:element name="ls_reduction_factor" type="typedef_exponential" minOccurs = "0" maxOccurs = "1"/>
    <xs:element name="min_ls_factor" type="typedef_exponential" minOccurs = "0" maxOccurs = "1"/>
    <xs:element name="ls_acceptance_factor" type="typedef_exponential" minOccurs = "0" maxOccurs = "1"/>
    <xs:element name="monitor_line_search" type="xs:integer" minOccurs = "0" maxOccurs = "1"/>
    <xs:element name="monitor_linear_solve" type="xs:integer" minOccurs = "0" maxOccurs = "1"/>
    <xs:element name="use_fd_jac" type="xs:boolean" minOccurs = "0" maxOccurs = "1"/>
    <xs:element name="perturbation_scale_for_J" type="typedef_exponential" minOccurs = "0" maxOccurs = "1"/>
    <xs:element name="use_dense_Jacobian" type="xs:boolean" minOccurs = "0" maxOccurs = "1"/>
    <xs:element name="upwind_krel" type="xs:boolean" minOccurs = "0" maxOccurs = "1"/>
    <xs:element name="pressure_maxorder" type="xs:integer" minOccurs = "0" maxOccurs = "1"/>
    <xs:element name="scale_solution_before_solve" type="xs:boolean" minOccurs = "0" maxOccurs = "1"/>
    <xs:element name="semi_analytic_J" type="xs:boolean" minOccurs = "0" maxOccurs = "1"/>
    <xs:element name="cfl" type="typedef_exponential" />
  </xs:all>
</xs:complexType>

<xs:complexType name="typedef_amr_controls">
  <xs:all minOccurs = "0" maxOccurs = "1">
    <xs:element name="comments" minOccurs = "0" maxOccurs = "1"/>
    <xs:element name="amr_levels" type="xs:integer" minOccurs = "0" maxOccurs = "1"/>
    <xs:element name="refinement_ratio" type="typedef_amr_array_ints" minOccurs = "0" maxOccurs = "1"/>
    <xs:element name="do_amr_cubcycling" type="xs:boolean" minOccurs = "0" maxOccurs = "1"/>
    <xs:element name="regrid_interval" type="typedef_amr_array_ints" minOccurs = "0" maxOccurs = "1"/>
    <xs:element name="blocking_factor" type="typedef_amr_array_ints" minOccurs = "0" maxOccurs = "1"/>
    <xs:element name="number_error_buffer_cells" type="typedef_amr_array_ints" minOccurs = "0" maxOccurs = "1"/>
    <xs:element name="max_grid_size" type="typedef_amr_array_ints" minOccurs = "0" maxOccurs = "1"/>
    <xs:element name="refinement_indicators" type="typedef_refinement_indicators" minOccurs = "0" maxOccurs = "unbounded"/>
  </xs:all>
</xs:complexType>

<xs:complexType name="typedef_amr_array_ints">
  <xs:sequence>
    <xs:element name="int" type="xs:integer" minOccurs="0" maxOccurs="unbounded"/>
  </xs:sequence>
</xs:complexType>

<xs:complexType name="typedef_refinement_indicators">
  <xs:sequence>
    <xs:element name="field_name" type="xs:string" minOccurs="0" maxOccurs="1"/>
    <xs:element name="regions" type="xs:string" minOccurs="0" maxOccurs="1"/>
    <xs:choice minOccurs="1" maxOccurs="1">
      <xs:element name="value_greater" type="typedef_exponential"/>
      <xs:element name="value_less" type="typedef_exponential"/>
      <xs:element name="adjacent_difference_greater" type="typedef_exponential"/>
      <xs:element name="inside_region" type="xs:boolean"/>
    </xs:choice>
    <xs:element name="max_refinement_level" type="xs:integer" minOccurs="0" maxOccurs="unbounded"/>
    <xs:element name="start_time" type="typedef_exponential" minOccurs="0" maxOccurs="unbounded"/>
    <xs:element name="end_time" type="typedef_exponential" minOccurs="0" maxOccurs="unbounded"/>
  </xs:sequence>
  <xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>

<!-- ============================================ Mesh ============================================== -->

<xs:complexType name="typedef_mesh_unstructured">
	<xs:annotation>
		<xs:documentation xml:lang="en">
		</xs:documentation>
	</xs:annotation>
	<xs:sequence>
		<xs:element name="comments" minOccurs="0" maxOccurs="1"/>
		<xs:element name="dimension" type="typedef_dimension" minOccurs="1" maxOccurs="1"/>
		<xs:choice minOccurs="1" maxOccurs="1">
			<xs:element name="read" type="typedef_read"/>
			<xs:element name="generate" type="typedef_generate"/>
		</xs:choice>
	</xs:sequence>
	<xs:attribute name="framework" type="xs:string" use="required"/>
	<xs:assert  test="@framework = ('mstk','stk::mesh','simple')"/>	 
            <!-- EIB: moab current doesn't work, exodus is a file format, boxlib in the future -->
            <!-- EIB: translator default is mstk -->
</xs:complexType>

<xs:complexType name="typedef_mesh_structured">
	<xs:annotation>
		<xs:documentation xml:lang="en">
		</xs:documentation>
	</xs:annotation>
	<xs:all>
		<xs:element name="comments" minOccurs="0" maxOccurs="1"/>
		<xs:element name="dimension" type="typedef_dimension" minOccurs="1" maxOccurs="1"/>
		<xs:element name="generate" type="typedef_generate" minOccurs="1" maxOccurs="1"/>
	</xs:all> 
</xs:complexType>

<!-- Typedefs -->
<xs:complexType name="typedef_xyz">
	<xs:attribute name="nx" type="xs:integer"/>
	<xs:attribute name="ny" type="xs:integer"/>
	<xs:attribute name="nz" type="xs:integer"/>
</xs:complexType>

<xs:complexType name="typedef_generate">
	<xs:all>
		<xs:element name="number_of_cells" type="typedef_xyz" minOccurs="1" maxOccurs="1"/>
		<xs:element name="box" type="typedef_box" minOccurs="1" maxOccurs="1"/>
	</xs:all>	
</xs:complexType>

<xs:complexType name="typedef_read">
	<xs:all>
		<xs:element name="format" type="typedef_mesh_file_formats" minOccurs="1" maxOccurs="1"/>
		<xs:element name="file" type="xs:string" minOccurs="1" maxOccurs="1"/>
	</xs:all>	
</xs:complexType>

<!-- ============================================ Regions ============================================== -->

<xs:complexType name="typedef_regions">
	<xs:sequence>
		<xs:choice minOccurs="1" maxOccurs="unbounded">
			<xs:element name="comments" minOccurs="0" maxOccurs= "unbounded"/>
			<xs:element name="region" type="typedef_region" minOccurs="0" maxOccurs="unbounded"/>
			<xs:element name="box" type="typedef_labeled_box" minOccurs="0" maxOccurs="unbounded"/>
			<xs:element name="point" type="typedef_labeled_point" minOccurs="0" maxOccurs="unbounded"/>
			<xs:element name="plane" type="typedef_labeled_plane" minOccurs="0" maxOccurs="unbounded"/>
		</xs:choice>
	</xs:sequence>
</xs:complexType>

<xs:complexType name="typedef_region">
	<xs:annotation>
		<xs:documentation xml:lang="en">
		</xs:documentation>
	</xs:annotation>
	<xs:sequence>
		<xs:element name="comments" minOccurs="0" maxOccurs="1"/>
		<xs:choice minOccurs="1" maxOccurs="1">
			<xs:element name="region_file" type="typedef_region_file"/>
			<xs:element name="box" type="typedef_box"/>
			<xs:element name="plane" type="typedef_plane"/>
		</xs:choice>
	</xs:sequence>
	<xs:attribute name="name" type="xs:string"/>
</xs:complexType>

<xs:complexType name="typedef_regions_unstructured">
  <xs:complexContent>
    <xs:extension base="typedef_regions">
      <xs:sequence>
        <xs:element name="polygonal_surface" type="typedef_polygonal_surface" minOccurs="0" maxOccurs="unbounded"/>
        <xs:element name="logical" type="typedef_logical" minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
    </xs:extension>
  </xs:complexContent>
</xs:complexType>

<xs:complexType name="typedef_regions_structured">
  <xs:complexContent>
    <xs:extension base="typedef_regions">
      <xs:sequence>
        <xs:element name="polygon" type = "typedef_polygon" minOccurs="0" maxOccurs="unbounded"/>
        <xs:element name="ellipse" type = "typedef_ellipse" minOccurs="0" maxOccurs="unbounded"/>
        <xs:element name="rotated_polygon" type="typedef_rotated_polygon" minOccurs="0" maxOccurs="unbounded"/>
        <xs:element name="swept_polygon" type="typedef_swept_polygon" minOccurs="0" maxOccurs="unbounded"/>
      </xs:sequence>
    </xs:extension>
  </xs:complexContent>
</xs:complexType>

<!-- unstructured only regions -->
<xs:complexType name="typedef_polygonal_surface">
  <xs:sequence>
    <xs:element name="point" type="typedef_coordinate" minOccurs="0" maxOccurs="unbounded"/>
  </xs:sequence>
  <xs:attribute name="name" type="xs:string"/>
  <xs:attribute name="num_points" type="xs:integer"/> <!-- optional -->
</xs:complexType>
  
<xs:complexType name="typedef_logical">
  <xs:all>
    <xs:element name="operation" type="typedef_logical_operation" minOccurs="1" maxOccurs="1"/>
    <xs:element name="region_list" type="typedef_assigned_regions" minOccurs="1" maxOccurs="1"/>
  </xs:all>
  <xs:attribute name="name" type="xs:string"/>
</xs:complexType>

<xs:simpleType name="typedef_logical_operation">
  <xs:restriction base="xs:string">
    <xs:enumeration value="union"/>
    <xs:enumeration value="intersection"/>
    <xs:enumeration value="subtraction"/>
    <xs:enumeration value="complement"/>
  </xs:restriction>
</xs:simpleType>

<!-- unstructured only regions -->
<xs:complexType name="typedef_polygon"> <!-- 2D only -->
  <xs:sequence>
    <xs:element name="point" type="typedef_coordinate" minOccurs="0" maxOccurs="unbounded"/>
  </xs:sequence>
  <xs:attribute name="name" type="xs:string"/>
  <xs:attribute name="num_points" type="xs:integer"/> <!-- optional -->
</xs:complexType>

<xs:complexType name="typedef_ellipse"> <!-- 2D only -->
  <xs:all>
    <xs:element name="center" type="typedef_coordinate" minOccurs="1" maxOccurs="1"/>
    <xs:element name="radius" type="typedef_coordinate" minOccurs="1" maxOccurs="1"/>
  </xs:all>
  <xs:attribute name="name" type="xs:string"/>
</xs:complexType>

<xs:complexType name="typedef_rotated_polygon"> <!-- 3D only -->
  <xs:sequence>
    <xs:sequence>
      <xs:element name="vertex" type="typedef_coordinate" minOccurs="1" maxOccurs="unbounded"/>
    </xs:sequence>
    <xs:element name="xyz_plane" type="typedef_xyz_plane" minOccurs="1" maxOccurs="1"/>
    <xs:element name="axis" type="typedef_axis" minOccurs="1" maxOccurs="1"/>
    <xs:element name="reference_point" type="typedef_coordinate" minOccurs="1" maxOccurs="1"/>
  </xs:sequence>
  <xs:attribute name="name" type="xs:string"/>
</xs:complexType>

<xs:complexType name="typedef_swept_polygon"> <!-- 3D only -->
  <xs:sequence>
    <xs:sequence>
      <xs:element name="vertex" type="typedef_coordinate" minOccurs="1" maxOccurs="unbounded"/>
    </xs:sequence>
    <xs:element name="xyz_plane" type="typedef_xyz_plane" minOccurs="1" maxOccurs="1"/>
    <xs:element name="extent_min" type="typedef_exponential" minOccurs="1" maxOccurs="1"/>
    <xs:element name="extent_max" type="typedef_exponential" minOccurs="1" maxOccurs="1"/>
  </xs:sequence>
  <xs:attribute name="name" type="xs:string"/>
</xs:complexType>

<xs:simpleType name="typedef_xyz_plane">
  <xs:restriction base="xs:string">
    <xs:enumeration value="xy"/>
    <xs:enumeration value="xz"/>
    <xs:enumeration value="yz"/>
  </xs:restriction>
</xs:simpleType>

<xs:simpleType name="typedef_axis">
  <xs:restriction base="xs:string">
    <xs:enumeration value="x"/>
    <xs:enumeration value="y"/>
    <xs:enumeration value="z"/>
  </xs:restriction>
</xs:simpleType>

<!-- ============================================ Geochemistry ========================================== -->

<xs:complexType name="typedef_main_geochemistry" mixed = "true">
	<xs:all>
		<xs:element name="comments" minOccurs="0" maxOccurs="1"/>
		<xs:element name="reaction_network" type="typedef_reaction_network" minOccurs="1" maxOccurs="1"/>
		<xs:element name="verbosity" type="typedef_chem_verbosity" minOccurs="0" maxOccurs="1"/>
		<xs:element name="activity_model" type="typedef_activity_model" minOccurs="0" maxOccurs="1"/>
		<xs:element name="auxillary_data" type="typedef_auxillary_data" minOccurs="0" maxOccurs="1"/>
		<xs:element name="constraints" type="typedef_geochem_constraints" minOccurs="1" maxOccurs= "1"/>
	</xs:all>
</xs:complexType>

<xs:complexType name="typedef_reaction_network">
	<xs:attribute name="file" type="xs:string"/>
	<xs:attribute name="format" type="xs:string"/>
	<!-- what are the different format types for amanzi chemistry? -->
	<xs:assert test="@format = ('simple','none')"/>
</xs:complexType>

<xs:simpleType name="typedef_chem_verbosity">
	<xs:restriction base="xs:string">
	<!-- what are the different verbosity options? -->
		<xs:enumeration value="verbose"/>
		<xs:enumeration value="low"/>
	</xs:restriction>
</xs:simpleType>

<xs:simpleType name="typedef_activity_model">
	<!-- what are the different activity models? -->
	<xs:restriction base="xs:string">
		<xs:enumeration value="unit"/>
		<xs:enumeration value="pitzer"/>
	</xs:restriction>
</xs:simpleType>

<xs:simpleType name="typedef_auxillary_data">
	<!-- what are the different options for aux data?  -->
	<xs:restriction base="xs:string">
		<xs:enumeration value="pH"/>
	</xs:restriction>
</xs:simpleType>

<xs:complexType name="typedef_geochem_constraints">
	<xs:all>
		<xs:element name="constraint" type="typedef_geochem_constraint" minOccurs="1" maxOccurs="unbounded"/>
	</xs:all>
</xs:complexType>

<xs:complexType name="typedef_geochem_constraint">
	<!-- TODO: at least one solute or mineral is required if filename is not given 
         -->
	<xs:all>
		<xs:element name="solute" type="typedef_geochem_solute" minOccurs="0" maxOccurs="unbounded"/>
		<xs:element name="mineral" type="typedef_geochem_mineral" minOccurs="0" maxOccurs="unbounded"/>
	</xs:all>
	<xs:attribute name="name" type="xs:string"/>
	<xs:attribute name="filename" type="xs:string"/>
</xs:complexType>

<xs:complexType name="typedef_geochem_solute">
	<!-- TODO: attributes gas and mineral should only appear 
             if the corresponding type is specified -->
	<xs:attribute name="name" type="xs:string"/>
	<xs:attribute name="value" type="typedef_exponential"/>
	<xs:attribute name="type" type="xs:string"/>
	<xs:attribute name="gas" type="xs:string"/>
	<xs:attribute name="mineral" type="xs:string"/>
</xs:complexType>

<xs:complexType name="typedef_geochem_mineral">
	<xs:attribute name="name" type="xs:string"/>
	<xs:attribute name="volume_fraction" type="typedef_exponential"/>
	<xs:attribute name="surface_area" type="typedef_exponential"/>
</xs:complexType>

<!-- ============================================ Material ============================================== -->

<xs:complexType name="typedef_materials">
	<xs:all>
		<xs:element name="material" type="typedef_material" minOccurs="1" maxOccurs="unbounded"/>
	</xs:all>
</xs:complexType>

<xs:complexType name="typedef_material">
	<xs:all>
		<xs:element name="comments" minOccurs="0" maxOccurs="1"/>
		<xs:element name="mechanical_properties" type="typedef_mechanical_properties" minOccurs="1" maxOccurs="1"/>
		<xs:element name="sorption_isotherms" type="typedef_sorption_isotherms" minOccurs="0" maxOccurs="1"/>
		<!-- We need either permeability or hydraulic conductivity, need to add a check with a choice? -->
                <xs:element name="permeability" minOccurs="0" maxOccurs="1">
		    <!-- EIB: may change value of type, therefore test for existance not value-->
                  <xs:alternative test="exists(@type)" type="typedef_property_file"/>
                  <xs:alternative type="typedef_permeability"/>
                </xs:element>
		<xs:element name="hydraulic_conductivity" type="typedef_hydraulic_conductivity" minOccurs="0" maxOccurs="1"/>
		<!-- cap_pressure and rel_perm are not needed if flow model = "saturated"; can we validate this? -->
		<xs:element name="cap_pressure" minOccurs="0" maxOccurs="1">
			<xs:alternative test="@model eq 'van_genuchten'" type="typedef_van_genuchten"/>
	 		<xs:alternative test="@model eq 'brooks_corey'" type="typedef_brooks_corey"/>
	 		<xs:alternative test="@model eq 'none'" type="typedef_cap_pressure"/>
	 		<xs:alternative type="xs:error"/>
		</xs:element>
		<xs:element name="rel_perm" minOccurs="0" maxOccurs="1">
			<xs:alternative test="@model eq 'mualem'" type="typedef_mualem"/>
			<xs:alternative test="@model eq 'burdine'" type="typedef_burdine"/>
			<xs:alternative test="@model eq 'none'" type="typedef_rel_perm"/>
			<xs:alternative type="xs:error"/>
		</xs:element>
		<xs:element name="assigned_regions" type="typedef_assigned_regions" minOccurs="1" maxOccurs="1"/>
	</xs:all>
	<xs:attribute name="name" type="xs:string"/>
</xs:complexType>

<xs:complexType name="typedef_mechanical_properties">
	<xs:all>
		<xs:element name="porosity" minOccurs="1" maxOccurs="1">			
		        <!-- EIB: may change value of type, therefore test for existance not value-->
			<xs:alternative test="exists(@type)" type="typedef_property_file"/>
			<xs:alternative type="typedef_porosity"/>
		</xs:element>
		<xs:element name="particle_density" minOccurs="0" maxOccurs="1">			
		        <!-- EIB: may change value of type, therefore test for existance not value-->
			<xs:alternative test="exists(@type)" type="typedef_property_file"/>
			<xs:alternative type="typedef_particle_density"/>
		</xs:element>
		<xs:element name="specific_storage" minOccurs="0" maxOccurs="1">			
		        <!-- EIB: may change value of type, therefore test for existance not value-->
			<xs:alternative test="exists(@type)" type="typedef_property_file"/>
			<xs:alternative type="typedef_specific_storage"/>
		</xs:element>
		<xs:element name="specific_yield" minOccurs="0" maxOccurs="1">			
		        <!-- EIB: may change value of type, therefore test for existance not value-->
			<xs:alternative test="exists(@type)" type="typedef_property_file"/>
			<xs:alternative type="typedef_specific_yield"/>
		</xs:element>
		<xs:element name="dispersion_tensor" minOccurs="0" maxOccurs="1">			
                        <xs:alternative test="@type='file'" type="typedef_property_file"/>
                        <xs:alternative test="@type='uniform_isotropic'" type="typedef_dispersion_tensor_uniform_isotropic"/>
                        <xs:alternative test="@type='burnett_frind'" type="typedef_dispersion_tensor_burnett_frind"/>
                        <xs:alternative test="@type='lichtner_kelkar_robinson'" type="typedef_dispersion_tensor_lichtner_kelkar_robinson"/>
		</xs:element>
		<xs:element name="tortuosity" minOccurs="0" maxOccurs="1">			
		        <!-- EIB: may change value of type, therefore test for existance not value-->
			<xs:alternative test="exists(@type)" type="typedef_property_file"/>
			<xs:alternative type="typedef_tortuosity"/>
		</xs:element>
	</xs:all>
</xs:complexType>


<xs:complexType name="typedef_particle_density">
	<xs:attribute name="value" use="required" type="restriction_ge0"/>
</xs:complexType>

<xs:complexType name="typedef_porosity">
	<xs:attribute name="value" use="required" type="restriction_porosity"/>
</xs:complexType>

<xs:complexType name="typedef_specific_storage">
	<xs:attribute name="value" type="typedef_exponential"/>
</xs:complexType>

<xs:complexType name="typedef_specific_yield">
	<xs:attribute name="value" type="typedef_exponential"/>
</xs:complexType>

<xs:complexType name="typedef_dispersion_tensor_uniform_isotropic">
	<xs:attribute name="alpha_l" use="required" type="typedef_exponential"/>
	<xs:attribute name="alpha_t" use="required" type="typedef_exponential"/>
</xs:complexType>
<xs:complexType name="typedef_dispersion_tensor_burnett_frind">
        <xs:attribute name="alpha_l" use="required" type="typedef_exponential"/>
        <xs:attribute name="alpha_th" use="required" type="typedef_exponential"/>
        <xs:attribute name="alpha_tv" use="required" type="typedef_exponential"/>
</xs:complexType>
<xs:complexType name="typedef_dispersion_tensor_lichtner_kelkar_robinson">
        <xs:attribute name="alpha_lh" use="required" type="typedef_exponential"/>
        <xs:attribute name="alpha_lv" use="required" type="typedef_exponential"/>
        <xs:attribute name="alpha_th" use="required" type="typedef_exponential"/>
        <xs:attribute name="alpha_tv" use="required" type="typedef_exponential"/>
</xs:complexType>

<xs:complexType name="typedef_tortuosity">
	<xs:attribute name="value" use="required" type="typedef_exponential"/>
</xs:complexType>

<xs:simpleType name="restriction_porosity">
	<xs:restriction base="xs:decimal">
		<xs:minInclusive value="0"/>
		<xs:maxInclusive value="1"/>
	</xs:restriction>
</xs:simpleType>

<xs:simpleType name="restriction_ge0">
	<xs:restriction base="xs:decimal">
		<xs:minInclusive value="0"/>
	</xs:restriction>
</xs:simpleType>

<xs:complexType name="typedef_permeability">
	<xs:attribute name="x" type="typedef_exponential"/>
	<xs:attribute name="y" type="typedef_exponential"/>
	<xs:attribute name="z" type="typedef_exponential"/>
</xs:complexType>

<xs:complexType name="typedef_hydraulic_conductivity">
	<xs:attribute name="x" type="typedef_exponential"/>
	<xs:attribute name="y" type="typedef_exponential"/>
	<xs:attribute name="z" type="typedef_exponential"/>
</xs:complexType>

<xs:complexType name="typedef_cap_pressure">
	<xs:attribute name="model" type="xs:string" use="required"/>
	<xs:assert test="@model = ('van_genuchten','brooks_corey','none')"/>
</xs:complexType>

<xs:complexType name="typedef_van_genuchten">	
	<xs:complexContent>
		<xs:extension base="typedef_cap_pressure">
			<xs:all>
				<xs:element name="parameters" minOccurs="1" maxOccurs="1">
					<xs:complexType>
						<xs:attribute name="alpha" type="typedef_exponential"/>
						<xs:attribute name="sr" type="typedef_exponential"/>
						<xs:attribute name="m" type="typedef_exponential"/>
                                                <xs:attribute name="optional_krel_smoothing_interval" type="typedef_exponential"/>
					</xs:complexType>
				</xs:element>
			</xs:all>
		</xs:extension>
	</xs:complexContent>
</xs:complexType>

<xs:complexType name="typedef_brooks_corey">	
	<xs:complexContent>
		<xs:extension base="typedef_cap_pressure">
			<xs:all>
				<xs:element name="parameters" minOccurs="1" maxOccurs="1">
					<xs:complexType>
						<xs:attribute name="lambda" type="typedef_exponential"/>
						<xs:attribute name="alpha" type="typedef_exponential"/>
						<xs:attribute name="sr" type="typedef_exponential"/>
                                                <xs:attribute name="optional_krel_smoothing_interval" type="typedef_exponential"/>
					</xs:complexType>
				</xs:element>
			</xs:all>
		</xs:extension>
	</xs:complexContent>
</xs:complexType>

<xs:complexType name="typedef_rel_perm">
	<xs:attribute name="model" type="xs:string" use="required"/>
	<xs:assert test="@model = ('mualem','burdine','none')"/>
</xs:complexType>

<xs:complexType name="typedef_mualem">	
	<xs:complexContent>
		<xs:extension base="typedef_rel_perm">
                        <!--
			<xs:all>
     				<xs:element name="optional_krel_smoothing_interval" minOccurs="0" maxOccurs="1"/>
			</xs:all>
                         -->
		</xs:extension>
	</xs:complexContent>
</xs:complexType>

<xs:complexType name="typedef_burdine">	
	<xs:complexContent>
		<xs:extension base="typedef_rel_perm">
			<xs:all>
				<xs:element name="exp" minOccurs="1" maxOccurs="1"/>
     				<!-- xs:element name="optional_krel_smoothing_interval" minOccurs="0" maxOccurs="1"/ -->
			</xs:all>
		</xs:extension>
	</xs:complexContent>
</xs:complexType>

<xs:complexType name="typedef_sorption_isotherms">
	<xs:sequence>
		<xs:element name="solute" type="typedef_solute_isotherms" minOccurs="1" maxOccurs="unbounded"/>
	</xs:sequence>
</xs:complexType>

<xs:complexType name="typedef_solute_isotherms">
	<xs:all>
        	<xs:element name="molecular_diffusion" minOccurs="0" maxOccurs="1">			
		        <!-- EIB: may change value of type, therefore test for existance not value-->
			<xs:alternative test="exists(@type)" type="typedef_property_file"/>
		        <xs:alternative type="typedef_molecular_diffusion"/>
	        </xs:element>
		<xs:element name="kd_model" type="typedef_kd_model" minOccurs="0" maxOccurs="1"/>
	</xs:all>
	<xs:attribute name="name" type="xs:string" use="required"/>
</xs:complexType>

<xs:complexType name="typedef_kd_model">
	<xs:attribute name="model" type="xs:string" use="required"/>
	<xs:attribute name="kd" type="typedef_exponential" use="required"/>
	<xs:attribute name="b" type="typedef_exponential" />
	<xs:attribute name="n" type="typedef_exponential" />
	<xs:assert test="@model = ('linear','langmuir','freundlich')"/>
</xs:complexType>

<xs:complexType name="typedef_molecular_diffusion">
	<xs:attribute name="value" use="required" type="typedef_exponential"/>
</xs:complexType>

<!-- ============================================ Process Kernels ============================================== -->

<xs:complexType name="typedef_process_kernels">
	<xs:all>
		<xs:element name="comments" minOccurs="0" maxOccurs="1"/>
		<xs:element name="flow" type="typedef_flow" minOccurs="1" maxOccurs="1"/>
		<xs:element name="transport" type="typedef_transport" minOccurs="1" maxOccurs="1"/>
		<xs:element name="chemistry" type="typedef_chemistry" minOccurs="1" maxOccurs="1"/>
	</xs:all>
</xs:complexType>

<xs:complexType name="typedef_flow">
	<xs:attribute name="state" type="xs:string"/>
	<xs:attribute name="model" type="xs:string"/>
	<xs:attribute name="discretization_method" type="xs:string"/>
	<xs:attribute name="rel_perm_method" type="xs:string"/>
	<xs:assert  test="@state = ('on','off')"/>	
	<xs:assert  test="@model = ('richards','saturated','constant')"/>	
	<xs:assert test="@discretization_method = ('fv-default','fv-monotone','fv-multi_point_flux_approximation','fv-extended_to_boundary_edges','mfd-default','mfd-optimized_for_sparsity','mfd-support_operator','mfd-optimized_for_monotonicity','mfd-two_point_flux_approximation)"/>
	<xs:assert  test="@rel_perm_method = ('upwind-darcy_velocity','upwind-gravity','upwind-amanzi','other-arithmetic_average','other-harmonic_average')"/>	
	<!-- default: upwind-darcy_velocity; experimental: 'upwind-amanzi -->
</xs:complexType>

<xs:complexType name="typedef_transport">
	<xs:attribute name="state" type="xs:string"/>
	<xs:attribute name="algorithm" type="xs:string"/>
	<xs:attribute name="sub_cycling" type="xs:string" default="off"/> 
	<xs:assert  test="@state = ('on','off')"/>	
	<xs:assert  test="@algorithm = ('explicit first-order', 'explicit second-order', 'implicit upwind', 'none')"/>
	<xs:assert  test="(@algorithm = 'none' and @state = 'off') or (@state = 'on' and not(@algorithm = 'none'))"/>	
	<xs:assert  test="@sub_cycling = ('on','off')"/>	
</xs:complexType>


<xs:complexType name="typedef_chemistry">
	<xs:attribute name="state" type="xs:string"/>
	<xs:attribute name="engine" type="xs:string"/>
	<xs:attribute name="process_model" type="xs:string"/>
	<xs:assert  test="@state = ('on','off')"/>	
	<xs:assert  test="@engine = ('amanzi','pflotran','none')"/>	
	<xs:assert  test="@process_model = ('implicit operator split','none')"/>	
	<xs:assert  test="(@engine = 'none' and @state = 'off') or (@state = 'on' and not(@engine = 'none'))"/>	
</xs:complexType>

<!-- ============================================ Phases ============================================== -->

<xs:complexType name="typedef_phases">
	<xs:all>
		<xs:element name="comments" minOccurs="0" maxOccurs="1"/>
		<xs:element name="liquid_phase" type="typedef_liquid_phase" minOccurs="1" maxOccurs="1"/> <!--MaxOccurs can be changed later for multiphase -->
		<xs:element name="solid_phase" type="typedef_solid_phase" minOccurs="0" maxOccurs="1"/>
	</xs:all>
</xs:complexType>

<xs:complexType name="typedef_liquid_phase">
	<xs:all>
		<xs:element name="eos" type="xs:string" minOccurs="0" maxOccurs="1"/>
		<xs:element name="viscosity" type="typedef_exponential" minOccurs="1" maxOccurs="1">
		    <!-- EIB: if attributes exist this is a file read, else get value from element text -->
		    <xs:alternative test="exists(@type)" type="typedef_property_file"/>
		    <xs:alternative type="typedef_exponential"/>
                </xs:element>
		<xs:element name="density" type="typedef_exponential" minOccurs="1" maxOccurs="1">
		    <!-- EIB: if attributes exist this is a file read, else get value from element text -->
		    <xs:alternative test="exists(@type)" type="typedef_property_file"/>
		    <xs:alternative type="typedef_exponential"/>
                </xs:element>
		<xs:element name="dissolved_components" type="typedef_dissolved_components" minOccurs="0" maxOccurs="1"/>
		<!-- Dissolved components should only be required if transport is on - is there a way to validate this? -->
	</xs:all>
	<xs:attribute name="name" type="xs:string"/>
	<xs:assert  test="@name = ('water')"/>	<!--This will change later for multiphase -->
</xs:complexType>

<xs:complexType name="typedef_dissolved_components">
	<xs:all>
			<xs:element name="solutes" type="typedef_solutes" minOccurs="1" maxOccurs="1"/>
	</xs:all>
</xs:complexType>

<xs:complexType name="typedef_solutes">
	<xs:all>
		<xs:element name="solute" type="typedef_solute" minOccurs="1" maxOccurs="unbounded"/>
	</xs:all>
</xs:complexType>

<xs:complexType name="typedef_solute">
  <xs:simpleContent>
  <xs:extension base="xs:string">
      <xs:attribute name="coefficient_of_diffusion" type="typedef_exponential"/>
      <xs:attribute name="first_order_decay_constant" type="typedef_exponential"/>	
  </xs:extension>
  </xs:simpleContent>
</xs:complexType>

<xs:complexType name="typedef_solid_phase">
	<xs:all>
		<xs:element name="minerals" type="typedef_minerals" minOccurs="1" maxOccurs="1"/>
	</xs:all>
</xs:complexType>

<xs:complexType name="typedef_minerals">
	<xs:all>
		<xs:element name="mineral" type="xs:string" minOccurs="1" maxOccurs="unbounded"/>
	</xs:all>
</xs:complexType>

<!-- ====================================== Initial Conditions ========================================= -->

<xs:complexType name="typedef_initial_conditions">
	<xs:all>
		<xs:element name="initial_condition" type="typedef_initial_condition" minOccurs="1" maxOccurs="unbounded"/>
	</xs:all>
</xs:complexType>

<xs:complexType name="typedef_initial_condition">
	<xs:all>
		<xs:element name="comments" minOccurs="0" maxOccurs="1"/>
		<xs:element name="assigned_regions" type="typedef_assigned_regions" minOccurs="1" maxOccurs="1"/>
		<xs:element name="liquid_phase" type="typedef_ic_liquid_phase" minOccurs="0" maxOccurs="1"/>
		<xs:element name="solid_phase" type="typedef_ic_solid_phase" minOccurs="0" maxOccurs="1"/>
	</xs:all>		
	<xs:attribute name="name" type="xs:string"/>
</xs:complexType>

<xs:complexType name="typedef_ic_liquid_phase">
	<xs:all>		
		<xs:element name="liquid_component" type="typedef_ic_liquid_component" minOccurs="1" maxOccurs="1"/>
		<xs:element name="solute_component" type="typedef_ic_solute_component" minOccurs="0" maxOccurs="unbounded"/>
		<xs:element name="geochemistry" type="typedef_ic_geochemistry" minOccurs="0" maxOccurs="1"/>
	</xs:all>
	<xs:attribute name="name" type="xs:string"/>
	<xs:assert  test="@name = ('water')"/>	
</xs:complexType>

<xs:complexType name="typedef_ic_solid_phase">
	<xs:all minOccurs="1">		
		<xs:element name="mineral" type="typedef_ic_mineral_component" minOccurs="0" maxOccurs="unbounded"/>
		<xs:element name="geochemistry" type="typedef_ic_geochemistry" minOccurs="0" maxOccurs="1"/>
	</xs:all>
	<xs:attribute name="name" type="xs:string"/>
</xs:complexType>

<xs:complexType name="typedef_ic_geochemistry">
	<xs:all>
		<xs:element name="constraint" type="typedef_ic_geochemistry_constraint"/>
	</xs:all>
</xs:complexType>

<xs:complexType name="typedef_ic_geochemistry_constraint">
	<xs:attribute name="name" type="xs:string"/>
	<xs:attribute name="start" type="typedef_labeled_time"/>
</xs:complexType>

<!--
<xs:complexType name="typedef_ic_liquid_component">
	<xs:sequence>
		<xs:element name="velocity" type="typedef_ic_velocity" minOccurs="0" maxOccurs="1"/>
		<xs:choice>
			<xs:element name="pressure" type="typedef_ic_pressure"/>
			<xs:element name="saturation" type="typedef_ic_saturation"/>
		</xs:choice>
	</xs:sequence>
	<xs:attribute name="name" type="xs:string"/>
</xs:complexType>
-->

<xs:element name="ic_choice" abstract="true"/>

<xs:element name="uniform_pressure" substitutionGroup="ic_choice" type="typedef_ic_uniform_pressure"/>

<xs:element name="linear_pressure" substitutionGroup="ic_choice" type="typedef_ic_pressure"/>

<xs:element name="uniform_saturation" substitutionGroup="ic_choice" type="typedef_ic_uniform_saturation"/>

<xs:element name="linear_saturation" substitutionGroup="ic_choice" type="typedef_ic_saturation"/>

<xs:complexType name="typedef_ic_liquid_component">
	<xs:all>
		<xs:element name="velocity" type="typedef_ic_velocity" minOccurs="0" maxOccurs="1"/>
		<xs:element ref="ic_choice" minOccurs="1" maxOccurs="1"/>
	</xs:all>
	<xs:attribute name="name" type="xs:string"/>
</xs:complexType>

<xs:complexType name="typedef_ic_uniform_pressure">
	<xs:attribute name="name" type="xs:string"/>
	<xs:attribute name="value" type="xs:string" use="required"/>
</xs:complexType>

<xs:complexType name="typedef_ic_pressure">
	<xs:attribute name="name" type="xs:string"/>
	<xs:attribute name="value" type="xs:string" use="required"/>
	<xs:attribute name="reference_coord" type="typedef_coordinate"/>
	<xs:attribute name="gradient" type="typedef_coordinate"/>
</xs:complexType>

<xs:complexType name="typedef_ic_uniform_saturation">
	<xs:attribute name="name" type="xs:string"/>
	<xs:attribute name="value" type="xs:string" use="required"/>
</xs:complexType>

<xs:complexType name="typedef_ic_saturation">
	<xs:attribute name="name" type="xs:string"/>
	<xs:attribute name="value" type="xs:string" use="required"/>
	<xs:attribute name="reference_coord" type="typedef_coordinate"/>
	<xs:attribute name="gradient" type="typedef_coordinate"/>
</xs:complexType>

<xs:complexType name="typedef_ic_solute_component">
	<xs:attribute name="name" type="xs:string"/>
	<xs:attribute name="filename" type="xs:string"/>
	<xs:attribute name="value" type="typedef_exponential"/>
	<xs:attribute name="function" type="xs:string"/>
	<xs:attribute name="reference_coord" type="typedef_coordinate"/>
	<xs:attribute name="gradient" type="typedef_coordinate"/>
	<!--<xs:assert  test="@function = ('linear','constant')"/>-->	
</xs:complexType>

<xs:complexType name="typedef_ic_mineral_component">
	<xs:all>
		<xs:element name="mineral" type="xs:string" minOccurs="1" maxOccurs="unbounded"/>
	</xs:all>
</xs:complexType>

<xs:complexType name="typedef_ic_velocity">
	<xs:attribute name="x" type="typedef_exponential"/>
	<xs:attribute name="y" type="typedef_exponential"/>
	<xs:attribute name="z" type="typedef_exponential"/>
</xs:complexType>
<!-- ====================================== Boundary Conditions ========================================= -->

<xs:complexType name="typedef_boundary_conditions">
	<xs:all>
		<xs:element name="comments" minOccurs="0" maxOccurs="1"/>
		<xs:element name="boundary_condition" type="typedef_boundary_condition" minOccurs="0" maxOccurs="unbounded"/>
	</xs:all>
</xs:complexType>

<xs:complexType name="typedef_boundary_condition">
	<xs:all>
		<xs:element name="comments" minOccurs="0" maxOccurs="1"/>
		<xs:element name="assigned_regions" type="typedef_assigned_regions" minOccurs="1" maxOccurs="1"/>
		<xs:element name="liquid_phase" type="typedef_bc_liquid_phase" minOccurs="1" maxOccurs="1"/>
	</xs:all>
	<xs:attribute name="name" type="xs:string"/>
</xs:complexType>

<xs:complexType name="typedef_bc_liquid_phase">
	<xs:all minOccurs="1">		
		<xs:element name="liquid_component" type="typedef_bc_liquid_component" minOccurs="1" maxOccurs="1"/>
		<xs:element name="solute_component" type="typedef_bc_solute_component" minOccurs="0" maxOccurs="unbounded"/>
		<xs:element name="geochemistry" type="typedef_bc_geochemistry" minOccurs="0" maxOccurs="1"/>
	</xs:all>
	<xs:attribute name="name" type="xs:string"/>
	<xs:assert  test="@name = ('water')"/>	
</xs:complexType>

<xs:complexType name="typedef_bc_liquid_component">
	<xs:all>
		<xs:element name="inward_mass_flux" type="typedef_bc_inward_mass_flux" minOccurs="0" maxOccurs="unbounded"/>
		<xs:element name="outward_mass_flux" type="typedef_bc_outward_mass_flux" minOccurs="0" maxOccurs="unbounded"/>
		<xs:element name="inward_volumetric_flux" type="typedef_bc_inward_volumetric_flux" minOccurs="0" maxOccurs="unbounded"/>
		<xs:element name="outward_volumetric_flux" type="typedef_bc_outward_volumetric_flux" minOccurs="0" maxOccurs="unbounded"/>
		<xs:element name="uniform_pressure" type="typedef_bc_uniform_pressure" minOccurs="0" maxOccurs="unbounded"/>
		<xs:element name="linear_pressure" type="typedef_bc_linear_pressure" minOccurs="0" maxOccurs="unbounded"/>
		<xs:element name="hydrostatic" type="typedef_bc_hydrostatic" minOccurs="0" maxOccurs="unbounded"/>
		<xs:element name="linear_hydrostatic" type="typedef_bc_linear_hydrostatic" minOccurs="0" maxOccurs="unbounded"/>
		<xs:element name="seepage_face" type="typedef_bc_seepage_face" minOccurs="0" maxOccurs="unbounded"/>
		<xs:element name="no_flow" type="typedef_bc_no_flow" minOccurs="0" maxOccurs="unbounded"/>
	</xs:all>
	<xs:attribute name="name" type="xs:string"/>
</xs:complexType>

<xs:complexType name="typedef_bc_solute_component">
	<xs:all>
		<xs:element name="aqueous_conc" type="typedef_bc_aqueous_conc" minOccurs="0" maxOccurs="unbounded"/>
	</xs:all>
	<xs:attribute name="name" type="xs:string"/>
</xs:complexType>

<xs:complexType name="typedef_bc_geochemistry">
	<xs:all>
		<xs:element name="constraint" type="typedef_bc_geochemistry_constraint" minOccurs="1" maxOccurs="unbounded"/>
	</xs:all>
</xs:complexType>

<xs:complexType name="typedef_bc_geochemistry_constraint">
	<xs:attribute name="name" type="xs:string"/>
	<xs:attribute name="start" type="xs:string" use="required"/>
	<xs:attribute name="function" type="xs:string" use="required"/>
	<xs:assert  test="@function = ('linear', 'constant')"/>	
</xs:complexType>

<xs:complexType name="typedef_bc_no_flow">
	<xs:attribute name="name" type="xs:string"/>
	<!-- TODO: It would be nice to evaluate these as either value or string somehow? 
         -->
	<xs:attribute name="start" type="xs:string" use="required"/>
	<xs:attribute name="function" type="xs:string" use="required"/>
	<xs:assert  test="@function = ('linear', 'constant')"/>	
</xs:complexType>

<xs:complexType name="typedef_bc_inward_mass_flux">
	<xs:attribute name="name" type="xs:string"/>
	<!-- TODO: It would be nice to evaluate these as either value or string somehow? 
         -->
	<xs:attribute name="start" type="xs:string" use="required"/>
	<xs:attribute name="function" type="xs:string" use="required"/>
	<xs:attribute name="value" type="xs:string" use="required"/>
	<xs:assert  test="@function = ('linear', 'constant')"/>	
</xs:complexType>

<xs:complexType name="typedef_bc_inward_volumetric_flux">
	<xs:attribute name="name" type="xs:string"/>
	<!-- TODO: It would be nice to evaluate these as either value or string somehow? 
         -->
	<xs:attribute name="start" type="xs:string" use="required"/>
	<xs:attribute name="function" type="xs:string" use="required"/>
	<xs:attribute name="value" type="xs:string" use="required"/>
	<xs:assert  test="@function = ('linear', 'constant')"/>	
</xs:complexType>

<xs:complexType name="typedef_bc_outward_mass_flux">
	<xs:attribute name="name" type="xs:string"/>
	<!-- TODO: It would be nice to evaluate these as either value or string somehow? 
         -->
	<xs:attribute name="start" type="xs:string" use="required"/>
	<xs:attribute name="function" type="xs:string" use="required"/>
	<xs:attribute name="value" type="xs:string" use="required"/>
	<xs:assert  test="@function = ('linear', 'constant')"/>	
</xs:complexType>

<xs:complexType name="typedef_bc_outward_volumetric_flux">
	<!-- TODO: It would be nice to evaluate these as either value or string somehow? 
         -->
	<xs:attribute name="name" type="xs:string"/>
	<xs:attribute name="start" type="xs:string" use="required"/>
	<xs:attribute name="function" type="xs:string" use="required"/>
	<xs:attribute name="value" type="xs:string" use="required"/>
	<xs:assert  test="@function = ('linear', 'constant')"/>	
</xs:complexType>

<xs:complexType name="typedef_bc_seepage_face">
	<!-- TODO: It would be nice to evaluate these as either value or string somehow? 
         -->
	<!-- TODO: Should be able to specify pressure as well (currently defaults to atm) 
         -->
	<xs:attribute name="start" type="xs:string" use="required"/>
	<xs:attribute name="function" type="xs:string" use="required"/>
	<xs:attribute name="inward_mass_flux" type="xs:string" use="required"/>
	<xs:assert  test="@function = ('linear', 'constant')"/>	
</xs:complexType>

<xs:complexType name="typedef_bc_uniform_pressure">
	<xs:attribute name="name" type="xs:string"/>
	<xs:attribute name="start" type="xs:string" use="required"/>
	<xs:attribute name="function" type="xs:string" use="required"/>
	<xs:attribute name="value" type="xs:string" use="required"/>
	<xs:assert  test="@function = ('linear', 'constant')"/>	
</xs:complexType>

<xs:complexType name="typedef_bc_linear_pressure">
	<xs:attribute name="name" type="xs:string"/>
	<xs:attribute name="gradient_value" type="xs:string" use="required"/>
	<xs:attribute name="reference_point" type="typedef_coordinate" use="required"/>
	<xs:attribute name="reference_value" type="xs:string" use="required"/>
</xs:complexType>

<xs:complexType name="typedef_bc_hydrostatic">
	<xs:attribute name="name" type="xs:string"/>
        <xs:attribute name="coordinate_system" type="xs:string"/>
        <xs:attribute name="submodel" type="xs:string"/>
	<xs:attribute name="start" type="xs:string" use="required"/>
	<xs:attribute name="function" type="xs:string" use="required"/>
	<xs:attribute name="value" type="xs:string" use="required"/>
	<xs:assert  test="@function = ('linear', 'constant')"/>	
	<xs:assert  test="not(exists(@coordinate_system)) or @coordinate_system = ('absolute','relative to mesh top')"/>
        <xs:assert  test="not(exists(@submodel)) or @submodel = ('no_flow_above_water_table', 'none')"/>
</xs:complexType>

<xs:complexType name="typedef_bc_linear_hydrostatic">
	<xs:attribute name="name" type="xs:string"/>
	<xs:attribute name="gradient_value" type="xs:string" use="required"/>
	<xs:attribute name="reference_point" type="typedef_coordinate" use="required"/>
        <xs:attribute name="reference_water_table_height" type="xs:string" use="required"/>
        <xs:attribute name="submodel" type="xs:string"/>
        <xs:assert  test="not(exists(@submodel)) or @submodel = ('no_flow_above_water_table', 'none')"/>
</xs:complexType>


<!-- TODO These could be files, perhaps we need to use tags not attributes! -->
<xs:complexType name="typedef_bc_aqueous_conc">
	<!-- TODO It would be nice to evaluate these as either value or string somehow? -->
	<xs:attribute name="start" type="xs:string" use="required"/>
	<xs:attribute name="name" type="xs:string" use="required"/>
	<xs:attribute name="value" type="xs:string" use="required"/>
	<xs:attribute name="function" type="xs:string" use="required"/>
	<xs:assert  test="@function = ('linear', 'constant')"/>	
</xs:complexType>
<!-- ====================================== Sources ========================================= -->

<xs:complexType name="typedef_sources">
	<xs:all>
		<xs:element name="comments" minOccurs="0" maxOccurs="1"/>
		<xs:element name="source" type="typedef_source" minOccurs="0" maxOccurs="unbounded"/>
	</xs:all>
</xs:complexType>

<xs:complexType name="typedef_source">
	<xs:all>
		<xs:element name="comments" minOccurs="0" maxOccurs="1"/>
		<xs:element name="assigned_regions" type="typedef_assigned_regions" minOccurs="1" maxOccurs="1"/>
		<xs:element name="liquid_phase" type="typedef_src_liquid_phase" minOccurs="1" maxOccurs="1"/>
	</xs:all>
	<xs:attribute name="name" type="xs:string"/>
</xs:complexType>

<xs:complexType name="typedef_src_liquid_phase">
	<xs:all minOccurs="1">		
		<xs:element name="liquid_component" type="typedef_src_liquid_component" minOccurs="0" maxOccurs="1"/>
		<xs:element name="solute_component" type="typedef_src_solute_component" minOccurs="0" maxOccurs="unbounded"/>
		<xs:element name="geochemistry" type="typedef_src_geochemistry" minOccurs="0" maxOccurs="unbounded"/>
	</xs:all>
	<xs:attribute name="name" type="xs:string"/>
	<xs:assert  test="@name = ('water')"/>	
</xs:complexType>

<xs:complexType name="typedef_src_liquid_component">
	<xs:all>
		<xs:element name="volume_weighted" type="typedef_src_volume_weighted" minOccurs="0" maxOccurs="unbounded"/>
		<xs:element name="perm_weighted" type="typedef_src_perm_weighted" minOccurs="0" maxOccurs="unbounded"/>
	</xs:all>
	<xs:attribute name="name" type="xs:string"/>
</xs:complexType>

<xs:complexType name="typedef_src_volume_weighted">
	<xs:attribute name="start" type="xs:string"/>
	<xs:attribute name="value" type="typedef_exponential"/>
	<xs:attribute name="function" type="xs:string"/>
	<xs:assert  test="not(exists(@function)) or @function = ('linear', 'constant')"/>	
</xs:complexType>

<xs:complexType name="typedef_src_perm_weighted">
	<xs:attribute name="start" type="xs:string"/>
	<xs:attribute name="value" type="typedef_exponential"/>
	<xs:attribute name="function" type="xs:string"/>
	<xs:assert  test="@function = ('linear', 'constant')"/>	
</xs:complexType>

<xs:complexType name="typedef_src_solute_component">
	<xs:all>
		<xs:element name="uniform_conc" type="typedef_src_conc" minOccurs="0" maxOccurs="unbounded"/>
		<xs:element name="flow_weighted_conc" type="typedef_src_conc" minOccurs="0" maxOccurs="unbounded"/>
		<xs:element name="diffusion_dominated_release" type="typedef_release_model" minOccurs="0" maxOccurs="unbounded"/>
	</xs:all>
	<xs:attribute name="name" type="xs:string"/>
</xs:complexType>

<xs:complexType name="typedef_src_conc">
	<xs:all>
		<xs:element name="aqueous_conc" type="typedef_src_aqueous_conc" minOccurs="0" maxOccurs="unbounded"/>
	</xs:all>
	<xs:attribute name="name" type="xs:string"/>
	<xs:attribute name="start" type="xs:string"/>
	<xs:attribute name="value" type="xs:string"/>
	<xs:attribute name="function" type="xs:string"/>
	<xs:assert  test="@function = ('linear', 'constant')"/>	
</xs:complexType>

<!-- TODO Do we need to define an aqueous conc specific to source? -->
<!--       Can't this definition be shared? -->
<xs:complexType name="typedef_src_aqueous_conc">
	<xs:attribute name="name" type="xs:string"/>
	<xs:attribute name="start" type="xs:string"/>
	<xs:attribute name="value" type="xs:string"/>
	<xs:attribute name="function" type="xs:string"/>
	<xs:assert  test="@function = ('linear', 'constant')"/>	
</xs:complexType>

<xs:complexType name="typedef_release_model">
	<xs:attribute name="name" type="xs:string"/>
	<xs:attribute name="start" type="xs:string"/>
	<xs:attribute name="total_inventory" type="typedef_exponential"/>
	<xs:attribute name="mixing_length" type="typedef_exponential"/>
	<xs:attribute name="effective_diffusion_coefficient" type="typedef_exponential"/>
</xs:complexType>

<xs:complexType name="typedef_src_geochemistry">
	<xs:all>
		<xs:element name="constraint" type="typedef_src_geochemistry_constraint" minOccurs="1" maxOccurs="unbounded"/>
	</xs:all>
</xs:complexType>

<xs:complexType name="typedef_src_geochemistry_constraint">
	<xs:attribute name="name" type="xs:string"/>
	<xs:attribute name="start" type="xs:string"/>
	<xs:attribute name="function" type="xs:string"/>
	<xs:assert  test="@function = ('linear', 'constant')"/>	
</xs:complexType>


<!-- ============================================ Outputs ============================================== -->

<xs:complexType name="typedef_outputs">
	<xs:all>
		<xs:element name="vis" type="typedef_vis" minOccurs="0" maxOccurs="1"/>
		<xs:element name="checkpoint" type="typedef_checkpoint" minOccurs="0" maxOccurs="1"/>
		<xs:element name="walkabout" type="typedef_walkabout" minOccurs="0" maxOccurs="1"/>
		<xs:element name="observations" type="typedef_observations" minOccurs="0" maxOccurs="1"/>
	</xs:all>
</xs:complexType>

<xs:complexType name="typedef_vis">
	<xs:all>
		<xs:element name="base_filename" type="xs:string" minOccurs="1" maxOccurs="1"/>
		<xs:element name="num_digits" type="xs:integer" minOccurs="1" maxOccurs="1"/>
		<xs:element name="time_macros" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
		<xs:element name="cycle_macros" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
		<xs:element name="write_regions" type="typedef_assigned_regions" minOccurs="1" maxOccurs="1"/>
	</xs:all>
</xs:complexType>


<xs:complexType name="typedef_checkpoint">
	<xs:all>
		<xs:element name="base_filename" type="xs:string" minOccurs="1" maxOccurs="1"/>
		<xs:element name="num_digits" type="xs:integer" minOccurs="1" maxOccurs="1"/>
		<xs:element name="cycle_macro" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
	</xs:all>
</xs:complexType>

<xs:complexType name="typedef_walkabout">
	<xs:all>
		<xs:element name="base_filename" type="xs:string" minOccurs="1" maxOccurs="1"/>
		<xs:element name="num_digits" type="xs:integer" minOccurs="1" maxOccurs="1"/>
		<xs:element name="cycle_macro" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
	</xs:all>
</xs:complexType>

<xs:complexType name="typedef_observations">
	<xs:all>
		<xs:element name="filename" type="xs:string" minOccurs="1" maxOccurs="1"/>
		<xs:element name="liquid_phase" type="typedef_obs_liquid_phase" minOccurs="1" maxOccurs="1"/>
	</xs:all>
</xs:complexType>

<xs:complexType name="typedef_obs_liquid_phase">
	<xs:all>
		<!--xs:element name="integrated_mass" type="typedef_observation" minOccurs="0" maxOccurs="unbounded"/-->
		<xs:element name="volumetric_water_content" type="typedef_observation" minOccurs="0" maxOccurs="unbounded"/>
		<xs:element name="gravimetric_water_content" type="typedef_observation" minOccurs="0" maxOccurs="unbounded"/>
		<xs:element name="aqueous_pressure" type="typedef_observation" minOccurs="0" maxOccurs="unbounded"/>
		<xs:element name="x_aqueous_volumetric_flux" type="typedef_observation" minOccurs="0" maxOccurs="unbounded"/>
		<xs:element name="y_aqueous_volumetric_flux" type="typedef_observation" minOccurs="0" maxOccurs="unbounded"/>
		<xs:element name="z_aqueous_volumetric_flux" type="typedef_observation" minOccurs="0" maxOccurs="unbounded"/>
		<xs:element name="material_id" type="typedef_observation" minOccurs="0" maxOccurs="unbounded"/>
		<xs:element name="hydraulic_head" type="typedef_observation" minOccurs="0" maxOccurs="unbounded"/>
		<xs:element name="aqueous_mass_flow_rate" type="typedef_observation" minOccurs="0" maxOccurs="unbounded"/>
		<xs:element name="aqueous_volumetric_flow_rate" type="typedef_observation" minOccurs="0" maxOccurs="unbounded"/>
		<xs:element name="aqueous_conc" type="typedef_solute_observation" minOccurs="0" maxOccurs="unbounded"/>
		<xs:element name="solute_volumetric_flow_rate" type="typedef_solute_observation" minOccurs="0" maxOccurs="unbounded"/>
	</xs:all>
	<xs:attribute name="name"/>
	<xs:assert  test="@name = ('water')"/>	
</xs:complexType>

<xs:complexType name="typedef_observation">
	<xs:all>
		<xs:element name="filename" type="xs:string" minOccurs="0" maxOccurs="1"/>
		<xs:element name="assigned_regions" type="typedef_assigned_regions" minOccurs="1" maxOccurs="1"/>
		<xs:element name="functional" type="xs:string" minOccurs="1" maxOccurs="1"/>
		<xs:element name="time_macro" type="xs:string" minOccurs="1" maxOccurs="unbounded"/>
		<xs:assert  test="@function = ('point', 'integral')"/>
	</xs:all>
</xs:complexType>

<xs:complexType name="typedef_solute_observation">
	<xs:all>
		<xs:element name="filename" type="xs:string" minOccurs="0" maxOccurs="1"/>
		<xs:element name="solute" type="xs:string" minOccurs="1" maxOccurs="1"/>
		<xs:element name="assigned_regions" type="typedef_assigned_regions" minOccurs="1" maxOccurs="1"/>
		<xs:element name="functional" type="xs:string" minOccurs="1" maxOccurs="1"/>
		<xs:element name="time_macro" type="xs:string" minOccurs="1" maxOccurs="unbounded"/>
		<xs:assert  test="@function = ('point', 'integral')"/>
	</xs:all>
	<xs:attribute name="solute"/>
</xs:complexType>
</xs:schema>
