From d311b829834929d8606ea0d5718fe036a72eb702 Mon Sep 17 00:00:00 2001 From: Joakim Hove Date: Fri, 29 May 2015 11:54:46 +0200 Subject: [PATCH] Added keyword documentation --- docs/keywords.txt | 287 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 242 insertions(+), 45 deletions(-) diff --git a/docs/keywords.txt b/docs/keywords.txt index d8cbd403f..e693eda64 100644 --- a/docs/keywords.txt +++ b/docs/keywords.txt @@ -1,25 +1,39 @@ -NB: Work in progress (25.th of August 2013) - ------------------------------------------------------------------ - -1. ........... The structure of a keyword - 1.1 ........ Records - 1.2 ........ How many records in a keyword - 1.3 ........ The content of a record: items -2. ........... The classes involved - 2.1 ........ Parser / ParserKeyword / ParserRecord / ParserItem - 2.2 ........ RawDeck / RawKeyword / RawRecord - 2.3 ........ Deck / DeckKeyword / DeckRecord / DeckItem -3. ........... Configuring the keywords with Json. - - Keywords is the most important aspect of the ECLIPSE datafile -parser. +parser. 1. The structure of a keyword ----------------------------- -1.1 Records +A keyword is the fundamental unit when parsing. The schema definition +of the keywords are given as Json files under the opm/share/keywords +directory. As part of the build process these keyword definitions are +compiled to ParserKeyword instances. + + +1.1 Starting a keyword +---------------------- +The keywords are defined as follows: + + 1. The keyword should start in column 0; everything beyond character + 8 is ignored. + + 2. The keyword should start with a alphabet character, subsequent + characters should be alphanumeric or in the set [-,_,+]. + + 3. We think ECLIPSE is case insensitive. + +This is cehcked by the static method: +ParserKeyword::validDeckName(). An important part of the parsing of +keywords is to detect when the keyword specification is complete. For +most keywords we can detect that either by a terminating '/' or the +keywords have a predefined size, but for some odd keywords we can not +reliably detect the end-of-keyword condition and instead we terminate +keyword1 when we find a string which corresponds to the start of a new +keyword. Examples of such oddball keywords include: VFPPROD and +VFPINJ. + + +1.2 Records ----------- The data content of a keyword comes as a collection of @@ -43,68 +57,255 @@ From these examples we see that: 3. Each record is terminated with a '/' -1.2 How many records in a keyword +1.3 How many records in a keyword --------------------------------- One of the first structural elements which must be configured into the the parser keywords is the number of records in the different keywords, this is closely related to how the keyboard is -terminated. Here comes three typical examples of keywords: +terminated. Here comes some typical examples of keywords: GRID + WCONHIST ... / ... / ... / / - EQLDIMS + ---\ + EQLDIMS | + .... / | + | + EQUIL | + .... / | + .... / | + ---/ + + VFPPROD + A .. / + B... / + .... / .... / - EQUIL - .... / - .... / + PVGO + / + / + In the list above here the GRID keyword has zero records, i.e. no data at all. The WCONHIST keyword has three records of data, the EQLDIMS -keyword has one record and the EQUIL keyword has two records of -data. When it comes to record size and termination the keywords can be -split in three groups: +keyword has one record, the EQUIL keyword has two records and finally +the VFPPROD keyword has four records. The number of records, or how to +infer it, must be configured with the "size" attribute in the JSON +configuration. When it comes to the number of records and termination +we currently have five different categories: 1. Keywords with a fixed number of records. Both the GRID keyword and the EQLDIMS keyword have a fixed number of records, zero and one respectively. These keywords are therefor not explicitly - terminated in any way. + terminated in any way, and the "size" attribute has the numerical + explicitly: + + {"name" : "EQLDIMS" , "size" : 1 , ....} + {"name" : "GRID" , "size" : 0, .... } + 2. Keywords with a variable number of records like the WCONHIST. Becase the number of records is not known in advance - this keyword must be explicitly terminated with a '/'. + this keyword must be explicitly terminated with a '/'. This is + the most common configuration and for keywords of this type it is + not necessary to specify a size attribute at all: + + {"name" : "WCONHIST" , .... } + 3. Keywords where the number of records is inferred from the content of another keyword; this is the case with EQUIL which reads the number of records from the xxx item of the EQLDIMS keyword. Since the number of records is known in advance (indirectly through the EQLDIMS keyword) the EQUIL keyword is not explicitly terminated - with a '/'. + with a '/'. In the json file this is specified with the "size" + attribute being an object containing the name and item of keyword + which should be consulted to infer the size; so for the EQUIL + keyword the size attribute looks like: -1.3 The content of a record: items + {"name" : "EQUIL" , + "size" : {"keyword" : "EQLDIMS" , "item" : "NTEQUL"} , ... -[ Disclaimer: The initial defintion of a item could be configured to - have a fixed number of elements greater than one, that possibility - has now been removed. However the code, and in particular the - configuration shows this heritage.] - -The different elements in a record are organized in items. An item can -either consist of one single element from the record, or alternatively -all the elements in the record. An item has a name, a data type and -optionally a default value. + When parsing the EQUIL keyword the parser will consult the + already parsed content of the 'EQLDIMS' keyword (i.e. a + DeckKeyword instance) and get the numerical value of the 'NTEQUL' + item. -2. The classes involved ------------------------ + 4. For some keywords the number of records should be calculated + run-time based based on the content of the first records in the + keyword - this at least applies to VFPPROD and VFPINJ. Since the + size of the keyword is deterministic - given the first few + records - the keyword is not slash terminated. + + To infer the number of records in the keyword based on an + internal calculation is not supported, hence for these keywords + size is given as unkown, and the keywords are terminated when the + next valid keyword is found: + + {"name" : "VFPPROD" , "size" : "UNKNOWN", .... + + + + 5. Tables PVTG and PVTO: The two tables PVTG and PVTO are special + cased. The special casing should probably be removed, and the + "size" : "UNKNOWN" could be used for these two keyword. + + + + +1.4 The content of a record: items +---------------------------------- + +A record consist of one or several items. An item can consist of one +or several values from the record, for items with more than one value +it is not possible to specify the exact number of values - the item +will just consume the remaining values in the input stream. An item +has a name, a data type and optionally a default value. For instance +the WCONHIST keyword has the the following items specification: + + "items": + [{"name" : "WELL" , "value_type" : "STRING"}, + {"name" : "STATUS" , "value_type" : "STRING" , "default" : "OPEN"}, + {"name" : "CMODE" , "value_type" : "STRING"}, + {"name" : "ORAT" , "value_type" : "DOUBLE", "default" : 0.0, "dimension" : "LiquidSurfaceVolume/Time"}, + {"name" : "WRAT" , "value_type" : "DOUBLE" , "default" : 0.0, "dimension" : "LiquidSurfaceVolume/Time"}, + {"name" : "GRAT" , "value_type" : "DOUBLE" , "default" : 0.0, "dimension" : "GasSurfaceVolume/Time"}, + {"name" : "VFPTable" , "value_type" : "INT" , "default" : 0.0 , "comment":"The default is a state variable"}, + {"name" : "Lift" , "value_type" : "DOUBLE" , "default" : 0.0 , "comment":"The default is a state variable"}, + {"name" : "THP" , "value_type" : "DOUBLE" , "default" : 0.0 , "dimension" : "Pressure"}, + {"name" : "BHP" , "value_type" : "DOUBLE" , "default" : 0.0 ,"dimension" : "Pressure"}, + {"name" : "NGLRAT" , "value_type" : "DOUBLE" , "default" : 0.0 ,"dimension" : "LiquidSurfaceVolume/Time"}]} + +Here we can see the following: + + 1. The items can be of types string, integer and float, the type is + specified with the "value_type" attribute which must equal + "STRING", "DOUBLE" or "INT". + + 2. You can optionally specify a default value, see the discussion of + the parsing workflow below for the treatment of defaults. + + 3. For items of type double you can specify a dimension, see XXXX for + the available dimensions. For quantities with a dimension the + parser will convert to SI units, and the DeckDoubleItem class has + a getSIDouble() and getRawDouble() method. + + +Items consuming the rest of the record +-------------------------------------- + +Most of the items will consume exactly one value from the input deck, +but it is also possible that the last item consumes the remaining +items in the input deck, these typically correspond to table keywords +or lists of memnonics. In the input deck the PVTG keyword will +typically appear like this: + +PVTG +200 0.15 0.15 10 + 0.20 0.20 12 + 0.25 0.20 15 / +250 0.05 0.05 20 + 0.15 0.10 40 / +... + +In the manual this is described as two tables with three columns, one +with three rows and one with two rows. The leading values of 200 and +250 are the pressure values where the two tables apply. The visual +formatting in the deck, and also the written desciption in the manual, +strongly hints at a table structure - however from a parsing point of +view this corresponds to just two records of different length. Both +records start with a pressure value, and then follows 3n consecutive +values. The item configuration of PVTG looks like this: + + "items" : [ + {"name":"GAS_PRESSURE", "value_type" : "DOUBLE", "dimension":"Pressure" }, + {"name":"DATA", "size_type" : "ALL" , "value_type":"DOUBLE" , + "dimension" : ["OilDissolutionFactor","OilDissolutionFactor","Viscosity"]} + ] + +I.e. first we consume one value from the input deck and assign it to +the GAS_PRESSURE item, then the DATA item has "size_type" : "ALL" - +meaning that this item will consume the the rest of the values in the +input record. Also observe that for the "DATA" item the dimension is a +vector of three elements, when converting to SI the dimension applied +to element i is given as: + + dim[i] = dimension[i % 3] + +In addition to tables the grid property keywords use items which +consume the rest of the record. For instance the PORO keyword will +typcially look like this in the input deck: + +PORO +0.14 0.15 0.0 0.10 +0.16 0.25 0.1 0.11 +0.14 0.15 0.0 0.09 +... +0.21 0.07 0.1 0.13 +/ + +From a parsing point of view this is one single record; which contains +one item consuming all of the values in the input deck. In the +configuration this could have been configured as: + + "items" : [{"name" : "DATA", + "value_type" : "DOUBLE" , + "size_type" : "ALL" , + "default" : 0 , + "dimension" : "1"}] + +However, since keywords containing large data arrays, like e.g. COORD +and PERMX are quite common a shortcut has been created for such +keywords, for instance the PORO keyword is configures as: + + {"name" : "PORO" , "sections" : ["GRID"], + "data" : {"value_type" : "DOUBLE" , "default" : 0 , "dimension":"1"}} + +i.e. the "data" attribute is used as shorthand to configure a keyword +with one record and one item which consumes all the data of the input +deck. + + +Multirecord keyword configuration +--------------------------------- + + +Units and dimensions +-------------------- + +The values given in the input dataset are generally dimensionfull, and +before the simulator can start we must convert to internal SI values +based on the unit system used in the input deck. In the input deck the +different physical quantities are generally expressed with +per-quantity units. The unit system is *not* based on selecting a unit +for the fundamental dimensions length, mass and time and then deriving +composite units based on the dimension of the composite quantity. As a +consequence the list of dimensions supported by the parser is long, +and growing. The current list can be found in the source file: + + opm/parser/eclipse/Units/UnitSystem.cpp + + + +Default values +-------------- + + + + +Classes: +-------- The library contains classes along two dimensions: @@ -130,7 +331,3 @@ The library contains classes along two dimensions: - -3. Configuring a parser keyword -------------------------------- -