import stringmap

Header =  {
  'Release'      : '2023',
  'Revision'     : '61624',
  'BuildDate'    : '23 Dec 2022',
  'CreationDate' : '09 Jan 2023',
  'CreationTime' : '14:18:35',
  'Creator'      : 'geodict',
  'Platform'     : '64 bit Linux',
  }

Description = '''
This macro generates a fiber structure, runs a flow simulation and returns permeability.
Vary the parameters solid volume percentage and fiber diameter.

Macro file for GeoDict 2023
recorded at 14:18:35 on 09 Jan 2023
by M2M-Cloud of Math2Market GmbH
'''

Variables = {
  'NumberOfVariables' : 2,
  'Variable1' : {
    'Name'           : 'gd_SVP',
    'Label'          : 'Solid Volume Percentage',
    'Type'           : 'double',
    'Unit'           : '%',
    'ToolTip'        : 'Solid volume percentage of the created structure.',
    'BuiltinDefault' : 10.0,
    'Check'          : 'min0;max100'
    },
  'Variable2' : {
    'Name'           : 'gd_FD',
    'Label'          : 'Fiber Diameter',
    'Type'           : 'double',
    'Unit'           : 'µ',
    'ToolTip'        : 'Fiber diameter of material 1.',
    'BuiltinDefault' : 10.0,
    },
  }

# Explanations of variables syntax:
###################################
# Name:           mandatory, name of the variable by that it can be addressed in the macro, must not contain white spaces!
# Label:          optional,  appears as text in the GeoDict GUI. If not present, then Name is used also as Label
# Type:           mandatory, known types are bool, boolgroup, double, uint, int, string, filestring, folderstring, material, combo, table, combogroup, labelgroup
# Unit:           optional,  appears only in GUI (not used to rescale any input parameters automatically)
#                            for type filestring, Unit contains the file suffix
#                            for type material,   Unit must be solid, fluid or porous
#                            for type combo,      Unit must contain the possible string-values for the variable separated by semicolon
#                            for type table,      Unit must be a list of type strings, allowed is "int", "float", "string". E.g. ["int", "float", "string"] for three columns.
# ToolTip:        optional,  appears in GUI (must be in one line)
# BuiltinDefault: optional,  default value which is used in macro (if not given, defaults to 0 or empty string)
#                            for type table, this should be a python list of entries, left to right, top to bottom, e.g. [1,2.0,"three"].
# ColumnHeaders:  optional,  only valid for type table: List of header texts for each table column, e.g. ["Column 1", "Second column", "Third Column"]
# Check:          optional,  known checks are positive, negative, min, max (checks are separated by semicolon)
# Member:         optional,  defines the member of group type variables. For Labelgroups defined by a list, for combogroup and boolgroup defined by a dictionary that maps states to lists

# Examples of variable usage in GeoDict command argument lists:
###############################################################
# 'SolidVolumePercentage' : (gd_SVP, '%'),                    # Set parameter SolidVolumePercentage value of variable gd_SVP
# 'ResultFileName'        : f'FilterEfficiency_{gd_SVP}.gdr'  # Make parameter ResultFileName include the string converted from the value of variable gd_SVP

# Frequently used Python syntax:
#####################################################
# print('The solid volume percentage is:', gd_SVP)             # Print to console and log - file
#
#   for x in range(0, 100) : # Use "for" loop statement
#     x_sq = x * x
#
#   if gd_SVP < 0:                                            # Use "if" statement
#     print('error')


