13     """ Functions to help parse the input file and check input parameters. 
   16             * params (list): list of parameters specified in the input file. 
   17             * minFracSize (float): the minimum fracture size. 
   28         """ '{1,2,3}' --> [1,2,3] 
   30         return re.sub(
"{|}", 
"", curlyList).strip().split(
",")
 
   33         """ [1,2,3] --> '{1,2,3}'   for writing output 
   35         curl = re.sub(
r'\[', 
'{', strList)
 
   36         curl = re.sub(
r'\]', 
'}', curl)
 
   37         curl = re.sub(
r"\'", 
'', curl)
 
   41         """ Checks to see that every { has a matching }. 
   43         if '{' in line 
and '}' in line: 
return True 
   44         elif '{' in line 
or '}' in line:
 
   46                 "Line defining \"{}\" contains a single curly brace.".format(
 
   51         """ Use to get key's value in params. writing always false   
   53         if (
not writing) 
and (len(self.
paramsparams[key]) > 1):
 
   55                 "\"{}\" can only correspond to 1 list. {} lists have been defined." 
   56                 .format(key, len(self.
paramsparams[key])))
 
   58             val = self.
paramsparams[key][0]
 
   59             if val == 
'' or val == []:
 
   60                 self.
errorerror(
"\"{}\" does not have a value.".format(key))
 
   63             self.
errorerror(
"\"{}\" has not been defined.".format(
 
   67         """ extract values between { and }  
   69         curlyGroup = re.compile(
'({.*?})')
 
   70         groups = re.findall(curlyGroup, line)
 
   72             line = line.replace(group, 
'', 1)  
 
   75         if line.strip() != 
"":
 
   77                 "Unexpected character found while parsing \"{}\".".format(key))
 
   80         """ pulls values from culry brackets  
   91             errString (str): a string describing the error 
   93         error = 
"\nERROR --- " + errString + 
"\n----Program terminated while parsing input----\n" 
   94         sys.stderr.write(error)
 
  101             warnStinrg (str): a string with the warning 
  103         print(
"WARNING --- " + warnString)
 
  105     def warning(self, warnString, warningFile=''):
 
  106         """ print a warning to a file (currently does not work)""" 
  108         print(
"WARNING --- " + warnString)
 
  112         """"returns True if num is negative, false otherwise 
  114         return True if num < 0 
else False 
  117         """Makes sure at least one polygon family has been defined in nFamRect or nFamEll 
  118         OR that there is a user input file for polygons. 
  120         userDefExists = (self.
value_ofvalue_of(
'userEllipsesOnOff') == 
'1') |\
 
  121                    (self.
value_ofvalue_of(
'userRectanglesOnOff') == 
'1') |\
 
  122                    (self.
value_ofvalue_of(
'userRecByCoord') == 
'1') |\
 
  123                    (self.
value_ofvalue_of(
'userEllByCoord') == 
'1')
 
  125         ellipseFams = len(self.
value_ofvalue_of(
'nFamRect'))
 
  126         rectFams = len(self.
value_ofvalue_of(
'nFamEll'))
 
  128         if ellipseFams + rectFams <= 0 
and not userDefExists:
 
  129             self.
errorerror(
"Zero polygon families have been defined. Please create at least one family "\
 
  130                   "of ellipses/rectagnles, or provide a user-defined-polygon input file path in "\
 
  131                   "\"UserEll_Input_File_Path\", \"UserRect_Input_File_Path\", \"UserEll_Input_File_Path\", or "\
 
  132                   "\"RectByCoord_Input_File_Path\" and set the corresponding flag to '1'.")
 
  134     def scale(self, probList, warningFile):
 
  135         """ scales list of probabilities (famProb) that doesn't add up to 1 
  136         ie [.2, .2, .4] --> [0.25, 0.25, 0.5]  
  138         total = sum(probList)
 
  139         scaled = [float(
"{:.6}".format(x / total)) 
for x 
in probList]
 
  140         self.
warningwarningwarning(
"'famProb' probabilities did not add to 1 and have been scaled accordingly "\
 
  141             "for their current sum, {:.6}. Scaled {} to {}".format(total, probList, scaled), warningFile)
 
  142         return [x / total 
for x 
in probList]
 
  145         """ returns True is there is a zero in valList of standard deviations 
  148             if float(val) == 0: 
return True 
  151         """ Checks that the minimum parameter for a family is not greater or equal to the maximum parameter. 
  153         for minV, maxV 
in zip(self.
value_ofvalue_of(minParam),
 
  156                 self.
errorerror(
"\"{}\" and \"{}\" contain equal values for the same {} family. "\
 
  157                       "If {} and {} were intended to be the same, use the constant distribution "\
 
  158                       "(4) instead.".format(minParam, maxParam, shape, minParam, maxParam))
 
  161                     "\"{}\" is greater than \"{}\" in a(n) {} family.".format(
 
  162                         minParam, maxParam, shape))
 
  165     def check_mean(self, minParam, maxParam, meanParam, warningFile=''):
 
  166         """ Warns the user if the minimum value of a parameter is greater than the family's mean value, or if the 
  167         maximum value of the parameter is less than the family's mean value. 
  169         for minV, meanV 
in zip(self.
value_ofvalue_of(minParam),
 
  172                 self.
warningwarningwarning(
"\"{}\" contains a min value greater than its family's mean value in "\
 
  173                        "\"{}\". This could drastically increase computation time due to increased "\
 
  174                        "rejection rate of the most common fracture sizes.".format(minParam, meanParam), warningFile)
 
  175         for maxV, meanV 
in zip(self.
value_ofvalue_of(maxParam),
 
  178                 self.
warningwarningwarning(
"\"{}\" contains a max value less than its family's mean value in "\
 
  179                        "\"{}\". This could drastically increase computation time due to increased "\
 
  180                        "rejection rate of the most common fracture sizes.".format(maxParam, meanParam), warningFile)
 
  183         """ Corrects the minimum fracture size if necessary, by looking at the values in valList. 
  187             if minFracSize == 
None:
 
  189             elif val < minFracSize:
 
  196         """Returns line without comments or white space. 
  200             line = line[:line.index(
 
  202             while "*/" not in comment:
 
  207             line = line[:line.index(
 
  212     def find_val(self, line, key, inputIterator, unfoundKeys, warningFile):
 
  213         """ Extract the value for key from line.  
  216         line = line[line.index(
":") + 1:].strip()
 
  217         if line != 
"": self.
val_helperval_helper(line, valList, key)
 
  220         while ':' not in line:
 
  227             except StopIteration:
 
  230         if valList == [] 