Create_args_1 = {
  'MaterialMode'             : 'Material',     # Possible values: Material, MaterialID
  'MaterialIDMode'           : 'MaterialIDPerObjectType',# Possible values: MaterialIDPerObjectType, MaterialIDPerMaterial
  'Domain' : {
    'PeriodicX'         : False,
    'PeriodicY'         : False,
    'PeriodicZ'         : False,
    'OriginX'           : (0, 'm'),
    'OriginY'           : (0, 'm'),
    'OriginZ'           : (0, 'm'),
    'VoxelLength'       : (1e-06, 'm'),
    'DomainMode'        : 'VoxelNumber',
    'NX'                : 100,
    'NY'                : 100,
    'NZ'                : 100,
    'OverlapMode'       : 'GivenMaterial', # Possible values: OverlapMaterial, NewMaterial, OldMaterial, GivenMaterial
    'Material' : {
      'Type'        : 'Fluid',
      'Name'        : 'Air',
      'Information' : '',
      },
    'OverlapMaterialID' : 3,
    'NumOverlapRules'   : 2,
    'OverlapRule1' : {
      'MaterialID1'       : 1,
      'MaterialID2'       : 1,
      'OverlapMaterialID' : 1,
      },
    'OverlapRule2' : {
      'MaterialID1'       : 2,
      'MaterialID2'       : 2,
      'OverlapMaterialID' : 2,
      },
    'HollowMaterialID'  : 0,
    'PostProcessing' : {
      'ResolveOverlap'    : False,
      'MarkContactVoxels' : False,
      'ContactMaterialID' : 3,
      },
    },
  'MaximalTime'              : (24, 'h'),
  'OverlapMode'              : 'AllowOverlap', # Possible values: AllowOverlap, RemoveOverlap, ForceConnection, IsolationDistance, ProhibitWithExisting, ProhibitOverlap, MatchSVFDistribution
  'NumberOfObjects'          : 100,
  'StoppingCriterion'        : 'SolidVolumePercentage',# Possible values: SolidVolumePercentage, NumberOfObjects, Grammage, Density, WeightPercentage, FillToRim, SVP, Number
  'SolidVolumePercentage'    : (gd_SVP, '%'),
  'Grammage'                 : (10, 'g/m^2'),
  'SaveGadStep'              : 10,
  'RecordIntermediateResult' : False,
  'InExisting'               : False,
  'KeepStructure'            : False,
  'WeightPercentage'         : (0, '%'),
  'Density'                  : (0, 'g/cm^3'),
  'RemoveOverlap' : {
    'Iterations'        : 1000,
    'OverlapSVP'        : (0, '%'),
    'SVPUnchanged'      : 20,
    'AllowShift'        : True,
    'AllowRotation'     : True,
    'AllowDeformation'  : True,
    'NumberOfShifts'    : 10,
    'ShiftDistance'     : (2, 'Voxel'),
    'NumberOfRotations' : 20,
    'MaximalAngle'      : 60,
    'DistanceMode'      : 'Touch',      # Possible values: Touch, Overlap, Isolation, AvoidContact
    'IsolationDistance' : (0, 'm'),
    'MaximalOverlap'    : (0, 'm'),
    },
  'MatchSVFDistribution' : {
    'ErrorBound'         : 0.001,
    'CorrelationLengthX' : (2e-05, 'm'),
    'CorrelationLengthY' : (2e-05, 'm'),
    'CorrelationLengthZ' : (1e-05, 'm'),
    'StandardDeviation'  : 0.5,
    'CoarseningFactor'   : 10,
    'MatchMode'          : 'Gauss',      # Possible values: Gauss, Gradient
    'RelativeDensity'    : True,
    'DensityFunction' : {
      'XValues' : [0, 0.5, 1],
      'YValues' : [1, 0.1, 1],
      },
    },
  'PercentageType'           : 0,
  'RandomSeed'               : 47,
  'IsolationDistance'        : (0, 'm'),
  'ResultFileName'           : f'FiberGeo_{gd_SVP}_{gd_FD}.gdr',
  'MatrixDensity'            : (0, 'g/cm^3'),
  'OverlapMaterial' : {
    'Type'        : 'Solid',
    'Name'        : 'Glass',
    'Information' : 'Overlap',
    },
  'ContactMaterial' : {
    'Type'        : 'Solid',
    'Name'        : 'Glass',
    'Information' : 'Contact',
    },
  'NumberOfGenerators'       : 2,
  'Generator1' : {
    'Material' : {
      'Type'        : 'Solid',
      'Name'        : 'Glass',
      'Information' : 'Fiber',
      },
    'Probability'             : 0.5,
    'SpecificWeight'          : (2.58, 'g/cm^3'),
    'Type'                    : 'InfiniteCircularFiberGenerator',
    'UseDTex'                 : False,
    'DiameterDistribution' : {
      'Type'  : 'Constant', # Possible values: Constant, UniformlyInInterval, Gaussian, Table, LogNormal
      'Value' : gd_FD * 1e-6,
      },
    'OrientationDistribution' : {
      'Type'          : 'AnisotropicDirection',# Possible values: Isotropic, AnisotropicDirection, AnisotropicOrientation, GivenDirection, InXYPlane, AngleAroundDirection, UNDEF
      'DirectionMode' : 'AnisotropyParameter',# Possible values: AnisotropyParameter, DirectionTensor
      'Anisotropy1'   : 7,
      'Anisotropy2'   : 1,
      'Phi'           : 0,
      'Theta'         : 0,
      'Psi'           : 0,
      },
    },
  'Generator2' : {
    'Material' : {
      'Type'        : 'Solid',
      'Name'        : 'Glass',
      'Information' : 'Fiber',
      },
    'Probability'             : 0.5,
    'SpecificWeight'          : (2.58, 'g/cm^3'),
    'Type'                    : 'InfiniteCircularFiberGenerator',
    'UseDTex'                 : False,
    'DiameterDistribution' : {
      'Type'  : 'Constant', # Possible values: Constant, UniformlyInInterval, Gaussian, Table, LogNormal
      'Value' : 6e-06,
      },
    'OrientationDistribution' : {
      'Type'          : 'AnisotropicDirection',# Possible values: Isotropic, AnisotropicDirection, AnisotropicOrientation, GivenDirection, InXYPlane, AngleAroundDirection, UNDEF
      'DirectionMode' : 'AnisotropyParameter',# Possible values: AnisotropyParameter, DirectionTensor
      'Anisotropy1'   : 5,
      'Anisotropy2'   : 1,
      'Phi'           : 0,
      'Theta'         : 0,
      'Psi'           : 0,
      },
    },
  'Temperature'              : (293.15, 'K'),
  }