and key 
in mandatory:
 
  232                 "\"{}\" is a mandatory parameter and must be defined.".format(
 
  235             self.
paramsparams[key] = valList 
if valList != [] 
else [
 
  239             self.
process_lineprocess_line(line, unfoundKeys, inputIterator, warningFile)
 
  241     def find_key(self, line, unfoundKeys, warningFile):
 
  242         """ Input: line containing a parameter (key) preceding a ":"  
  245             * key -- if it has not been defined yet and is valid 
  246             * None -- if key does not exist 
  247             * exits -- if the key has already been defined to prevent duplicate confusion         
  249         key = line[:line.index(
":")].strip()
 
  250         if key 
in unfoundKeys:
 
  251             unfoundKeys.remove(key)
 
  255             self.
errorerror(
"\"{}\" has been defined more than once.".format(key))
 
  258                 "\"" + key + 
"\" is not one of the valid parameter names.",
 
  262         """ Find the key in a line, and the value for that key. 
  265             key = self.
find_keyfind_key(line, unfoundKeys, warningFile)
 
  267                 self.
find_valfind_val(line, key, inputIterator, unfoundKeys,
 
  280         """ Verify that value is either a 0 or a 1. 
  282         if value 
is '0' or value 
is '1':
 
  287             self.
errorerror(
"\"{}\" must be either '0' or '1'".format(key))
 
  290         """ Verify that value is a positive float. 
  292         if type(value) 
is list:
 
  294                 "\"{}\" contains curly braces {{}} but should not be a list value." 
  297             if noNeg 
and float(value) < 0:
 
  298                 self.
errorerror(
"\"{}\" cannot be a negative number.".format(key))
 
  301             if inList: 
return None 
  303                 self.
errorerror(
"\"{}\" contains an unexpected character. Must be a single "\
 
  304                       "floating point value (0.5, 1.6, 4.0, etc.)".format(key))
 
  306     def verify_int(self, value, key="", inList=False, noNeg=False):
 
  307         """ Verify that value is a positive integer. 
  309         if type(value) 
is list:
 
  311                 "\"{}\" contains curly braces {{}} but should not be a list value." 
  314             if noNeg 
and int(re.sub(
r'\.0*$', 
'', value)) < 0:
 
  315                 self.
errorerror(
"\"{}\" cannot be a negative number.".format(key))
 
  316             return int(re.sub(
r'\.0*$', 
'',
 
  319             if inList: 
return None 
  321                 self.
errorerror(
"\"{}\" contains an unexpected character. Must be a single "\
 
  322                       "integer value (0,1,2,3,etc.)".format(key))
 
  331         """verifies input list that come in format {0, 1, 2, 3} 
  334             * valList - list of values (flags, floats, or ints) corresponding to a parameter 
  335             * key - the name of the parameter whose list is being verified 
  336             * verificationFn - (either verifyflag, verifyfloat or verifyint) checks each list element  
  337             * desiredLength - how many elements are supposed to be in the list 
  338             * noZeros - (optional) True for lists than cannot contain 0's, false if 0's are ok   
  339             * noNegs - (optional) True for lists than cannot contain negative numbers, false otherwise 
  341             * returns negative value of list length to indicate incorrect length and provide meaningful error message 
  342             * prints error and exits if a value of the wrong type is found in the list 
  343             * returns None if successful""" 
  345         if valList == [
'']: 
return 0
 
  346         if type(valList) 
is not list:
 
  348                 "\"{}\"'s value must be a list enclosed in curly brackets {{}}." 
  350         if desiredLength != 0 
and int(len(valList)) != int(desiredLength):
 
  351             print(
'list desired length is ', desiredLength, 
'but valList is ',
 
  352                   valList, 
'with length ', len(valList))
 
  354         for i, value 
in enumerate(valList):
 
  355             value = value.strip()
 
  356             verifiedVal = verificationFn(value, inList=
True)
 
  357             if verifiedVal == 
None:
 
  362                         verificationFn.__name__))  
 
  363                 self.
errorerror(
"\"{}\" must be a list of {}s {}. non-{} found in "\
 
  364                       "list".format(key, listType, examples[listType], listType))
 
  365             if noZeros 
and verifiedVal == 0:
 
  366                 self.
errorerror(
"\"{}\" list cannot contain any zeros.".format(key))
 
  367             if noNegs 
and self.
is_negativeis_negative(float(verifiedVal)):
 
  369                     "\"{}\" list cannot contain negative values.".format(key))
 
  370             valList[i] = verifiedVal
 
  379     """Check input file for DFNGen to make sure all necessary parameters are defined 
  381      Input Format Requirements:   
  382         * Each parameter must be defined on its own line (separate by newline) 
  383         * A parameter (key) MUST be separated from its value by a colon ':' (ie. --> key: value) 
  384         * Values may also be placed on lines after the 'key' 
  385         * Comment Format:  On a line containing  // or / ``*``, nothing after ``*`` / or // will be processed  but text before a comment will be processed  
  390             name of dfnGen input file 
  392             Name of stripped down input file for DFNGen (input_file_clean.dat)  
  400     There are warnings and errors raised in this function. Warning will let you continue while errors will stop the run. Continue past warnings are your own risk.      
  409         'insertUserRectanglesFirst': [],
 
  410         'keepOnlyLargestCluster': [],
 
  411         'keepIsolatedFractures': [],
 
  415         'userRectanglesOnOff': [],
 
  416         'printRejectReasons': [],
 
  419         'RectByCoord_Input_File_Path': [],
 
  422         'lengthCorrelatedAperture': [],
 
  423         'ebetaDistribution': [],
 
  424         'tripleIntersections': [],
 
  429         'constantPermeability': [],
 
  436         'outputAllRadii': [],
 
  439         'userRecByCoord': [],
 
  440         'RectByCoord_Input_File_Path': [],
 
  441         'userRectanglesOnOff': [],
 
  442         'UserRect_Input_File_Path': [],
 
  443         'userEllByCoord': [],
 
  444         'EllByCoord_Input_File_Path': [],
 
  445         'userEllipsesOnOff': [],
 
  446         'UserEll_Input_File_Path': [],
 
  447         'userPolygonByCoord': [],
 
  448         'PolygonByCoord_Input_File_Path': [],
 
  450         'rbetaDistribution': [],
 
  457         'domainSizeIncrease': [],
 
  459         'outputFinalRadiiPerFamily': [],
 
  469         'constantAperture': [],
 
  479         'ignoreBoundaryFaces': [],
 
  480         'visualizationMode': [],
 
  481         'outputAcceptedRadiiPerFamily': [],
 
  482         'apertureFromTransmissivity': [],
 
  496         'rejectsPerFracture': [],
 
  499         'forceLargeFractures': [],
 
  500         'radiiListIncrease': [],
 
  501         'removeFracturesLessThan': []
 
  506         'stopCondition', 
'nPoly', 
'outputAllRadii', 
'outputAllRadii',
 
  507         'outputFinalRadiiPerFamily', 
'outputAcceptedRadiiPerFamily',
 
  508         'domainSize', 
'numOfLayers', 
'layers', 
'numOfRegions', 
'regions', 
'h',
 
  509         'tripleIntersections', 
'printRejectReasons', 
'disableFram',
 
  510         'visualizationMode', 
'seed', 
'domainSizeIncrease',
 
  511         'keepOnlyLargestCluster', 
'keepIsolatedFractures',
 
  512         'ignoreBoundaryFaces', 
'boundaryFaces', 
'rejectsPerFracture',
 
  513         'famProb', 
'insertUserRectanglesFirst', 
'nFamEll', 
'eLayer', 
'eRegion',
 
  514         'edistr', 
'ebetaDistribution', 
'e_p32Targets', 
'easpect', 
'enumPoints',
 
  515         'eAngleOption', 
'etheta', 
'ephi', 
'ebeta', 
'ekappa', 
'eLogMean', 
'esd',
 
  516         'eLogMin', 
'eLogMax', 
'eExpMean', 
'eExpMin', 
'eExpMax', 
'econst',
 
  517         'emin', 
'emax', 
'ealpha', 
'nFamRect', 
'rLayer', 
'rRegion', 
'rdistr',
 
  518         'rbetaDistribution', 
'r_p32Targets', 
'raspect', 
'rAngleOption',
 
  519         'rtheta', 
'rphi', 
'rbeta', 
'rkappa', 
'rLogMean', 
'rsd', 
'rLogMin',
 
  520         'rLogMax', 
'rmin', 
'rmax', 
'ralpha', 
'rExpMean', 
'rExpMin', 
'rExpMax',
 
  521         'rconst', 
'userEllipsesOnOff', 
'UserEll_Input_File_Path',
 
  522         'userRectanglesOnOff', 
'UserRect_Input_File_Path',
 
  523         'EllByCoord_Input_File_Path', 
'userEllByCoord', 
'userRecByCoord',
 
  524         'userPolygonByCoord', 
'RectByCoord_Input_File_Path',
 
  525         'PolygonByCoord_Input_File_Path', 
'aperture', 
'meanAperture',
 
  526         'stdAperture', 
'apertureFromTransmissivity', 
'constantAperture',
 
  527         'lengthCorrelatedAperture', 
'permOption', 
'constantPermeability',
 
  528         'forceLargeFractures', 
'radiiListIncrease', 
'removeFracturesLessThan' 
  533         'stopCondition', 
'domainSize', 
'numOfLayers', 
'numOfRegions',
 
  534         'outputAllRadii', 
'outputFinalRadiiPerFamily',
 
  535         'outputAcceptedRadiiPerFamily', 
'tripleIntersections',
 
  536         'printRejectReasons', 
'disableFram', 
'visualizationMode', 
'seed',
 
  537         'domainSizeIncrease', 
'keepOnlyLargestCluster',
 
  538         'keepIsolatedFractures', 
'ignoreBoundaryFaces', 
'rejectsPerFracture',
 
  539         'famProb', 
'insertUserRectanglesFirst', 
'nFamEll', 
'nFamRect',
 
  540         'userEllipsesOnOff', 
'userRectanglesOnOff', 
'userEllByCoord',
 
  541         'userRecByCoord', 
'userPolygonByCoord', 
'aperture', 
'permOption',
 
  542         'forceLargeFractures', 
'radiiListIncrease', 
'removeFracturesLessThan' 
  545     global noDependancyFlags
 
  546     noDependancyFlags = [
 
  547         'outputAllRadii', 
'outputFinalRadiiPerFamily',
 
  548         'outputAcceptedRadiiPerFamily', 
'tripleIntersections',
 
  549         'printRejectReasons', 
'visualizationMode', 
'keepOnlyLargestCluster',
 
  550         'keepIsolatedFractures', 
'insertUserRectanglesFirst',
 
  551         'forceLargeFractures' 
  556         "Float": 
"(0.5, 1.6, 4.0, etc.)",
 
  557         "Int": 
"(0,1,2,3,etc.)" 
  581     warningFile = open(
"warningFileDFNGen.txt", 
'w')
 
  583     jobname = self.jobname
 
  585     input_helper_methods = 
input_helper(params, minFracSize)
 
  593         """ Check the number of families of ellipses.""" 
  596         ellipseFams = input_helper_methods.verify_int(
 
  597             input_helper_methods.value_of(
'nFamEll', params),
 
  601             input_helper_methods.warning(
 
  602                 "You have set the number of ellipse families to 0, outside user-defined ellipses, no ellipses will be generated.",
 
  606         """ Check the number of families of rectangles.""" 
  609         rectFams = input_helper_methods.verify_int(
 
  610             input_helper_methods.value_of(
'nFamRect', params),
 
  614             input_helper_methods.warning(
 
  615                 "You have set the number of rectangle families to 0, outside user-defined rectangles, no rectangles will be generated.",
 
  618     def stop_condition():
 
  619         """ Check the number of polygons if stopCondition is set to 1, else check the p32 target parameters.""" 
  621         if input_helper_methods.verify_flag(
 
  622                 input_helper_methods.value_of(
'stopCondition', params),
 
  623                 'stopCondition') == 0:
 
  628     def check_no_dep_flags():
 
  629         """ Check for dependency flags.""" 
  630         for flagName 
in noDependancyFlags:
 
  631             input_helper_methods.verify_flag(
 
  632                 input_helper_methods.value_of(flagName, params), flagName)
 
  635         """ Check that domainSize has 3 non-zero values to define the  
  636         size of each dimension (x,y,z) of the domain. 
  638         errResult = input_helper_methods.verify_list(
 
  639             input_helper_methods.value_of(
'domainSize', params),
 
  641             input_helper_methods.verify_float,
 
  645         if errResult != 
None:
 
  646             input_helper_methods.error(
"\"domainSize\" has defined {} value(s) but there must be 3 non-zero "\
 
  647                   "values to represent x, y, and z dimensions".format(-errResult))
 
  649     def domain_size_increase():
 
  650         """ Check the domain size increase parameters. 
  652         errResult = input_helper_methods.verify_list(
 
  653             input_helper_methods.value_of(
'domainSizeIncrease', params),
 
  654             domain_size_increase,
 
  655             input_helper_methods.verify_float,
 
  657         if errResult != 
None:
 
  658             input_helper_methods.error(
"\"domainSizeIncrease\" has defined {} value(s) but there must be 3 non-zero "\
 
  659                   "values to represent extensions in the x, y, and z dimensions".format(-errResult))
 
  661         for i, val 
in enumerate(
 
  662                 input_helper_methods.value_of(
'domainSizeIncrease', params)):
 
  663             if val >= input_helper_methods.value_of(
'domainSize',
 
  665                 input_helper_methods.error(
 
  666                     "\"domainSizeIncrease\" contains {} which is more than half of the domain's " 
  667                     "range in that dimension. Cannot change the domain's size by more than half of " 
  668                     "that dimension's value defined in \"domainSize\". This risks collapsing or " 
  669                     "doubling the domain.".format(val))
 
  672         """ Check the number of layers parameter.""" 
  674         numLayers = input_helper_methods.verify_int(
 
  675             input_helper_methods.value_of(
'numOfLayers', params),
 
  679             if numLayers != len(params[
'layers']):
 
  680                 input_helper_methods.error(
"\"layers\" has defined {} layers but \"numLayers\" was defined to "\
 
  681                       "be {}.".format(len(params[
'layers']), numLayers))
 
  686         """ Check the layer parameters provided. """ 
  687         halfZdomain = params[
'domainSize'][0][
 
  691         for i, layer 
in enumerate(params[
'layers']):
 
  692             errResult = input_helper_methods.verify_list(
 
  694                 "layer #{}".format(i + 1),
 
  695                 input_helper_methods.verify_float,
 
  697             if errResult != 
None:
 
  698                 input_helper_methods.error(
"\"layers\" has defined layer #{} to have {} element(s) but each layer must "\
 
  699                       "have 2 elements, which define its upper and lower bounds".format(i+1, -errResult))
 
  700             if params[
'layers'].count(layer) > 1:
 
  701                 input_helper_methods.error(
 
  702                     "\"layers\" has defined the same layer more than once.")
 
  706                 input_helper_methods.error(
"\"layers\" has defined layer #{0} where zmin: {1} is "\
 
  707                     "greater than zmax {2}".format(i+1,minZ, maxZ))
 
  708             if minZ <= -halfZdomain 
and maxZ <= -halfZdomain:
 
  709                 input_helper_methods.error(
"\"layers\" has defined layer #{} to have both upper and lower bounds completely "\
 
  710                       "below the domain's z-dimensional range ({} to {}). At least one boundary must be within "\
 
  711                       "the domain's range. The domain's range is half of 3rd value in \"domainSize\" "\
 
  712                       "(z-dimension) in both positive and negative directions.".format(i+1, -halfZdomain, halfZdomain))
 
  713             if minZ >= halfZdomain 
and maxZ >= halfZdomain:
 
  714                 input_helper_methods.error(
"\"layers\" has defined layer #{} to have both upper and lower bounds completely "\
 
  715                       "above the domain's z-dimensional range ({} to {}). At least one boundary must be within "\
 
  716                       "the domain's range. The domain's range is half of 3rd value in \"domainSize\" "\
 
  717                       "(z-dimension) in both positive and negative directions.".format(i+1, -halfZdomain, halfZdomain))
 
  719     def num_of_regions():
 
  720         """ Check the number of regions parameter.""" 
  722         numRegions = input_helper_methods.verify_int(
 
  723             input_helper_methods.value_of(
'numOfRegions', params),
 
  727             print(
"Number of Regions {0}".format(numRegions))
 
  728             if numRegions != len(params[
'regions']):
 
  729                 input_helper_methods.error(
"\"regions\" has defined {} regions but \"numOfRegions\" was defined to "\
 
  730                       "be {}.".format(len(params[
'regions']), numRegions))
 
  735         """ Check the regions parameters provided. """ 
  736         half_x_domain = params[
'domainSize'][0][
 
  738         half_y_domain = params[
'domainSize'][0][
 
  740         half_z_domain = params[
'domainSize'][0][
 
  744         for i, region 
in enumerate(params[
'regions']):
 
  745             errResult = input_helper_methods.verify_list(
 
  747                 "regions #{}".format(i + 1),
 
  748                 input_helper_methods.verify_float,
 
  750             if errResult != 
None:
 
  751                 input_helper_methods.error(
"\"regions\" has defined layer #{} to have {} element(s) but each region must "\
 
  752                       "have 6 elements, which define its upper and lower bounds".format(i+1, -errResult))
 
  753             if params[
'regions'].count(regions) > 1:
 
  754                 input_helper_methods.error(
 
  755                     "\"regions\" has defined the same region more than once.")
 
  764             if region[1] <= region[0]:
 
  765                 input_helper_methods.error(
"\"regions\" has defined region #{0} where xmin: {1} is "\
 
  766                     "greater than xmax {2}".format(i+1,region[0], region[1]))
 
  767             if region[0] <= -half_x_domain 
and region[1] <= -half_x_domain:
 
  768                 input_helper_methods.error(
"\"regions\" has defined layer #{} to have both upper and lower bounds completely "\
 
  769                       "below the domain's x-dimensional range ({} to {}). At least one boundary must be within "\
 
  770                       "the domain's range. The domain's range is half of 1st value in \"domainSize\" "\
 
  771                       "(x-dimension) in both positive and negative directions.".format(i+1, -half_x_domain, half_x_domain))
 
  772             if region[0] >= half_x_domain 
and region[1] >= half_x_domain:
 
  773                 input_helper_methods.error(
"\"regions\" has defined layer #{} to have both upper and lower bounds completely "\
 
  774                       "above the domain's x-dimensional range ({} to {}). At least one boundary must be within "\
 
  775                       "the domain's range. The domain's range is half of 1st  value in \"domainSize\" "\
 
  776                       "(x-dimension) in both positive and negative directions.".format(i+1, -half_x_domain, half_x_domain))
 
  778             if region[3] <= region[2]:
 
  779                 input_helper_methods.error(
"\"regions\" has defined region #{0} where ymin: {1} is "\
 
  780                     "greater than ymax {2}".format(i+1,region[3], region[2]))
 
  781             if region[2] <= -half_y_domain 
and region[3] <= -half_y_domain:
 
  782                 input_helper_methods.error(
"\"regions\" has defined layer #{} to have both upper and lower bounds completely "\
 
  783                       "below the domain's y-dimensional range ({} to {}). At least one boundary must be within "\
 
  784                       "the domain's range. The domain's range is half of 2nd value in \"domainSize\" "\
 
  785                       "(y-dimension) in both positive and negative directions.".format(i+1, -half_x_domain, half_x_domain))
 
  786             if region[2] >= half_y_domain 
and region[3] >= half_y_domain:
 
  787                 input_helper_methods.error(
"\"regions\" has defined layer #{} to have both upper and lower bounds completely "\
 
  788                       "above the domain's y-dimensional range ({} to {}). At least one boundary must be within "\
 
  789                       "the domain's range. The domain's range is half of 2nd  value in \"domainSize\" "\
 
  790                       "(y-dimension) in both positive and negative directions.".format(i+1, -half_y_domain, half_y_domain))
 
  793             if region[5] <= region[4]:
 
  794                 input_helper_methods.error(
"\"regions\" has defined region #{0} where zmin: {1} is "\
 
  795                     "greater than zmax {2}".format(i+1,region[5], region[4]))
 
  796             if region[4] <= -half_z_domain 
and region[5] <= -half_z_domain:
 
  797                 input_helper_methods.error(
"\"regions\" has defined layer #{} to have both upper and lower bounds completely "\
 
  798                       "below the domain's z-dimensional range ({} to {}). At least one boundary must be within "\
 
  799                       "the domain's range. The domain's range is half of 3rd value in \"domainSize\" "\
 
  800                       "(z-dimension) in both positive and negative directions.".format(i+1, -half_z_domain, half_z_domain))
 
  801             if region[4] >= half_z_domain 
and region[5] >= half_z_domain:
 
  802                 input_helper_methods.error(
"\"regions\" has defined layer #{} to have both upper and lower bounds completely "\
 
  803                       "above the domain's z-dimensional range ({} to {}). At least one boundary must be within "\
 
  804                       "the domain's range. The domain's range is half of 3rd  value in \"domainSize\" "\
 
  805                       "(z-dimension) in both positive and negative directions.".format(i+1, -half_z_domain, half_z_domain))
 
  808         """ Verify the flag that indicates whether if FRAM is disabled. 
  809             If FRAM is enabled, verify the value of h is valid.   
  811         if input_helper_methods.verify_flag(
 
  812                 input_helper_methods.value_of(
'disableFram', params),
 
  816             input_helper_methods.warning(
"FRAM (feature rejection algorithm for meshing) is disabled. This means that"\
 
  817                                          "dfnWorks will only run through fracture network generation (the code will stop before meshing)."\
 
  818                                          "To run the full code change the disableFram option to 1")
 
  821         """ Check the value of the seed used for pseudorandom number generation. 
  823         val = input_helper_methods.verify_int(input_helper_methods.value_of(
 
  828             input_helper_methods.warning(
"\"seed\" has been set to 0. Random generator will use current wall "\
 
  829                 "time so distribution's random selection will not be as repeatable. "\
 
  830                 "Use an integer greater than 0 for better repeatability.", params)
 
  831         params[
'seed'][0] = val
 
  833     def ignore_boundary_faces():
 
  834         """ Check the value fo the ignoreBoundaryFaces flag. 
  836         if input_helper_methods.verify_flag(
 
  837                 input_helper_methods.value_of(
'ignoreBoundaryFaces', params),
 
  838                 'ignoreBoundaryFaces') == 0:
 
  841     def rejects_per_fracture():
 
  842         """ Check the value of the rejectsPerFracture int.  
  844         val = input_helper_methods.verify_int(input_helper_methods.value_of(
 
  845             'rejectsPerFracture', params),
 
  846                                               'rejectsPerFracture',
 
  850             input_helper_methods.warning(
 
  851                 "changing \"rejectsPerFracture\" from 0 to 1. Can't ensure 0 rejections.",
 
  854         params[
'rejectsPerFracture'][0] = val
 
  857         """ Check the list of family probabilites (the list of  probabilities that a fracture is in each family). 
  860         errResult = input_helper_methods.verify_list(
 
  861             input_helper_methods.value_of(
'famProb', params),
 
  863             input_helper_methods.verify_float,
 
  864             desiredLength=ellipseFams + rectFams,
 
  868         if errResult != 
None:
 
  870             input_helper_methods.error(
"\"famProb\" must have {} (nFamEll + nFamRect) non-zero elements,"\
 
  871                   "one for each family of ellipses and rectangles. {} probabiliies have "\
 
  872                   "been defined.".format(ellipseFams + rectFams, -errResult))
 
  875             float(x) 
for x 
in input_helper_methods.value_of(
'famProb', params)
 
  877         if sum(probList) != 1:
 
  878             input_helper_methods.scale(probList, warningFile)
 
  881         """ Check the parameters for user-defined rectangles and ellipses. 
  883         userEs = 
"userEllipsesOnOff" 
  884         userRs = 
"userRectanglesOnOff" 
  885         recByCoord = 
"userRecByCoord" 
  886         ellByCoord = 
"userEllByCoord" 
  887         polygonByCoord = 
"userPolygonByCoord" 
  888         ePath = 
"UserEll_Input_File_Path" 
  889         rPath = 
"UserRect_Input_File_Path" 
  890         coordPath = 
"RectByCoord_Input_File_Path" 
  891         ecoordPath = 
"EllByCoord_Input_File_Path" 
  892         polycoordPath = 
"PolygonByCoord_Input_File_Path" 
  893         invalid = 
"\"{}\" is not a valid path." 
  895         if input_helper_methods.verify_flag(
 
  896                 input_helper_methods.value_of(ellByCoord, params),
 
  898             if not os.path.isfile(
 
  899                     input_helper_methods.value_of(ecoordPath, params)):
 
  900                 print(
'THIS PATH IS NOT A VALID FILE PATH: ',
 
  901                       input_helper_methods.value_of(ecoordPath, params))
 
  902                 input_helper_methods.error(invalid.format(ecoordPath))
 
  904                 shutil.copy(input_helper_methods.value_of(ecoordPath, params),
 
  907         if input_helper_methods.verify_flag(
 
  908                 input_helper_methods.value_of(userEs, params), userEs) == 1:
 
  909             if not os.path.isfile(input_helper_methods.value_of(ePath,
 
  911                 print(
'THIS PATH IS NOT A VALID FILE PATH: ',
 
  912                       input_helper_methods.value_of(ePath, params))
 
  913                 input_helper_methods.error(invalid.format(ePath))
 
  915                 shutil.copy(input_helper_methods.value_of(ePath, params),
 
  918         if input_helper_methods.verify_flag(
 
  919                 input_helper_methods.value_of(userRs, params), userRs) == 1:
 
  920             if not os.path.isfile(input_helper_methods.value_of(rPath,
 
  922                 print(
'THIS PATH IS NOT A VALID FILE PATH: ',
 
  923                       input_helper_methods.value_of(rPath, params))
 
  924                 input_helper_methods.error(invalid.format(rPath))
 
  926                 shutil.copy(input_helper_methods.value_of(rPath, params),
 
  929         if input_helper_methods.verify_flag(
 
  930                 input_helper_methods.value_of(recByCoord, params),
 
  932             if not os.path.isfile(
 
  933                     input_helper_methods.value_of(coordPath, params)):
 
  934                 print(
'THIS PATH IS NOT A VALID FILE PATH: ',
 
  935                       input_helper_methods.value_of(coordPath, params))
 
  936                 input_helper_methods.error(invalid.format(coordPath))
 
  938                 shutil.copy(input_helper_methods.value_of(coordPath, params),
 
  942         """ Verify the int value used for aperture. 
  944         apOption = input_helper_methods.verify_int(
 
  945             input_helper_methods.value_of(
'aperture', params), 
'aperture')
 
  948             if input_helper_methods.verify_float(input_helper_methods.value_of(
 
  949                     'meanAperture', params),
 
  952                 input_helper_methods.error(
"\"meanAperture\" cannot be 0.")
 
  953             if input_helper_methods.verify_float(input_helper_methods.value_of(
 
  954                     'stdAperture', params),
 
  957                 input_helper_methods.error(
"\"stdAperture\" cannot be 0. If you wish to have a standard deviation "\
 
  958                       "of 0, use a constant aperture instead.")
 
  961             input_helper_methods.verify_list(input_helper_methods.value_of(
 
  962                 'apertureFromTransmissivity', params),
 
  963                                              'apertureFromTransmissivity',
 
  964                                              input_helper_methods.verify_float,
 
  967             if input_helper_methods.value_of(
'apertureFromTransmissivity',
 
  969                 input_helper_methods.error(
 
  970                     "\"apertureFromTransmissivity\"'s first value cannot be 0." 
  972             if input_helper_methods.value_of(
'apertureFromTransmissivity',
 
  974                 input_helper_methods.warning(
 
  975                     "\"apertureFromTransmissivity\"'s second value is 0, which will result in a constant aperature.",
 
  979             if input_helper_methods.verify_float(input_helper_methods.value_of(
 
  980                     'constantAperture', params),
 
  984                 params[
'constantAperture'][0] = 1e-25
 
  985                 input_helper_methods.warning(
"\"constantAperture\" was set to 0 and has been changed "\
 
  986                       "to 1e-25 so fractures have non-zero thickness.", params)
 
  989             input_helper_methods.verify_list(input_helper_methods.value_of(
 
  990                 'lengthCorrelatedAperture', params),
 
  991                                              'lengthCorrelatedAperture',
 
  992                                              input_helper_methods.verify_float,
 
  995             if input_helper_methods.value_of(
'lengthCorrelatedAperture',
 
  997                 input_helper_methods.error(
 
  998                     "\"lengthCorrelatedAperture\"'s first value cannot be 0.")
 
  999             if input_helper_methods.value_of(
'lengthCorrelatedAperture',
 
 1001                 input_helper_methods.warning(
 
 1002                     "\"lengthCorrelatedAperture\"'s second value is 0, which will result in a constant aperature.",
 
 1006             input_helper_methods.error(
"\"aperture\" must only be option 1 (log-normal), 2 (from transmissivity), "\
 
 1007                   "3 (constant), or 4 (length correlated).")
 
 1010         """Verify the float used for permeability, if permOption is set to 1""" 
 1011         if input_helper_methods.verify_flag(
 
 1012                 input_helper_methods.value_of(
'permOption'),
 
 1014             if input_helper_methods.verify_float(
 
 1015                     input_helper_methods.value_of(
'constantPermeability',
 
 1017                     'constantPermeability') == 0:
 
 1018                 params[
'constantPermeability'][0] = 1e-25
 
 1019                 input_helper_methods.warning(
"\"constantPermeability\" was set to 0 and has been changed "\
 
 1020                       "to 1e-25 so fractures have non-zero permeability.", params)
 
 1027         """Verify the number of polygons integer.""" 
 1028         val = input_helper_methods.verify_int(input_helper_methods.value_of(
 
 1032         if val == 0: input_helper_methods.error(
"\"nPoly\" cannot be zero.")
 
 1033         params[
'nPoly'][0] = val
 
 1036         """Verify the p32 target parameters for ellipses and parameters.""" 
 1037         global ellipseFams, rectFams
 
 1038         errResult = 
None if (ellipseFams == 0) 
else input_helper_methods.verify_list(input_helper_methods.value_of(
'e_p32Targets', params), 
'e_p32Targets', \
 
 1039                                   input_helper_methods.verify_float, desiredLength =  ellipseFams, noNegs=
True, noZeros=
True)
 
 1040         if errResult != 
None:
 
 1041             input_helper_methods.error(
"\"e_p32Targets\" has defined {} p32 values but there is(are) {} ellipse family(ies). "\
 
 1042                   "Need one p32 value per ellipse family.".format(-errResult, ellipseFams))
 
 1044         errResult = 
None if (rectFams == 0) 
else input_helper_methods.verify_list(input_helper_methods.value_of(
'r_p32Targets', params), 
"r_p32Targets", \
 
 1045                                 input_helper_methods.verify_float, desiredLength =  rectFams, noNegs=
True, noZeros=
True)
 
 1046         if errResult != 
None:
 
 1047             input_helper_methods.error(
"\"r_p32Targets\" has defined {} p32 value(s) but there is(are) {} rectangle "\
 
 1048                   "family(ies). Need one p32 value per rectangle family)".format(-errResult, rectFams))
 
 1050     def f(theta, t, a, b):
 
 1051         """Differential Equation Angle Theta as a function of arc length, see Hyman et al. 2014, SIAM J. Sci. Compu 
 1053         return 1.0 / np.sqrt((a * np.sin(theta))**2 + (b * np.cos(theta)**2))
 
 1055     def h_shape_check(aspect, minRadius, num_points=4):
 
 1056         """ Check that the arc length discretized ellipse is greater than 3*h """ 
 1066         c = np.pi * (a + b) * (1.0 + (3.0 * ((a - b) / (a + b))**2) /
 
 1067                                (10. + np.sqrt(4. - 3. * ((a - b) /
 
 1076         steps = np.linspace(0, c, n + 1)
 
 1078         theta = scipy.integrate.odeint(f, 0, steps, args=(a, b), rtol=10**-10)
 
 1081         x = a * r * np.cos(theta)
 
 1082         y = b * r * np.sin(theta)
 
 1086         for i 
in range(1, n):
 
 1087             for j 
in range(i, n):
 
 1089                     h_current = np.sqrt((x[i] - x[j])**2 + (y[i] - y[j])**2)
 
 1090                     if (h_current < h_min):
 
 1095     def compare_pts_v_sh(prefix, hval):
 
 1096         """ Check that the rectangles and ellipses generated will not involve features with length less than 3*h value used in FRAM.  
 1098         shape = 
"ellipse" if prefix == 
'e' else "rectangle" 
 1099         aspectList = params[prefix + 
"aspect"][0]
 
 1100         numPointsList = 
None 
 1102         if shape == 
"ellipse":
 
 1103             numPointsList = params[
'enumPoints'][0]
 
 1112         for distrib 
in params[prefix + 
'distr'][0]:
 
 1113             if distrib 
in [1, 2, 3, 4]:
 
 1115                     minRad = params[prefix + 
'LogMin'][0][numLog]
 
 1118                     minRad = params[prefix + 
'min'][0][numTPL]
 
 1121                     minRad = params[prefix + 
'ExpMin'][0][numEXP]
 
 1124                     minRad = params[prefix + 
'const'][0][numConst]
 
 1126                 if shape == 
"ellipse":
 
 1127                     hmin = h_shape_check(float(aspectList[numAspect]),
 
 1129                                          int(numPointsList[numAspect]))
 
 1131                     hmin = h_shape_check(
 
 1132                         float(aspectList[numAspect]), float(minRad)
 
 1135                 if hmin < (3 * hval):
 
 1136                     input_helper_methods.error(shape + 
" family #{} has defined a shape with features too small for meshing. Increase the aspect "\
 
 1137                              "ratio or minimum radius so that no 2 points of the polygon create a line of length less "\
 
 1138                              "than 3h".format(numAspect+1))
 
 1143         """ Check the float value provided for h to be used in FRAM (the feautre rejection algorithm for meshing. 
 1147         val = input_helper_methods.verify_float(input_helper_methods.value_of(
 
 1152         if val == 0: input_helper_methods.error(
"\"h\" cannot be 0.")
 
 1153         if minFracSize 
is None:
 
 1155         if val < minFracSize / 1000.0 
and ellipseFams + rectFams > 0:  
 
 1162             input_helper_methods.warning(
"\"h\" (length scale) is smaller than one 1000th of the minimum "\
 
 1163                   "fracture size ({}). The generated mesh will be extremely fine and will likely be "\
 
 1164                   "computationally exhausting to create. Computation may take longer than usual.".format(minFracSize))
 
 1165         if val > minFracSize / 10.0:
 
 1166             input_helper_methods.warning(
"\"h\" (length scale) is greater than one 10th of the minimum "\
 
 1167                   "fracture size ({}). The generated mesh will be very coarse and there will likely "\
 
 1168                   "be a high rate of fracture rejection.".format(minFracSize))
 
 1170         if val > minFracSize:
 
 1171             input_helper_methods.error(
"\"h\" (length scale) is greater than the minimum fracture size ({}). "\
 
 1172                                              "Choose a smaller value for h or a greater minimum fracure size."\
 
 1173                                              " ".format(minFracSize))
 
 1174         compare_pts_v_sh(
'e', val)
 
 1175         compare_pts_v_sh(
'r', val)
 
 1177         params[
'h'][0] = val
 
 1179     def boundary_faces():
 
 1180         """Check that the boundaryFaceis list is a list of flags of length 6, one for each side of the domain 
 1181         ie {1, 1, 1, 0, 0, 1} represents --> {+x, -x, +y, -y, +z, -z} 
 1182         DFN only keeps clusters with connections to domain boundaries set to 1. 
 1184         errResult = input_helper_methods.verify_list(
 
 1185             input_helper_methods.value_of(
'boundaryFaces', params),
 
 1186             'boundaryFaces', input_helper_methods.verify_flag, 6)
 
 1187         if errResult != 
None:
 
 1188             input_helper_methods.error(
"\"boundaryFaces\" must be a list of 6 flags (0 or 1), {} have(has) been defined. Each flag "\
 
 1189                   "represents a side of the domain, {{+x, -x, +y, -y, +z, -z}}.".format(-errResult))
 
 1192         """ Check the integer value of enumPoints for each ellipse family.""" 
 1193         errResult = input_helper_methods.verify_list(
 
 1194             input_helper_methods.value_of(
'enumPoints', params),
 
 1196             input_helper_methods.verify_int,
 
 1197             desiredLength=ellipseFams,
 
 1200         if errResult != 
None:
 
 1201             input_helper_methods.error(
"\"enumPoints\" has defined {} value(s) but there is(are) {} families of ellipses. Please "\
 
 1202                   "define one enumPoints value greater than 4 for each ellipse family.".format(-errResult, ellipseFams))
 
 1203         for val 
in input_helper_methods.value_of(
"enumPoints"):
 
 1205                 input_helper_methods.error(
"\"enumPoints\" contains a value less than or equal to 4. If 4 points were intended, "\
 
 1206                       "define this family as a rectangle family. No polygons with less than 4 verticies are acceptable.")
 
 1217         """ Check the aspect of the the rectangle or ellipse families. """ 
 1218         shape = 
"ellipse" if prefix == 
'e' else "rectangle" 
 1219         numFamilies = ellipseFams 
if prefix == 
'e' else rectFams
 
 1220         paramName = prefix + 
"aspect" 
 1222         errResult = input_helper_methods.verify_list(
 
 1223             input_helper_methods.value_of(paramName),
 
 1225             input_helper_methods.verify_float,
 
 1226             desiredLength=numFamilies,
 
 1229         if errResult != 
None:
 
 1230             input_helper_methods.error(
"\"{}\" has defined {} value(s) but there is(are) {} {} families. Please define one "\
 
 1231                   "aspect ratio for each family.".format(paramName, -errResult, numFamilies, shape))
 
 1233     def angle_option(prefix):
 
 1234         """ Check the angle option flag. """ 
 1235         paramName = prefix + 
"AngleOption" 
 1236         input_helper_methods.verify_flag(
 
 1237             input_helper_methods.value_of(paramName), paramName)
 
 1240         """ Check the number of layers. """ 
 1241         shape = 
"ellipse" if prefix == 
'e' else "rectangle" 
 1242         numFamilies = ellipseFams 
if prefix == 
'e' else rectFams
 
 1243         paramName = prefix + 
"Layer" 
 1245         errResult = input_helper_methods.verify_list(
 
 1246             input_helper_methods.value_of(paramName),
 
 1248             input_helper_methods.verify_int,
 
 1249             desiredLength=numFamilies)
 
 1250         if errResult != 
None:
 
 1251             input_helper_methods.error(
"\"{}\" has defined {} layer(s) but there is(are) {} {} families. "\
 
 1252                   "Need one layer per {} family. Layers are numbered by the order they "\
 
 1253                   "are defined in 'layers' parameter. Layer 0 is the whole domain."\
 
 1254                   .format(paramName, -errResult, numFamilies, shape, shape))
 
 1256         for layer 
in input_helper_methods.value_of(paramName):
 
 1257             if input_helper_methods.is_negative(int(layer)):
 
 1258                 input_helper_methods.error(
"\"{}\" contains a negative layer number. Only values from 0 to "\
 
 1259                       "{} (numOfLayers) are accepted. Layer 0 corresponds to the entire"\
 
 1260                       "domain.".format(paramName, numLayers))
 
 1261             if int(layer) > numLayers:
 
 1262                 input_helper_methods.error(
"\"{}\" contains value '{}' but only {} layer(s) is(are) defined. Make sure the "\
 
 1263                       "layer numbers referenced here are found in that same position in \"layers\" "\
 
 1264                       "parameter.".format(paramName, layer, numLayers))
 
 1267         """ Check the number of region. """ 
 1268         shape = 
"ellipse" if prefix == 
'e' else "rectangle" 
 1269         numFamilies = ellipseFams 
if prefix == 
'e' else rectFams
 
 1270         paramName = prefix + 
"Region" 
 1272         errResult = input_helper_methods.verify_list(
 
 1273             input_helper_methods.value_of(paramName),
 
 1275             input_helper_methods.verify_int,
 
 1276             desiredLength=numFamilies)
 
 1277         if errResult != 
None:
 
 1278             input_helper_methods.error(
"\"{}\" has defined {} layer(s) but there is(are) {} {} families. "\
 
 1279                   "Need one layer per {} family. Regions are numbered by the order they "\
 
 1280                   "are defined in 'region' parameter. Layer 0 is the whole domain."\
 
 1281                   .format(paramName, -errResult, numFamilies, shape, shape))
 
 1283         for region 
in input_helper_methods.value_of(paramName):
 
 1284             if input_helper_methods.is_negative(int(region)):
 
 1285                 input_helper_methods.error(
"\"{}\" contains a negative layer number. Only values from 0 to "\
 
 1286                       "{} (numOfRegions) are accepted. Layer 0 corresponds to the entire"\
 
 1287                       "domain.".format(paramName, numRegions))
 
 1288             if int(region) > numRegions:
 
 1289                 input_helper_methods.error(
"\"{}\" contains value '{}' but only {} region(s) is(are) defined. Make sure the "\
 
 1290                       "region numbers referenced here are found in that same position in \"region\" "\
 
 1291                       "parameter.".format(paramName, region, numRegions))
 
 1293     def theta_phi_kappa(prefix):
 
 1294         """ Check the angle parameters used for Fisher distributions  
 1296         shape = 
"ellipse" if prefix == 
'e' else "rectangle" 
 1297         numFamilies = ellipseFams 
if prefix == 
'e' else rectFams
 
 1298         paramNames = [prefix + name 
for name 
in [
"theta", 
"phi", 
"kappa"]]
 
 1299         errString = 
"\"{}\" has defined {} angle(s) but there is(are) {} {} family(ies)."\
 
 1300                 "Please defined one angle for each {} family." 
 1302         for param 
in paramNames:
 
 1303             errResult = input_helper_methods.verify_list(
 
 1304                 input_helper_methods.value_of(param),
 
 1306                 input_helper_methods.verify_float,
 
 1307                 desiredLength=numFamilies)
 
 1308             if errResult != 
None:
 
 1309                 input_helper_methods.error(
 
 1310                     errString.format(param, -errResult, numFamilies, shape,
 
 1336         """ Parse each line of the input file.  
 1338         for line 
in inputIterator:
 
 1339             line = input_helper_methods.extract_parameters(
 
 1340                 line, inputIterator)  
 
 1341             if (line != 
"" and ":" in line):
 
 1342                 input_helper_methods.process_line(line, unfoundKeys,
 
 1343                                                   inputIterator, warningFile)
 
 1344         needed = [unfound 
for unfound 
in unfoundKeys 
if unfound 
in mandatory]
 
 1348                 errString += 
"\t\"" + key + 
"\"\n" 
 1349             input_helper_methods.error(
 
 1350                 "Missing the following mandatory parameters: \n{}".format(
 
 1354         """ Verify all of the parameters in the input file. 
 1356         distributions = distr_module.distr(params, numEdistribs, numRdistribs,
 
 1359             n_fam_ell, n_fam_rect, stop_condition, domain_size, num_of_layers,
 
 1360             num_of_regions, seed, domain_size_increase, ignore_boundary_faces,
 
 1361             rejects_per_fracture, user_defined,
 
 1362             input_helper_methods.check_fam_count, check_no_dep_flags, fam_prob
 
 1366             layer, region, aspect, angle_option, theta_phi_kappa,
 
 1367             distributions.beta_distribution, distributions.distr
 
 1371             distributions.lognormal_dist, distributions.tpl_dist,
 
 1372             distributions.exponential_dist, distributions.constant_dist
 
 1375         checkLast = [disable_fram, aperture, permeability]
 
 1377         for paramFunc 
in firstPriority:
 
 1381             for paramFunc 
in generalized:
 
 1386             for paramFunc 
in generalized:
 
 1389         for i, paramFunc 
in enumerate(distribs):
 
 1390             if numEdistribs[i + 1] > 0:
 
 1394             if numRdistribs[i + 1] > 0:
 
 1398         for paramFunc 
in checkLast:
 
 1402         """ Write the parameters from the verbose input file back to a simplified input file. 
 1404         for param 
in params:
 
 1405             if param == 
'layers':
 
 1406                 writer.write(param + 
': ')
 
 1407                 for layer 
in params[
'layers']:
 
 1409                         input_helper_methods.list_to_curly(str(layer)) + 
" ")
 
 1412             elif param == 
'regions':
 
 1413                 writer.write(param + 
': ')
 
 1414                 for region 
in params[
'regions']:
 
 1416                         input_helper_methods.list_to_curly(str(region)) + 
" ")
 
 1419             elif type(input_helper_methods.value_of(param,
 
 1420                                                     writing=
True)) 
is list:
 
 1421                 curl = input_helper_methods.list_to_curly(
 
 1422                     str(input_helper_methods.value_of(param, writing=
True)))
 
 1423                 writer.write(param + 
': ' + curl + 
'\n')
 
 1427                     str(input_helper_methods.value_of(param, writing=
True)) +
 
 1432         if not os.path.exists(os.getcwd()):
 
 1433             print(
"ERROR: cwd: ", os.getcwd(), 
" does not exist")
 
 1434         if not os.path.exists(os.path.abspath(self.dfnGen_file)):
 
 1435             print(
"ERROR: dfnGen input file path: ",
 
 1436                   os.path.abspath(self.dfnGen_file), 
" does not exist")
 
 1437         print(os.path.abspath(self.dfnGen_file))
 
 1438         shutil.copy(os.path.abspath(self.dfnGen_file), os.getcwd())
 
 1440         sys.exit(
"Unable to copy dfnGen input file\n%s\nExiting" %
 
 1443     ioPaths = {
"input": 
"", 
"output": 
""}
 
 1445         ioPaths[
"input"] = self.dfnGen_file
 
 1447         input_helper_methods.error(
"Please provide an input file path as the first command line argument.\n"\
 
 1448               "    $ python3 inputParser.py [inputPath] [outputPath (Optional)]")
 
 1450         ioPaths[
"output"] = self.jobname + 
'/' + self.dfnGen_file.split(
 
 1451             '/')[-1][:-4] + 
'_clean.dat' 
 1452         ioPaths[
"output"] = os.path.abspath(ioPaths[
"output"])
 
 1453         print(ioPaths[
"output"])
 
 1455         ioPaths[
"output"] = 
"polishedOutput.txt" 
 1456         input_helper_methods.warning(
"No output path has been provided so output will be written to "\
 
 1457             "\"polishedOutput.txt\" in your current working directory.", params)
 
 1459         reader = open(ioPaths[
"input"], 
'r')
 
 1461         input_helper_methods.error(
 
 1462             "Check that the path of your input file is valid")
 
 1464         writer = open(ioPaths[
"output"], 
'w')
 
 1466         input_helper_methods.error(
 
 1467             "Check that the path of your output file is valid.")
 
 1469     inputIterator = iter(reader)
 
 1470     print(
'--> Checking input data')
 
 1471     print(
'--> Input Data: ', ioPaths[
"input"])
 
 1472     print(
'--> Output File: ', ioPaths[
"output"])
 
 1477     print(
'--> Checking Input Data Complete')