gd.runCmd("FiberGeo:Create", Create_args_1, Header['Release'])

SolveStokes_args_1 = {
  'ResultFileName'       : f'StokesResult_{gd_SVP}_{gd_FD}.gdr',
  'Experiment' : {
    'DirectionEnabledX'  : False,
    'DirectionEnabledY'  : False,
    'DirectionEnabledZ'  : True,
    'CharLengthMode'     : 'PERMEABILITY', # Possible values: PERMEABILITY, PORE_SIZE, FIBER_SIZE, USER_GIVEN
    'GivenCharLength'    : 1,
    'PressureDifference' : (0.02, 'Pa'),
    'MeanVelocity'       : (0.1, 'm/s'),
    'FlowRate'           : (60, 'l/min'),
    'FlowArea'           : (100, 'cm^2'),
    'ExperimentIO'       : 'PressureDrop', # Possible values: PressureDrop, MeanVelocity, FlowRate
    'AddInletOutlet'     : True,
    'InletLength'        : 10,
    'OutletLength'       : 10,
    'NormalBcType'       : 'Periodic',     # Possible values: Periodic, Symmetric, VinPout
    'SlipLength'         : 0,
    'TangentialBcYInX'   : 'Periodic',     # Possible values: Periodic, Symmetric, NoSlip
    'TangentialBcZInX'   : 'Periodic',     # Possible values: Periodic, Symmetric, NoSlip
    'TangentialBcXInY'   : 'Periodic',     # Possible values: Periodic, Symmetric, NoSlip
    'TangentialBcZInY'   : 'Periodic',     # Possible values: Periodic, Symmetric, NoSlip
    'TangentialBcXInZ'   : 'Periodic',     # Possible values: Periodic, Symmetric, NoSlip
    'TangentialBcYInZ'   : 'Periodic',     # Possible values: Periodic, Symmetric, NoSlip
    },
  'SolverData' : {
    'Solver'    : 'LIR', # Possible values: LIR, SimpleFFT, EJ
    'LIR' : {
      'Parallelization' : {
        'Mode' : 'LOCAL_MAX', # Possible values: Sequential, LOCAL_THREADS, LOCAL_MPI, LOCAL_MAX, CLUSTER, Undefined
        },
      'DiscardTemporaryFiles'   : False,
      'AnalyzeGeometry'         : True,
      'RestartFileName'         : '',
      'Restart'                 : False,
      'RestartSaveIntervalTime' : 6,
      'Tolerance'               : 0.0001,
      'MaxNumberOfIterations'   : 100000,
      'MaximalSolverRunTime'    : (240, 'h'),
      'UseMaxIterations'        : False,
      'UseMaxTime'              : False,
      'UseTolerance'            : False,
      'UseErrorBound'           : True,
      'ErrorBound'              : 0.01,
      'UseLateral'              : False,
      'Refinement'              : 'ENABLED',   # Possible values: ENABLED, DISABLED, MANUAL
      'NumberOfRefinements'     : 10,
      'Threshold'               : 0.1,
      'Optimization'            : 'Speed',
      'GridType'                : 'LIR-Tree',
      'UseMultigrid'            : True,
      'UseKrylov'               : 'Automatic', # Possible values: Automatic, Enabled, Disabled
      'Relaxation'              : 1,
      'WriteCompressedFields'   : True,
      },
    'SimpleFFT' : {
      'UseResidual'             : False,
      'Residual'                : 0.0001,
      'Tolerance'               : 0.0001,
      'MaxNumberOfIterations'   : 100000,
      'MaximalSolverRunTime'    : (240, 'h'),
      'UseMaxIterations'        : False,
      'UseMaxTime'              : False,
      'UseTolerance'            : False,
      'UseErrorBound'           : True,
      'ErrorBound'              : 0.01,
      'UseLateral'              : False,
      'Parallelization' : {
        'Mode' : 'LOCAL_MAX', # Possible values: Sequential, LOCAL_THREADS, LOCAL_MPI, LOCAL_MAX, CLUSTER, Undefined
        },
      'DiscardTemporaryFiles'   : False,
      'AnalyzeGeometry'         : True,
      'RestartFileName'         : '',
      'Restart'                 : False,
      'RestartSaveIntervalTime' : 6,
      'RelaxationVelocity'      : 1,
      'RelaxationPressure'      : 1,
      'TdmaMode'                : 'Automatic', # Possible values: Automatic, NotUseTdma, UseTdma
      },
    'EJ' : {
      'UseResidual'             : False,
      'Residual'                : 0.001,
      'Tolerance'               : 0.001,
      'MaxNumberOfIterations'   : 100000,
      'MaximalSolverRunTime'    : (240, 'h'),
      'UseMaxIterations'        : False,
      'UseMaxTime'              : False,
      'UseTolerance'            : True,
      'Parallelization' : {
        'Mode' : 'LOCAL_MAX', # Possible values: Sequential, LOCAL_THREADS, LOCAL_MPI, LOCAL_MAX, CLUSTER, Undefined
        },
      'DiscardTemporaryFiles'   : False,
      'AnalyzeGeometry'         : True,
      'RestartFileName'         : '',
      'Restart'                 : False,
      'RestartSaveIntervalTime' : 6,
      'SolverType'              : 0,
      },
    },
  'Grid' : {
    'UseBoxels'    : False,
    'BoxelLengthX' : 1e-06,
    'BoxelLengthY' : 1e-06,
    'BoxelLengthZ' : 1e-06,
    },
  'ConstituentMaterials' : {
    'Temperature' : (293.15, 'K'),
    'Material00' : {
      'Type'            : 'Fluid',
      'Name'            : 'Air',
      'Information'     : '',
      'FluidProperties' : {
        'CurrentLaw'   : 1,
        'NumberOfLaws' : 1,
        'MaterialLaw1' : {
          'Name'      : 'Material Law 1',
          'Density'   : (1.204, 'kg/m^3'),
          'Viscosity' : (1.834e-05, 'kg/(ms)'),
          },
        },
      },
    'Material01' : {
      'Type'        : 'Solid',
      'Name'        : 'Glass',
      'Information' : 'Fiber',
      },
    'Material02' : {
      'Type'        : 'Solid',
      'Name'        : 'Glass',
      'Information' : 'Fiber',
      },
    'Material03' : {
      'Type'        : 'Solid',
      'Name'        : 'Glass',
      'Information' : 'Overlap',
      },
    'ChosenFluid' : {
      'Fluid'      : 'Air',
      'CurrentLaw' : 1,
      },
    },
  }
gd.runCmd("FlowDict:SolveStokes", SolveStokes_args_1, "2023")

gdr = stringmap.parseGDR(f'StokesResult_{gd_SVP}_{gd_FD}.gdr')
perm_string = gdr["ResultMap:Permeability33"]
perm = float(perm_string)
gd.msgBox(f"For svp = {gd_SVP} and diameter = {gd_FD} permeability is {perm:.2e}.")

